package com.gh.common.util; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.util.Base64; import android.view.Gravity; import android.view.KeyEvent; 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 androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.gh.common.constant.Config; import com.gh.gamecenter.BuildConfig; import com.gh.gamecenter.ImageViewerActivity; import com.gh.gamecenter.R; import com.gh.gamecenter.WeiBoShareActivity; import com.gh.gamecenter.common.utils.BitmapUtils; import com.gh.gamecenter.common.utils.ImageUtils; import com.gh.gamecenter.common.utils.PermissionHelper; import com.gh.gamecenter.common.utils.ShareUtils; import com.gh.gamecenter.core.utils.DisplayUtils; import com.lightgame.utils.Utils; import com.tencent.connect.auth.QQToken; import com.tencent.connect.share.QQShare; import com.tencent.mm.opensdk.modelmsg.SendMessageToWX; import com.tencent.mm.opensdk.modelmsg.WXImageObject; import com.tencent.mm.opensdk.modelmsg.WXMediaMessage; import com.tencent.mm.opensdk.modelmsg.WXTextObject; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; import com.tencent.open.TDialog; import com.tencent.tauth.IUiListener; import com.tencent.tauth.Tencent; import com.tencent.tauth.UiError; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Date; /** * Created by khy on 2016/11/8. */ public class MessageShareUtils { private static MessageShareUtils instance; private final IWXAPI mIWXAPI; private final Tencent mTencent; private WeakReference mActivity; // 用来关闭分享页面 private Context mContext; // application context private PopupWindow mPopupWindow; private Bitmap shareBm; //分享截图 private String picName; private ShareWay shareWay; private boolean isFromInviteFriends = false; private String mWriteBitmapPath; private String[] mArrLabel = {"微信好友", "朋友圈", "QQ好友", "QQ空间", "保存"}; 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_save }; public enum ShareWay { qq("qq"), qqZone("qq空间"), weibo("微博"), wechat("微信"), wechatMoments("朋友圈"); private String name; ShareWay(String name) { this.name = name; } public String getName() { return name; } } //QQ或者QQ空间分享回调处理 public IUiListener QqShareListener = new IUiListener() { @Override public void onComplete(Object o) { Utils.toast(mContext, "分享成功"); if (isFromInviteFriends) { IntegralLogHelper.INSTANCE.logInviteResult("成功", shareWay.getName()); } } @Override public void onError(UiError uiError) { if (isFromInviteFriends) { IntegralLogHelper.INSTANCE.logInviteResult("失败", shareWay.getName()); } // 单分享图片不支持显示未安装弹窗,手动调出 if (mActivity != null) { Activity activity = mActivity.get(); if (activity != null && !ShareUtils.isQQClientAvailable(activity.getApplication())) { new TDialog(activity, "", "http://openmobile.qq.com/oauth2.0/m_jump_by_version", null, new QQToken("")).show(); } else { Utils.toast(mContext, "分享失败"); } } else { Utils.toast(mContext, "分享失败"); } } @Override public void onCancel() { Utils.toast(mContext, R.string.share_cancel_hint); if (isFromInviteFriends) { IntegralLogHelper.INSTANCE.logInviteResult("取消", shareWay.getName()); } } @Override public void onWarning(int i) { } }; // 适配快传成绩单分享 private int contentSize; private int paddTop; private int picSize; private int itemSize; private int gridCount; private int marImg; private int shareType; private MessageShareUtils(Context context) { Tencent.setIsPermissionGranted(true); mContext = context.getApplicationContext(); mTencent = Tencent.createInstance(Config.TENCENT_APPID, mContext); //初始化QQ分享 mIWXAPI = WXAPIFactory.createWXAPI(mContext, Config.WECHAT_APPID); //初始化微信分享 mWriteBitmapPath = getSaveBitmapBasePath(context); } public static MessageShareUtils getInstance(Context context) { if (instance == null) { instance = new MessageShareUtils(context); } return instance; } public Tencent getTencent() { return mTencent; } public void showShareWindows(Activity activity, View view, Bitmap bitmap, String picName, int shareType) { this.shareBm = bitmap; this.picName = picName; this.shareType = shareType; this.mActivity = new WeakReference<>(activity); if (shareType == 2) { contentSize = 75; paddTop = 0; gridCount = 4; picSize = 30; itemSize = 75; marImg = 10; } else { contentSize = 100; paddTop = 10; gridCount = 5; picSize = 43; itemSize = 90; marImg = 13; } RelativeLayout contentView = new RelativeLayout(mContext); contentView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); contentView.setBackgroundColor(0x8c000000); contentView.setFocusable(true); contentView.setFocusableInTouchMode(true); RecyclerView shareRecyclerView = new RecyclerView(mContext); shareRecyclerView.setPadding(DisplayUtils.dip2px(mContext, 10), DisplayUtils.dip2px(mContext, paddTop), DisplayUtils.dip2px(mContext, 10), 0); shareRecyclerView.setBackgroundColor(Color.WHITE); //RecyclerView禁止滑动 GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, gridCount) { @Override public boolean canScrollVertically() { return false; } }; shareRecyclerView.setLayoutManager(gridLayoutManager); shareRecyclerView.setAdapter(new ShareRecyclerViewAdapter()); if (shareType == 0 || shareType == 2) { LinearLayout llBottom = (LinearLayout) view; ViewGroup.LayoutParams layoutParams = llBottom.getLayoutParams(); layoutParams.height = DisplayUtils.dip2px(mContext, contentSize); shareRecyclerView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); llBottom.addView(shareRecyclerView); return; } RelativeLayout.LayoutParams rlParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT , DisplayUtils.dip2px(mContext, 106)); rlParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); contentView.addView(shareRecyclerView, rlParams); mPopupWindow = new PopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT , LinearLayout.LayoutParams.MATCH_PARENT, true); mPopupWindow.setAnimationStyle(R.style.mypopwindow_anim_style); mPopupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0); contentView.setOnClickListener(v -> mPopupWindow.dismiss()); contentView.setOnKeyListener((v, keyCode, event) -> { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && mPopupWindow != null && mPopupWindow.isShowing()) { mPopupWindow.dismiss(); } return false; }); } public void shareInviteFriends(Activity activity, String type) { isFromInviteFriends = true; shareFromWeb(activity, type); } public void shareFromWeb(Activity activity, String type) { this.mActivity = new WeakReference<>(activity); if ("weibo".equals(type)) { shareWay = ShareWay.weibo; weiboShare(); } else { // base64转bitmap byte[] decode = Base64.decode(ImageViewerActivity.base64Image, Base64.DEFAULT); Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length); // 转完后重新置位 ImageViewerActivity.base64Image = ""; this.picName = "shareImgPic.jpg"; this.shareBm = bitmap; // 保存图片 File file = new File(mWriteBitmapPath); if (!file.isDirectory()) { file.delete(); file.mkdirs(); } if (!file.exists()) { file.mkdirs(); } writeBitmap(file.getPath(), picName, bitmap, false); // 分享 switch (type) { case "qq": shareWay = ShareWay.qq; qqShare(); break; case "qq_zone": shareWay = ShareWay.qqZone; qZoneShare(); break; case "wechat": shareWay = ShareWay.wechat; wechatShare(); break; case "wechat_moments": shareWay = ShareWay.wechatMoments; wechatMomentsShare(); break; case "save": String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/"; writeBitmap(savePath, "gh-" + new Date().getTime() + ".jpg", shareBm, true); break; } } } public void shareTextFromWeb(Activity activity, String text, String type) { if ("qq".equals(type)) { Utils.toast(mContext, "分享跳转中..."); if (ShareUtils.isQQClientAvailable(activity)) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, text); intent.setType("text/plain"); intent.setPackage("com.tencent.mobileqq"); intent.setClassName("com.tencent.mobileqq", "com.tencent.mobileqq.activity.JumpActivity"); try { activity.startActivity(intent); } catch (Exception e) { Utils.toast(mContext, "分享失败"); } } else { Utils.toast(mContext, "请安装QQ客户端"); } } else if ("wechat".equals(type)) { Utils.toast(mContext, "分享跳转中..."); if (!mIWXAPI.isWXAppInstalled() && !PermissionHelper.isGetInstalledListPermissionDisabled(mContext)) { Utils.toast(mContext, mContext.getString(R.string.share_no_wechat_hint)); return; } WXTextObject textObj = new WXTextObject(); textObj.text = text; WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = textObj; msg.description = text; SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("text"); req.message = msg; req.scene = SendMessageToWX.Req.WXSceneSession; mIWXAPI.sendReq(req); } } //QQ分享 private void qqShare() { Utils.toast(mContext, "分享跳转中..."); Bundle params = new Bundle(); params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE); params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, mWriteBitmapPath + picName); params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name)); params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_ITEM_HIDE); Activity activity = mActivity.get(); if (activity != null) { mTencent.shareToQQ(activity, params, QqShareListener); } if (mPopupWindow == null) return; mPopupWindow.dismiss(); } //QQ空间分享 private void qZoneShare() { Utils.toast(mContext, "分享跳转中..."); Bundle params = new Bundle(); params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE); params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, mWriteBitmapPath + picName); params.putString(QQShare.SHARE_TO_QQ_APP_NAME, mContext.getString(R.string.app_name)); params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_AUTO_OPEN); Activity activity = mActivity.get(); if (activity != null) { mTencent.shareToQQ(activity, params, QqShareListener); } if (mPopupWindow == null) return; mPopupWindow.dismiss(); } //微信好友分享 private void wechatShare() { Utils.toast(mContext, "分享跳转中..."); if (!mIWXAPI.isWXAppInstalled() && !PermissionHelper.isGetInstalledListPermissionDisabled(mContext)) { Utils.toast(mContext, mContext.getString(R.string.share_no_wechat_hint)); return; } //官方分享 WXImageObject imgObj = new WXImageObject(); imgObj.setImagePath(getWechatImagePath()); WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = imgObj; SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("img"); req.message = msg; req.scene = SendMessageToWX.Req.WXSceneSession; Bitmap compressBp = compressBitmap(shareBm); msg.thumbData = ImageUtils.bmpToByteArray(compressBp, true); mIWXAPI.sendReq(req); // //调用手机系统分享 // try { // mContext.startActivity(IntentUtils.getWechatShareIntent(mContext, picName)); // } catch (Exception e) { // Utils.toast(mContext, "分享失败!请检查是否已安装微信"); // e.printStackTrace(); // } if (mPopupWindow == null) return; mPopupWindow.dismiss(); } //微信朋友圈分享 private void wechatMomentsShare() { Utils.toast(mContext, "分享跳转中..."); if (!mIWXAPI.isWXAppInstalled() && !PermissionHelper.isGetInstalledListPermissionDisabled(mContext)) { Utils.toast(mContext, mContext.getString(R.string.share_no_wechat_hint)); return; } WXImageObject imgObj = new WXImageObject(); imgObj.setImagePath(getWechatImagePath()); WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = imgObj; SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("img"); req.message = msg; req.scene = SendMessageToWX.Req.WXSceneTimeline; Bitmap compressBp = compressBitmap(shareBm); msg.thumbData = ImageUtils.bmpToByteArray(compressBp, true); mIWXAPI.sendReq(req); if (mPopupWindow == null) return; mPopupWindow.dismiss(); } //新浪微博分享 public void weiboShare() { Activity activity = mActivity.get(); if (activity != null) { Intent intent = WeiBoShareActivity.getWeiboImageShareIntent(activity); activity.startActivity(intent); } if (mPopupWindow == null) return; mPopupWindow.dismiss(); } private String buildTransaction(final String type) { return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis(); } //压缩图片 private Bitmap compressBitmap(Bitmap bitmap) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 85, bos); float zoom = (float) Math.sqrt(10 * 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, 85, bos); while (bos.toByteArray().length > 10 * 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, 85, bos); } return result; } //写到存储卡中 public void writeBitmap(String path, String name, Bitmap bitmap, boolean isToast) { File file = new File(path); if (!file.exists()) { file.mkdirs(); } File _file = new File(path, name); if (_file.exists()) { _file.delete(); } FileOutputStream fos = null; try { fos = new FileOutputStream(_file); if (name != null && !"".equals(name)) { int index = name.lastIndexOf("."); if (index != -1 && (index + 1) < name.length()) { String extension = name.substring(index + 1).toLowerCase(); if ("png".equals(extension)) { bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); } else if ("jpg".equals(extension) || "jpeg".equals(extension)) { bitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos); } if (isToast) { Utils.toast(mContext, "图片已保存到/Pictures/ghzhushou/"); //刷新手机图片库 BitmapUtils.refreshImage(mContext, _file); } } } } catch (Exception e) { Utils.log("消息分享异常" + e.toString()); e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Android11需要使用FileProvider方式分享,所以要判断是否能用FileProvider * OpenSDK版本必须大于或等于 5.4.3 版本,微信版本为7.0.13及以上,Android版本7.0及以上 * 微信版本的判断方式:当且仅当通过 IWXAPI.getWXAppSupportAPI() 接口获取到的值 >= 0x27000D00,才能支持FileProvider的方式进行分享 */ private String getWechatImagePath() { String path = mWriteBitmapPath + picName; if (mIWXAPI.getWXAppSupportAPI() >= 0x27000D00 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID, new File(mWriteBitmapPath + picName)); // 授权给微信访问路径 mContext.grantUriPermission("com.tencent.mm", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); path = uri.toString(); } return path; } // 获取保存图片通用路径 public static String getSaveBitmapBasePath(Context context) { String path; // 安卓11无法访问Android/data目录 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/ShareImg/"; } else { path = context.getExternalCacheDir().getPath() + "/ShareImg/"; } return path; } class ShareRecyclerViewAdapter extends RecyclerView.Adapter { @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LinearLayout linearLayout = new LinearLayout(mContext); linearLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(mContext, itemSize))); linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setGravity(Gravity.CENTER_HORIZONTAL); linearLayout.setBackgroundResource(R.drawable.cardview_item_style); ImageView shareLogo = new ImageView(mContext); LinearLayout.LayoutParams logoParams = new LinearLayout.LayoutParams(DisplayUtils.dip2px(mContext, picSize), DisplayUtils.dip2px(mContext, picSize)); logoParams.setMargins(0, DisplayUtils.dip2px(mContext, 10), 0, 0); shareLogo.setLayoutParams(logoParams); TextView shareLabel = new TextView(mContext); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(0, DisplayUtils.dip2px(mContext, 10), 0, 0); shareLabel.setLayoutParams(layoutParams); shareLabel.setGravity(Gravity.CENTER); shareLabel.setTextColor(ContextCompat.getColor(mContext, R.color.text_3a3a3a)); shareLabel.setTextSize(marImg); linearLayout.addView(shareLogo); linearLayout.addView(shareLabel); return new ViewHolder(linearLayout); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.shareLogo.setImageResource(arrLogo[position]); holder.shareLabel.setText(mArrLabel[position]); holder.itemView.setOnClickListener(v -> { switch (holder.getPosition()) { case 0: wechatShare(); if (shareType != 2) { // activity.finish(); } break; case 1: wechatMomentsShare(); if (shareType != 2) { // activity.finish(); } break; case 2: qqShare(); break; case 3: qZoneShare(); break; case 4: String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/"; writeBitmap(savePath, "gh-" + new Date().getTime() + ".jpg", shareBm, true); if (mPopupWindow == null) return; mPopupWindow.dismiss(); // activity.finish(); break; } }); } @Override public int getItemCount() { return gridCount; } 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); } } } }