【问题标题】:Reordering applications in Intent chooser在意图选择器中重新排序应用程序
【发布时间】:2017-06-12 16:53:47
【问题描述】:

我的 Android 应用程序上有一个“共享”按钮,它调用 Intent.ACTION_SEND 来显示用户可以用来共享链接的可用应用程序。但我希望应用程序按特定顺序显示,比如说,Whatsapp,然后是 Messenger,然后是 Facebook,然后是不加选择的所有其他应用程序。

我尝试了几种方法,当我将应用程序过滤到这三个时,它有点工作,但是如果我添加其余的应用程序,要么应用程序总是以相同的顺序显示(发生在我的小米上),或者整个事情变得一团糟,甚至复制了一些应用程序(发生在我测试过的摩托罗拉上)。

这是我尝试做的,只是为了测试目的:

Intent sharingIntent = new Intent(Intent.ACTION_SEND);
List<ResolveInfo> resInfo = mActivity.getPackageManager().queryIntentActivities(sharingIntent, 0);

然后我执行了三个 for() 循环,每个循环将完全遍历 resInfo 列表。每个循环都会搜索一个特定的应用程序(Whatsapp,然后是 Messenger,然后是 Facebook)并将其添加到选择器。然后我添加了另一个类似的 for() 方法,这次是为了添加剩余的应用程序:

for (ResolveInfo resolveInfo : resInfo) {
    String packageName = resolveInfo.activityInfo.packageName;

    Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND);
    targetedShareIntent.setType("text/plain");
    targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
    targetedShareIntent.setPackage(packageName);

    if (!packageName.equals("com.whatsapp") ||
            !packageName.equals("com.facebook.orca") ||
            !packageName.equals("com.facebook.katana")) {
        Toast.makeText(mActivity, packageName, Toast.LENGTH_SHORT).show();
        targetedShareIntents.add(targetedShareIntent);
    }
}

如果我不添加最后一个方法,选择器将只显示我添加的前三个应用程序,如果我更改 for() 循环的顺序,它们甚至会以不同的顺序显示。但是当我添加这个方法时,每个应用程序都将以相同的顺序显示,就像我刚刚定期调用选择器意图一样。

有什么办法可以解决这个问题吗?

【问题讨论】:

  • “我尝试了几种方法”——请注意,您拒绝提供 minimal reproducible example,因此没有人可以帮助您。 “有什么办法可以解决这个问题”——编写自己的 UI,而不是依赖设备的选择器。您可以使用PackageManagerqueryIntentActivities() 找出候选人是什么,按照您认为合适的方式对它们进行排序,并允许用户根据您认为合适的方式从它们中进行选择。
  • @CommonsWare 这对于我正在尝试做的事情并不是绝对强制性的,是的,我可以编写自己的 UI,事实上,在使用设备的选择器之前,我已经开始这样做了,但由于设计限制,这对我来说是一个更优雅的选择。你说得对,我更新了我原来的问题。
  • @Jaqualembo 你有没有解决这个问题?我确实删除了一些应用程序,但我希望顺序与原始设备的选择器相同。

标签: java android


【解决方案1】:

注意:此答案仅供参考。这不是一个完整的解决方案。

我创建了从选择器中排除某些应用程序的自定义 http 意图。这可能对您有帮助。如果我有足够的时间,我会为您的要求创建代码。我正在分享我的代码,可能对你有帮助。

public static void showBrowserIntent(Activity activity, String fileUrl, String[] forbiddenApps) {
    String[] blacklist = new String[]{"com.google.android.apps.docs"};

    if (forbiddenApps != null) {
        blacklist = forbiddenApps;
    }

    Intent httpIntent = new Intent(Intent.ACTION_VIEW);
    httpIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    httpIntent.setData(Uri.parse(fileUrl));
    httpIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


    List<Intent> targetedShareIntents = new ArrayList<Intent>();
    List<HashMap<String, String>> intentMetaInfo = new ArrayList<HashMap<String, String>>();
    Intent chooserIntent;

    List<ResolveInfo> resInfo = activity.getPackageManager().queryIntentActivities(httpIntent, 0);

    Intent chooser = Intent.createChooser(httpIntent, "Choose Downloader/Browser");

    if (!resInfo.isEmpty()) {
        for (ResolveInfo resolveInfo : resInfo) {
            if (resolveInfo.activityInfo == null
                    || Arrays.asList(blacklist).contains(
                    resolveInfo.activityInfo.packageName))
                continue;
            //Get all the posible sharers
            HashMap<String, String> info = new HashMap<String, String>();
            info.put("packageName", resolveInfo.activityInfo.packageName);
            info.put("className", resolveInfo.activityInfo.name);
            String appName = String.valueOf(resolveInfo.activityInfo
                    .loadLabel(activity.getPackageManager()));
            info.put("simpleName", appName);
            //Add only what we want
            if (!Arrays.asList(blacklist).contains(
                    appName.toLowerCase())) {
                intentMetaInfo.add(info);
            }
        }

        if (!intentMetaInfo.isEmpty()) {
            // sorting for nice readability
            Collections.sort(intentMetaInfo,
                    new Comparator<HashMap<String, String>>() {
                        @Override
                        public int compare(
                                HashMap<String, String> map,
                                HashMap<String, String> map2) {
                            return map.get("simpleName").compareTo(
                                    map2.get("simpleName"));
                        }
                    });

            // create the custom intent list
            for (HashMap<String, String> metaInfo : intentMetaInfo) {
                Intent targetedShareIntent = (Intent) httpIntent.clone();
                targetedShareIntent.setPackage(metaInfo.get("packageName"));
                targetedShareIntent.setClassName(
                        metaInfo.get("packageName"),
                        metaInfo.get("className"));
                targetedShareIntents.add(targetedShareIntent);
            }
            String shareVia = "Open with";
            String shareTitle = shareVia.substring(0, 1).toUpperCase()
                    + shareVia.substring(1);
            chooserIntent = Intent.createChooser(targetedShareIntents
                    .remove(targetedShareIntents.size() - 1), shareTitle);
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
                    targetedShareIntents.toArray(new Parcelable[]{}));
            activity.startActivity(chooserIntent);
        }
    } else {
        activity.startActivity(chooser);
    }

}

【讨论】:

  • 感谢您的回复,就像我提到的那样,我已经设法从选择器中排除了我不想要的应用程序(我可能没有对此非常明确,抱歉)使用一个漂亮的简短方法.重新排序虽然是我无法管理的。 (我更新了我原来的问题)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
  • 2013-10-08
  • 1970-01-01
相关资源
最近更新 更多