package com.gh.common.util; import android.app.Activity; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.media.ThumbnailUtils; import android.os.Bundle; import android.text.TextUtils; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.RelativeLayout; import android.widget.TextView; import com.facebook.common.references.CloseableReference; import com.facebook.datasource.DataSource; import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber; import com.facebook.imagepipeline.image.CloseableImage; import com.gh.common.constant.Config; import com.gh.gamecenter.R; import com.gh.gamecenter.WeiBoShareActivity; import com.gh.gamecenter.eventbus.EBShare; import com.lightgame.utils.Utils; import com.sina.weibo.sdk.WbSdk; import com.sina.weibo.sdk.auth.AuthInfo; import com.tencent.connect.share.QQShare; import com.tencent.connect.share.QzoneShare; import com.tencent.mm.opensdk.modelmsg.SendMessageToWX; import com.tencent.mm.opensdk.modelmsg.WXMediaMessage; import com.tencent.mm.opensdk.modelmsg.WXWebpageObject; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; import com.tencent.tauth.IUiListener; import com.tencent.tauth.Tencent; import com.tencent.tauth.UiError; import org.greenrobot.eventbus.EventBus; import java.io.ByteArrayOutputStream; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import static com.gh.common.util.LoginHelper.WEIBO_SCOPE; /** * Created by khy on 2016/9/4. */ public class ShareUtils { private static ShareUtils sInstance; private IWXAPI mIWXAPI; private Tencent mTencent; private String shareUrl; private String shareIcon; private String mTitle; private String mSummary; private int[] arrLogo = { R.drawable.share_wechat_logo, R.drawable.share_wechatmoments_logo, R.drawable.share_qq_logo, R.drawable.share_qzone_logo, R.drawable.share_sinaweibo_logo, R.drawable.share_shortmessage_logo, R.drawable.share_copyfont_logo, R.drawable.share_cancel_logo }; public enum ShareType { news, game, // 普通游戏 plugin, // 插件游戏 tools, askInvite, askNormal, // 问答问题/答案 shareGh, communityArticle, video } private String[] arrLabel = {"微信好友", "朋友圈", "QQ好友", "QQ空间", "新浪微博", "短信", "复制链接", "取消"}; private PopupWindow popupWindow; private ShareType mShareType; public static ShareType shareType;//全局保存shareType,分享成功后判断分享的类型 private WeakReference mActivity; private Context mContext; // application context //QQ或者QQ空间分享回调处理 public IUiListener QqShareListener = new IUiListener() { @Override public void onComplete(Object o) { Utils.toast(mContext, R.string.share_success_hint); EventBus.getDefault().post(new EBShare(ShareUtils.shareType)); } @Override public void onError(UiError uiError) { Utils.toast(mContext, R.string.share_fail_hint); } @Override public void onCancel() { Utils.toast(mContext, R.string.share_cancel_hint); } }; private ShareUtils(Context context) { mTencent = Tencent.createInstance(Config.TENCENT_APPID, context); //初始化QQ分享 mIWXAPI = WXAPIFactory.createWXAPI(context, Config.WECHAT_APPID); //初始化微信分享 WbSdk.install(context, new AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE)); mContext = context.getApplicationContext(); } public static ShareUtils getInstance(Context context) { if (sInstance == null) { sInstance = new ShareUtils(context); } return sInstance; } //检查是否安装手机QQ public static boolean isQQClientAvailable(Context context) { final PackageManager packageManager = context.getPackageManager(); List pinfo = packageManager.getInstalledPackages(0); if (pinfo != null) { for (int i = 0; i < pinfo.size(); i++) { String pn = pinfo.get(i).packageName; if ("com.tencent.mobileqq".equals(pn) || "com.tencent.tim".equals(pn)) { return true; } } } return false; } public void showShareWindowsCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType, ShareCallBack callBack) { if (activity.isFinishing()) return; this.mActivity = new WeakReference<>(activity); this.shareIcon = icon; this.shareUrl = url; this.mSummary = shareSummary; this.mTitle = shareTitle; this.mShareType = shareType; ShareUtils.shareType = mShareType; View contentView = View.inflate(activity, R.layout.share_popup_layout, null); contentView.setFocusable(true); contentView.setFocusableInTouchMode(true); RecyclerView shareRecyclerView = contentView.findViewById(R.id.share_rv); shareRecyclerView.setPadding(DisplayUtils.dip2px(mContext, 20), DisplayUtils.dip2px(mContext, 10), DisplayUtils.dip2px(mContext, 20), 0); //RecyclerView禁止滑动 GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, 4) { @Override public boolean canScrollVertically() { return false; } }; shareRecyclerView.setLayoutManager(gridLayoutManager); ShareRecyclerViewAdapter shareRecyclerViewAdapter = new ShareRecyclerViewAdapter(); shareRecyclerView.setAdapter(shareRecyclerViewAdapter); shareRecyclerViewAdapter.setOnItemClickListener(position -> { if (callBack != null) { if (position == arrLabel.length - 1) { callBack.onCancel(); } else { callBack.onSuccess(arrLabel[position]); } } }); if (mShareType == ShareType.shareGh) { RelativeLayout layout = (RelativeLayout) view; layout.addView(contentView); arrLabel[6] = "邮件"; arrLogo[6] = R.drawable.share_email_logo; arrLabel[7] = "复制链接"; arrLogo[7] = R.drawable.share_copyfont_logo; return; } else { arrLabel[6] = "复制链接"; arrLogo[6] = R.drawable.share_copyfont_logo; arrLabel[7] = "取消"; arrLogo[7] = R.drawable.share_cancel_logo; } popupWindow = new SharePopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT , LinearLayout.LayoutParams.MATCH_PARENT, true); popupWindow.setAnimationStyle(R.style.popwindow_exit_only_anim_style); //解决PopupWindow无法覆盖状态栏 popupWindow.setClippingEnabled(false); int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity); if (!DisplayUtils.isNavigationBarShow(activity)) { bottomLocation = 0; } try { popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation); } catch (Exception e) { e.printStackTrace(); } contentView.setOnClickListener(v -> popupWindow.dismiss()); contentView.setOnKeyListener((v, keyCode, event) -> { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && popupWindow != null && popupWindow.isShowing()) { if (callBack != null) { callBack.onCancel(); } popupWindow.dismiss(); } return false; }); } public void showShareWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareType shareType) { showShareWindowsCallback(activity, view, url, icon, shareTitle, shareSummary, shareType, null); } //QQ分享 private void qqShare() { Utils.toast(mContext, R.string.share_skip); Bundle params = new Bundle(); switch (mShareType) { case plugin: mSummary += "(光环加速版)"; break; case askNormal: case video: case communityArticle: mTitle += " - 光环助手"; break; } params.putString(QQShare.SHARE_TO_QQ_TITLE, mTitle); params.putString(QQShare.SHARE_TO_QQ_SUMMARY, mSummary); params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT); params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, shareUrl); params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, shareIcon); params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name)); Activity activity = mActivity.get(); if (activity != null) { mTencent.shareToQQ(activity, params, QqShareListener); } if (mShareType != ShareType.shareGh) { popupWindow.dismiss(); } } //微信好友分享 private void wechatShare() { Utils.toast(mContext, R.string.share_skip); if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) { Utils.toast(mContext, "没安装微信,分享失败"); return; } WXWebpageObject webpage = new WXWebpageObject(); WXMediaMessage msg = new WXMediaMessage(webpage); webpage.webpageUrl = shareUrl; switch (mShareType) { case plugin: mSummary += "(光环加速版)"; break; case askNormal: case video: case communityArticle: mTitle += " - 光环助手"; break; } msg.title = mTitle; msg.description = !TextUtils.isEmpty(mSummary) && mSummary.length() > 1024 ? mSummary.substring(0, 1024) : mSummary; SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("webpage"); req.message = msg; req.scene = SendMessageToWX.Req.WXSceneSession; loadBitMap(shareIcon, msg, req); if (mShareType != ShareType.shareGh) { popupWindow.dismiss(); } } private String buildTransaction(final String type) { return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis(); } private void loadBitMap(final String iconUrl, final WXMediaMessage msg, final SendMessageToWX.Req req) { ImageUtils.display(mContext, iconUrl, new BaseBitmapDataSubscriber() { @Override protected void onNewResultImpl(Bitmap bitmap) { if (mShareType == ShareType.video) { // 分享类型为视频时裁为正方形 int dimension = Math.min(bitmap.getWidth(), bitmap.getHeight()); bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension); } Bitmap compressBp = compressBitmap(bitmap); if (mShareType == ShareType.askNormal || mShareType == ShareType.askInvite) { msg.thumbData = ImageUtils.bmpToByteArray(compressBp, true); } else { Bitmap resultBp = addBackGround(compressBp); msg.thumbData = ImageUtils.bmpToByteArray(resultBp, true); } mIWXAPI.sendReq(req); } @Override protected void onFailureImpl(DataSource> dataSource) { Utils.log("分享获取bitmap失败"); } }); } //压缩图片 public static Bitmap compressBitmap(Bitmap bitmap) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); float zoom = (float) Math.sqrt(9 * 1024 / (float) bos.toByteArray().length); Matrix matrix = new Matrix(); matrix.setScale(zoom, zoom); Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); bos.reset(); result.compress(Bitmap.CompressFormat.JPEG, 100, bos); while (bos.toByteArray().length > 9 * 1024) { System.out.println(bos.toByteArray().length); matrix.setScale(0.9f, 0.9f); result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true); bos.reset(); result.compress(Bitmap.CompressFormat.JPEG, 100, bos); } return result; } //添加背景,防止图片格式为PNG的图片分享出现黑框问题 public Bitmap addBackGround(Bitmap result) { Bitmap bgBitmap; int[] colors = new int[result.getWidth() * result.getHeight()]; for (int i = 0; i < colors.length; i++) { colors[i] = Color.WHITE; } bgBitmap = Bitmap.createBitmap(colors, result.getWidth(), result.getHeight(), Bitmap.Config.ARGB_8888); Bitmap newmap = Bitmap .createBitmap(result.getWidth(), result.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(newmap); canvas.drawBitmap(bgBitmap, 0, 0, null); canvas.drawBitmap(result, (result.getHeight() - result.getWidth()) / 2, (result.getHeight() - result.getWidth()) / 2, null); canvas.save(); canvas.restore(); return newmap; } //QQ空间分享 private void qZoneShare() { Utils.toast(mContext, R.string.share_skip); Bundle params = new Bundle(); switch (mShareType) { case plugin: mSummary += "(光环加速版)"; break; case askNormal: case video: case communityArticle: mTitle += " - 光环助手"; break; } ArrayList imageUrls = new ArrayList<>(); imageUrls.add(shareIcon); if (!TextUtils.isEmpty(mSummary)) { params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, mSummary); } params.putString(QzoneShare.SHARE_TO_QQ_TITLE, mTitle); params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_NO_TYPE); params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, shareUrl); params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, imageUrls); params.putString(QzoneShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name)); Activity activity = mActivity.get(); if (activity != null) { mTencent.shareToQzone(activity, params, QqShareListener); } if (mShareType != ShareType.shareGh) { popupWindow.dismiss(); } } //微信朋友圈分享 private void wechatMomentsShare() { Utils.toast(mContext, R.string.share_skip); if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) { Utils.toast(mContext, "没安装微信,分享失败"); return; } WXWebpageObject webpage = new WXWebpageObject(); WXMediaMessage msg = new WXMediaMessage(webpage); webpage.webpageUrl = shareUrl; switch (mShareType) { case plugin: msg.title = mSummary + "(光环加速版)"; break; case game: msg.title = mSummary; break; case askNormal: case video: case communityArticle: msg.title = mTitle + " - 光环助手"; break; default: msg.title = mTitle; break; } SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("webpage"); req.message = msg; req.scene = SendMessageToWX.Req.WXSceneTimeline; loadBitMap(shareIcon, msg, req); if (mShareType != ShareType.shareGh) { popupWindow.dismiss(); } } //新浪微博分享 private void sinaWeiboShare() { Activity activity = mActivity.get(); if (activity != null) { Intent intent = WeiBoShareActivity.getWeiboshareIntent( activity, shareUrl, shareIcon, mTitle, mSummary, mShareType.toString()); activity.startActivity(intent); } if (mShareType != ShareType.shareGh) { popupWindow.dismiss(); } } //短信分享 private void shortMessageShare() { String smsBody; switch (mShareType) { case news: case tools: smsBody = mTitle + shareUrl; break; case plugin: smsBody = mTitle + mSummary + "(光环加速版)" + shareUrl; break; case game: smsBody = mTitle + mSummary + shareUrl; break; case shareGh: smsBody = "这个App可以下载各种热门卡牌手游的加速版,绿色安全,超级省心,做日常效率提高3-5倍!光环助手官网地址:" + shareUrl; break; case askInvite: case askNormal: case video: case communityArticle: smsBody = mTitle + " - 光环助手" + shareUrl; break; default: smsBody = mTitle; break; } try { Intent sendIntent = IntentUtils.getSMSIntent(smsBody); mContext.startActivity(sendIntent); } catch (Exception e) { Utils.toast(mContext, "设备短信服务异常,分享失败"); e.printStackTrace(); } if (mShareType != ShareType.shareGh) { popupWindow.dismiss(); } } //复制文字链接 private void copyLink(String copyContent) { ClipboardManager cmb = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); cmb.setText(copyContent); if (mShareType != ShareType.shareGh) { Utils.toast(mContext, "复制成功"); popupWindow.dismiss(); } else { Utils.toast(mContext, "复制成功,请到微信/QQ粘贴分享"); } } private class ShareRecyclerViewAdapter extends RecyclerView.Adapter { private OnItemClickListener listener; @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.share_popup_item, parent, false); return new ViewHolder(view); } public void setOnItemClickListener(OnItemClickListener listener) { this.listener = listener; } @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.shareLogo.setImageResource(arrLogo[position]); holder.shareLabel.setText(arrLabel[position]); holder.itemView.setOnClickListener(v -> { if (mShareType == ShareUtils.ShareType.shareGh) { MtaHelper.onEvent("我的光环_新", "分享光环", arrLabel[position]); } if (listener != null) { listener.onItemClick(holder.getAdapterPosition()); } switch (holder.getPosition()) { case 0: MtaHelper.onEvent("内容分享", "微信好友", mTitle); wechatShare(); break; case 1: MtaHelper.onEvent("内容分享", "微信朋友圈", mTitle); wechatMomentsShare(); break; case 2: MtaHelper.onEvent("内容分享", "QQ好友", mTitle); qqShare(); break; case 3: MtaHelper.onEvent("内容分享", "QQ空间", mTitle); qZoneShare(); break; case 4: MtaHelper.onEvent("内容分享", "新浪微博", mTitle); sinaWeiboShare(); break; case 5: MtaHelper.onEvent("内容分享", "短信", mTitle); shortMessageShare(); break; case 6: MtaHelper.onEvent("内容分享", "复制链接", mTitle); if (mShareType == ShareType.askInvite) { copyLink(mTitle + " - 光环助手" + shareUrl); } else if (mShareType == ShareType.askNormal) { copyLink(shareUrl); } else if (mShareType != ShareType.shareGh) { copyLink(shareUrl); } else { try { Intent data = IntentUtils.getEmailToGHIntent(); mContext.startActivity(data); } catch (Exception e) { e.printStackTrace(); Utils.toast(mContext, "设备邮件服务异常,分享失败"); } } break; case 7: if (mShareType != ShareType.shareGh) { popupWindow.dismiss(); } else { copyLink("推荐光环助手,绿色安全的手游加速助手:" + shareUrl); } break; } }); } @Override public int getItemCount() { return 8; } public class ViewHolder extends RecyclerView.ViewHolder { LinearLayout linearLayout; TextView shareLabel; ImageView shareLogo; public ViewHolder(View itemView) { super(itemView); linearLayout = (LinearLayout) itemView; shareLogo = (ImageView) linearLayout.getChildAt(0); shareLabel = (TextView) linearLayout.getChildAt(1); } } } interface OnItemClickListener { void onItemClick(int position); } public interface ShareCallBack { void onSuccess(String label); void onCancel(); } private static class SharePopupWindow extends PopupWindow { SharePopupWindow(View contentView, int width, int height, boolean focusable) { super(contentView, width, height, focusable); } @Override public void dismiss() { View backgroundView = getContentView().findViewById(R.id.share_container); if (backgroundView != null) { backgroundView.setBackgroundColor(Color.TRANSPARENT); } getContentView().postDelayed(super::dismiss, 0); } } }