fix(share): 优化QQ分享在系统面板中的容错拉起逻辑

1. 引入了 resolveShareComponent 动态解析指定包内真实的 ACTION_SEND 接收组件。
2. 抛弃原本硬编码的 JumpActivity 这种由于某些系统内部拉起问题可能报错导致失败的方案。
3. 如果指定 Component 和解析失败则直接兜底进入单纯的 setPackage 调用即可完成精确跳转。
This commit is contained in:
2026-03-11 13:03:18 +08:00
parent adba5618fd
commit 9be3406d52

View File

@@ -58,6 +58,24 @@ public class QQIntentShareUtil {
private static final String QZONE_COMPONENT = "com.tencent.mobileqq.activity.QzonePublishMoodActivity"; 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 final String TIM_QZONE_COMPONENT = "com.tencent.tim.activity.QzonePublishMoodActivity";
/**
* 动态获取分享组件(适配鸿蒙等定制系统)
*/
private ComponentName resolveShareComponent(Activity activity, Intent intent, String packageName) {
try {
List<android.content.pm.ResolveInfo> resolveInfoList =
activity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfoList != null && !resolveInfoList.isEmpty()) {
for (android.content.pm.ResolveInfo resolveInfo : resolveInfoList) {
if (packageName.equals(resolveInfo.activityInfo.packageName)) {
return new ComponentName(packageName, resolveInfo.activityInfo.name);
}
}
}
} catch (Exception e) {}
return null;
}
private static QQIntentShareUtil instance; private static QQIntentShareUtil instance;
private final Context mContext; private final Context mContext;
private QQShareCallback mCallback; private QQShareCallback mCallback;
@@ -222,7 +240,7 @@ public class QQIntentShareUtil {
String packageName = getInstalledQQPackage(); String packageName = getInstalledQQPackage();
boolean launched = false; boolean launched = false;
// 方法1: 尝试使用系统Chooser这是最兼容的方式特别适合鸿蒙环境 // 方法1: 尝试直接拉起
try { try {
Intent intent = new Intent(Intent.ACTION_SEND); Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain"); intent.setType("text/plain");
@@ -231,32 +249,18 @@ public class QQIntentShareUtil {
// 鸿蒙/卓易通关键适配Flags // 鸿蒙/卓易通关键适配Flags
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME;
ComponentName resolvedComp = resolveShareComponent(activity, intent, targetPackage);
// 如果检测到了包名,优先尝试指定包名,但不是必须的 if (resolvedComp != null) {
if (isPackageDetected) { intent.setComponent(resolvedComp);
try { } else {
Intent directIntent = new Intent(intent); intent.setPackage(targetPackage);
ComponentName comp = new ComponentName(packageName, getQQShareComponent());
directIntent.setComponent(comp);
activity.startActivity(directIntent);
launched = true;
} catch (Exception e) {
Log.e(TAG, "直接拉起QQ文本分享失败: " + e.getMessage());
}
} }
if (!launched) { activity.startActivity(intent);
// 没有检测到包名更需要使用Chooser并提示用户选择QQ launched = true;
if (packageName != null && !packageName.isEmpty()) {
intent.setPackage(packageName);
} else {
intent.setPackage(QQ_PACKAGE_NAME); // 强制限制为QQ包名防止出现抖音等其他应用
}
Intent chooser = Intent.createChooser(intent, "请选择QQ进行分享");
chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(chooser);
launched = true;
}
Log.d(TAG, "成功启动分享"); Log.d(TAG, "成功启动分享");
activity.runOnUiThread(() -> Toast.makeText(activity, "已将内容复制到剪贴板请在QQ中粘贴并分享", Toast.LENGTH_LONG).show()); activity.runOnUiThread(() -> Toast.makeText(activity, "已将内容复制到剪贴板请在QQ中粘贴并分享", Toast.LENGTH_LONG).show());
@@ -334,17 +338,20 @@ public class QQIntentShareUtil {
Intent intent = new Intent(Intent.ACTION_SEND); Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain"); intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, text); intent.putExtra(Intent.EXTRA_TEXT, text);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String packageName = getInstalledQQPackage(); String packageName = getInstalledQQPackage();
if (packageName != null && !packageName.isEmpty()) { String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME;
intent.setPackage(packageName);
ComponentName resolvedComp = resolveShareComponent(activity, intent, targetPackage);
if (resolvedComp != null) {
intent.setComponent(resolvedComp);
} else { } else {
intent.setPackage(QQ_PACKAGE_NAME); intent.setPackage(targetPackage);
} }
Intent chooser = Intent.createChooser(intent, "分享到QQ空间"); activity.startActivity(intent);
activity.startActivity(chooser); Toast.makeText(activity, "已将内容复制到剪贴板,请从打开的界面中粘贴分享", Toast.LENGTH_LONG).show();
Toast.makeText(activity, "已将内容复制到剪贴板请从列表中选择QQ并粘贴分享", Toast.LENGTH_LONG).show();
if (mCallback != null) { if (mCallback != null) {
new Handler(Looper.getMainLooper()).postDelayed(() -> { new Handler(Looper.getMainLooper()).postDelayed(() -> {
@@ -403,41 +410,24 @@ public class QQIntentShareUtil {
// 尝试直接拉起 // 尝试直接拉起
boolean launched = false; boolean launched = false;
if (isPackageDetected) { try {
try { String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME;
// 复制一份Intent用于尝试 ComponentName resolvedComp = resolveShareComponent(activity, shareIntent, targetPackage);
Intent directIntent = new Intent(shareIntent);
ComponentName comp = new ComponentName(packageName, getQQShareComponent()); if (resolvedComp != null) {
directIntent.setComponent(comp); shareIntent.setComponent(resolvedComp);
activity.startActivity(directIntent); } else {
launched = true; shareIntent.setPackage(targetPackage);
Log.d(TAG, "已发送分享图片Intent到QQ");
activity.runOnUiThread(() -> Toast.makeText(activity, "已发送分享图片Intent到QQ", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
Log.e(TAG, "直接分享到QQ失败: " + e.getMessage());
final String failMsg = "直接分享失败: " + e.getMessage();
activity.runOnUiThread(() -> Toast.makeText(activity, failMsg, Toast.LENGTH_SHORT).show());
}
}
// 如果直接拉起失败或者未检测到包名使用Chooser
if (!launched) {
try {
if (packageName != null && !packageName.isEmpty()) {
shareIntent.setPackage(packageName);
} else {
shareIntent.setPackage(QQ_PACKAGE_NAME);
}
Intent chooserIntent = Intent.createChooser(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, "使用System Chooser分享图片");
activity.runOnUiThread(() -> Toast.makeText(activity, "尝试使用System Chooser分享图片", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
Log.e(TAG, "Chooser分享失败: " + e.getMessage());
} }
activity.startActivity(shareIntent);
launched = true;
Log.d(TAG, "已发送分享图片Intent到QQ");
activity.runOnUiThread(() -> Toast.makeText(activity, "已发送分享图片Intent到QQ", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
Log.e(TAG, "直接分享到QQ失败: " + e.getMessage());
final String failMsg = "直接分享失败: " + e.getMessage();
activity.runOnUiThread(() -> Toast.makeText(activity, failMsg, Toast.LENGTH_SHORT).show());
} }
if (launched) { if (launched) {
@@ -512,17 +502,21 @@ public class QQIntentShareUtil {
}, 1000); }, 1000);
} }
} catch (android.content.ActivityNotFoundException e) { } catch (android.content.ActivityNotFoundException e) {
Log.e(TAG, "直接分享到QQ空间失败尝试使用选择器: " + e.getMessage()); Log.e(TAG, "直接分享到QQ空间失败尝试降级为通用QQ分享: " + e.getMessage());
// 如果直接分享失败,使用选择器并且限制包名 // 如果直接分享失败,直接拉起应用并且限制包名
if (packageName != null && !packageName.isEmpty()) { String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME;
shareIntent.setPackage(packageName); ComponentName resolvedComp = resolveShareComponent(activity, shareIntent, targetPackage);
if (resolvedComp != null) {
shareIntent.setComponent(resolvedComp);
} else { } else {
shareIntent.setPackage(QQ_PACKAGE_NAME); shareIntent.setComponent(null);
shareIntent.setPackage(targetPackage);
} }
Intent chooserIntent = Intent.createChooser(shareIntent.setComponent(null), "分享到QQ空间");
activity.startActivity(chooserIntent); activity.startActivity(shareIntent);
Toast.makeText(activity, "请从列表中选择QQ", Toast.LENGTH_SHORT).show(); Toast.makeText(activity, "即将打开QQ请选择分享位置", Toast.LENGTH_SHORT).show();
// 假设分享成功 // 假设分享成功
if (mCallback != null) { if (mCallback != null) {
@@ -632,39 +626,28 @@ public class QQIntentShareUtil {
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); // 鸿蒙卓易通适配 intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); // 鸿蒙卓易通适配
boolean launched = false; boolean launched = false;
boolean isPackageDetected = isQQInstalled();
try {
if (isPackageDetected) { String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME;
try { ComponentName resolvedComp = null;
Intent directIntent = new Intent(intent);
// 设置组件名称 if (isQzone) {
if (isQzone) { resolvedComp = new ComponentName(targetPackage, getQZoneShareComponent());
ComponentName comp = new ComponentName(packageName, getQZoneShareComponent());
directIntent.setComponent(comp);
} else {
ComponentName comp = new ComponentName(packageName, getQQShareComponent());
directIntent.setComponent(comp);
}
activity.startActivity(directIntent);
launched = true;
Log.d(TAG, "已发送多图分享Intent到QQ");
} catch (Exception e) {
Log.e(TAG, "直接分享多图到QQ失败: " + e.getMessage());
}
}
if (!launched) {
if (packageName != null && !packageName.isEmpty()) {
intent.setPackage(packageName);
} else { } else {
intent.setPackage(QQ_PACKAGE_NAME); resolvedComp = resolveShareComponent(activity, intent, targetPackage);
} }
Intent chooser = Intent.createChooser(intent, isQzone ? "分享到QQ空间" : "分享到QQ");
chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (resolvedComp != null) {
chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setComponent(resolvedComp);
activity.startActivity(chooser); } else {
Log.d(TAG, "使用System Chooser分享多图"); intent.setPackage(targetPackage);
}
activity.startActivity(intent);
launched = true; launched = true;
Log.d(TAG, "已发送多图分享Intent到QQ");
} catch (Exception e) {
Log.e(TAG, "直接分享多图到QQ失败: " + e.getMessage());
} }
if (launched) { if (launched) {