android - ACTION_CHOOSER 和 ACTION_PICK_ACTIVITY 之间的 Intent 解析和区别

标签 android android-intent intentfilter

我对 Intent 解析以及 Intent.ACTION_PICK_ACTIVITY 和 Intent.ACTION_CHOOSER 之间的区别有疑问(包括它的便利函数版本 Intent.createChooser())。

我正在编写一个“程序包管理器”应用程序。我在其中有一个 ListActivity,它显示设备上安装的所有包(使用 PackageManager.getInstalledPackages() 填充)。我还在列表中注册了一个上下文菜单,其中一项是“启动”。

下面是我来自 onContextItemSelected() 的代码,用于处理“启动”上下文菜单项。

Intent intent ;
List<ResolveInfo> ris ;
int nLauchables ;
int REQUEST_LAUNCH = 1 ;    // for use in onActivityResult()
// PackageInfo pi ;         // set outside this code

intent = new Intent (Intent.ACTION_MAIN) ;
intent.addCategory (Intent.CATEGORY_LAUNCHER) ;
intent.setPackage (pi.packageName) ; // limit to launchable activities in the package represented by pi

ris = getPackageManager ().queryIntentActivities (intent, 0) ; // get list of launchable activities in pi
nLaunchables = ris.size () ;

if (ris == null || nLaunchables == 0) {
// do nothing (in the real code, the "Launch" item is already disabled in this case, so this never happens)
    }
else if (nLaunchables == 1) {
// only 1 launchable activity, so just start that activity

    intent.setComponent (new ComponentName (ris.get (0).activityInfo.packageName, ris.get (0).activityInfo.name)) ;

    startActivity (intent) ;
    }
else if (nLaunchables > 1) {
// mutiple launchable activites, so let the user choose which one they want to launch

//  Intent chooseIntent = new Intent (Intent.ACTION_CHOOSER) ;
//  chooseIntent.putExtra (Intent.EXTRA_INTENT, intent) ;
//  chooseIntent.putExtra (Intent.EXTRA_TITLE, "Select activity") ;
//  startActivity (chooseIntent) ;                                     // doesn't show all launchable activities in the package
//
// or
//
//  startActivity (Intent.createChooser (intent, "Select activity") ;  // doesn't show all launchable activities in the package

    Intent pickIntent = new Intent (Intent.ACTION_PICK_ACTIVITY) ;
    pickIntent.putExtra (Intent.EXTRA_INTENT, intent) ;

    startActivityForResult (pickIntent, REQUEST_LAUNCH) ;
    }

我首先尝试了 ACTION_CHOOSER 版本...但它并不总是显示包中的所有可启动 Activity 。例如,Google map 有 4 个可启动的 Activity (纬度、 map 、导航和地点)显示为 ACTION_PICK_ACTIVITY,但 ACTION_CHOOSER 仅显示 2 个(纬度、 map )。在使用 ACTION_CHOOSER 时显示的 Activity 与不显示的 Activity 之间,我唯一能看到的不同之处在于它们的 中有 CATEGORY_DEFAULT。

以下是我查阅过的文档部分以了解正在发生的事情:

Docs for CATEGORY_DEFAULT部分地说,“设置此设置将向用户隐藏在对某些数据执行操作时未设置它的任何 Activity 。”

这似乎可以解释我所看到的行为...但是...

Docs for ACTION_CHOOSER部分地说,“...将始终显示所有可能的 Activity ,即使其中之一当前被标记为首选 Activity 。” (强调我的)

这似乎与 CATEGORY_DEFAULT 的上述文档冲突,并建议使用 ACTION_CHOOSER 和 ACTION_PICK_ACTIVITY 应该产生相同的结果。...和...

Intents 和 Intent Resolution 文档(抱歉,作为新用户,我在一篇文章中被限制为 2 个链接,所以我无法链接到这个...只需查看“Intent Resolution”部分,“类别测试”小节)部分地表示,“Android 将所有传递给 startActivity() 的隐式 Intent 视为它们至少包含一个类别:android.intent.category.DEFAULT”(CATEGORY_DEFAULT 常量)。因此,愿意接收隐式 Intent 的 Activity 必须在其 Intent 过滤器中包含 android.intent.category.DEFAULT”。(Filters with android.intent.action.MAIN” 和 android.intent.category.LAUNCHER” 设置是异常。它们标记开始新任务并显示在启动器屏幕上的 Activity 。它们可以在类别列表中包含“android.intent.category.DEFAULT”,但不需要.)"(强调我的)

同样,这似乎明确表示使用 ACTION_CHOOSER 和 ACTION_PICK_ACTIVITY 应该产生相同的结果。

那么,这只是 ACTION_CHOOSER 文档不完整的情况(即它没有提到 CATEGORY_DEFAULT Activity 被排除在外)还是有其他事情发生?

使用 ACTION_PICK_ACTIVITY 对我有用,但并不理想,因为需要用它调用 startActivityForResult()(而不仅仅是 startActivity())。

最佳答案

我认为您阅读文档的最后两段摘录并不是预期的意思。从 ACTION_CHOOSER 文档开始,“...将始终显示所有可能的 Activity ,即使其中之一当前被标记为首选 Activity ”,具体指的是首选 Activity 。通常,当您使用隐式意向并且有多个 Activity 匹配时,如果用户之前从先前的选择器中为此意向选择了“始终”,那么您将在没有选择器的情况下获得该 Activity 。如果您使用 ACTION_CHOOSER Intent ,您将获得所有匹配的 Activity ,即使已经选择了一个 Activity 。这就是这一行的全部意思:“所有可能的 Activity ”是指与 Intent 过滤器匹配的所有 Activity ,同时也考虑了类别。这只是对自动获取选择器与使用 ACTION_CHOOSER 之间的区别的另一种解释。

你说的另一部分,关于android.intent.action.MAINandroid.intent.category.LAUNCHER,并不意味着那个action和category在 Intent 过滤过程中进行了特殊处理。不要忘记大多数阅读本文档的人只是在编写可启动的应用程序,并且需要知道在他们的 list 中放入什么才能在启动器中显示一个 Activity 。这里的“异常(exception)”不是 Intent 过滤器规则的异常(exception):它是隐式 Intent 使用 CATEGORY_DEFAULT 的通常行为的异常(exception),这只是一个异常(exception),因为启动器设置了这个类别( CATEGORY_LAUNCHER) 而不是 CATEGORY_DEFAULT

总而言之,正如您所发现的那样, Intent 解析的整个领域都没有足够的文档记录,但是您提到的摘录中没有不一致之处:它们只是在谈论略有不同的事情。

关于android - ACTION_CHOOSER 和 ACTION_PICK_ACTIVITY 之间的 Intent 解析和区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7614652/

相关文章:

Android:寻找具有内外半径的 drawArc() 方法

android - 如何从命令行使用 gradle 创建 android 项目?

android - 设置的 Intent - 数据使用

android - 广播和 Intent 过滤器

android - android list 中的 intent-filter 下可以包含多少方案和主机标签

java - 只有创建 View 层次结构的原始线程才能触摸它的 View ?

java - LibGDX 在暂停时停止时间计数器

javascript - 从 Android 浏览器打开 Instagram

java - 将数据从 Activity 传递到同一 Activity 中在 webView 加载的 HTML 文件中使用的 JavaScript

android - 主机是否是 Android 深度链接所需的配置?