fix(WeChatShare): 将微信的直接分享逻辑对齐到QQ(使用ComponentName),确保文本及图片均能绕过系统直接拉起微信

This commit is contained in:
2026-03-11 07:48:00 +08:00
parent 2432fc333e
commit bdc7144cf8

View File

@@ -1,6 +1,7 @@
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;
@@ -53,6 +54,27 @@ public class WeChatIntentShareUtil {
return instance;
}
/**
* 兼容性复制文本到剪贴板
*/
private void copyToClipboard(Context context, String text) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
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 {
android.text.ClipboardManager clipboardManager =
(android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboardManager.setText(text);
}
} catch (Exception e) {
Log.e(TAG, "复制到剪贴板失败: " + e.getMessage(), e);
}
}
/**
* 设置分享回调
* @param callback 回调接口
@@ -71,6 +93,18 @@ public class WeChatIntentShareUtil {
pm.getPackageInfo(WECHAT_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
// 在鸿蒙或较高版本安卓下,可能会因为权限问题无法获取包信息
try {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.setPackage(WECHAT_PACKAGE_NAME);
List<?> list = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (list != null && list.size() > 0) {
return true;
}
} catch (Exception ex) {
// 忽略
}
return false;
}
}
@@ -82,9 +116,11 @@ public class WeChatIntentShareUtil {
* @param scene 分享场景0-好友1-朋友圈
*/
public void shareTextToWeChat(Activity activity, String text, int scene) {
if (!isWeChatInstalled()) {
handleNotInstalled(activity);
return;
boolean isPackageDetected = isWeChatInstalled();
// 应对鸿蒙等可能存在的限制环境,仅在分享到朋友圈时先复制文本
if (scene != SCENE_FRIENDS) {
copyToClipboard(activity, text);
}
try {
@@ -93,26 +129,48 @@ public class WeChatIntentShareUtil {
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, text);
// 指定微信包名
intent.setPackage(WECHAT_PACKAGE_NAME);
// 鸿蒙/卓易通关键适配Flags
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();
Toast.makeText(activity, "微信朋友圈不支持纯文本分享,建议使用图文", Toast.LENGTH_SHORT).show();
if (mCallback != null) {
mCallback.onError(-1, "微信朋友圈不支持纯文本分享");
}
return;
}
try {
activity.startActivity(intent);
handleShareSuccess();
} catch (Exception e) {
Log.e(TAG, "分享文本到微信失败: " + e.getMessage(), e);
handleShareException(activity, e);
boolean launched = false;
if (isPackageDetected) {
try {
Intent directIntent = new Intent(intent);
ComponentName comp = new ComponentName(WECHAT_PACKAGE_NAME, WECHAT_FRIENDS_ACTIVITY);
directIntent.setComponent(comp);
activity.startActivity(directIntent);
launched = true;
} catch (Exception e) {
Log.e(TAG, "直接分享文本到微信失败: " + e.getMessage(), e);
}
}
if (!launched) {
try {
Intent chooserIntent = Intent.createChooser(intent, "请选择微信进行分享");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(chooserIntent);
launched = true;
} catch (Exception e) {
Log.e(TAG, "Chooser分享失败: " + e.getMessage());
}
}
activity.runOnUiThread(() -> Toast.makeText(activity, "已复制内容,请在微信中粘贴", Toast.LENGTH_SHORT).show());
handleShareSuccess(activity);
} catch (Exception e) {
Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e);
handleShareException(activity, e);
@@ -126,10 +184,7 @@ public class WeChatIntentShareUtil {
* @param scene 分享场景0-好友1-朋友圈
*/
public void shareImage(Activity activity, String localImagePath, int scene) {
if (!isWeChatInstalled()) {
handleNotInstalled(activity);
return;
}
boolean isPackageDetected = isWeChatInstalled();
File imageFile = new File(localImagePath);
if (!imageFile.exists()) {
@@ -158,36 +213,44 @@ public class WeChatIntentShareUtil {
intent.putExtra(Intent.EXTRA_STREAM, imageUri);
// 指定微信包名
intent.setPackage(WECHAT_PACKAGE_NAME);
// 鸿蒙/卓易通关键适配Flags
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 根据分享场景指定目标Activity
if (scene == SCENE_MOMENTS) {
// 分享到朋友圈
intent.setClassName(WECHAT_PACKAGE_NAME, WECHAT_MOMENTS_ACTIVITY);
} else {
// 分享给好友
intent.setClassName(WECHAT_PACKAGE_NAME, WECHAT_FRIENDS_ACTIVITY);
}
boolean launched = false;
try {
activity.startActivity(intent);
handleShareSuccess();
} catch (Exception e) {
Log.e(TAG, "分享图片到微信失败: " + e.getMessage(), e);
// 如果指定Activity失败尝试使用通用分享
if (isPackageDetected) {
try {
Intent generalIntent = new Intent(Intent.ACTION_SEND);
generalIntent.setType("image/*");
generalIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
generalIntent.setPackage(WECHAT_PACKAGE_NAME);
activity.startActivity(generalIntent);
handleShareSuccess();
} catch (Exception ex) {
handleShareException(activity, ex);
Intent directIntent = new Intent(intent);
// 根据分享场景指定目标Activity
if (scene == SCENE_MOMENTS) {
ComponentName comp = new ComponentName(WECHAT_PACKAGE_NAME, WECHAT_MOMENTS_ACTIVITY); directIntent.setComponent(comp);
} else {
ComponentName comp = new ComponentName(WECHAT_PACKAGE_NAME, WECHAT_FRIENDS_ACTIVITY); directIntent.setComponent(comp);
}
activity.startActivity(directIntent);
launched = true;
} catch (Exception e) {
Log.e(TAG, "指定组件分享图片到微信失败: " + e.getMessage(), e);
}
}
if (!launched) {
// 如果指定Activity失败或未检测到包名尝试使用兜底的选择器
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 ex) {
handleShareException(activity, ex);
return;
}
}
handleShareSuccess(activity);
} catch (Exception e) {
Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e);
handleShareException(activity, e);
@@ -201,10 +264,7 @@ public class WeChatIntentShareUtil {
* @param scene 分享场景0-好友1-朋友圈
*/
public void shareImages(Activity activity, ArrayList<String> imagePaths, int scene) {
if (!isWeChatInstalled()) {
handleNotInstalled(activity);
return;
}
boolean isPackageDetected = isWeChatInstalled();
if (imagePaths == null || imagePaths.isEmpty()) {
Toast.makeText(activity, "分享图片为空", Toast.LENGTH_SHORT).show();
@@ -242,39 +302,46 @@ public class WeChatIntentShareUtil {
Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setType("image/*");
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
intent.setPackage(WECHAT_PACKAGE_NAME);
// 根据分享场景指定不同的Activity
if (scene == SCENE_MOMENTS) {
// 分享到朋友圈
intent.setClassName(WECHAT_PACKAGE_NAME, WECHAT_MOMENTS_ACTIVITY);
} else {
// 分享给好友
intent.setClassName(WECHAT_PACKAGE_NAME, WECHAT_FRIENDS_ACTIVITY);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
try {
activity.startActivity(intent);
handleShareSuccess();
} catch (Exception e) {
Log.e(TAG, "多图分享失败,尝试使用通用分享: " + e.getMessage());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); // 鸿蒙卓易通适配
// 尝试使用通用分享
boolean launched = false;
if (isPackageDetected) {
try {
Intent generalIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
generalIntent.setType("image/*");
generalIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
generalIntent.setPackage(WECHAT_PACKAGE_NAME);
activity.startActivity(generalIntent);
handleShareSuccess();
} catch (Exception ex) {
handleShareException(activity, ex);
Intent directIntent = new Intent(intent);
// 根据分享场景指定不同的Activity
if (scene == SCENE_MOMENTS) {
ComponentName comp = new ComponentName(WECHAT_PACKAGE_NAME, WECHAT_MOMENTS_ACTIVITY); directIntent.setComponent(comp);
} else {
ComponentName comp = new ComponentName(WECHAT_PACKAGE_NAME, WECHAT_FRIENDS_ACTIVITY); directIntent.setComponent(comp);
}
activity.startActivity(directIntent);
launched = true;
} catch (Exception e) {
Log.e(TAG, "多图直接分享失败: " + e.getMessage());
}
}
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 ex) {
handleShareException(activity, ex);
return;
}
}
handleShareSuccess(activity);
} catch (Exception e) {
handleShareException(activity, e);
}
@@ -328,10 +395,7 @@ public class WeChatIntentShareUtil {
* @param scene 分享场景0-好友1-朋友圈
*/
public void shareWebPage(Activity activity, String webUrl, String title, String description, int scene) {
if (!isWeChatInstalled()) {
handleNotInstalled(activity);
return;
}
boolean isPackageDetected = isWeChatInstalled();
try {
// 微信不支持直接分享网页链接,只能作为文本分享
@@ -342,33 +406,57 @@ public class WeChatIntentShareUtil {
if (!TextUtils.isEmpty(description)) {
sb.append(description);
}
// 根据需求限制:分享的链接(webUrl)不需要分享出去
// 根据需求,复制和分享出去的文本均不再拼接网页链接
// if (!TextUtils.isEmpty(webUrl)) {
// sb.append("\n\n").append(webUrl);
// }
String text = sb.toString();
if (scene != SCENE_FRIENDS) {
copyToClipboard(activity, text);
}
// 朋友圈不支持纯文本分享,需要准备一个默认图片
if (scene == SCENE_MOMENTS) {
Toast.makeText(activity, "微信朋友圈不支持直接分享网页链接,将作为文本分享", Toast.LENGTH_SHORT).show();
Toast.makeText(activity, "朋友圈不支持纯文本分享,已复制内容可手动发表", Toast.LENGTH_SHORT).show();
// 尝试使用WebView截图分享
// 实际项目中可以实现WebView加载页面并截图分享的功能
// 这里为简化处理,可以使用应用图标作为默认图片
try {
// 调用系统分享
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, sb.toString());
intent.setPackage(WECHAT_PACKAGE_NAME);
activity.startActivity(intent);
handleShareSuccess();
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, sb.toString(), scene);
shareTextToWeChat(activity, text, scene);
}
} catch (Exception e) {
Log.e(TAG, "分享过程中出现异常: " + e.getMessage(), e);
@@ -379,7 +467,10 @@ public class WeChatIntentShareUtil {
/**
* 处理分享成功的情况
*/
private void handleShareSuccess() {
private void handleShareSuccess(Activity activity) {
if (activity != null) {
// activity.runOnUiThread(() -> Toast.makeText(activity, "唤起分享成功(可能无法获取取消状态)", Toast.LENGTH_SHORT).show());
}
if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
mCallback.onSuccess();
@@ -416,3 +507,5 @@ public class WeChatIntentShareUtil {
void onCancel();
}
}