fix(share): 修复系统分享无法拉起的问题

在卓易通等类鸿蒙沙盒中:
如果在使用 Intent.createChooser(intent, title) 时,intent 提前设置了 setPackage(...) 限制包名,底层拉取时会被拦截或报错从而无法弹窗。
因此:
1. 抛弃 intent.setPackage() 限定目标包名的方式。
2. 引入 createTargetedChooserIntent 工具方法,在不设置目标包名的前提下,利用 Intent.EXTRA_EXCLUDE_COMPONENTS 将抖音相关组件屏蔽掉出面板。
既恢复了原生 Chooser 界面,也实现了不过度污染的要求。
This commit is contained in:
2026-03-11 17:40:42 +08:00
parent 821ac0bdc5
commit f1530a3173

View File

@@ -250,16 +250,13 @@ public class QQIntentShareUtil {
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; // 在卓易通系统上,提前设置 package 会导致 createChooser 失效,因此改用排除法
// 通过设包名系统分享面板中就只会出现QQ相关的组件从而过滤掉抖音 Intent chooser = createTargetedChooserIntent(activity, intent, "分享到QQ");
intent.setPackage(targetPackage);
Intent chooser = Intent.createChooser(intent, "分享到QQ");
chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(chooser); activity.startActivity(chooser);
launched = true; 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());
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "启动分享失败: " + e.getMessage()); Log.e(TAG, "启动分享失败: " + e.getMessage());
@@ -337,11 +334,8 @@ public class QQIntentShareUtil {
intent.putExtra(Intent.EXTRA_TEXT, text); intent.putExtra(Intent.EXTRA_TEXT, text);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String packageName = getInstalledQQPackage(); // 在卓易通系统上,提前设置 package 会导致 createChooser 失效,因此改用排除法
String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME; Intent chooser = createTargetedChooserIntent(activity, intent, "分享到QQ空间");
intent.setPackage(targetPackage);
Intent chooser = Intent.createChooser(intent, "分享到QQ空间");
chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(chooser); activity.startActivity(chooser);
Toast.makeText(activity, "已将内容复制到剪贴板,请从打开的界面中粘贴分享", Toast.LENGTH_LONG).show(); Toast.makeText(activity, "已将内容复制到剪贴板,请从打开的界面中粘贴分享", Toast.LENGTH_LONG).show();
@@ -404,10 +398,8 @@ public class QQIntentShareUtil {
boolean launched = false; boolean launched = false;
try { try {
String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME; // 在卓易通系统上,提前设置 package 会导致 createChooser 失效,因此改用排除法
shareIntent.setPackage(targetPackage); // 限制只能分享到QQ防止出现抖音 Intent chooserIntent = createTargetedChooserIntent(activity, shareIntent, "分享到QQ");
Intent chooserIntent = Intent.createChooser(shareIntent, "分享到QQ");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 确保Chooser也有权限 chooserIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 确保Chooser也有权限
@@ -494,12 +486,8 @@ public class QQIntentShareUtil {
} catch (android.content.ActivityNotFoundException e) { } catch (android.content.ActivityNotFoundException e) {
Log.e(TAG, "直接分享到QQ空间失败尝试系统分享: " + e.getMessage()); Log.e(TAG, "直接分享到QQ空间失败尝试系统分享: " + e.getMessage());
// 采用调用系统分享 // 采用调用系统分享并排除其他组件以过滤出QQ
String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME; Intent chooserIntent = createTargetedChooserIntent(activity, shareIntent, "分享到QQ空间");
shareIntent.setComponent(null);
shareIntent.setPackage(targetPackage);
Intent chooserIntent = Intent.createChooser(shareIntent, "分享到QQ空间");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(chooserIntent); activity.startActivity(chooserIntent);
@@ -613,11 +601,8 @@ public class QQIntentShareUtil {
boolean launched = false; boolean launched = false;
try { try {
String targetPackage = (packageName != null && !packageName.isEmpty()) ? packageName : QQ_PACKAGE_NAME; // 采用调用系统分享,通过排除法避免设 package 导致的 chooser 失效
// 采用调用系统分享 Intent chooser = createTargetedChooserIntent(activity, intent, isQzone ? "分享到QQ空间" : "分享到QQ");
intent.setPackage(targetPackage);
Intent chooser = Intent.createChooser(intent, isQzone ? "分享到QQ空间" : "分享到QQ");
chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -726,6 +711,45 @@ public class QQIntentShareUtil {
} }
} }
/**
* 构建排除特定组件(如抖音)的系统分享选择器
* 在卓易通等环境下,给 intent setPackage 会导致 createChooser 直接失效不弹窗,
* 所以我们通过原生的 intent 送入 createChooser然后利用 EXTRA_EXCLUDE_COMPONENTS 排除抖音。
*/
private Intent createTargetedChooserIntent(Activity activity, Intent targetIntent, CharSequence title) {
// 重要:确保本体 intent 不要携带 package 限制,否则在卓易通系统的 chooser 会失效静默
targetIntent.setPackage(null);
targetIntent.setComponent(null);
Intent chooser = Intent.createChooser(targetIntent, title);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
try {
// 找出抖音可能接收分享的所有组件
Intent queryIntent = new Intent(targetIntent.getAction());
queryIntent.setType(targetIntent.getType());
queryIntent.setPackage("com.ss.android.ugc.aweme");
List<android.content.pm.ResolveInfo> resInfo = activity.getPackageManager().queryIntentActivities(queryIntent, 0);
List<ComponentName> excludedComponents = new ArrayList<>();
if (resInfo != null && !resInfo.isEmpty()) {
for (android.content.pm.ResolveInfo info : resInfo) {
excludedComponents.add(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
}
} else {
// 兜底硬编码过滤最常见的涉事抖音组件
excludedComponents.add(new ComponentName("com.ss.android.ugc.aweme", "com.ss.android.ugc.aweme.share.ShareToAwemeActivity"));
}
chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponents.toArray(new ComponentName[0]));
} catch (Exception e) {
Log.e(TAG, "设置排他组件失败", e);
}
}
return chooser;
}
/** /**
* QQ分享回调接口 * QQ分享回调接口
*/ */