diff --git a/app/src/main/java/com/tagmae/tsgame_erwang/DouYinIntentShareHelper.java b/app/src/main/java/com/tagmae/tsgame_erwang/DouYinIntentShareHelper.java index 3a3e0dc..19d781a 100644 --- a/app/src/main/java/com/tagmae/tsgame_erwang/DouYinIntentShareHelper.java +++ b/app/src/main/java/com/tagmae/tsgame_erwang/DouYinIntentShareHelper.java @@ -91,15 +91,12 @@ public class DouYinIntentShareHelper { // } // 根据分享目标类型执行不同的分享操作 - if ("private_message".equals(shareTarget)) { - // 分享到私信 - shareToPrivateMessage(context, douYinIntentShareUtil, type, bean, imagePath); - } else if ("group_chat".equals(shareTarget)) { - // 分享到群聊 - shareToGroupChat(context, douYinIntentShareUtil, type, bean, imagePath); + if (com.tsgame.tsgame_niuniu.util.EnvironmentUtil.isHarmonyOS()) { + // 鸿蒙专属的抖音分享逻辑 + executeHarmonyDouYinShare(context, douYinIntentShareUtil, shareTarget, type, bean, imagePath); } else { - // 默认分享到主页 -// shareToFeed(context, douYinIntentShareUtil, type, bean, imagePath); + // 安卓的抖音分享逻辑 + executeAndroidDouYinShare(context, douYinIntentShareUtil, shareTarget, type, bean, imagePath); } } catch (Exception e) { @@ -108,6 +105,23 @@ public class DouYinIntentShareHelper { } } + private static void executeAndroidDouYinShare(Context context, DouYinIntentShareUtil douYinIntentShareUtil, String shareTarget, String type, sharetypeBean bean, String imagePath) { + if ("private_message".equals(shareTarget)) { + // 分享到私信 + shareToPrivateMessage(context, douYinIntentShareUtil, type, bean, imagePath); + } else if ("group_chat".equals(shareTarget)) { + // 分享到群聊 + shareToGroupChat(context, douYinIntentShareUtil, type, bean, imagePath); + } else { + // 默认分享到主页 +// shareToFeed(context, douYinIntentShareUtil, type, bean, imagePath); + } + } + + private static void executeHarmonyDouYinShare(Context context, DouYinIntentShareUtil douYinIntentShareUtil, String shareTarget, String type, sharetypeBean bean, String imagePath) { + // 当前默认调用通用的抖音分享,如需针对卓易通做鸿蒙定制分享可在此处扩展 + executeAndroidDouYinShare(context, douYinIntentShareUtil, shareTarget, type, bean, imagePath); + } /** * 分享到抖音私信 @@ -634,12 +648,6 @@ public class DouYinIntentShareHelper { */ public static void shareImageDirectToPrivateMessage(Activity activity, Bitmap bitmap) { try { - // 检查抖音是否已安装 - HarmonyOS兼容性修改:移除强制检查 - // if (!isAppInstalled(activity, "com.ss.android.ugc.aweme")) { - // Toast.makeText(activity, "抖音未安装,无法分享", Toast.LENGTH_SHORT).show(); - // return; - // } - // 保存bitmap到文件 File cacheDir = activity.getExternalCacheDir(); if (cacheDir == null) { @@ -652,13 +660,18 @@ public class DouYinIntentShareHelper { fos.flush(); fos.close(); - // 获取图片URI - Uri imageUri = FileProviderUtil.getUriForFile(activity, imageFile); - if (imageUri != null) { - // 创建专门用于私信分享的Intent - shareImageToPrivateMessageIntent(activity, imageUri); + if (!com.tsgame.tsgame_niuniu.util.EnvironmentUtil.isHarmonyOS()) { + // 安卓环境:直接使用Util的shareImageToDouyin(与ref一致,Intent+setPackage拉起抖音) + DouYinIntentShareUtil util = DouYinIntentShareUtil.getInstance(activity); + util.shareImageToDouyin(activity, imageFile.getAbsolutePath()); } else { - Toast.makeText(activity, "获取图片文件失败", Toast.LENGTH_SHORT).show(); + // 鸿蒙/卓易通环境:使用剪贴板+引导弹窗 + Uri imageUri = FileProviderUtil.getUriForFile(activity, imageFile); + if (imageUri != null) { + shareImageToPrivateMessageIntent(activity, imageUri); + } else { + Toast.makeText(activity, "获取图片文件失败", Toast.LENGTH_SHORT).show(); + } } } catch (Exception e) { @@ -673,8 +686,8 @@ public class DouYinIntentShareHelper { * @param imageUri 图片Uri */ /** - * 使用剪贴板 + 弹窗引导的方式进行图片分享 - * 不再使用系统分享Intent,因为在鸿蒙/卓易通上兼容性问题较多 + * 鸿蒙/卓易通环境:使用剪贴板 + 弹窗引导的方式进行图片分享 + * 安卓环境应通过shareImageDirectToPrivateMessage直接调用Util的shareImageToDouyin */ private static void shareImageToPrivateMessageIntent(Activity activity, Uri imageUri) { try { diff --git a/app/src/main/java/com/tagmae/tsgame_erwang/NewwebviewActivity.java b/app/src/main/java/com/tagmae/tsgame_erwang/NewwebviewActivity.java index 7f054ab..bd5d76d 100644 --- a/app/src/main/java/com/tagmae/tsgame_erwang/NewwebviewActivity.java +++ b/app/src/main/java/com/tagmae/tsgame_erwang/NewwebviewActivity.java @@ -2279,22 +2279,8 @@ public class NewwebviewActivity extends AppCompatActivity implements sharetypeBean currentShareData = gson.fromJson(data, sharetypeBean.class); String scene = currentShareData.getSharefriend(); if (scene.equals("2")){ - //朋友圈分享 - - //第一步:必须注册回调 handler 给 WXEntryActivity - apputil.wxtype = 1; - Wxistrue.sharetype = 2; - WXEntryActivity.setshareHandler(handler); - - //第二步:调用隔离好的原生SDK方法发请求 - String type = currentShareData.getType() == null ? "" : currentShareData.getType(); - final int sceneType = com.tencent.mm.opensdk.modelmsg.SendMessageToWX.Req.WXSceneTimeline; - - // 网页分享 - com.tsgame.tsgame_niuniu.util.WeChatOfficialShareUtil.getInstance(NewwebviewActivity.this) - .shareWebPage(NewwebviewActivity.this, currentShareData.getWebpageUrl(), currentShareData.getTitle(), currentShareData.getDescription(), sceneType); - - + //朋友圈分享: 抛弃 SDK,走重构后的无SDK统一流 + com.tagmae.tsgame_erwang.WeChatShareHelper.doWeChatShare(NewwebviewActivity.this, data); }else if (scene.equals("1")){ //好友分享 @@ -3488,13 +3474,7 @@ public class NewwebviewActivity extends AppCompatActivity implements if (bean.getType().equals("1")) { - com.jx.jyhd.simcpux.util.WeChatShareUtil.getInstance(this).shareWebPage( - this, - bean.getWebpageUrl(), - bean.getTitle(), - bean.getDescription(), - com.tsgame.tsgame_niuniu.util.WeChatIntentShareUtil.SCENE_FRIENDS - ); + WeChatShareHelper.doWeChatShare(this, new Gson().toJson(bean), false); } else if (bean.getType().equals("2")) { @@ -3611,69 +3591,12 @@ public class NewwebviewActivity extends AppCompatActivity implements } private void photosharefriend() { - // 使用新的微信分享辅助类替换原有的直接API调用 + // 废弃原先的 API 调用 apputil.wxtype = 1; Wxistrue.sharetype = 2; - - // 获取微信分享工具实例 - WeChatShareUtil weChatShareUtil = WeChatShareUtil.getInstance(this); - - // 设置分享回调 - weChatShareUtil.setShareCallback(new WeChatShareUtil.WeChatShareCallback() { - @Override - public void onSuccess() { - // 分享成功后的处理逻辑保持不变 - runOnUiThread(() -> { - // 可以添加成功提示或其他逻辑 - }); - } - @Override - public void onError(int code, String message) { - // 分享失败后的处理逻辑 - runOnUiThread(() -> { - // 可以添加失败提示或其他逻辑 - }); - } - - @Override - public void onCancel() { - // 分享取消后的处理逻辑 - runOnUiThread(() -> { - // 可以添加取消提示或其他逻辑 - }); - } - }); - - // 使用getCanvasBase64FromWebView获取Canvas内容并分享 - WebViewScreenshotUtil.getCanvasBase64FromWebView(x5webview,null, new WebViewScreenshotUtil.CanvasToBase64Callback() { @Override - public void onSuccess(String base64Data) { - // getCanvasBase64FromWebView直接返回base64数据,不需要复杂的JSON解析 - try { - if (base64Data != null && !base64Data.isEmpty()) { - - - // 直接使用获取到的base64数据分享 - weChatShareUtil.shareImage(NewwebviewActivity.this, base64Data, 0); - } else { - - // 回退到原来的方法 - weChatShareUtil.shareImage(NewwebviewActivity.this, bitmappath, 0); - } - } catch (Exception e) { - - // 异常时回退到原来的方法 - weChatShareUtil.shareImage(NewwebviewActivity.this, bitmappath, 0); - } - } - - @Override - public void onError(String error) { -// Toast.makeText(NewwebviewActivity.this, "截图失败成功"+error, Toast.LENGTH_SHORT).show(); - // Canvas获取失败,回退到原来的方法 - weChatShareUtil.shareImage(NewwebviewActivity.this, bitmappath, 0); - } - }); + // 组装bean并调用新的脱机Helper逻辑 + WeChatShareHelper.doWeChatShare(this, new Gson().toJson(bean), true); } protected void sharefriends() { @@ -3683,13 +3606,7 @@ public class NewwebviewActivity extends AppCompatActivity implements if (bean.getType().equals("1")) { System.out.println("hhhhhhh"); - com.jx.jyhd.simcpux.util.WeChatShareUtil.getInstance(this).shareWebPage( - this, - bean.getWebpageUrl(), - bean.getTitle(), - bean.getDescription(), - com.tsgame.tsgame_niuniu.util.WeChatIntentShareUtil.SCENE_MOMENTS - ); + WeChatShareHelper.doWeChatShare(this, new Gson().toJson(bean), false); } else if (bean.getType().equals("2")) { photosharefriends(); @@ -3698,42 +3615,11 @@ public class NewwebviewActivity extends AppCompatActivity implements } private void photosharefriends() { - // 使用新的微信分享辅助类替换原有的直接API调用 + // 废弃原先的 API 调用 apputil.wxtype = 1; Wxistrue.sharetype = 2; - // 获取微信分享工具实例 - WeChatShareUtil weChatShareUtil = WeChatShareUtil.getInstance(this); - - // 设置分享回调 - weChatShareUtil.setShareCallback(new WeChatShareUtil.WeChatShareCallback() { - @Override - public void onSuccess() { - // 分享成功后的处理逻辑保持不变 - runOnUiThread(() -> { - // 可以添加成功提示或其他逻辑 - }); - } - - @Override - public void onError(int code, String message) { - // 分享失败后的处理逻辑 - runOnUiThread(() -> { - // 可以添加失败提示或其他逻辑 - }); - } - - @Override - public void onCancel() { - // 分享取消后的处理逻辑 - runOnUiThread(() -> { - // 可以添加取消提示或其他逻辑 - }); - } - }); - - // 使用新的分享方法分享图片到微信朋友圈(scene = 1) - weChatShareUtil.shareImage(this, bitmappath, 1); + WeChatShareHelper.doWeChatShare(this, new Gson().toJson(bean), true); System.out.println(bitmappath); } diff --git a/app/src/main/java/com/tagmae/tsgame_erwang/QQIntentShareHelper.java b/app/src/main/java/com/tagmae/tsgame_erwang/QQIntentShareHelper.java index 627a25b..e12a9da 100644 --- a/app/src/main/java/com/tagmae/tsgame_erwang/QQIntentShareHelper.java +++ b/app/src/main/java/com/tagmae/tsgame_erwang/QQIntentShareHelper.java @@ -48,7 +48,17 @@ public class QQIntentShareHelper { // 显示开始分享提示 //Toast.makeText(context, "正在分享到QQ", Toast.LENGTH_SHORT).show(); - shareToQQ(context, qqIntentShareUtil, type, bean); + + if (com.tsgame.tsgame_niuniu.util.EnvironmentUtil.isHarmonyOS()) { + // 鸿蒙环境下的QQ分享逻辑 + Toast.makeText(context, "isHarmonyOS", Toast.LENGTH_SHORT).show(); + shareToQQHarmony(context, qqIntentShareUtil, type, bean); + } else { + // 安卓环境下的QQ分享逻辑 + Toast.makeText(context, "isAndroid", Toast.LENGTH_SHORT).show(); + shareToQQ(context, qqIntentShareUtil, type, bean); + } + // 根据目标平台执行不同的分享操作 // if ("2".equals(scene)) { // // 分享到QQ空间 @@ -148,6 +158,73 @@ public class QQIntentShareHelper { } } + /** + * 鸿蒙环境下的QQ分享处理逻辑 + */ + private static void shareToQQHarmony(Context context, QQIntentShareUtil qqIntentShareUtil, String type, sharetypeBean bean) { + + ((Activity) context).runOnUiThread(() -> Toast.makeText(context, "shareToQQHarmony", Toast.LENGTH_SHORT).show()); + // 设置分享回调 + qqIntentShareUtil.setShareCallback(new QQIntentShareUtil.QQShareCallback() { + @Override + public void onSuccess() {} + + @Override + public void onError(int code, String msg) {} + + @Override + public void onCancel() {} + }); + + // 鸿蒙环境:直接调用 QQIntentShareUtil 内部封装的 _Harmony 方法 + if ("1".equals(type)) { + // 纯文本分享 + StringBuilder sb = new StringBuilder(); + String title = bean.getTitle(); + String description = bean.getDescription(); + if (!TextUtils.isEmpty(bean.getTitle())) { + sb.append(title).append("\n\n"); + } + if (!TextUtils.isEmpty(description)) { + sb.append(description).append("\n\n"); + } + String text = sb.toString().trim(); + + + // 因为 `shareTextToQQ` 内部已经通过 `EnvironmentUtil.isHarmonyOS()` 实现了分发! + qqIntentShareUtil.shareTextToQQ((Activity) context, text); + + } else if ("2".equals(type)) { + // 图片分享 - 使用Canvas截图 + GlobalWebViewHelper.getCanvasBase64(new WebViewScreenshotUtil.CanvasToBase64Callback() { + @Override + public void onSuccess(String canvasBase64) { + // 使用Canvas截图的base64数据 + Bitmap bitmap = Base64ImageUtil.base64ToBitmap(canvasBase64); + // 同样,shareBitmapToQQ -> shareImageToQQ 内部也做了 isHarmonyOS() 分发 + qqIntentShareUtil.shareBitmapToQQ((Activity) context, bitmap, false); + bitmap.recycle(); + } + + @Override + public void onError(String error) { + // 截图失败回调 + } + }); + } else { + // 网页链接分享 + // shareWebPageToQQ 内部最后调用的是 shareTextToQQ,同样具备 Harmony 分发能力 + qqIntentShareUtil.shareWebPageToQQ( + (Activity) context, + bean.getTitle(), + bean.getDescription(), + "", + "", + false + ); + } + } + /** * 分享到QQ空间 */ diff --git a/app/src/main/java/com/tagmae/tsgame_erwang/SharePanelHelper.java b/app/src/main/java/com/tagmae/tsgame_erwang/SharePanelHelper.java index d245d44..06ed863 100644 --- a/app/src/main/java/com/tagmae/tsgame_erwang/SharePanelHelper.java +++ b/app/src/main/java/com/tagmae/tsgame_erwang/SharePanelHelper.java @@ -160,7 +160,8 @@ public class SharePanelHelper { @Override public void onClick(View v) { if (currentShareData != null) { - // 调用微信分享 + // 调用微信分享 (已脱离微信SDK) + WeChatShareHelper.doWeChatShare(activity, new Gson().toJson(currentShareData)); Toast.makeText(activity, "微信分享", Toast.LENGTH_SHORT).show(); hideSharePanel(activity); } diff --git a/app/src/main/java/com/tagmae/tsgame_erwang/WeChatShareHelper.java b/app/src/main/java/com/tagmae/tsgame_erwang/WeChatShareHelper.java index 30581de..3be4e09 100644 --- a/app/src/main/java/com/tagmae/tsgame_erwang/WeChatShareHelper.java +++ b/app/src/main/java/com/tagmae/tsgame_erwang/WeChatShareHelper.java @@ -2,34 +2,20 @@ package com.tagmae.tsgame_erwang; import android.app.Activity; import android.content.Context; -import android.graphics.Bitmap; -import android.os.Bundle; -import android.os.Environment; -import android.os.Message; import android.widget.Toast; -import com.android.volley.VolleyError; -import com.android.volley.toolbox.ImageRequest; -import com.game.webgame.network.volleymanager; import com.google.gson.Gson; -import com.jx.jyhd.simcpux.Util; -import com.jx.jyhd.simcpux.Wxistrue; -import com.jx.jyhd.simcpux.util.WeChatShareUtil; import com.tsgame.tsgame_niuniu.simcpux.bean.sharetypeBean; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.security.InvalidParameterException; +import com.tsgame.tsgame_niuniu.util.WeChatIntentShareUtil; +import com.tsgame.tsgame_niuniu.util.EnvironmentUtil; /** - * 微信分享辅助类 + * 微信分享辅助类(已脱离微信SDK重构版) */ public class WeChatShareHelper { - private static String bitmappath; /** - * 微信分享 + /** + * 微信分享(默认无Canvas) * * @param context 上下文 * @param jsonData 分享数据JSON字符串 @@ -37,12 +23,12 @@ public class WeChatShareHelper { public static void doWeChatShare(Context context, String jsonData) { doWeChatShare(context, jsonData, false); } - + /** * 微信分享(支持Canvas截图) * - * @param context 上下文 - * @param jsonData 分享数据JSON字符串 + * @param context 上下文 + * @param jsonData 分享数据JSON字符串 * @param useCanvas 是否使用Canvas截图(仅对图片分享type=2有效) */ public static void doWeChatShare(Context context, String jsonData, boolean useCanvas) { @@ -51,98 +37,131 @@ public class WeChatShareHelper { Gson gson = new Gson(); sharetypeBean bean = gson.fromJson(jsonData, sharetypeBean.class); - // 初始化微信分享工具 - WeChatShareUtil weChatShareUtil = WeChatShareUtil.getInstance(context); + // 初始化微信纯Intent分享工具 + WeChatIntentShareUtil weChatIntentShareUtil = WeChatIntentShareUtil.getInstance(context); // 检查微信是否已安装 - if (!weChatShareUtil.isWeChatInstalled()) { + if (!weChatIntentShareUtil.isWeChatInstalled()) { Toast.makeText(context, "微信未安装,无法进行微信分享", Toast.LENGTH_SHORT).show(); return; } - // 设置分享回调 - weChatShareUtil.setShareCallback(new WeChatShareUtil.WeChatShareCallback() { - @Override - public void onSuccess() { -// ((Activity) context).runOnUiThread(() -> -// Toast.makeText(context, "微信分享成功", Toast.LENGTH_SHORT).show() -// ); - } - - @Override - public void onError(int code, String message) { -// ((Activity) context).runOnUiThread(() -> -// Toast.makeText(context, "微信分享失败: " + message, Toast.LENGTH_SHORT).show() -// ); - } - - @Override - public void onCancel() { -// ((Activity) context).runOnUiThread(() -> -// Toast.makeText(context, "微信分享已取消", Toast.LENGTH_SHORT).show() -// ); - } - }); - // 处理分享类型字段 if (bean.getType() == null) { bean.setType(""); } - - // 处理分享对象字段(朋友或朋友圈) if (bean.getSharefriend() == null) { bean.setSharefriend(""); } - - // 处理分享类型字段 if (bean.getSharetype() == null) { bean.setSharetype(""); } // 确定分享场景(0:好友, 1:朋友圈) - int scene = bean.getSharefriend().equals("1") ? 0 : 1; // 根据类型进行不同的分享处理 - if (bean.getType().equals("2")) { - // 图片分享 - 使用Canvas截图 - GlobalWebViewHelper.getCanvasBase64(new WebViewScreenshotUtil.CanvasToBase64Callback() { - @Override - public void onSuccess(String canvasBase64) { - // 使用Canvas截图的base64数据 - weChatShareUtil.shareImage( - (Activity) context, - canvasBase64, // Canvas截图的base64数据 - scene - ); - } + int scene = bean.getSharefriend().equals("1") ? WeChatIntentShareUtil.SCENE_FRIENDS + : WeChatIntentShareUtil.SCENE_MOMENTS; + + // 设置分享回调(区分朋友圈和好友场景) + weChatIntentShareUtil.setShareCallback(new WeChatIntentShareUtil.WeChatShareCallback() { + @Override + public void onSuccess() { - @Override - public void onError(String error) { - // Canvas截图失败,回退到原有的图片数据 - // String imagebitmapString = bean.getDescription(); - // weChatShareUtil.shareImage( - // (Activity) context, - // imagebitmapString, // 回退到原有数据 - // scene - // ); + // 如果仅需要通知前端朋友圈分享成功,可以在此处加 if(scene == WeChatIntentShareUtil.SCENE_MOMENTS) 判断 + if (scene == WeChatIntentShareUtil.SCENE_MOMENTS) { + try { + org.json.JSONObject json = new org.json.JSONObject(); + json.put("success", 2); // 2表示成功 1表示失败 + json.put("type", 2); + + System.out.println("---分享成功回调JS: " + json.toString()); + ((Activity) context).runOnUiThread(() -> { + if (NewwebviewActivity.x5webview != null) { + NewwebviewActivity.x5webview.callHandler("sharesuccess", json.toString(), new com.tagmae.jsbridge.CallBackFunction() { + @Override + public void onCallBack(String data) { + //这里也是可以进行js回传的 + } + }); + } + }); + } catch (org.json.JSONException e) { + e.printStackTrace(); + } } - }); - //Toast.makeText(context, "分享图片到微信" + (scene == 0 ? "好友" : "朋友圈"), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onError(int code, String message) { + + } + + @Override + public void onCancel() { + + } + }); + + // 系统环境分流 (鸿蒙 vs 安卓) + if (EnvironmentUtil.isHarmonyOS()) { + executeHarmonyWeChatShare(context, weChatIntentShareUtil, bean, scene); } else { - // 网页分享 - weChatShareUtil.shareWebPage( - (Activity) context, - bean.getWebpageUrl(), // 网页链接 - bean.getTitle(), // 标题 - bean.getDescription(), // 描述 - scene - ); -// Toast.makeText(context, "分享网页到微信" + (scene == 0 ? "好友" : "朋友圈"), Toast.LENGTH_SHORT).show(); + executeAndroidWeChatShare(context, weChatIntentShareUtil, bean, scene); } } catch (Exception e) { e.printStackTrace(); - //Toast.makeText(context, "微信分享异常: " + e.getMessage(), Toast.LENGTH_SHORT).show(); } } + /** + * 执行安卓环境下的微信分享 + */ + private static void executeAndroidWeChatShare(Context context, WeChatIntentShareUtil util, sharetypeBean bean, + int scene) { + if (bean.getType().equals("2") || bean.getType().equals("3")) { + if (scene == WeChatIntentShareUtil.SCENE_MOMENTS) { + // 朋友圈分享:测试网络图片分享 + String testImageUrl = "https://tsgames.daoqi88.cn/image_download/download_cgmj.png"; + util.shareNetworkImage((Activity) context, testImageUrl, scene); + } else { + // 好友分享:原有的 Canvas 截图逻辑 + GlobalWebViewHelper.getCanvasBase64(new WebViewScreenshotUtil.CanvasToBase64Callback() { + @Override + public void onSuccess(String canvasBase64) { + // canvasBase64转为Bitmap + android.graphics.Bitmap bitmap = com.tagmae.tsgame_erwang.utils.Base64ImageUtil + .base64ToBitmap(canvasBase64); + util.shareBitmap((Activity) context, bitmap, scene); + if (bitmap != null) { + bitmap.recycle(); + } + } + @Override + public void onError(String error) { + // 截图失败处理 + } + }); + } + } else { + // 网页或文本分享 + util.shareWebPage( + (Activity) context, + bean.getWebpageUrl(), + bean.getTitle(), + bean.getDescription(), + scene); + } + } + + /** + * 执行鸿蒙环境下的微信分享 + */ + private static void executeHarmonyWeChatShare(Context context, WeChatIntentShareUtil util, sharetypeBean bean, + int scene) { + // 由于已经使用了Intent分享工具,在工具内部也做了一定的鸿蒙兼容 + // 如果鸿蒙需要特殊的URI桥接、或者特殊的应用跳转方式,可以在此处定制鸿蒙代码 + // 目前暂时退化到通用Android方法或保持一致 + executeAndroidWeChatShare(context, util, bean, scene); + } } \ No newline at end of file diff --git a/app/src/main/java/com/tsgame/tsgame_niuniu/util/DouYinIntentShareUtil.java b/app/src/main/java/com/tsgame/tsgame_niuniu/util/DouYinIntentShareUtil.java index ddf96aa..0a61487 100644 --- a/app/src/main/java/com/tsgame/tsgame_niuniu/util/DouYinIntentShareUtil.java +++ b/app/src/main/java/com/tsgame/tsgame_niuniu/util/DouYinIntentShareUtil.java @@ -162,19 +162,119 @@ public class DouYinIntentShareUtil { * @return 是否成功启动 */ private boolean tryLaunchDouyin(Activity activity) { + if (EnvironmentUtil.isHarmonyOS()) { + return tryLaunchDouyin_Harmony(activity); + } else { + return tryLaunchDouyin_Android(activity); + } + } + + /** + * 安卓环境启动抖音 - 完整4+方法尝试(与ref一致) + */ + private boolean tryLaunchDouyin_Android(Activity activity) { + try { + String packageName = getInstalledDouYinPackage(); + Log.d(TAG, "尝试启动抖音,包名: " + packageName); + + // 方法1:使用标准启动方式 + Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName); + if (launchIntent != null) { + launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + activity.startActivity(launchIntent); + Log.d(TAG, "成功使用标准方式启动抖音"); + return true; + } + + // 方法2:使用ACTION_MAIN + CATEGORY_LAUNCHER + try { + Intent mainIntent = new Intent(Intent.ACTION_MAIN); + mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); + mainIntent.setPackage(packageName); + + List resolveInfoList = + activity.getPackageManager().queryIntentActivities(mainIntent, 0); + if (resolveInfoList != null && !resolveInfoList.isEmpty()) { + android.content.pm.ResolveInfo resolveInfo = resolveInfoList.get(0); + String className = resolveInfo.activityInfo.name; + + Intent componentIntent = new Intent(Intent.ACTION_MAIN); + componentIntent.addCategory(Intent.CATEGORY_LAUNCHER); + componentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + componentIntent.setComponent(new ComponentName(packageName, className)); + + activity.startActivity(componentIntent); + Log.d(TAG, "成功使用组件方式启动抖音"); + return true; + } + } catch (Exception e) { + Log.e(TAG, "方法2失败: " + e.getMessage()); + } + + // 方法3:尝试所有可能的抖音URI schemes + String[] schemes = { + "snssdk1128://", + "aweme://", + "douyin://", + "douyinlite://", + "snssdk1128://feed", + "aweme://feed", + "douyin://feed", + "snssdk1128://home/trending", + "douyin://home/trending", + "snssdk1128://post", + "douyin://post" + }; + + for (String scheme : schemes) { + try { + Intent schemeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme)); + schemeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + schemeIntent.setPackage(packageName); + activity.startActivity(schemeIntent); + Log.d(TAG, "成功使用scheme方式启动抖音: " + scheme); + return true; + } catch (Exception e) { + Log.e(TAG, "scheme方式失败 " + scheme + ": " + e.getMessage()); + } + } + + // 方法4:尝试使用系统VIEW处理 + try { + Intent viewIntent = new Intent(Intent.ACTION_VIEW); + viewIntent.setData(Uri.parse("https://www.douyin.com")); + viewIntent.setPackage(packageName); + viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(viewIntent); + Log.d(TAG, "成功使用Web链接方式启动抖音"); + return true; + } catch (Exception e) { + Log.e(TAG, "Web链接方式失败: " + e.getMessage()); + } + + Log.e(TAG, "所有启动抖音的方法均失败"); + return false; + } catch (Exception e) { + Log.e(TAG, "启动抖音过程中发生异常: " + e.getMessage(), e); + return false; + } + } + + /** + * 鸿蒙/卓易通环境启动抖音 - 简化版(绕过包名拦截) + */ + private boolean tryLaunchDouyin_Harmony(Activity activity) { String packageName = "com.ss.android.ugc.aweme"; try { Intent launchIntent = null; - // 方法1: 尝试获取官方启动Intent try { launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName); } catch (Exception e) { // 忽略异常 } - // 方法2: 如果获取不到,尝试构造Intent盲拉 if (launchIntent == null) { launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); @@ -186,7 +286,6 @@ public class DouYinIntentShareUtil { return true; } catch (Exception e) { - // 方法3: 最后的救命稻草 - 纯净版URL Scheme(不设置Package,绕过包名拦截) try { Uri uri = Uri.parse("snssdk1128://"); Intent schemeIntent = new Intent(Intent.ACTION_VIEW, uri); @@ -207,14 +306,67 @@ public class DouYinIntentShareUtil { * @param text 要分享的文本 */ public void shareTextToDouyin(Activity activity, String text) { - // 在鸿蒙卓易通环境下,避免过早报错,尝试强制分享 + if (EnvironmentUtil.isHarmonyOS()) { + shareTextToDouyin_Harmony(activity, text); + } else { + shareTextToDouyin_Android(activity, text); + } + } + + /** + * 安卓环境分享文本 - tryLaunchDouyin + 系统分享选择器(与ref一致) + */ + private void shareTextToDouyin_Android(Activity activity, String text) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + try { + copyToClipboard(activity, text); + + boolean launched = tryLaunchDouyin(activity); + + if (launched) { + Toast.makeText(activity, "已将内容复制到剪贴板,请在抖音中粘贴并分享", Toast.LENGTH_LONG).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return; + } + + // 如果所有方法都失败了,尝试使用系统分享菜单 + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_TEXT, text); + + Intent chooser = Intent.createChooser(shareIntent, "分享到"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从分享列表中选择抖音", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 鸿蒙/卓易通环境分享文本 - 引导弹窗 + */ + private void shareTextToDouyin_Harmony(Activity activity, String text) { boolean isPackageDetected = isDouyinInstalled(); try { - // 复制到剪贴板 copyToClipboard(activity, text); - // 弹出提示框引导用户 activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, false)); } catch (Exception e) { Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e); @@ -228,7 +380,80 @@ public class DouYinIntentShareUtil { * @param localImagePath 本地图片路径 */ public void shareImageToDouyin(Activity activity, String localImagePath) { - // 在鸿蒙卓易通环境下,避免过早报错,尝试强制分享 + if (EnvironmentUtil.isHarmonyOS()) { + shareImageToDouyin_Harmony(activity, localImagePath); + } else { + shareImageToDouyin_Android(activity, localImagePath); + } + } + + /** + * 安卓环境分享图片 - setPackage(不用setClassName)+ chooser fallback(与ref一致) + */ + private void shareImageToDouyin_Android(Activity activity, String localImagePath) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + File imageFile = new File(localImagePath); + if (!imageFile.exists()) { + Toast.makeText(activity, "分享图片不存在", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "图片文件不存在"); + } + return; + } + + try { + String packageName = getInstalledDouYinPackage(); + + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setPackage(packageName); + shareIntent.setType("image/*"); + + Uri imageUri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + imageUri = FileProviderUtil.getUriForFile(activity, imageFile); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + imageUri = Uri.fromFile(imageFile); + } + + shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); + + try { + activity.startActivity(shareIntent); + Log.d(TAG, "已发送分享图片Intent到抖音"); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (android.content.ActivityNotFoundException e) { + Log.e(TAG, "直接分享到抖音失败,尝试使用选择器: " + e.getMessage()); + + Intent chooserIntent = Intent.createChooser(shareIntent.setPackage(null), "分享到抖音"); + activity.startActivity(chooserIntent); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } + } catch (Exception e) { + Log.e(TAG, "分享图片到抖音失败: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 鸿蒙/卓易通环境分享图片 - setClassName + 引导弹窗 + */ + private void shareImageToDouyin_Harmony(Activity activity, String localImagePath) { boolean isPackageDetected = isDouyinInstalled(); File imageFile = new File(localImagePath); @@ -243,72 +468,55 @@ public class DouYinIntentShareUtil { try { String packageName = getInstalledDouYinPackage(); - // 创建分享Intent Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("image/*"); - // 根据Android版本使用不同的Uri方式 Uri imageUri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - // Android 7.0及以上使用FileProvider imageUri = FileProviderUtil.getUriForFile(activity, imageFile); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { - // Android 7.0以下直接使用文件Uri imageUri = Uri.fromFile(imageFile); } shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); - // 鸿蒙/卓易通关键适配Flags shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); shareIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 确保Flags也被设置在Intent上 + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - boolean launched = false; - if (isPackageDetected) { - // 抖音仅支持图片视频直接拉起 - try { - shareIntent.setPackage(packageName); - if ("com.ss.android.ugc.aweme".equals(packageName)) { - shareIntent.setClassName(packageName, "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"); - } - activity.startActivity(shareIntent); - launched = true; - Log.d(TAG, "已发送分享图片Intent到抖音"); - final String successMsg = "已发送分享图片Intent到抖音"; - activity.runOnUiThread(() -> Toast.makeText(activity, successMsg, Toast.LENGTH_SHORT).show()); - } catch (Exception e) { - Log.e(TAG, "直接分享到抖音失败: " + e.getMessage()); - final String failMsg = "直接分享失败: " + e.getMessage(); - activity.runOnUiThread(() -> Toast.makeText(activity, failMsg, Toast.LENGTH_SHORT).show()); - } - } - - if (!launched) { + if (isPackageDetected) { try { - // 废弃系统Chooser,改用自定义引导弹窗 - activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, false)); - launched = true; + shareIntent.setPackage(packageName); + if ("com.ss.android.ugc.aweme".equals(packageName)) { + shareIntent.setClassName(packageName, "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"); + } + activity.startActivity(shareIntent); + launched = true; + Log.d(TAG, "已发送分享图片Intent到抖音"); + } catch (Exception e) { + Log.e(TAG, "直接分享到抖音失败: " + e.getMessage()); + } + } + + if (!launched) { + try { + activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, false)); + launched = true; } catch (Exception e) { Log.e(TAG, "引导弹窗分享失败: " + e.getMessage()); - final String failMsg2 = "引导弹窗失败: " + e.getMessage(); - activity.runOnUiThread(() -> Toast.makeText(activity, failMsg2, Toast.LENGTH_SHORT).show()); } } if (launched) { - // 延迟回调成功 if (mCallback != null) { new Handler(Looper.getMainLooper()).postDelayed(() -> { mCallback.onSuccess(); }, 1000); } - } - // 如果launched为false,前面已经弹出了Toast,这里不再重复提示"请检查抖音是否安装" - // else { ... } + } } catch (Exception e) { Log.e(TAG, "分享图片到抖音失败: " + e.getMessage(), e); @@ -322,7 +530,21 @@ public class DouYinIntentShareUtil { * @param imagePaths 图片路径列表 */ public void shareImagesToDouyin(Activity activity, ArrayList imagePaths) { - // boolean isDouyinInstalled = isDouyinInstalled(); // Relaxed check + if (EnvironmentUtil.isHarmonyOS()) { + shareImagesToDouyin_Harmony(activity, imagePaths); + } else { + shareImagesToDouyin_Android(activity, imagePaths); + } + } + + /** + * 安卓环境分享多图 - setPackage + startShareActivity chooser(与ref一致) + */ + private void shareImagesToDouyin_Android(Activity activity, ArrayList imagePaths) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } if (imagePaths == null || imagePaths.isEmpty()) { Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); @@ -337,13 +559,66 @@ public class DouYinIntentShareUtil { for (String path : imagePaths) { File file = new File(path); if (file.exists()) { - // 根据Android版本使用不同的Uri方式 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - // Android 7.0及以上使用FileProvider Uri fileUri = FileProviderUtil.getUriForFile(activity, file); imageUris.add(fileUri); } else { - // Android 7.0以下直接使用文件Uri + imageUris.add(Uri.fromFile(file)); + } + } + } + + if (imageUris.isEmpty()) { + Toast.makeText(activity, "没有有效图片可分享", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "没有有效图片可分享"); + } + return; + } + + Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); + String packageName = getInstalledDouYinPackage(); + intent.setPackage(packageName); + intent.setType("image/*"); + intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + + try { + startShareActivity(activity, intent); + } catch (Exception e) { + Log.d(TAG, "多图直接分享失败,使用系统分享: " + e.getMessage()); + Intent chooser = Intent.createChooser(intent.setPackage(null), "分享到抖音"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 鸿蒙/卓易通环境分享多图 - setClassName + 引导弹窗 + */ + private void shareImagesToDouyin_Harmony(Activity activity, ArrayList imagePaths) { + if (imagePaths == null || imagePaths.isEmpty()) { + Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "分享图片为空"); + } + return; + } + + try { + ArrayList imageUris = new ArrayList<>(); + for (String path : imagePaths) { + File file = new File(path); + if (file.exists()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Uri fileUri = FileProviderUtil.getUriForFile(activity, file); + imageUris.add(fileUri); + } else { imageUris.add(Uri.fromFile(file)); } } @@ -361,7 +636,6 @@ public class DouYinIntentShareUtil { intent.setType("image/*"); intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); - // 鸿蒙/卓易通关键适配Flags intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); @@ -369,24 +643,17 @@ public class DouYinIntentShareUtil { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } - boolean launched = false; String packageName = getInstalledDouYinPackage(); - // 1. 尝试直接定向分享 try { - // 抖音分享建议只用 setPackage 直接唤起 intent.setPackage(packageName); if ("com.ss.android.ugc.aweme".equals(packageName)) { intent.setClassName(packageName, "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"); } activity.startActivity(intent); - launched = true; - activity.runOnUiThread(() -> Toast.makeText(activity, "多图直接分享成功", Toast.LENGTH_SHORT).show()); } catch (Exception e) { Log.d(TAG, "直接分享多图失败: " + e.getMessage()); - // 直接分享失败,改用自定义引导弹窗 activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, false)); - launched = true; } } catch (Exception e) { handleShareException(activity, e); @@ -436,7 +703,62 @@ public class DouYinIntentShareUtil { * @param videoPath 视频路径 */ public void shareVideoToDouyin(Activity activity, String videoPath) { - // 在鸿蒙卓易通环境下,避免过早报错,尝试强制分享 + if (EnvironmentUtil.isHarmonyOS()) { + shareVideoToDouyin_Harmony(activity, videoPath); + } else { + shareVideoToDouyin_Android(activity, videoPath); + } + } + + /** + * 安卓环境分享视频 - setPackage + startShareActivity chooser(与ref一致) + */ + private void shareVideoToDouyin_Android(Activity activity, String videoPath) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + File videoFile = new File(videoPath); + if (!videoFile.exists()) { + Toast.makeText(activity, "视频文件不存在", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "视频文件不存在"); + } + return; + } + + try { + Intent intent = new Intent(Intent.ACTION_SEND); + String packageName = getInstalledDouYinPackage(); + intent.setPackage(packageName); + intent.setType("video/*"); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Uri videoUri = FileProviderUtil.getUriForFile(activity, videoFile); + intent.putExtra(Intent.EXTRA_STREAM, videoUri); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(videoFile)); + } + + try { + startShareActivity(activity, intent); + } catch (Exception e) { + Log.d(TAG, "视频直接分享失败,使用系统分享: " + e.getMessage()); + Intent chooser = Intent.createChooser(intent.setPackage(null), "分享到抖音"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 鸿蒙/卓易通环境分享视频 - setClassName + 引导弹窗 + */ + private void shareVideoToDouyin_Harmony(Activity activity, String videoPath) { boolean isPackageDetected = isDouyinInstalled(); File videoFile = new File(videoPath); @@ -452,63 +774,49 @@ public class DouYinIntentShareUtil { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("video/*"); - // 鸿蒙/卓易通关键适配Flags intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - // 根据Android版本使用不同的Uri方式 - Uri videoUri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - // Android 7.0及以上使用FileProvider - videoUri = FileProviderUtil.getUriForFile(activity, videoFile); + Uri videoUri = FileProviderUtil.getUriForFile(activity, videoFile); intent.putExtra(Intent.EXTRA_STREAM, videoUri); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { - // Android 7.0以下直接使用文件Uri - videoUri = Uri.fromFile(videoFile); - intent.putExtra(Intent.EXTRA_STREAM, videoUri); + intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(videoFile)); } boolean launched = false; if (isPackageDetected) { - try { - String packageName = getInstalledDouYinPackage(); - intent.setPackage(packageName); - if ("com.ss.android.ugc.aweme".equals(packageName)) { - intent.setClassName(packageName, "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"); - } - activity.startActivity(intent); - activity.runOnUiThread(() -> Toast.makeText(activity, "已发送分享视频Intent到抖音", Toast.LENGTH_SHORT).show()); - } catch (Exception e) { - Log.e(TAG, "直接分享视频到抖音失败: " + e.getMessage()); - final String failMsg = "直接分享视频失败: " + e.getMessage(); - activity.runOnUiThread(() -> Toast.makeText(activity, failMsg, Toast.LENGTH_SHORT).show()); - } + try { + String packageName = getInstalledDouYinPackage(); + intent.setPackage(packageName); + if ("com.ss.android.ugc.aweme".equals(packageName)) { + intent.setClassName(packageName, "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"); + } + activity.startActivity(intent); + launched = true; + } catch (Exception e) { + Log.e(TAG, "直接分享视频到抖音失败: " + e.getMessage()); + } } if (!launched) { try { - // 废弃系统Chooser,改用自定义引导弹窗 - activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, true)); - launched = true; + activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, true)); + launched = true; } catch (Exception e) { Log.e(TAG, "引导弹窗分享视频失败: " + e.getMessage()); - final String failMsg2 = "引导弹窗视频失败: " + e.getMessage(); - activity.runOnUiThread(() -> Toast.makeText(activity, failMsg2, Toast.LENGTH_SHORT).show()); } } if (launched) { - // 延迟回调成功 if (mCallback != null) { new Handler(Looper.getMainLooper()).postDelayed(() -> { mCallback.onSuccess(); }, 1000); } } - // 失败时已由Catch块提示,不再重复显示通用错误 - // else { ... } } catch (Exception e) { handleShareException(activity, e); @@ -524,9 +832,7 @@ public class DouYinIntentShareUtil { * @param webUrl 网页链接 */ public void shareWebPageToDouyin(Activity activity, String title, String description, String webUrl) { - // Strict check removed - - // 抖音只能通过文本方式分享网页链接 + // 用户要求不需要分享链接,所有环境都不追加webUrl StringBuilder sb = new StringBuilder(); if (!TextUtils.isEmpty(title)) { sb.append(title).append("\n\n"); @@ -534,8 +840,6 @@ public class DouYinIntentShareUtil { if (!TextUtils.isEmpty(description)) { sb.append(description); } - - // 用户要求不需要分享链接,因此这里不再追加webUrl的内容 shareTextToDouyin(activity, sb.toString().trim()); } @@ -548,22 +852,103 @@ public class DouYinIntentShareUtil { * @param description 分享描述,可选 */ public void shareWebpageToDouyin(Activity activity, String url, String title, String description) { + if (EnvironmentUtil.isHarmonyOS()) { + shareWebpageToDouyin_Harmony(activity, url, title, description); + } else { + shareWebpageToDouyin_Android(activity, url, title, description); + } + } + + /** + * 安卓环境分享网页 - 用户要求不需要链接,复制内容也不含链接 + * 使用 ACTION_SEND → tryLaunchDouyin → chooser + */ + private void shareWebpageToDouyin_Android(Activity activity, String url, String title, String description) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + try { - // 构建完整分享内容 + String packageName = getInstalledDouYinPackage(); + + // 构建分享内容(不含链接) StringBuilder shareContent = new StringBuilder(); if (!TextUtils.isEmpty(title)) { - shareContent.append(title).append("\n"); + shareContent.append(title).append("\n\n"); + } + if (!TextUtils.isEmpty(description)) { + shareContent.append(description); + } + + String contentStr = shareContent.toString().trim(); + copyToClipboard(activity, contentStr); + + // 方法1: 尝试使用系统分享直接发送到抖音 + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setPackage(packageName); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_TEXT, contentStr); + + try { + activity.startActivity(shareIntent); + Log.d(TAG, "已发送网页分享Intent到抖音"); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return; + } catch (android.content.ActivityNotFoundException e) { + Log.e(TAG, "直接分享网页到抖音失败,尝试替代方法: " + e.getMessage()); + } + + // 方法2: 启动抖音并提示用户手动粘贴分享 + boolean launched = tryLaunchDouyin(activity); + if (launched) { + Toast.makeText(activity, "已将内容复制到剪贴板,请在抖音中粘贴并分享", Toast.LENGTH_LONG).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return; + } + + // 方法3: 使用系统分享选择器 + Intent chooserIntent = Intent.createChooser(shareIntent.setPackage(null), "分享到"); + activity.startActivity(chooserIntent); + Toast.makeText(activity, "请从分享列表中选择抖音", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + + } catch (Exception e) { + Log.e(TAG, "分享网页过程中出现异常: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 鸿蒙/卓易通环境分享网页 - 引导弹窗(不包含链接) + */ + private void shareWebpageToDouyin_Harmony(Activity activity, String url, String title, String description) { + try { + StringBuilder shareContent = new StringBuilder(); + if (!TextUtils.isEmpty(title)) { + shareContent.append(title).append("\n\n"); } if (!TextUtils.isEmpty(description)) { shareContent.append(description); } - - // 用户要求不需要链接,分享的内容也不需要复制链接,因此不再追加url的内容 - // 复制到剪贴板,便于用户在抖音中粘贴 copyToClipboard(activity, shareContent.toString().trim()); - // 弹出提示框引导用户 activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, true)); } catch (Exception e) { @@ -575,14 +960,44 @@ public class DouYinIntentShareUtil { /** - * 启动分享Activity - 不再直接调用,使用系统分享菜单代替 + * 启动分享Activity */ private void startShareActivity(Activity activity, Intent intent) { + if (EnvironmentUtil.isHarmonyOS()) { + startShareActivity_Harmony(activity, intent); + } else { + startShareActivity_Android(activity, intent); + } + } + + /** + * 安卓环境 - 使用系统分享选择器(与ref一致) + */ + private void startShareActivity_Android(Activity activity, Intent intent) { + try { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + Intent chooser = Intent.createChooser(intent, "分享到抖音"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 鸿蒙/卓易通环境 - 使用引导弹窗 + */ + private void startShareActivity_Harmony(Activity activity, Intent intent) { try { - // 废弃系统Chooser,统一使用引导弹窗 activity.runOnUiThread(() -> showDouYinTextGuideDialog(activity, false)); - // 假设分享成功 if (mCallback != null) { new Handler(Looper.getMainLooper()).postDelayed(() -> { mCallback.onSuccess(); @@ -692,11 +1107,13 @@ public class DouYinIntentShareUtil { * @return 是否成功启动分享 */ public boolean shareToPrivateMessage(Activity activity, String content, Uri mediaUri, String mediaType) { - // Strict check removed for HarmonyOS compatibility - // if (!isDouyinInstalled()) { - // handleNotInstalled(activity); - // return false; - // } + // 安卓环境恢复安装检测(与ref一致) + if (!EnvironmentUtil.isHarmonyOS()) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return false; + } + } try { // 简化处理:将文本复制到剪贴板 @@ -744,11 +1161,13 @@ public class DouYinIntentShareUtil { * @return 是否成功启动分享 */ public boolean shareToGroupChat(Activity activity, String content, Uri mediaUri, String mediaType) { - // Strict check removed for HarmonyOS compatibility - // if (!isDouyinInstalled()) { - // handleNotInstalled(activity); - // return false; - // } + // 安卓环境恢复安装检测(与ref一致) + if (!EnvironmentUtil.isHarmonyOS()) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return false; + } + } try { String packageName = getInstalledDouYinPackage(); @@ -824,11 +1243,15 @@ public class DouYinIntentShareUtil { shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } - // 废弃系统Chooser,改用自定义引导弹窗 - activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, "video".equals(mediaType))); - - // 已在向导弹窗中引导用户 - // Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show(); + if (EnvironmentUtil.isHarmonyOS()) { + // 鸿蒙/卓易通:使用引导弹窗 + activity.runOnUiThread(() -> showDouYinMediaGuideDialog(activity, "video".equals(mediaType))); + } else { + // 安卓:使用系统分享选择器(与ref一致) + Intent chooser = Intent.createChooser(shareIntent, "分享到抖音"); + activity.startActivity(chooser); + Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show(); + } } catch (Exception e) { Log.e(TAG, "准备媒体分享失败: " + e.getMessage()); // 如果媒体分享失败,至少已经将文本内容复制到剪贴板 diff --git a/app/src/main/java/com/tsgame/tsgame_niuniu/util/EnvironmentUtil.java b/app/src/main/java/com/tsgame/tsgame_niuniu/util/EnvironmentUtil.java new file mode 100644 index 0000000..ae4474c --- /dev/null +++ b/app/src/main/java/com/tsgame/tsgame_niuniu/util/EnvironmentUtil.java @@ -0,0 +1,61 @@ +package com.tsgame.tsgame_niuniu.util; + +import android.os.Build; +import android.text.TextUtils; +public class EnvironmentUtil { + + /** + * 判断当前系统是否为鸿蒙系统 (HarmonyOS) + * @return true=鸿蒙系统, false=安卓系统 + */ + // public static boolean isHarmonyOS() { + // try { + // // 通过获取华为特定的构建类判断 + // Class buildExClass = Class.forName("com.huawei.system.BuildEx"); + // Object osBrand = buildExClass.getMethod("getOsBrand").invoke(buildExClass); + // if ("Harmony".equalsIgnoreCase(osBrand != null ? osBrand.toString() : null)) { + // return true; + // } + // } catch (Throwable e) { + // // ignore + // } + + // try { + // // 备用判断:通过 ohos.system.version 判断 + // Class clz = Class.forName("ohos.system.version.SystemVersion"); + // return clz != null; + // } catch (Throwable e) { + // // ignore + // } + + // return false; + // } + /** + * 判断是否为鸿蒙系统 + */ + public static boolean isHarmonyOS() { + boolean isHarmony = false; + try { + Class clz = Class.forName("com.huawei.system.BuildEx"); + java.lang.reflect.Method method = clz.getMethod("getOsBrand"); + String brand = (String) method.invoke(clz); + if ("Harmony".equalsIgnoreCase(brand)) { + isHarmony = true; + } + } catch (Exception e) { + // Ignored + } + if (!isHarmony) { + try { + Class propertyClass = Class.forName("android.os.SystemProperties"); + java.lang.reflect.Method getMethod = propertyClass.getMethod("get", String.class); + String version = (String) getMethod.invoke(propertyClass, "hw_sc.build.platform.version"); + isHarmony = !TextUtils.isEmpty(version); + } catch (Exception e) { + // Ignored + } + } + + return isHarmony; + } +} diff --git a/app/src/main/java/com/tsgame/tsgame_niuniu/util/QQIntentShareUtil.java b/app/src/main/java/com/tsgame/tsgame_niuniu/util/QQIntentShareUtil.java index ac9975d..a158c23 100644 --- a/app/src/main/java/com/tsgame/tsgame_niuniu/util/QQIntentShareUtil.java +++ b/app/src/main/java/com/tsgame/tsgame_niuniu/util/QQIntentShareUtil.java @@ -226,51 +226,134 @@ public class QQIntentShareUtil { * @param text 要分享的文本 */ public void shareTextToQQ(Activity activity, String text) { - // 在鸿蒙卓易通环境下,不完全依赖isQQInstalled,尝试强制拉起 - boolean isPackageDetected = isQQInstalled(); - - try { - // 尝试复制文本到剪贴板,作为兜底 - try { - copyToClipboard(activity, text); - } catch (Exception e) { - // 忽略剪贴板异常 - } + if (EnvironmentUtil.isHarmonyOS()) { + shareTextToQQ_Harmony(activity, text); + } else { + shareTextToQQ_Android(activity, text); + } + } + /** Android环境:与ref一致的多级回退逻辑 */ + private void shareTextToQQ_Android(Activity activity, String text) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + + try { + // 1. 将文本复制到剪贴板 + copyToClipboard(activity, text); + + // 2. 使用QQ的特定组件启动联系人选择界面 String packageName = getInstalledQQPackage(); boolean launched = false; - - // 方法1: 采用调用系统分享 - try { + + // 方法1: 使用QQ的联系人选择器组件 + if (!launched) { + try { + Intent intent = new Intent(); + ComponentName comp = new ComponentName(packageName, "com.tencent.mobileqq.activity.contacts.SortContactsListActivity"); + intent.setComponent(comp); + intent.putExtra("key_operation_type", 5); + intent.putExtra("key_is_friend_chooser", 1); + intent.putExtra("key_source_from", 12); + intent.putExtra("isFromShare", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + activity.startActivity(intent); + launched = true; + Log.d(TAG, "成功使用联系人选择器组件启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用联系人选择器组件启动QQ失败: " + e.getMessage()); + } + } + + // 方法2: 使用与图片分享一致的规范Action拉起QQ分享组件 + if (!launched) { + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + ComponentName comp = new ComponentName(packageName, getQQShareComponent()); + intent.setComponent(comp); + intent.putExtra(Intent.EXTRA_TEXT, text); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + launched = true; + + // 提示用户文字已复制,手动粘贴分享 + Toast.makeText(activity, "已将内容复制到剪贴板,请选择好友后粘贴分享", Toast.LENGTH_LONG).show(); + + Log.d(TAG, "成功使用分享组件启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用分享组件启动QQ失败: " + e.getMessage()); + } + } + + // 方法3: 使用QQ的会话Activity + if (!launched) { + try { + Intent intent = new Intent(); + ComponentName comp = new ComponentName(packageName, "com.tencent.mobileqq.activity.FriendlistActivity"); + intent.setComponent(comp); + intent.putExtra("isFromShare", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + launched = true; + // 提示用户文字已复制,手动粘贴分享 + Toast.makeText(activity, "已将内容复制到剪贴板,请选择好友后粘贴分享", Toast.LENGTH_LONG).show(); + Log.d(TAG, "成功使用好友列表Activity启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用好友列表Activity启动QQ失败: " + e.getMessage()); + } + } + + // 方法4: 使用通常的标准聊天组件 + if (!launched) { + try { + Intent intent = new Intent(); + ComponentName comp = new ComponentName(packageName, getQQChatComponent()); + intent.setComponent(comp); + intent.putExtra("uinname", ""); + intent.putExtra("uintype", 0); + intent.putExtra("isFromShare", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + launched = true; + // 提示用户文字已复制,手动粘贴分享 + Toast.makeText(activity, "已将内容复制到剪贴板,请选择好友后粘贴分享", Toast.LENGTH_LONG).show(); + Log.d(TAG, "成功使用聊天组件启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用聊天组件启动QQ失败: " + e.getMessage()); + } + } + + // 如果以上方法都失败,回退到标准启动方法 + if (!launched) { + try { + Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName); + if (launchIntent != null) { + launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(launchIntent); + launched = true; + // 提示用户文字已复制,手动粘贴分享 + Toast.makeText(activity, "已将内容复制到剪贴板,请选择好友后粘贴分享", Toast.LENGTH_LONG).show(); + Log.d(TAG, "成功使用标准方式启动QQ"); + } + } catch (Exception e) { + Log.e(TAG, "标准方式启动QQ失败: " + e.getMessage()); + } + } + + // 如果以上方法都失败,尝试系统分享 + if (!launched) { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, text); - - // 鸿蒙/卓易通关键适配Flags - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - - // 在卓易通系统上,提前设置 package 会导致 createChooser 失效,因此改用排除法 - Intent chooser = createTargetedChooserIntent(activity, intent, "分享到QQ"); - chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Intent chooser = Intent.createChooser(intent, "分享到QQ"); activity.startActivity(chooser); - launched = true; - - Log.d(TAG, "成功启动系统分享面板"); - activity.runOnUiThread(() -> Toast.makeText(activity, "已将内容复制到剪贴板,请在QQ中粘贴并分享", Toast.LENGTH_LONG).show()); - } catch (Exception e) { - Log.e(TAG, "启动分享失败: " + e.getMessage()); - final String msg = "启动分享失败: " + e.getMessage(); - activity.runOnUiThread(() -> Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show()); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); } - // 方法2: 如果上面的方法失败,回退到原有的特定Intent启动逻辑 - if (!launched) { - // 原有的逻辑保留作为备选... - - // ... (原有代码可以保留在if (!launched)块中,或简化) - } - // 假设分享过程启动成功 if (mCallback != null) { new Handler(Looper.getMainLooper()).postDelayed(() -> { @@ -279,9 +362,42 @@ public class QQIntentShareUtil { } } catch (Exception e) { Log.e(TAG, "分享文本到QQ失败: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** 鸿蒙环境:使用系统分享面板 */ + private void shareTextToQQ_Harmony(Activity activity, String text) { + activity.runOnUiThread(() -> Toast.makeText(activity, "shareTextToQQ_Harmony", Toast.LENGTH_LONG).show()); + try { + try { + copyToClipboard(activity, text); + } catch (Exception e) { + // 忽略剪贴板异常 + } + + // 鸿蒙系统下直接调用无针对性拦截的纯系统分享面板 + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, text); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + + Intent chooser = Intent.createChooser(intent, "分享到..."); + chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(chooser); + + Log.d(TAG, "成功启动系统分享面板"); + activity.runOnUiThread(() -> Toast.makeText(activity, "已将内容复制到剪贴板,请从列表中选择QQ并粘贴分享", Toast.LENGTH_LONG).show()); - // 最终兜底:提示手动分享 - Toast.makeText(activity, "暂无法直接拉起QQ,已复制内容,请手动打开QQ粘贴分享", Toast.LENGTH_LONG).show(); + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + Log.e(TAG, "分享文本到QQ失败: " + e.getMessage(), e); + Toast.makeText(activity, "暂无法拉起分享,已复制内容", Toast.LENGTH_LONG).show(); handleShareException(activity, e); } } @@ -357,8 +473,19 @@ public class QQIntentShareUtil { * @param localImagePath 本地图片路径 */ public void shareImageToQQ(Activity activity, String localImagePath) { - // 在鸿蒙卓易通环境下,避免过早报错,尝试强制分享 - boolean isPackageDetected = isQQInstalled(); + if (EnvironmentUtil.isHarmonyOS()) { + shareImageToQQ_Harmony(activity, localImagePath); + } else { + shareImageToQQ_Android(activity, localImagePath); + } + } + + /** Android环境:与ref一致,使用JumpActivity直接拉起 */ + private void shareImageToQQ_Android(Activity activity, String localImagePath) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } File imageFile = new File(localImagePath); if (!imageFile.exists()) { @@ -372,56 +499,101 @@ public class QQIntentShareUtil { try { String packageName = getInstalledQQPackage(); - // 创建分享Intent Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("image/*"); - // 根据Android版本使用不同的Uri方式 + // 设置组件名称 + ComponentName comp = new ComponentName(packageName, getQQShareComponent()); + shareIntent.setComponent(comp); + Uri imageUri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - // Android 7.0及以上使用FileProvider imageUri = FileProviderUtil.getUriForFile(activity, imageFile); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { - // Android 7.0以下直接使用文件Uri imageUri = Uri.fromFile(imageFile); } - + shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); - - // 鸿蒙/卓易通关键适配Flags - shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - shareIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 确保Flags也被设置在Intent上 + shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // 采用调用系统分享 - boolean launched = false; - try { - // 在卓易通系统上,提前设置 package 会导致 createChooser 失效,因此改用排除法 - Intent chooserIntent = createTargetedChooserIntent(activity, shareIntent, "分享到QQ"); - chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 确保Chooser也有权限 - - activity.startActivity(chooserIntent); - launched = true; - Log.d(TAG, "已发送分享图片Intent到QQ系统面板"); - } catch (Exception e) { - Log.e(TAG, "启动分享图片到QQ系统面板失败: " + e.getMessage()); - final String failMsg = "分享失败: " + e.getMessage(); - activity.runOnUiThread(() -> Toast.makeText(activity, failMsg, Toast.LENGTH_SHORT).show()); - } + activity.startActivity(shareIntent); + Log.d(TAG, "已发送分享图片Intent到QQ"); - if (launched) { if (mCallback != null) { new Handler(Looper.getMainLooper()).postDelayed(() -> { mCallback.onSuccess(); }, 1000); } - } else { - Toast.makeText(activity, "分享图片失败,请手动打开QQ分享", Toast.LENGTH_SHORT).show(); - } + } catch (android.content.ActivityNotFoundException e) { + Log.e(TAG, "直接分享到QQ失败,尝试使用选择器: " + e.getMessage()); + Intent chooserIntent = Intent.createChooser(shareIntent.setComponent(null), "分享到QQ"); + activity.startActivity(chooserIntent); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } + } catch (Exception e) { + Log.e(TAG, "分享图片到QQ失败: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** 鸿蒙环境:使用系统分享面板 */ + private void shareImageToQQ_Harmony(Activity activity, String localImagePath) { + File imageFile = new File(localImagePath); + if (!imageFile.exists()) { + Toast.makeText(activity, "分享图片不存在", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "图片文件不存在"); + } + return; + } + + try { + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("image/*"); + + Uri imageUri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + imageUri = FileProviderUtil.getUriForFile(activity, imageFile); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + imageUri = Uri.fromFile(imageFile); + } + + shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); + shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + shareIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + try { + // 鸿蒙系统下直接调用无针对性拦截的纯系统分享面板 + Intent chooserIntent = Intent.createChooser(shareIntent, "分享图片到..."); + chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + activity.startActivity(chooserIntent); + Log.d(TAG, "已发送分享图片Intent到纯系统面板"); + + activity.runOnUiThread(() -> Toast.makeText(activity, "请从列表中选择QQ进行分享", Toast.LENGTH_SHORT).show()); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + Log.e(TAG, "启动分享图片到QQ系统面板失败: " + e.getMessage()); + final String failMsg = "分享失败: " + e.getMessage(); + activity.runOnUiThread(() -> Toast.makeText(activity, failMsg, Toast.LENGTH_SHORT).show()); + } } catch (Exception e) { Log.e(TAG, "分享图片到QQ失败: " + e.getMessage(), e); handleShareException(activity, e); @@ -552,6 +724,20 @@ public class QQIntentShareUtil { * @param isQzone 是否分享到QQ空间 */ public void shareImagesToQQ(Activity activity, ArrayList imagePaths, boolean isQzone) { + if (EnvironmentUtil.isHarmonyOS()) { + shareImagesToQQ_Harmony(activity, imagePaths, isQzone); + } else { + shareImagesToQQ_Android(activity, imagePaths, isQzone); + } + } + + /** Android环境:与ref一致 */ + private void shareImagesToQQ_Android(Activity activity, ArrayList imagePaths, boolean isQzone) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + if (imagePaths == null || imagePaths.isEmpty()) { Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); if (mCallback != null) { @@ -565,13 +751,10 @@ public class QQIntentShareUtil { for (String path : imagePaths) { File file = new File(path); if (file.exists()) { - // 根据Android版本使用不同的Uri方式 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - // Android 7.0及以上使用FileProvider Uri fileUri = FileProviderUtil.getUriForFile(activity, file); imageUris.add(fileUri); } else { - // Android 7.0以下直接使用文件Uri imageUris.add(Uri.fromFile(file)); } } @@ -586,9 +769,84 @@ public class QQIntentShareUtil { } Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); - // 获取已安装的QQ包名 String packageName = getInstalledQQPackage(); - //intent.setPackage(packageName); // 不再强制依赖包名 + intent.setPackage(packageName); + intent.setType("image/*"); + intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); + + // 设置组件名称 + if (isQzone) { + ComponentName comp = new ComponentName(packageName, getQZoneShareComponent()); + intent.setComponent(comp); + } else { + ComponentName comp = new ComponentName(packageName, getQQShareComponent()); + intent.setComponent(comp); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + activity.startActivity(intent); + Log.d(TAG, "已发送多图分享Intent到QQ"); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + Log.d(TAG, "多图直接分享失败,使用系统分享: " + e.getMessage()); + Intent chooser = Intent.createChooser(intent.setComponent(null), isQzone ? "分享到QQ空间" : "分享到QQ"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** 鸿蒙环境:使用系统分享面板 */ + private void shareImagesToQQ_Harmony(Activity activity, ArrayList imagePaths, boolean isQzone) { + if (imagePaths == null || imagePaths.isEmpty()) { + Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "分享图片为空"); + } + return; + } + + try { + ArrayList imageUris = new ArrayList<>(); + for (String path : imagePaths) { + File file = new File(path); + if (file.exists()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Uri fileUri = FileProviderUtil.getUriForFile(activity, file); + imageUris.add(fileUri); + } else { + imageUris.add(Uri.fromFile(file)); + } + } + } + + if (imageUris.isEmpty()) { + Toast.makeText(activity, "没有有效图片可分享", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "没有有效图片可分享"); + } + return; + } + + Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); intent.setType("image/*"); intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); @@ -596,26 +854,26 @@ public class QQIntentShareUtil { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); // 鸿蒙卓易通适配 - - boolean launched = false; + intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); try { - // 采用调用系统分享,通过排除法避免设 package 导致的 chooser 失效 - Intent chooser = createTargetedChooserIntent(activity, intent, isQzone ? "分享到QQ空间" : "分享到QQ"); + // 鸿蒙系统下直接调用无针对性拦截的纯系统分享面板 + Intent chooser = Intent.createChooser(intent, isQzone ? "分享到QQ空间" : "分享到..."); chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); activity.startActivity(chooser); - launched = true; - Log.d(TAG, "已打开系统分享面板进行多图分享"); - } catch (Exception e) { - Log.e(TAG, "开启系统多图分享到QQ失败: " + e.getMessage()); + Log.d(TAG, "已打开纯系统分享面板进行多图分享"); + + activity.runOnUiThread(() -> Toast.makeText(activity, "请从列表中选择QQ进行分享", Toast.LENGTH_SHORT).show()); + if (mCallback != null) { new Handler(Looper.getMainLooper()).postDelayed(() -> { mCallback.onSuccess(); }, 1000); } + } catch (Exception e) { + Log.e(TAG, "开启系统多图分享到QQ失败: " + e.getMessage()); } } catch (Exception e) { diff --git a/app/src/main/java/com/tsgame/tsgame_niuniu/util/WeChatIntentShareUtil.java b/app/src/main/java/com/tsgame/tsgame_niuniu/util/WeChatIntentShareUtil.java index bb291a7..d22d168 100644 --- a/app/src/main/java/com/tsgame/tsgame_niuniu/util/WeChatIntentShareUtil.java +++ b/app/src/main/java/com/tsgame/tsgame_niuniu/util/WeChatIntentShareUtil.java @@ -117,14 +117,41 @@ public class WeChatIntentShareUtil { */ public void shareTextToWeChat(Activity activity, String text, int scene) { boolean isPackageDetected = isWeChatInstalled(); - - // 应对鸿蒙等可能存在的限制环境,仅在分享到朋友圈时先复制文本 - if (scene != SCENE_FRIENDS) { - copyToClipboard(activity, text); + + if (scene == SCENE_MOMENTS) { + // 提取出不包含链接的纯内容 + String textNoUrl = text.replaceAll("(http|https)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", "").trim(); + copyToClipboard(activity, textNoUrl); + + try { + // 尝试拉起微信朋友圈界面 + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("image/*"); // 朋友圈通常要求图片类型才能拉起对应界面 + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setComponent(new ComponentName(WECHAT_PACKAGE_NAME, WECHAT_MOMENTS_ACTIVITY)); + activity.startActivity(intent); + activity.runOnUiThread(() -> Toast.makeText(activity, "已复制内容,请长按粘贴以发布", Toast.LENGTH_SHORT).show()); + handleShareSuccess(activity); + } catch (Exception e) { + Log.e(TAG, "拉起朋友圈界面失败,尝试打开微信主界面: " + e.getMessage()); + try { + Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(WECHAT_PACKAGE_NAME); + if (launchIntent != null) { + launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(launchIntent); + activity.runOnUiThread(() -> Toast.makeText(activity, "已复制内容,请打开朋友圈长按粘贴", Toast.LENGTH_SHORT).show()); + handleShareSuccess(activity); + } + } catch (Exception ex) { + Log.e(TAG, "打开微信主界面失败: " + ex.getMessage()); + handleShareException(activity, ex); + } + } + return; } try { - // 创建分享Intent + // 以下为分享给好友的正常逻辑 Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, text); @@ -133,16 +160,6 @@ public class WeChatIntentShareUtil { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - // 根据分享场景指定目标Activity - if (scene == SCENE_MOMENTS) { - // 微信朋友圈分享不支持纯文本分享,提示用户 - Toast.makeText(activity, "微信朋友圈不支持纯文本分享,建议使用图文", Toast.LENGTH_SHORT).show(); - if (mCallback != null) { - mCallback.onError(-1, "微信朋友圈不支持纯文本分享"); - } - return; - } - boolean launched = false; if (isPackageDetected) { @@ -384,6 +401,46 @@ public class WeChatIntentShareUtil { } } + /** + * 分享网络图片到微信 + * 原理:先下载网络图片为Bitmap,再通过分享Bitmap的流程保存本地并拉起微信 + * @param activity 活动 + * @param imageUrl 网络图片URL + * @param scene 分享场景:0-好友,1-朋友圈 + */ + public void shareNetworkImage(Activity activity, String imageUrl, int scene) { + if (TextUtils.isEmpty(imageUrl)) { + Toast.makeText(activity, "图片链接不能为空", Toast.LENGTH_SHORT).show(); + return; + } + Toast.makeText(activity, "正在准备分享图片,请稍候...", Toast.LENGTH_SHORT).show(); + + // 开启子线程下载图片 + new Thread(() -> { + try { + java.net.URL url = new java.net.URL(imageUrl); + java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.connect(); + java.io.InputStream input = connection.getInputStream(); + Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(input); + + // 返回主线程调用现有的分享Bitmap逻辑 + activity.runOnUiThread(() -> { + shareBitmap(activity, bitmap, scene); + }); + } catch (Exception e) { + Log.e(TAG, "下载网络图片失败: " + e.getMessage(), e); + activity.runOnUiThread(() -> { + Toast.makeText(activity, "获取网络图片失败", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-3, "获取网络图片失败: " + e.getMessage()); + } + }); + } + }).start(); + } + /** * 分享网页链接到微信 * 注意:微信原生分享不支持直接分享链接,这里实际是分享文本 @@ -412,52 +469,8 @@ public class WeChatIntentShareUtil { // } String text = sb.toString(); - if (scene != SCENE_FRIENDS) { - copyToClipboard(activity, text); - } - - // 朋友圈不支持纯文本分享,需要准备一个默认图片 - if (scene == SCENE_MOMENTS) { - Toast.makeText(activity, "朋友圈不支持纯文本分享,已复制内容可手动发表", Toast.LENGTH_SHORT).show(); - - try { - // 调用系统分享 - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, text); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - - boolean launched = false; - if (isPackageDetected) { - try { - Intent directIntent = new Intent(intent); - ComponentName comp = new ComponentName(WECHAT_PACKAGE_NAME, WECHAT_MOMENTS_ACTIVITY); - directIntent.setComponent(comp); - activity.startActivity(directIntent); - launched = true; - } catch (Exception e) {} - } - - if (!launched) { - try { - Intent chooserIntent = Intent.createChooser(intent, "请选择微信分享"); - chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - activity.startActivity(chooserIntent); - launched = true; - } catch (Exception e) {} - } - - handleShareSuccess(activity); - } catch (Exception e) { - Log.e(TAG, "分享文本到微信失败: " + e.getMessage(), e); - handleShareException(activity, e); - } - } else { - // 分享给好友,可以直接分享文本 - shareTextToWeChat(activity, text, scene); - } + // 直接复用统一的文本分享逻辑(内部会自动处理朋友圈剥离链接并拉起朋友圈界面) + shareTextToWeChat(activity, text, scene); } catch (Exception e) { Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e); handleShareException(activity, e); diff --git a/app/src/main/java/com/tsgame/tsgame_niuniu/util/WeChatOfficialShareUtil.java b/app/src/main/java/com/tsgame/tsgame_niuniu/util/WeChatOfficialShareUtil.java deleted file mode 100644 index c8d3ed0..0000000 --- a/app/src/main/java/com/tsgame/tsgame_niuniu/util/WeChatOfficialShareUtil.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.tsgame.tsgame_niuniu.util; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.widget.Toast; - -import com.jx.jyhd.R; -import com.jx.jyhd.simcpux.Constants; -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.WXWebpageObject; -import com.tencent.mm.opensdk.openapi.IWXAPI; -import com.tencent.mm.opensdk.openapi.WXAPIFactory; - -/** - * 微信官方 SDK 分享工具类 - * 用来发送请求给微信,并且可以接通 WXEntryActivity 的回调 - */ -public class WeChatOfficialShareUtil { - - private static WeChatOfficialShareUtil instance; - private IWXAPI api; - - private WeChatOfficialShareUtil(Context context) { - api = WXAPIFactory.createWXAPI(context, Constants.APP_ID); - } - - public static WeChatOfficialShareUtil getInstance(Context context) { - if (instance == null) { - synchronized (WeChatOfficialShareUtil.class) { - if (instance == null) { - instance = new WeChatOfficialShareUtil(context); - } - } - } - return instance; - } - - public boolean isWeChatInstalled() { - return api != null && api.isWXAppInstalled(); - } - - /** - * 分享网页到微信 - */ - public void shareWebPage(Context context, String webpageUrl, String title, String description, int sceneType) { - if (!isWeChatInstalled()) { - Toast.makeText(context, "您还未安装微信客户端", Toast.LENGTH_SHORT).show(); - return; - } - - WXWebpageObject webpage = new WXWebpageObject(); - // 追加随机时间戳参数,强制跳过微信的缩略图缓存 - String finalUrl = webpageUrl; - if (finalUrl != null && !finalUrl.isEmpty()) { - String separator = finalUrl.contains("?") ? "&" : "?"; - finalUrl = finalUrl + separator + "t=" + System.currentTimeMillis(); - } - webpage.webpageUrl = webpageUrl; - - WXMediaMessage msg = new WXMediaMessage(webpage); - msg.title = title; - msg.description = description; - - try { - Bitmap thumbBmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.logo6); - if (thumbBmp != null) { - Bitmap scaled = Bitmap.createScaledBitmap(thumbBmp, 120, 120, true); - msg.setThumbImage(scaled); - thumbBmp.recycle(); - } - } catch (Exception e) { - e.printStackTrace(); - } - - SendMessageToWX.Req req = new SendMessageToWX.Req(); - req.transaction = "webpage" + System.currentTimeMillis(); - req.message = msg; - req.scene = sceneType; - api.sendReq(req); - } - - /** - * 分享图片到微信 - */ - public void shareImage(Context context, String imagePath, int sceneType) { - if (!isWeChatInstalled()) { - Toast.makeText(context, "您还未安装微信客户端", Toast.LENGTH_SHORT).show(); - return; - } - - WXImageObject imgObj = new WXImageObject(); - try { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { // Android 7.0及以上即可使用FileProvider - android.net.Uri contentUri = com.tsgame.tsgame_niuniu.util.FileProviderUtil.getUriForFile(context, new java.io.File(imagePath)); - if (contentUri != null && "content".equals(contentUri.getScheme())) { - context.grantUriPermission("com.tencent.mm", contentUri, android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION); - imgObj.imagePath = contentUri.toString(); - } else { - imgObj.imagePath = imagePath; - } - } else { - imgObj.imagePath = imagePath; - } - } catch (Exception e) { - e.printStackTrace(); - imgObj.imagePath = imagePath; - } - - WXMediaMessage msg = new WXMediaMessage(); - msg.mediaObject = imgObj; - - try { - Bitmap bmp = BitmapFactory.decodeFile(imagePath); - if (bmp != null) { - Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 120, 120, true); - msg.setThumbImage(thumbBmp); - bmp.recycle(); - } - } catch (Exception e) { - e.printStackTrace(); - } - - SendMessageToWX.Req req = new SendMessageToWX.Req(); - req.transaction = "img" + System.currentTimeMillis(); - req.message = msg; - req.scene = sceneType; - api.sendReq(req); - } -} diff --git a/ref/DouYinIntentShareUtil.java b/ref/DouYinIntentShareUtil.java new file mode 100644 index 0000000..6ff8a5e --- /dev/null +++ b/ref/DouYinIntentShareUtil.java @@ -0,0 +1,1009 @@ +package com.tsgame.tsgame_niuniu.util; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.text.TextUtils; +import android.util.Log; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +/** + * 抖音分享工具类 - 无需SDK,使用Intent实现 + */ +public class DouYinIntentShareUtil { + + private static final String TAG = "DouYinIntentShareUtil"; + + // 抖音可能的包名列表,不同版本或地区的抖音可能使用不同的包名 + private static final String DOUYIN_PACKAGE_NAME = "com.ss.android.ugc.aweme"; + private static final String DOUYIN_LITE_PACKAGE_NAME = "com.ss.android.ugc.aweme.lite"; + private static final String DOUYIN_GLOBAL_PACKAGE_NAME = "com.zhiliaoapp.musically"; + + // 可能的抖音包名列表 + private static final List DOUYIN_PACKAGES = Arrays.asList( + DOUYIN_PACKAGE_NAME, // 主要抖音包名 + DOUYIN_LITE_PACKAGE_NAME, // 抖音极速版 + DOUYIN_GLOBAL_PACKAGE_NAME // TikTok国际版 + ); + + private static DouYinIntentShareUtil instance; + private final Context mContext; + private DouYinShareCallback mCallback; + + // 缓存已安装的抖音包名 + private String installedDouYinPackage = null; + + private DouYinIntentShareUtil(Context context) { + this.mContext = context.getApplicationContext(); + } + + public static DouYinIntentShareUtil getInstance(Context context) { + if (instance == null && context != null) { + instance = new DouYinIntentShareUtil(context); + } + return instance; + } + + /** + * 设置分享回调 + * @param callback 分享回调 + */ + public void setShareCallback(DouYinShareCallback callback) { + this.mCallback = callback; + } + + /** + * 检查抖音是否已安装 + * @return 是否安装 + */ + public boolean isDouyinInstalled() { + // 如果之前已找到包名,直接返回true + if (installedDouYinPackage != null) { + return true; + } + + // 检查所有可能的抖音包名 + PackageManager pm = mContext.getPackageManager(); + for (String packageName : DOUYIN_PACKAGES) { + try { + pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); + // 找到已安装的抖音,缓存包名 + installedDouYinPackage = packageName; + Log.d(TAG, "找到已安装的抖音: " + packageName); + return true; + } catch (PackageManager.NameNotFoundException e) { + // 继续检查下一个包名 + continue; + } + } + + Log.d(TAG, "未找到已安装的抖音应用"); + return false; + } + + /** + * 获取已安装的抖音包名 + * @return 抖音包名,如果未安装则返回默认包名 + */ + private String getInstalledDouYinPackage() { + if (installedDouYinPackage != null) { + return installedDouYinPackage; + } + + // 如果没有缓存,重新检测 + isDouyinInstalled(); + return installedDouYinPackage != null ? installedDouYinPackage : DOUYIN_PACKAGE_NAME; + } + + /** + * 与isDouyinInstalled方法功能相同,保持兼容性 + * @return 是否安装抖音 + */ + public boolean isDouYinInstalled() { + return isDouyinInstalled(); + } + + /** + * 通过各种方法尝试启动抖音应用 + * @param activity 活动上下文 + * @return 是否成功启动 + */ + private boolean tryLaunchDouyin(Activity activity) { + try { + String packageName = getInstalledDouYinPackage(); + Log.d(TAG, "尝试启动抖音,包名: " + packageName); + + // 方法1:使用标准启动方式 + Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName); + if (launchIntent != null) { + launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + activity.startActivity(launchIntent); + Log.d(TAG, "成功使用标准方式启动抖音"); + return true; + } + + // 方法2:使用ACTION_MAIN + CATEGORY_LAUNCHER + try { + Intent mainIntent = new Intent(Intent.ACTION_MAIN); + mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); + mainIntent.setPackage(packageName); + + List resolveInfoList = + activity.getPackageManager().queryIntentActivities(mainIntent, 0); + if (resolveInfoList != null && !resolveInfoList.isEmpty()) { + android.content.pm.ResolveInfo resolveInfo = resolveInfoList.get(0); + String className = resolveInfo.activityInfo.name; + + Intent componentIntent = new Intent(Intent.ACTION_MAIN); + componentIntent.addCategory(Intent.CATEGORY_LAUNCHER); + componentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + componentIntent.setComponent(new ComponentName(packageName, className)); + + activity.startActivity(componentIntent); + Log.d(TAG, "成功使用组件方式启动抖音"); + return true; + } + } catch (Exception e) { + Log.e(TAG, "方法2失败: " + e.getMessage()); + } + + // 尝试所有可能的抖音URI schemes + String[] schemes = { + "snssdk1128://", // 原有scheme + "aweme://", // 原有scheme + "douyin://", // 新增scheme + "douyinlite://", // 抖音极速版scheme + "snssdk1128://feed", // 带路径的scheme + "aweme://feed", // 带路径的scheme + "douyin://feed", // 带路径的scheme + "snssdk1128://home/trending", // 热门页 + "douyin://home/trending", // 热门页 + "snssdk1128://post", // 发布页 + "douyin://post" // 发布页 + }; + + for (String scheme : schemes) { + try { + Intent schemeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme)); + schemeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + // 如果设置包名,可以确保只打开抖音应用 + schemeIntent.setPackage(packageName); + activity.startActivity(schemeIntent); + Log.d(TAG, "成功使用scheme方式启动抖音: " + scheme); + return true; + } catch (Exception e) { + Log.e(TAG, "scheme方式失败 " + scheme + ": " + e.getMessage()); + // 继续尝试下一个scheme + } + } + + // 方法4:尝试使用系统VIEW处理 + try { + Intent viewIntent = new Intent(Intent.ACTION_VIEW); + viewIntent.setData(Uri.parse("https://www.douyin.com")); + viewIntent.setPackage(packageName); + viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(viewIntent); + Log.d(TAG, "成功使用Web链接方式启动抖音"); + return true; + } catch (Exception e) { + Log.e(TAG, "Web链接方式失败: " + e.getMessage()); + } + + Log.e(TAG, "所有启动抖音的方法均失败"); + return false; + } catch (Exception e) { + Log.e(TAG, "启动抖音过程中发生异常: " + e.getMessage(), e); + return false; + } + } + + /** + * 分享纯文本到抖音 + * @param activity 活动 + * @param text 要分享的文本 + */ + public void shareTextToDouyin(Activity activity, String text) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + try { + // 使用兼容方式复制到剪贴板 + copyToClipboard(activity, text); + + // 尝试通过各种方式启动抖音 + boolean launched = tryLaunchDouyin(activity); + + if (launched) { + Toast.makeText(activity, "已将内容复制到剪贴板,请在抖音中粘贴并分享", Toast.LENGTH_LONG).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return; + } + + // 如果所有方法都失败了,尝试使用系统分享菜单 + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_TEXT, text); + + Intent chooser = Intent.createChooser(shareIntent, "分享到"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从分享列表中选择抖音", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 分享图片到抖音 + * @param activity 活动 + * @param localImagePath 本地图片路径 + */ + public void shareImageToDouyin(Activity activity, String localImagePath) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + File imageFile = new File(localImagePath); + if (!imageFile.exists()) { + Toast.makeText(activity, "分享图片不存在", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "图片文件不存在"); + } + return; + } + + try { + String packageName = getInstalledDouYinPackage(); + + // 创建分享Intent + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setPackage(packageName); // 指定只分享到抖音 + shareIntent.setType("image/*"); + + // 根据Android版本使用不同的Uri方式 + Uri imageUri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // Android 7.0及以上使用FileProvider + imageUri = FileProviderUtil.getUriForFile(activity, imageFile); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + // Android 7.0以下直接使用文件Uri + imageUri = Uri.fromFile(imageFile); + } + + shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); + + try { + activity.startActivity(shareIntent); + Log.d(TAG, "已发送分享图片Intent到抖音"); + + // 延迟回调成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (android.content.ActivityNotFoundException e) { + Log.e(TAG, "直接分享到抖音失败,尝试使用选择器: " + e.getMessage()); + + // 如果直接分享失败,使用选择器 + Intent chooserIntent = Intent.createChooser(shareIntent.setPackage(null), "分享到抖音"); + activity.startActivity(chooserIntent); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } + } catch (Exception e) { + Log.e(TAG, "分享图片到抖音失败: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 分享多张图片到抖音 + * @param activity 活动 + * @param imagePaths 图片路径列表 + */ + public void shareImagesToDouyin(Activity activity, ArrayList imagePaths) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + if (imagePaths == null || imagePaths.isEmpty()) { + Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "分享图片为空"); + } + return; + } + + try { + ArrayList imageUris = new ArrayList<>(); + for (String path : imagePaths) { + File file = new File(path); + if (file.exists()) { + // 根据Android版本使用不同的Uri方式 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // Android 7.0及以上使用FileProvider + Uri fileUri = FileProviderUtil.getUriForFile(activity, file); + imageUris.add(fileUri); + } else { + // Android 7.0以下直接使用文件Uri + imageUris.add(Uri.fromFile(file)); + } + } + } + + if (imageUris.isEmpty()) { + Toast.makeText(activity, "没有有效图片可分享", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "没有有效图片可分享"); + } + return; + } + + Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); + // 获取已安装的抖音包名 + String packageName = getInstalledDouYinPackage(); + intent.setPackage(packageName); + intent.setType("image/*"); + intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + + try { + startShareActivity(activity, intent); + } catch (Exception e) { + // 如果直接分享失败,使用系统分享选择器 + Log.d(TAG, "多图直接分享失败,使用系统分享: " + e.getMessage()); + Intent chooser = Intent.createChooser(intent.setPackage(null), "分享到抖音"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 分享Bitmap到抖音 + * @param activity 活动 + * @param bitmap 位图 + */ + public void shareBitmapToDouyin(Activity activity, Bitmap bitmap) { + if (bitmap == null) { + Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "分享图片为空"); + } + return; + } + + // 直接在此类中实现保存Bitmap到临时文件的功能,避免依赖外部工具类 + try { + File cacheDir = activity.getExternalCacheDir(); + if (cacheDir == null) { + cacheDir = activity.getCacheDir(); + } + + File imageFile = new File(cacheDir, "douyin_share_" + UUID.randomUUID().toString() + ".jpg"); + FileOutputStream fos = new FileOutputStream(imageFile); + bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); + fos.flush(); + fos.close(); + + // 保存成功,分享图片 + shareImageToDouyin(activity, imageFile.getAbsolutePath()); + } catch (Exception e) { + Toast.makeText(activity, "保存图片失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "保存图片失败: " + e.getMessage()); + } + } + } + + /** + * 分享视频到抖音 + * @param activity 活动 + * @param videoPath 视频路径 + */ + public void shareVideoToDouyin(Activity activity, String videoPath) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + File videoFile = new File(videoPath); + if (!videoFile.exists()) { + Toast.makeText(activity, "视频文件不存在", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "视频文件不存在"); + } + return; + } + + try { + Intent intent = new Intent(Intent.ACTION_SEND); + // 获取已安装的抖音包名 + String packageName = getInstalledDouYinPackage(); + intent.setPackage(packageName); + intent.setType("video/*"); + + // 根据Android版本使用不同的Uri方式 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // Android 7.0及以上使用FileProvider + Uri videoUri = FileProviderUtil.getUriForFile(activity, videoFile); + intent.putExtra(Intent.EXTRA_STREAM, videoUri); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + // Android 7.0以下直接使用文件Uri + intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(videoFile)); + } + + try { + startShareActivity(activity, intent); + } catch (Exception e) { + // 如果直接分享失败,使用系统分享选择器 + Log.d(TAG, "视频直接分享失败,使用系统分享: " + e.getMessage()); + Intent chooser = Intent.createChooser(intent.setPackage(null), "分享到抖音"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 分享网页链接到抖音 + * 抖音不支持直接分享网页,只能通过文本方式 + * @param activity 活动 + * @param title 标题 + * @param description 描述 + * @param webUrl 网页链接 + */ + public void shareWebPageToDouyin(Activity activity, String title, String description, String webUrl) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + // 抖音只能通过文本方式分享网页链接 + StringBuilder sb = new StringBuilder(); + if (!TextUtils.isEmpty(title)) { + sb.append(title).append("\n\n"); + } + if (!TextUtils.isEmpty(description)) { + sb.append(description).append("\n\n"); + } + if (!TextUtils.isEmpty(webUrl)) { + sb.append(webUrl); + } + + shareTextToDouyin(activity, sb.toString()); + } + + /** + * 分享网页链接到抖音 + * @param activity 活动 + * @param url 要分享的网页链接 + * @param title 分享标题,可选 + * @param description 分享描述,可选 + */ + public void shareWebpageToDouyin(Activity activity, String url, String title, String description) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return; + } + + if (TextUtils.isEmpty(url)) { + Toast.makeText(activity, "分享链接不能为空", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "分享链接不能为空"); + } + return; + } + + try { + String packageName = getInstalledDouYinPackage(); + + // 构建完整分享内容 + StringBuilder shareContent = new StringBuilder(); + if (!TextUtils.isEmpty(title)) { + shareContent.append(title).append("\n"); + } + if (!TextUtils.isEmpty(description)) { + shareContent.append(description).append("\n"); + } + shareContent.append(url); + + // 复制到剪贴板,便于用户在抖音中粘贴 + copyToClipboard(activity, shareContent.toString()); + + // 方法1: 尝试使用系统分享直接发送到抖音 + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setPackage(packageName); // 指定只分享到抖音 + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_TEXT, shareContent.toString()); + + try { + activity.startActivity(shareIntent); + Log.d(TAG, "已发送网页分享Intent到抖音"); + + // 延迟回调成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return; + } catch (android.content.ActivityNotFoundException e) { + Log.e(TAG, "直接分享网页到抖音失败,尝试替代方法: " + e.getMessage()); + } + + // 方法2: 如果直接分享失败,尝试使用VIEW操作打开抖音分享页面 + try { + // 抖音支持的分享scheme,尝试不同的形式 + String[] shareSchemes = { + "snssdk1128://share?content=" + Uri.encode(shareContent.toString()), + "douyin://share?content=" + Uri.encode(shareContent.toString()), + "aweme://share?content=" + Uri.encode(shareContent.toString()) + }; + + for (String scheme : shareSchemes) { + try { + Intent schemeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme)); + schemeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + schemeIntent.setPackage(packageName); + activity.startActivity(schemeIntent); + Log.d(TAG, "成功使用scheme方式分享网页到抖音: " + scheme); + + // 延迟回调成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return; + } catch (Exception schemeEx) { + Log.e(TAG, "scheme方式分享失败 " + scheme + ": " + schemeEx.getMessage()); + // 继续尝试下一个scheme + } + } + } catch (Exception e) { + Log.e(TAG, "scheme分享过程中出现异常: " + e.getMessage()); + } + + // 方法3: 如果前两种方法都失败,启动抖音并提示用户手动粘贴分享 + boolean launched = tryLaunchDouyin(activity); + if (launched) { + Toast.makeText(activity, "已将链接复制到剪贴板,请在抖音中粘贴并分享", Toast.LENGTH_LONG).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return; + } + + // 方法4: 如果启动抖音也失败,尝试使用系统分享选择器 + Intent chooserIntent = Intent.createChooser(shareIntent.setPackage(null), "分享到"); + activity.startActivity(chooserIntent); + Toast.makeText(activity, "请从分享列表中选择抖音", Toast.LENGTH_SHORT).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + + } catch (Exception e) { + Log.e(TAG, "分享网页过程中出现异常: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + + + /** + * 启动分享Activity - 不再直接调用,使用系统分享菜单代替 + */ + private void startShareActivity(Activity activity, Intent intent) { + try { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + // 创建选择器并提示用户选择抖音 + Intent chooser = Intent.createChooser(intent, "分享到抖音"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择抖音", Toast.LENGTH_SHORT).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 处理未安装抖音的情况 + */ + private void handleNotInstalled(Activity activity) { + Toast.makeText(activity, "请先安装抖音客户端", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "未安装抖音客户端"); + } + } + + /** + * 处理分享异常 + */ + private void handleShareException(Activity activity, Exception e) { + Toast.makeText(activity, "分享失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-3, "分享失败: " + e.getMessage()); + } + } + + /** + * 处理抖音分享结果回调 + * @param req 请求对象 + * @param resp 响应对象 + */ + public void handleShareResult(Object req, Object resp) { + if (resp == null) { + return; + } + + try { + // 尝试通过反射获取状态码 + int errorCode = -1; + String errorMsg = "未知错误"; + + try { + // 尝试从响应对象获取状态码和错误信息 + Class respClass = resp.getClass(); + java.lang.reflect.Field errCodeField = respClass.getDeclaredField("errCode"); + java.lang.reflect.Field errStrField = respClass.getDeclaredField("errStr"); + + errCodeField.setAccessible(true); + errStrField.setAccessible(true); + + errorCode = (int) errCodeField.get(resp); + errorMsg = (String) errStrField.get(resp); + } catch (Exception e) { + // 反射失败,尝试通过toString()方法解析响应信息 + String respStr = resp.toString(); + if (respStr.contains("errCode=")) { + try { + int startIndex = respStr.indexOf("errCode=") + 8; + int endIndex = respStr.indexOf(",", startIndex); + if (endIndex < 0) { + endIndex = respStr.indexOf("}", startIndex); + } + if (endIndex > startIndex) { + errorCode = Integer.parseInt(respStr.substring(startIndex, endIndex).trim()); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + // 根据错误码处理不同的结果 + if (errorCode == 0) { + // 分享成功 + if (mCallback != null) { + mCallback.onSuccess(); + } + } else if (errorCode == -2) { + // 用户取消 + if (mCallback != null) { + mCallback.onCancel(); + } + } else { + // 分享失败 + if (mCallback != null) { + mCallback.onError(errorCode, errorMsg); + } + } + } catch (Exception e) { + e.printStackTrace(); + if (mCallback != null) { + mCallback.onError(-1, "处理分享结果异常: " + e.getMessage()); + } + } + } + + /** + * 分享内容到抖音私信 + * @param activity 活动上下文 + * @param content 要分享的内容 + * @param mediaUri 要分享的媒体Uri (可为null) + * @param mediaType 媒体类型 ("image"或"video",仅在mediaUri不为null时有效) + * @return 是否成功启动分享 + */ + public boolean shareToPrivateMessage(Activity activity, String content, Uri mediaUri, String mediaType) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return false; + } + + try { + // 简化处理:将文本复制到剪贴板 + if (content != null && !content.isEmpty()) { + copyToClipboard(activity, content); + Toast.makeText(activity, "内容已复制到剪贴板,请在抖音中粘贴发送", Toast.LENGTH_LONG).show(); + } + + // 直接启动抖音主应用 + boolean launched = tryLaunchDouyin(activity); + if (launched) { + // 成功启动,提示用户操作步骤 + Toast.makeText(activity, "请点击抖音底部\"消息\"按钮,选择联系人并粘贴内容", Toast.LENGTH_LONG).show(); + + // 假设操作成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + return true; + } else { + // 启动失败 + Toast.makeText(activity, "无法启动抖音,请手动打开抖音进行分享", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "无法启动抖音"); + } + return false; + } + } catch (Exception e) { + Log.e(TAG, "分享到抖音私信过程中发生异常: " + e.getMessage(), e); + if (mCallback != null) { + mCallback.onError(-1, "分享失败: " + e.getMessage()); + } + return false; + } + } + + /** + * 分享内容到抖音群聊 + * @param activity 活动上下文 + * @param content 要分享的内容 + * @param mediaUri 要分享的媒体Uri (可为null) + * @param mediaType 媒体类型 ("image"或"video",仅在mediaUri不为null时有效) + * @return 是否成功启动分享 + */ + public boolean shareToGroupChat(Activity activity, String content, Uri mediaUri, String mediaType) { + if (!isDouyinInstalled()) { + handleNotInstalled(activity); + return false; + } + + try { + String packageName = getInstalledDouYinPackage(); + + // 尝试各种可能的群聊URI scheme + String[] groupChatSchemes = { + "snssdk1128://chat_group", // 可能的群聊scheme + "douyin://chat_group", // 可能的群聊scheme + "aweme://chat_group", // 可能的群聊scheme + "snssdk1128://im/group", // 可能的群聊scheme + "douyin://im/group", // 可能的群聊scheme + }; + + boolean groupPageOpened = false; + + for (String scheme : groupChatSchemes) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(scheme)); + intent.setPackage(packageName); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + activity.startActivity(intent); + Log.d(TAG, "成功使用scheme打开抖音群聊页面: " + scheme); + groupPageOpened = true; + break; + } catch (Exception e) { + Log.e(TAG, "scheme方式失败 " + scheme + ": " + e.getMessage()); + // 继续尝试下一个scheme + } + } + + if (!groupPageOpened) { + // 如果无法直接打开群聊页面,尝试打开普通消息页面 + boolean messagePageOpened = openDouYinMessagePage(activity); + + if (!messagePageOpened) { + // 如果消息页面也打不开,就直接启动抖音 + boolean launched = tryLaunchDouyin(activity); + if (launched) { + Toast.makeText(activity, "抖音已启动,请点击底部消息按钮进入并选择群聊", Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(activity, "无法启动抖音,请手动操作", Toast.LENGTH_SHORT).show(); + return false; + } + } else { + Toast.makeText(activity, "请在消息页面选择或创建群聊进行分享", Toast.LENGTH_LONG).show(); + } + } else { + Toast.makeText(activity, "请选择群聊进行分享", Toast.LENGTH_LONG).show(); + } + + // 将内容复制到剪贴板以便用户粘贴 + if (content != null && !content.isEmpty()) { + copyToClipboard(activity, content); + Toast.makeText(activity, "内容已复制到剪贴板,可在群聊中粘贴", Toast.LENGTH_SHORT).show(); + } + + // 如果有媒体文件,通过临时文件存储,以便用户手动分享 + if (mediaUri != null) { + try { + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setPackage(packageName); + + if ("image".equals(mediaType)) { + shareIntent.setType("image/*"); + } else if ("video".equals(mediaType)) { + shareIntent.setType("video/*"); + } else { + shareIntent.setType("*/*"); + } + + shareIntent.putExtra(Intent.EXTRA_STREAM, mediaUri); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + + // 创建临时分享弹窗,辅助用户操作 + Intent chooser = Intent.createChooser(shareIntent, "请选择'抖音'"); + activity.startActivity(chooser); + + Toast.makeText(activity, "请在弹出窗口中选择抖音,进入群聊后再选择群组", Toast.LENGTH_LONG).show(); + } catch (Exception e) { + Log.e(TAG, "准备媒体分享失败: " + e.getMessage()); + // 如果媒体分享失败,至少已经将文本内容复制到剪贴板 + } + } + + // 假设分享过程启动成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + + return true; + } catch (Exception e) { + Log.e(TAG, "分享到群聊过程中发生异常: " + e.getMessage(), e); + if (mCallback != null) { + mCallback.onError(-1, "分享到群聊失败: " + e.getMessage()); + } + return false; + } + } + + /** + * 兼容性复制文本到剪贴板 + * 支持API 9及以上版本 + * @param context 上下文 + * @param text 要复制的文本 + */ + private void copyToClipboard(Context context, String text) { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // API 11及以上使用ClipboardManager + android.content.ClipboardManager clipboardManager = + (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clipData = + android.content.ClipData.newPlainText("分享内容", text); + clipboardManager.setPrimaryClip(clipData); + } else { + // API 11以下使用旧版的android.text.ClipboardManager + android.text.ClipboardManager clipboardManager = + (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + clipboardManager.setText(text); + } + Log.d(TAG, "成功复制文本到剪贴板"); + } catch (Exception e) { + Log.e(TAG, "复制到剪贴板失败: " + e.getMessage(), e); + } + } + + /** + * 打开抖音消息页面 + * @param activity 活动 + * @return 是否成功打开 + */ + private boolean openDouYinMessagePage(Activity activity) { + String packageName = getInstalledDouYinPackage(); + + // 抖音消息页面的可能URI schemas + String[] messageSchemas = { + "snssdk1128://chat?type=im_friend", // 标准抖音 + "douyin://chat?type=im_friend", // 新版抖音 + "aweme://chat?type=im_friend", // 旧版抖音 + "snssdk1128://im/friend", // 其他可能的schema + "douyin://im/friend", // 其他可能的schema + }; + + // 尝试打开抖音消息选择页面 + for (String schema : messageSchemas) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(schema)); + intent.setPackage(packageName); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + Log.d(TAG, "成功使用Schema打开抖音消息页面: " + schema); + return true; + } catch (Exception e) { + Log.e(TAG, "使用Schema " + schema + " 打开抖音消息页面失败: " + e.getMessage()); + // 继续尝试下一个schema + } + } + + // 如果所有Schema都失败了,尝试直接打开具体的消息Activity + try { + Intent intent = new Intent(); + intent.setComponent(new ComponentName(packageName, packageName + ".module.message.ui.MessageListActivity")); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + Log.d(TAG, "成功使用组件名称打开抖音消息页面"); + return true; + } catch (Exception e) { + Log.e(TAG, "使用组件名称打开抖音消息页面失败: " + e.getMessage()); + } + + return false; + } + /** + * 抖音分享回调接口 + */ + public interface DouYinShareCallback { + void onSuccess(); + void onError(int code, String message); + void onCancel(); + } +} diff --git a/ref/QQIntentShareUtil.java b/ref/QQIntentShareUtil.java new file mode 100644 index 0000000..6928b5c --- /dev/null +++ b/ref/QQIntentShareUtil.java @@ -0,0 +1,783 @@ +package com.tsgame.tsgame_niuniu.util; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.text.TextUtils; +import android.util.Log; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +/** + * QQ分享工具类 - 无需SDK,使用Intent实现 + */ +public class QQIntentShareUtil { + + private static final String TAG = "QQIntentShareUtil"; + + // QQ可能的包名列表 + private static final String QQ_PACKAGE_NAME = "com.tencent.mobileqq"; + private static final String TIM_PACKAGE_NAME = "com.tencent.tim"; + private static final String QQ_LITE_PACKAGE_NAME = "com.tencent.qqlite"; + private static final String QQ_INTERNATIONAL_PACKAGE_NAME = "com.tencent.mobileqqi"; + + // 可能的QQ包名列表 + private static final List QQ_PACKAGES = Arrays.asList( + QQ_PACKAGE_NAME, // 标准QQ + TIM_PACKAGE_NAME, // TIM + QQ_LITE_PACKAGE_NAME, // QQ轻聊版 + QQ_INTERNATIONAL_PACKAGE_NAME // 国际版QQ + ); + + // QQ分享的Activity组件名称 + private static final String QQ_SHARE_COMPONENT = "com.tencent.mobileqq.activity.JumpActivity"; + private static final String QQ_TIM_SHARE_COMPONENT = "com.tencent.tim.activity.JumpActivity"; + + // QQ聊天的Activity组件名称 + private static final String QQ_CHAT_COMPONENT = "com.tencent.mobileqq.activity.ChatActivity"; + private static final String TIM_CHAT_COMPONENT = "com.tencent.tim.activity.ChatActivity"; + + // QQ临时会话的Activity组件名称 + private static final String QQ_TEMP_CHAT_COMPONENT = "com.tencent.mobileqq.activity.TempSessionActivity"; + private static final String TIM_TEMP_CHAT_COMPONENT = "com.tencent.tim.activity.TempSessionActivity"; + + // QQ空间分享的Activity组件名称 + private static final String QZONE_COMPONENT = "com.tencent.mobileqq.activity.QzonePublishMoodActivity"; + private static final String TIM_QZONE_COMPONENT = "com.tencent.tim.activity.QzonePublishMoodActivity"; + + private static QQIntentShareUtil instance; + private final Context mContext; + private QQShareCallback mCallback; + + // 缓存已安装的QQ包名 + private String installedQQPackage = null; + + private QQIntentShareUtil(Context context) { + this.mContext = context.getApplicationContext(); + } + + public static QQIntentShareUtil getInstance(Context context) { + if (instance == null && context != null) { + instance = new QQIntentShareUtil(context); + } + return instance; + } + + /** + * 设置分享回调 + * @param callback 分享回调 + */ + public void setShareCallback(QQShareCallback callback) { + this.mCallback = callback; + } + + /** + * 检查QQ是否已安装 + * @return 是否安装 + */ + public boolean isQQInstalled() { + // 如果之前已找到包名,直接返回true + if (installedQQPackage != null) { + return true; + } + + // 检查所有可能的QQ包名 + PackageManager pm = mContext.getPackageManager(); + for (String packageName : QQ_PACKAGES) { + try { + pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); + // 找到已安装的QQ,缓存包名 + installedQQPackage = packageName; + Log.d(TAG, "找到已安装的QQ: " + packageName); + return true; + } catch (PackageManager.NameNotFoundException e) { + // 继续检查下一个包名 + continue; + } + } + + Log.d(TAG, "未找到已安装的QQ应用"); + return false; + } + + /** + * 获取已安装的QQ包名 + * @return QQ包名,如果未安装则返回默认包名 + */ + private String getInstalledQQPackage() { + if (installedQQPackage != null) { + return installedQQPackage; + } + + // 如果没有缓存,重新检测 + isQQInstalled(); + return installedQQPackage != null ? installedQQPackage : QQ_PACKAGE_NAME; + } + + /** + * 获取QQ分享的组件名称 + */ + private String getQQShareComponent() { + String packageName = getInstalledQQPackage(); + if (TIM_PACKAGE_NAME.equals(packageName)) { + return QQ_TIM_SHARE_COMPONENT; + } + return QQ_SHARE_COMPONENT; + } + + /** + * 获取QQ聊天的组件名称 + */ + private String getQQChatComponent() { + String packageName = getInstalledQQPackage(); + if (TIM_PACKAGE_NAME.equals(packageName)) { + return TIM_CHAT_COMPONENT; + } + return QQ_CHAT_COMPONENT; + } + + /** + * 获取QQ临时会话的组件名称 + */ + private String getQQTempChatComponent() { + String packageName = getInstalledQQPackage(); + if (TIM_PACKAGE_NAME.equals(packageName)) { + return TIM_TEMP_CHAT_COMPONENT; + } + return QQ_TEMP_CHAT_COMPONENT; + } + + /** + * 获取QQ空间分享的组件名称 + */ + private String getQZoneShareComponent() { + String packageName = getInstalledQQPackage(); + if (TIM_PACKAGE_NAME.equals(packageName)) { + return TIM_QZONE_COMPONENT; + } + return QZONE_COMPONENT; + } + + /** + * 分享纯文本到QQ好友 + * @param activity 活动 + * @param text 要分享的文本 + */ + public void shareTextToQQ(Activity activity, String text) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + + try { + // 1. 将文本复制到剪贴板 + copyToClipboard(activity, text); +// Toast.makeText(activity, "内容已复制到剪贴板,请选择联系人后粘贴发送", Toast.LENGTH_LONG).show(); + + // 2. 使用QQ的特定组件启动联系人选择界面 + String packageName = getInstalledQQPackage(); + boolean launched = false; + +// // 新增方法: 使用QQ最新的联系人选择器组件 +// if (!launched) { +// try { +// Intent intent = new Intent(); +// // 使用QQ联系人选择Activity (QQ8.x及以上版本支持) +// ComponentName comp = new ComponentName(packageName, "com.tencent.mobileqq.activity.FriendProfileCardActivity"); +// intent.setComponent(comp); +// // 添加特定参数 +// intent.putExtra("fling_action_key", 2); // 2表示选择联系人 +// intent.putExtra("preAct", "ContactsActivity"); +// intent.putExtra("need_update_friend_list", true); +// intent.putExtra("isFromShare", true); +// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// activity.startActivity(intent); +// launched = true; +// Log.d(TAG, "成功使用FriendProfileCardActivity启动QQ联系人选择器"); +// } catch (Exception e) { +// Log.e(TAG, "使用FriendProfileCardActivity启动QQ联系人选择器失败: " + e.getMessage()); +// } +// } + + // 方法1: 使用QQ的联系人选择器组件 + if (!launched) { + try { + Intent intent = new Intent(); + // 使用专门的联系人选择Activity + ComponentName comp = new ComponentName(packageName, "com.tencent.mobileqq.activity.contacts.SortContactsListActivity"); + intent.setComponent(comp); + // 添加特定参数,提示QQ这是一个分享操作 + intent.putExtra("key_operation_type", 5); // 5表示分享操作类型 + intent.putExtra("key_is_friend_chooser", 1); + intent.putExtra("key_source_from", 12); + intent.putExtra("isFromShare", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + launched = true; + Log.d(TAG, "成功使用联系人选择器组件启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用联系人选择器组件启动QQ失败: " + e.getMessage()); + } + } + + // 方法2: 使用QQ的跳转组件并携带分享标识 + if (!launched) { + try { + Intent intent = new Intent(); + ComponentName comp = new ComponentName(packageName, getQQShareComponent()); + intent.setComponent(comp); + // 添加分享参数 + intent.setAction(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, text); + // 添加特定参数,强制打开联系人选择器 + intent.putExtra("pkg_name", activity.getPackageName()); + intent.putExtra("from_scene", 10); // 10表示APP分享 + intent.putExtra("req_type", 1); // 1表示选择好友 + intent.putExtra("to_scene", 2); // 2表示聊天窗口 + intent.putExtra("isFromShare", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + launched = true; + Log.d(TAG, "成功使用分享组件启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用分享组件启动QQ失败: " + e.getMessage()); + } + } + + // 方法3: 使用QQ的会话Activity + if (!launched) { + try { + Intent intent = new Intent(); + ComponentName comp = new ComponentName(packageName, "com.tencent.mobileqq.activity.FriendlistActivity"); + intent.setComponent(comp); + intent.putExtra("isFromShare", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + launched = true; + Log.d(TAG, "成功使用好友列表Activity启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用好友列表Activity启动QQ失败: " + e.getMessage()); + } + } + + // 方法4: 使用通常的标准聊天组件 + if (!launched) { + try { + Intent intent = new Intent(); + ComponentName comp = new ComponentName(packageName, getQQChatComponent()); + intent.setComponent(comp); + intent.putExtra("uinname", ""); + intent.putExtra("uintype", 0); + intent.putExtra("isFromShare", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + launched = true; + Log.d(TAG, "成功使用聊天组件启动QQ"); + } catch (Exception e) { + Log.e(TAG, "使用聊天组件启动QQ失败: " + e.getMessage()); + } + } + + // 如果以上方法都失败,回退到标准启动方法 + if (!launched) { + try { + Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(packageName); + if (launchIntent != null) { + launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(launchIntent); + launched = true; + Log.d(TAG, "成功使用标准方式启动QQ"); + } + } catch (Exception e) { + Log.e(TAG, "标准方式启动QQ失败: " + e.getMessage()); + } + } + + // 如果以上方法都失败,尝试系统分享 + if (!launched) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, text); + Intent chooser = Intent.createChooser(intent, "分享到QQ"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); + } else { +// Toast.makeText(activity, "请选择联系人并粘贴内容", Toast.LENGTH_LONG).show(); + } + + // 假设分享过程启动成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + Log.e(TAG, "分享文本到QQ失败: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 分享纯文本到QQ空间 + * @param activity 活动 + * @param text 要分享的文本 + */ + public void shareTextToQZone(Activity activity, String text) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + + try { + String packageName = getInstalledQQPackage(); + + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, text); + + // 使用组件名称直接跳转到QQ空间分享界面 + ComponentName comp = new ComponentName(packageName, getQZoneShareComponent()); + intent.setComponent(comp); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + activity.startActivity(intent); + Toast.makeText(activity, "正在分享到QQ空间", Toast.LENGTH_SHORT).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + Log.e(TAG, "分享文本到QQ空间失败: " + e.getMessage(), e); + + // 尝试使用通用分享 + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, text); + + Intent chooser = Intent.createChooser(intent, "分享到QQ空间"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); + + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception ex) { + handleShareException(activity, ex); + } + } + } + + /** + * 分享图片到QQ + * @param activity 活动 + * @param localImagePath 本地图片路径 + */ + public void shareImageToQQ(Activity activity, String localImagePath) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + + File imageFile = new File(localImagePath); + if (!imageFile.exists()) { + Toast.makeText(activity, "分享图片不存在", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "图片文件不存在"); + } + return; + } + + try { + String packageName = getInstalledQQPackage(); + + // 创建分享Intent + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("image/*"); + + // 设置组件名称 + ComponentName comp = new ComponentName(packageName, getQQShareComponent()); + shareIntent.setComponent(comp); + + // 根据Android版本使用不同的Uri方式 + Uri imageUri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // Android 7.0及以上使用FileProvider + imageUri = FileProviderUtil.getUriForFile(activity, imageFile); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + // Android 7.0以下直接使用文件Uri + imageUri = Uri.fromFile(imageFile); + } + + shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); + shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + activity.startActivity(shareIntent); + Log.d(TAG, "已发送分享图片Intent到QQ"); + + // 延迟回调成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (android.content.ActivityNotFoundException e) { + Log.e(TAG, "直接分享到QQ失败,尝试使用选择器: " + e.getMessage()); + + // 如果直接分享失败,使用选择器 + Intent chooserIntent = Intent.createChooser(shareIntent.setComponent(null), "分享到QQ"); + activity.startActivity(chooserIntent); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } + } catch (Exception e) { + Log.e(TAG, "分享图片到QQ失败: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 分享图片到QQ空间 + * @param activity 活动 + * @param localImagePath 本地图片路径 + */ + public void shareImageToQZone(Activity activity, String localImagePath) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + + File imageFile = new File(localImagePath); + if (!imageFile.exists()) { + Toast.makeText(activity, "分享图片不存在", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "图片文件不存在"); + } + return; + } + + try { + String packageName = getInstalledQQPackage(); + + // 创建分享Intent + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("image/*"); + + // 设置组件名称 + ComponentName comp = new ComponentName(packageName, getQZoneShareComponent()); + shareIntent.setComponent(comp); + + // 根据Android版本使用不同的Uri方式 + Uri imageUri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // Android 7.0及以上使用FileProvider + imageUri = FileProviderUtil.getUriForFile(activity, imageFile); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + // Android 7.0以下直接使用文件Uri + imageUri = Uri.fromFile(imageFile); + } + + shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); + shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + activity.startActivity(shareIntent); + Log.d(TAG, "已发送分享图片Intent到QQ空间"); + + // 延迟回调成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (android.content.ActivityNotFoundException e) { + Log.e(TAG, "直接分享到QQ空间失败,尝试使用选择器: " + e.getMessage()); + + // 如果直接分享失败,使用选择器 + Intent chooserIntent = Intent.createChooser(shareIntent.setComponent(null), "分享到QQ空间"); + activity.startActivity(chooserIntent); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } + } catch (Exception e) { + Log.e(TAG, "分享图片到QQ空间失败: " + e.getMessage(), e); + handleShareException(activity, e); + } + } + + /** + * 分享Bitmap到QQ + * @param activity 活动 + * @param bitmap 位图 + * @param isQzone 是否分享到QQ空间 + */ + public void shareBitmapToQQ(Activity activity, Bitmap bitmap, boolean isQzone) { + if (bitmap == null) { + Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "分享图片为空"); + } + return; + } + + try { + File cacheDir = activity.getExternalCacheDir(); + if (cacheDir == null) { + cacheDir = activity.getCacheDir(); + } + + File imageFile = new File(cacheDir, "qq_share_" + UUID.randomUUID().toString() + ".jpg"); + FileOutputStream fos = new FileOutputStream(imageFile); + bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); + fos.flush(); + fos.close(); + + // 保存成功,分享图片 + if (isQzone) { + shareImageToQZone(activity, imageFile.getAbsolutePath()); + } else { + shareImageToQQ(activity, imageFile.getAbsolutePath()); + } + } catch (Exception e) { + Toast.makeText(activity, "保存图片失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-2, "保存图片失败: " + e.getMessage()); + } + } + } + + /** + * 分享多张图片到QQ(群发) + * @param activity 活动 + * @param imagePaths 图片路径列表 + * @param isQzone 是否分享到QQ空间 + */ + public void shareImagesToQQ(Activity activity, ArrayList imagePaths, boolean isQzone) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + + if (imagePaths == null || imagePaths.isEmpty()) { + Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "分享图片为空"); + } + return; + } + + try { + ArrayList imageUris = new ArrayList<>(); + for (String path : imagePaths) { + File file = new File(path); + if (file.exists()) { + // 根据Android版本使用不同的Uri方式 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + // Android 7.0及以上使用FileProvider + Uri fileUri = FileProviderUtil.getUriForFile(activity, file); + imageUris.add(fileUri); + } else { + // Android 7.0以下直接使用文件Uri + imageUris.add(Uri.fromFile(file)); + } + } + } + + if (imageUris.isEmpty()) { + Toast.makeText(activity, "没有有效图片可分享", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "没有有效图片可分享"); + } + return; + } + + Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); + // 获取已安装的QQ包名 + String packageName = getInstalledQQPackage(); + intent.setPackage(packageName); + intent.setType("image/*"); + intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); + + // 设置组件名称 + if (isQzone) { + ComponentName comp = new ComponentName(packageName, getQZoneShareComponent()); + intent.setComponent(comp); + } else { + ComponentName comp = new ComponentName(packageName, getQQShareComponent()); + intent.setComponent(comp); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + activity.startActivity(intent); + Log.d(TAG, "已发送多图分享Intent到QQ"); + + // 延迟回调成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } catch (Exception e) { + // 如果直接分享失败,使用系统分享选择器 + Log.d(TAG, "多图直接分享失败,使用系统分享: " + e.getMessage()); + Intent chooser = Intent.createChooser(intent.setComponent(null), isQzone ? "分享到QQ空间" : "分享到QQ"); + activity.startActivity(chooser); + Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); + + // 假设分享成功 + if (mCallback != null) { + new Handler(Looper.getMainLooper()).postDelayed(() -> { + mCallback.onSuccess(); + }, 1000); + } + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 分享网页链接到QQ + * @param activity 活动 + * @param title 标题 + * @param description 描述 + * @param webUrl 网页链接 + * @param imageUrl 图片链接(可选) + * @param isQzone 是否分享到QQ空间 + */ + public void shareWebPageToQQ(Activity activity, String title, String description, String webUrl, String imageUrl, boolean isQzone) { + if (!isQQInstalled()) { + handleNotInstalled(activity); + return; + } + + try { + // QQ支持直接分享网页链接,但实际上QQ会解析文本内容来查找URL + StringBuilder sb = new StringBuilder(); + if (!TextUtils.isEmpty(title)) { + sb.append(title).append("\n\n"); + } + if (!TextUtils.isEmpty(description)) { + sb.append(description).append("\n\n"); + } + + + String text = sb.toString().trim(); + + if (isQzone) { + shareTextToQZone(activity, text); + } else { + shareTextToQQ(activity, text); + } + } catch (Exception e) { + handleShareException(activity, e); + } + } + + /** + * 处理未安装QQ的情况 + */ + private void handleNotInstalled(Activity activity) { + Toast.makeText(activity, "请先安装QQ客户端", Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-1, "未安装QQ客户端"); + } + } + + /** + * 处理分享异常 + */ + private void handleShareException(Activity activity, Exception e) { + Toast.makeText(activity, "分享失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + if (mCallback != null) { + mCallback.onError(-3, "分享失败: " + e.getMessage()); + } + } + + /** + * 兼容性复制文本到剪贴板 + * 支持API 9及以上版本 + * @param context 上下文 + * @param text 要复制的文本 + */ + private void copyToClipboard(Context context, String text) { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // API 11及以上使用ClipboardManager + android.content.ClipboardManager clipboardManager = + (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipData clipData = + android.content.ClipData.newPlainText("分享内容", text); + clipboardManager.setPrimaryClip(clipData); + } else { + // API 11以下使用旧版的android.text.ClipboardManager + android.text.ClipboardManager clipboardManager = + (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + clipboardManager.setText(text); + } + } catch (Exception e) { + Log.e(TAG, "复制到剪贴板失败: " + e.getMessage(), e); + } + } + + /** + * QQ分享回调接口 + */ + public interface QQShareCallback { + /** + * 分享成功 + */ + void onSuccess(); + + /** + * 分享失败 + * @param code 错误码 + * @param msg 错误信息 + */ + void onError(int code, String msg); + + /** + * 分享取消 + */ + void onCancel(); + } +}