首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根据安装的Android包名称自定义过滤意图选择器

根据安装的Android包名称自定义过滤意图选择器
EN

Stack Overflow用户
提问于 2011-04-21 02:06:39
回答 6查看 51.9K关注 0票数 58

我想利用内置的意图选择器来显示一个自定义的过滤列表,供用户选择和启动。

我知道如何获取已安装软件包的列表:

代码语言:javascript
复制
final Intent myIntent = new Intent(android.content.Intent.ACTION_MAIN);  
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(myIntent, 0);

此时,我希望根据包名称中包含的特定字符串(或字符串的变体)来过滤列表,我也可以弄清楚如何做到这一点。

但这就是我被卡住的地方。据我所知,Intent.createChooser()只接受一个目标意图作为参数。我希望有一个重载,它基于包和类名或其他东西获取意图列表。但我没有看到任何这样的东西。我是不是漏掉了什么?

所以问题是,这可以用一个内置的选择器来实现吗,还是我必须用AlertDialog生成器来构建自己的选择器?我希望避免后一种情况。

提前谢谢。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-04-21 03:12:43

选择器的唯一一个附加参数是Intent.EXTRA_INITIAL_INTENTS。它的描述是:

使用附加活动的Parcelable[]设置的意图或LabeledIntent对象,当使用ACTION_CHOOSER向用户显示时,它将放在选项列表的最前面。

我还没有在Android源代码中找到任何方法来排除列表中的其他活动,所以似乎没有办法使用选择器来做你想做的事情。

:这真的很容易找到。只需查看ChooserActivityResolverActivity源代码即可。这些班级相当小。

票数 26
EN

Stack Overflow用户

发布于 2011-12-18 13:38:38

这是我提出的一个解决方案。我使用它来为选择器中的每个选择提供不同的意图数据,但您也可以很容易地从列表中删除一个意图。希望这能有所帮助:

代码语言:javascript
复制
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0);
if (!resInfo.isEmpty()) {
    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_SUBJECT, "subject to be shared");
        if (TextUtils.equals(packageName, "com.facebook.katana")) {
            targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "http://link-to-be-shared.com");
        } else {
            targetedShareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "text message to shared");
        }
        targetedShareIntent.setPackage(packageName);
        targetedShareIntents.add(targetedShareIntent);
    }
    Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share");
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
    startActivity(chooserIntent);
}

编辑

在使用此方法时,我得到了一些应用程序的名称,如android system。如果任何人收到此错误,请在targetedShareIntents.add(targetedShareIntent);前添加以下行

代码语言:javascript
复制
 targetedShareIntent.setClassName(
                        resolveInfo.activityInfo.packageName,
                        resolveInfo.activityInfo.name);

来源:Android share intent Twitter: How to share only by Tweet or Direct Message?

票数 112
EN

Stack Overflow用户

发布于 2014-01-07 00:12:49

我做了一个小小的修改,列出了你想要分享的应用程序的名字。这几乎就是您已经发布的内容,但添加了要按名称共享的应用程序

代码语言:javascript
复制
String[] nameOfAppsToShareWith = new String[] { "facebook", "twitter", "gmail" };
String[] blacklist = new String[]{"com.any.package", "net.other.package"};
// your share intent
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "some text");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "a subject");
// ... anything else you want to add invoke custom chooser
startActivity(generateCustomChooserIntent(intent, blacklist));

private Intent generateCustomChooserIntent(Intent prototype,
            String[] forbiddenChoices)
    {
        List<Intent> targetedShareIntents = new ArrayList<Intent>();
        List<HashMap<String, String>> intentMetaInfo = new ArrayList<HashMap<String, String>>();
        Intent chooserIntent;

        Intent dummy = new Intent(prototype.getAction());
        dummy.setType(prototype.getType());
        List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(dummy,0);

        if (!resInfo.isEmpty())
        {
            for (ResolveInfo resolveInfo : resInfo)
            {
                if (resolveInfo.activityInfo == null
                        || Arrays.asList(forbiddenChoices).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(getPackageManager()));
                info.put("simpleName", appName);
                //Add only what we want
                if (Arrays.asList(nameOfAppsToShareWith).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) prototype.clone();
                    targetedShareIntent.setPackage(metaInfo.get("packageName"));
                    targetedShareIntent.setClassName(
                            metaInfo.get("packageName"),
                            metaInfo.get("className"));
                    targetedShareIntents.add(targetedShareIntent);
                }
                String shareVia = getString(R.string.offer_share_via);
                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[] {}));
                return chooserIntent;
            }
        }

        return Intent.createChooser(prototype,
                getString(R.string.offer_share_via));
    }

这几乎与Makibo发布的解决方案相同,但只需添加名称,就可以简单地选择你想要分享的应用程序,这样在他们更改包名称或类似的情况下,你就不会有任何问题。只要他们不改名字就行。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5734678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档