自定义ACTION_SEND分享功能:ResolveInfo优先级始终为0排序异常求助
解决ACTION_SEND自定义分享列表的两个问题:排除自家应用+匹配系统排序
我之前做自定义分享功能的时候也踩过一模一样的坑!queryIntentActivityOptions()这个方法确实不太靠谱,返回的优先级总是0,排序也和系统自带的分享框对不上。咱们一步步来解决这两个问题:
1. 正确获取带优先级的可分享应用列表
queryIntentActivityOptions()的设计初衷并不是获取完整的可处理Intent的Activity列表,而是用来获取与特定组件关联的操作选项,所以它不会返回正确的优先级和排序信息。咱们应该用queryIntentActivities()来替代,这个方法会返回系统认可的优先级(priority)和评分(score),这两个字段就是系统用来排序分享列表的关键。
首先构建正确的ACTION_SEND Intent:
Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); // 根据你的分享内容类型调整,比如"image/*" shareIntent.putExtra(Intent.EXTRA_TEXT, "要分享的内容"); shareIntent.addCategory(Intent.CATEGORY_DEFAULT); // 必须添加,因为大多数分享Activity都声明了这个category
然后获取完整的ResolveInfo列表:
PackageManager pm = getPackageManager(); // MATCH_DEFAULT_ONLY确保只返回支持CATEGORY_DEFAULT的Activity,和系统分享框的范围一致 List<ResolveInfo> allResolveInfos = pm.queryIntentActivities(shareIntent, PackageManager.MATCH_DEFAULT_ONLY);
2. 排除自家应用
遍历列表的时候,对比包名就能轻松过滤掉自己的应用:
String myAppPackage = getPackageName(); List<ResolveInfo> filteredInfos = new ArrayList<>(); for (ResolveInfo info : allResolveInfos) { // 跳过自家应用的Activity if (!info.activityInfo.packageName.equals(myAppPackage)) { filteredInfos.add(info); } }
3. 匹配系统默认排序
系统分享列表的排序逻辑是:先按priority降序(优先级高的应用靠前),优先级相同的话按score降序(评分高的靠前)。咱们直接用这个规则排序就可以和系统保持一致:
Collections.sort(filteredInfos, new Comparator<ResolveInfo>() { @Override public int compare(ResolveInfo o1, ResolveInfo o2) { // 先比优先级,大的在前 int priorityDiff = Integer.compare(o2.priority, o1.priority); if (priorityDiff != 0) { return priorityDiff; } // 优先级相同比评分 return Integer.compare(o2.score, o1.score); } });
额外提示
如果你的目标是完全复刻系统分享框的“最近使用应用靠前”的逻辑,那上面的排序还不够——系统会把用户最近使用过的分享应用放在最前面,这部分数据是系统维护的,咱们没法直接拿到。如果不是必须要这个功能,上面的排序已经能做到和系统默认列表90%的一致性了。
内容的提问来源于stack exchange,提问作者YTerle
相关产品推荐
相关产品推荐

