Android官方API Guide学习之四 Intents和Intent Filters

来源:互联网 发布:java时间格式化 校验 编辑:程序博客网 时间:2024/06/06 00:59

  Intent是一个用来进行app component间请求的消息对象,可以方便地实现components间的通讯。常用的有3种基本方式:

  • 启动Activity(动作):
    一个Activity在app中表示一个单独的屏幕,可以通过两种方式来启动一个新的Activity:
    1、startActivity(),Intent描述了要启动的Activity信息并携带必要的数据。
    2、startActivityForResult(),如果想要接受一个返回值,需要调用该方法,此时,Activity在onActivityResult()回调函数中,接受一个新的Intent作为返回值。

  • 启动Service(服务)
    Service是后台操作,同样,有两种方式启动一个新的Service
    1、startService(),Intent描述了要启动的Service信息并携带必要的数据。
    2、bindService(),当Service被设计为客户-服务器的接口时,调用该方法,可以将Service绑定到一个组件上。

  • 发送Broadcast(广播)
    Broadcast是一个任何app能接受的消息。系统为系统事件发送各种各样的Broadcast,如系统启动、充电等。我们可以通过调用sendBroadcast(), sendOrderedBroadcast(), 或者sendStickyBroadcast()方法来发送Broadcast给其他的app。

Intent类型
两种:explicit intents(显式意图)和implicit intents(隐式意图)

  • explicit intents:明确想要启动的组件名称(全限定名),一般的,我们会在自己的app内部使用显示的方式来启动组件,因为我们知道这个组件的全限定名。
  • implicit intents:我们不知道组件的全限定名,作为代替,我们声明一个能够接受它的动作属性。一般的,我们在app间的Activity调用使用implicit intents,只需指明我们想要完成的动作,让系统去匹配能够完成该动作的app组件。

当我们使用explicit intents来启动组件时,系统能够立即Intent中指定的app组件。
当我们使用implicit intents来启动组件时,系统通过匹配其他app在Manifest文件中声明的intent filters中的内容来发现合适的组件,并启动它。过程如下图:
implicit intents说明
如上图,implicit intents启动Activity分为3步:
第一步:Activity A创建包含动描述的Intent传递给startActivity()
第二步:Android系统需找所有的app的Intent filter,看是否有匹配,若有(Activity B),进入第三步
第三步:系统通过调用onCreate()方法创建匹配的动作,并传递这个Intent中的数据给它。
警告:为了保证app的安全,总是使用显示的方式启动Service,而且不要为你的Services声明intent filter。若用隐式的方式启动Service,你无法估计到底那个Service会被启动,从而导致不可估计的错误。
从Android 5.0(API级别为21)开始,当使用隐式方式调用bindService()方法时,系统将抛出异常。

构建一个Intent
  一个Intent携带的信息,一部分是为了定位要启动的组件的信息(如明确给出组件的名字或者指出能够接收该Intent的组件的类别),另一方面是为了完成功能所携带的数据。
  在一个Intent中主要包含的信息如下:

  • 组件名称(component name)
      顾名思义,表示组件名,能够唯一确定接收组件的名称。非必须,但是却是explicit intent的关键部分,如果intent中不包含component name,那么这个intent就是implicit的,至于到底会启动哪个组件,由系统去判断(根据action、data、category等信息),所以使用app内部的component,一般通过component name以显示的方式来启动。
       注意:当启动一个service时,一定要指定component name,否则,无法确定哪个service被启动。
    component name通过全限定名来确定,是一个ComponentName对象。如com.example.ExampleActivity,可以通过setComponent(), setClass(), setClassName()函数,或者Intent的构造函数进行设置。

  • 动作(Action)
      一个字符串,表示要执行的动作。
      如果是一个broadcast intent,那么表示action要起作用并被报告的地方。Action字段,很大程度上决定了intent中其他剩余部分的结构,如intent所包含的data和extras。
      我们可以指定action用在我们自己app中的intent上(或者被用来其他app调用我们的组件),但一般情况下,我们应该使用在Intent类或者其他框架的类中定义好的action字符串常量。如ACTION_VIEW,ACTION_SEND等。详细的action信息可以参考Intent类的官方api以及其他Android框架中的定义。
      我们可以通过调用setAction()方法或者Intent的构造函数来指定Action。如果我们自己定义action,那么一定要确定带上包名前缀,如:

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
  • 数据(Data)
      数据是作用于Intent上的数据URI或/和数据的MIME类型,根据不同action,会有不同的数据规格。如:如果动作是ACTION_EDIT,那么数据字段应该包含将用于编辑的文档的URI。
      当创建Intent时,在给出数据的URI基础上,指明数据的MIME类型也是很重要的。如:一个设计用来展示图片的Activity不能播放音频,尽管URI的格式很相似。因此,指明数据的MIME类型,能够帮助Android系统找到更加适合的组件来接收你的Intent。不过,有时候数据的MIME数据类型隐含在URI中,特别的,当数据content:URI时,表明了数据是被ContentProvider所定位和控制,那么数据的MIME数据类型是不可见的。
      设置URI调用setData(),设置MIME类型调用setType(),二者同时设置调用setDataAndType().
      注意:如果想要设置二者,调用setDataAndType()方法,因为前两个方法,会将另外一个值设成NULL。

  • 类别(Category)
      字符串类型的额外信息,表明处理Intent的组件类别。一个Intent中能够添加任意数量的Category描述信息,但是大部分的intent不需要Category。常见的Category如:
      CATEGORY_BROWSABLE:目标Activity允许自己通过浏览器启动来展示数据通过一个链接。
      CATEGORY_LAUNCHER:Activity是一个任务的初始Activity,并在应用的launcher列表中。
      可参考Intent类文档,查看所有的category列表。
      可以调用addCategory()方法指定一个Category。

上述的属性(component name,action,data,category)表示了Intent的定义性特征,通过这些信息,系统能够确定应该哪个组件被调用。
然而,Intent也可以包含其他不影响解析应用组件的信息,主要有Extras和Flags。

  • 附加功能(Extras)
      键值对,用来提供额外信息来完成必要功能,正想一些action需要URI一样,一些action需要Extras。
      可以通过putExtras()方法添加,或者创建一个Bundle对象,里面包含所有需要的Extras,然后利用putExtras()方法,将Bundle对象插入到Intent中去。
      Intent类中定义了很多Extras_*的标准数据类型常量,如果需要自己定义Extras的key,同样需要以包名为前缀,如:static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";

  • 标记(Flags)
      Intent 类中定义的标志位,用作 Intent 的元数据。 这些标志位可以告知 Android 系统一些 Activity 的启动信息,包括 Activity 的启动方式(如该 Activity 所属的 任务), 和启动之后的处理方式(如该 Activity 是否在最近常用 Activity 列表中显示)

显示Intent示例
  显式 Intent 是用于启动指定组件的 Intent,比如应用程序内部的某个特定 Activity 或 Service。 要创建一个显式 Intent,需要为 Intent 对象给定组件名称 — 其他的 Intent 参数都是可选的。
例如,假设应用程序中已有一个名为 DownloadService 的服务, 用于从 Web 上下载一个文件,你就可以用以下代码来启动它:

// Executed in an Activity, so 'this' is the Context// The fileUrl is a string URL, such as "http://www.example.com/image.png"Intent downloadIntent = new Intent(this, DownloadService.class);downloadIntent.setData(Uri.parse(fileUrl));startService(downloadIntent);

  构造方法 Intent(Context, Class) 给出了 Context 和组件对象 Class。 因此,该 Intent 将显式启动应用程序中的 DownloadService 类。

隐式Intent示例
  隐式 Intent 指定了一个 Action,当前设备上所有可执行这个 Action 的应用程序都可以被它激活。 如果当前应用程序没有能力执行这个 Action,而有其他应用程序可以处理且可以让用户使用它,隐式 Intent 就非常有用了。
  例如,假设用户有些数据需要与其他人分享,就可以用 ACTION_SEND action创建一个 Intent,并将需分享的数据放入extras中。 只要用该 Intent 调用 startActivity() ,用户就可以启动某个应用程序并分享数据。
  注意:有可能任何应用程序都无法处理发给 startActivity() 的隐式 Intent 。 如果是这样,调用将会失败,应用程序就会崩溃。 为了判断是否存在可接收 Intent 的 Activity ,请调用 Intent 对象的 resolveActivity() 方法。 如果结果为非空,则表示至少有一个应用程序可以处理该 Intent , startActivity() 的调用就是安全的。 如果结果为 null,就不要使用该 Intent。如果可能的话,请关闭那些提交该 Intent 的功能。

// Create the text message with a stringIntent sendIntent = new Intent();sendIntent.setAction(Intent.ACTION_SEND);sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);sendIntent.setType("text/plain");// Verify that the intent will resolve to an activityif (sendIntent.resolveActivity(getPackageManager()) != null) {    startActivity(sendIntent);}

  注意: 这种情况下,没有使用 URI , 而是声明了 Intent 的数据类型,以指明附件中包含的内容。
  当调用 startActivity() 时,系统会检查所有已安装的应用程序,进而确定可以处理这种 Intent 的应用(带有 ACTION_SEND 的 Intent 和包含“”text/plain”数据的 Intent)。 如果可处理该 Intent 的应用程序只有一个,则会立即打开该应用并传入该 Intent。 如果有多个 Activity 都可以接收该 Intent ,则系统会显示一个对话框,用户可以从中采用一个。

强制打开应用程序选择对话框  
  如果有超过一个应用程序都可以响应某隐式 Intent,则用户可以选用其中一个并指定为该 Action 的默认处理程序。 假如从这时开始,用户都期望用同一个应用程序执行这类 Action ,比如打开网页(用户通常会优先选用一种浏览器), 那这种做法是非常合适的。
  但是,如果总是有多个应用程序可以响应该 Intent,并且用户每次都需要使用不同的应用程序, 那就应该显示一个选择对话框。 该对话框每次都会要求用户选择一个用于处理 Action 的应用程序(用户无法为 Action 选择默认应用程序)。 例如,假设应用程序用 ACTION_SEND 执行“共享”操作,用户可能需要根据当前环境来选用一个应用程序, 所以一定要使用选择对话框,如下图所示。
  这里写图片描述
要显示选择对话框,请用 createChooser() 创建一个 Intent 并将其传入 startActivity()。 例如:

Intent intent = new Intent(Intent.ACTION_SEND); ... // Always use string resources for UI text. // This says something like "Share this photo with" String title = getResources().getString(R.string.chooser_title); // Create intent to show chooser Intent chooser = Intent.createChooser(intent, title); // Verify the intent will resolve to at least one activity if (sendIntent.resolveActivity(getPackageManager()) != null) {     startActivity(sendIntent); }

  上述对话框显示了一个应用程序列表,这些应用都可以响应传给 createChooser() 的 Intent ,对话框的标题也由其给定。

接受隐式Intent
  要将应用程序可接收的隐式 Intent 发布出去,需要在 manifest file 中用 <intent-filter> 元素为每个组件声明一个或多个 Intent 过滤器。 每个 Intent 过滤器定义了其可根据 Intent 的 action 、data 和 category 接受的 Intent 类别。 只有符合了组件中某个过滤器的条件,系统才会向组件分发该隐式 Intent 。
注意: 显式 Intent 一定是分发给目标组件的,无论组件中声明了什么 Intent 过滤器。

  应用程序组件应该为每个可完成的任务声明独立的过滤器。 例如,图库应用中的某个 Activity 可能会包含两个过滤器: 一个用于查看图片,另一个用于编辑图片。 在启动时, Activity 会检查 Intent 并根据其中的信息决定如何操作(比如是否显示编辑控件)。
  每个 Intent 过滤器都通过 Manifest 文件中的一项 <intent-filter> 元素来定义,该元素包含在相应的应用程序组件中(比如 <activity> 元素)。在 <intent-filter> 中,可以使用一个或多个以下三种元素来指定能够接受的 Intent 类型:

  • < action >
    在 name 属性中声明可接受的 Intent 的 Action。 属性值必须是表示 Action 的纯字符串,而不能是在类中定义的常量。
  • < data >
    通过一个或多个属性来声明可接受的数据类型,每个属性对应着数据 URI 的各个部分( scheme 、 host 、 port 、 path 等等)。
  • < category >
    在 name 属性中声明可接受的 Intent 类型。 属性值必须是表示 Category 的纯字符串,而不能是在类中定义的常量。

注意: 为了能够接收到隐式 Intent ,Intent 过滤器中必须包含 CATEGORY_DEFAULT 的类型。 startActivity() 和 startActivityForResult() 方法认为所有的 Intent 都应该声明了 CATEGORY_DEFAULT 类型。 如果 Activity 的 Intent 过滤器中未能给出这个类型,则不会有隐式 Intent 分发给它。

例如,下面是一个声明了 Intent 过滤器的 Activity,用于接收文本型数据的 ACTION_SEND Intent。

<activity android:name="ShareActivity">    <intent-filter>        <action android:name="android.intent.action.SEND"/>        <category android:name="android.intent.category.DEFAULT"/>        <data android:mimeType="text/plain"/>    </intent-filter></activity>

  可以创建包含了多个 <action><data><category> 的过滤器。 如果是这样,请确认该组件能够处理这些过滤条件的所有组合即可。
  如果需要处理多种类型的 Intent ,但仅限于某些特定 Action、Data 和 Category 的组合,那就需要创建多个 Intent 过滤器。

  限制对组件的访问
  使用 Intent 过滤器是一种不太安全的方式,无法阻止其他应用程序启动你的组件。 虽然 Intent 过滤器限制组件只能响应某些指定类型的隐式 Intent , 但只要其他应用程序的开发人员知道了组件名称,还是有可能通过显式 Intent 来启动该组件。 如果一定只有应用程序自身才能启动自己的组件,请将该组件的 exported 属性设为“false”。

  通过与过滤器的三个元素进行对比,隐式 Intent 将接受系统的检测。 Intent 要能分发到组件,必须三个条件全部通过。 只要有一个条件不满足, Android 系统就不会把该 Intent 分发给组件。 不过,组件可能拥有多个 Intent 过滤器,所以一个没通过还有可能通过另一个。 关于系统对 Intent 的分发方式,更多信息请参阅后续章节 Intent 解析。
  注意: 为了避免无意间运行了其他应用程序的 Service ,请一定要使用显式 Intent 来启动自己的服务,并且不要为服务声明 Intent 过滤器。
  提示: 所有的 Activity 都必须在 Manifest 文件中声明 Intent 过滤器。 但广播接收器的 Intent 过滤器可以实现动态注册,这通过调用 registerReceiver() 来完成。 然后可以通过 unregisterReceiver() 来注销。 通过这种方式,应用程序可以仅在运行过程中的某个阶段对指定的广播消息实现侦听。
  
Filter示例
  为了更好地理解 Intent 过滤器的运行机制,请参阅下面的 Manifest 文件片段,它来自于某个社交类应用。

<activity android:name="MainActivity">    <!-- This activity is the main entry, should appear in app launcher -->    <intent-filter>        <action android:name="android.intent.action.MAIN" />        <category android:name="android.intent.category.LAUNCHER" />    </intent-filter></activity><activity android:name="ShareActivity">    <!-- This activity handles "SEND" actions with text data -->    <intent-filter>        <action android:name="android.intent.action.SEND"/>        <category android:name="android.intent.category.DEFAULT"/>        <data android:mimeType="text/plain"/>    </intent-filter>    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->    <intent-filter>        <action android:name="android.intent.action.SEND"/>        <action android:name="android.intent.action.SEND_MULTIPLE"/>        <category android:name="android.intent.category.DEFAULT"/>        <data android:mimeType="application/vnd.google.panorama360+jpg"/>        <data android:mimeType="image/*"/>        <data android:mimeType="video/*"/>    </intent-filter></activity>

  第一个 Activity , MainActivity , 是程序的主入口, 当用户第一次通过启动器中的图标启动应用程序时,将会打开该 Activity :

  • ACTION_MAIN 指明了这是主入口,且不用包含任何 Intent 数据。
  • CATEGORY_LAUNCHER 指明了该 Activity 的图标应该在系统的应用程序启动器中显示出来。如果 <activity>元素未用 icon 给出图标的定义,系统会使用 <application> 中定义的图标。

为了要让 Activity 能够在应用程序启动器中显式出来,上述两项必须放在一起成对给出。

  第二个 Activity ,ShareActivity ,用于实现文本和多媒体数据的共享。 用户可以从 MainActivity 中跳转到 ShareActivity ,也可以从其他应用程序中直接进入, 只要发起一个匹配两个过滤器之一的隐式 Intent 即可。
  注意: MIME 类型 application/vnd.google.panorama360+jpg 是一种特殊的数据类型,定义了可用 Google panorama API 进行处理的全景照片

使用 Pending Intent
  PendingIntent 对象是对 Intent 对象的二次封装。 PendingIntent 的主要用途是对需要使用其 Intent 的外部应用程序进行授权,使得它就像在本应用程序的进程中运行一样。
Pending Intent 的主要应用场景包括:

  • 当用户通过 通知 进行某项操作时,需要执行的 Intent ( Android 系统的 NotificationManager 将会执行此
    Intent)。
  • 当用户通过 App Widget 进行某项操作时,需要执行的 Intent (主屏幕管理应用程序将会执行此 Intent)。
  • 未来某个时间点需要执行的 Intent( Android 系统的 AlarmManager 将会执行此 Intent)。

因为每种 Intent 对象都被设计为仅能由某个指定类型的组件进行处理( Activity、 Service 或 BroadcastReceiver 之一), 所以 PendingIntent 也必须如此。 在使用 Pending Intent 时,应用程序无法通过 startActivity() 之类的调用来执行 Intent 。 而是必须在创建 PendingIntent 时,调用以下创建方法来表明对应的组件类型:

  • 启动 Activity ,则调用PendingIntent.getActivity()方法 。
  • 启动 Service ,则使用 PendingIntent.getService()方法。
  • 启动 BroadcastReceiver ,则调用 PendingIntent.getBroadcast()方法。

上述创建 PendingIntent 的方法就已经是需要用到的全部 PendingIntent 方法,除非需要从其他应用程序接收 Pending Intent 。
每个方法都会带入当前应用程序的 Context、 要封装的 Intent 以及一个或多个指明 Intent 使用方式的标志位(比如 Intent 是否可以多次使用)。

Intent 解析
  当系统收到一个启动 Activity 的隐式 Intent 后,将会查找最合适的 Activity , 这通过比较 Intent 和 Intent 过滤器的三个部分来实现:

  • Intent 的 Action
  • Intent 的数据(包括 URI 和 数据类型)
  • Intent 的类型

以下章节说明了一个 Intent 如何在一系列的组件中匹配到最合适的那个以及如何在 Manifest 文件中声明Intent Filter。
  1、Action 验证
  为了指定可接受的 Intent Action,Intent 过滤器可以声明0个以上的 < action > 元素。例如:

<intent-filter>    <action android:name="android.intent.action.EDIT" />    <action android:name="android.intent.action.VIEW" />    ...</intent-filter>

  为了通过这个过滤器的验证, Intent 中指定的 Action 必须匹配上述过滤器中的一种 Action。
  如果过滤器没有给出任何 Action , Intent 就没有可匹配的目标,因此所有的验证都会失败。 但是,如果是 Intent 未给出 Action ,则它会通过验证(假设过滤器中至少包含了一个 Action)。
  
  2、Category 验证
  为了指定可接收的 Intent 类型, Intent 过滤器可以声明0个以上的 < category > 元素。例如:

<intent-filter>    <category android:name="android.intent.category.DEFAULT" />    <category android:name="android.intent.category.BROWSABLE" />    ...</intent-filter>

  为了通过类型验证, Intent 中的每个 Category 都必须与过滤器中的相匹配。 反之则不然 — Intent 过滤器中声明的 Category 可以多于 Intent 中的,验证将会通过。 因此,不带任何 Category 的 Intent 也将会通过验证,不管过滤器中的 Category 怎么声明都会通过。
  注意: Android 会对传入 startActivity() 和 startActivityForResult() 的隐式 Intent 自动应用 CATEGORY_DEFAULT 类型。 因此,如果 Activity 需要接收隐式 Intent ,它就必须在 Intent 过滤器中包含 “android.intent.category.DEFAULT” (正如上述 < intent-filter > 所示)。

  3、Data 验证
  为了指定可接收的 Intent 数据, Intent 过滤器可以声明0个以上的 < data > 元素。例如:

<intent-filter>    <data android:mimeType="video/mpeg" android:scheme="http" ... />    <data android:mimeType="audio/mpeg" android:scheme="http" ... />    ...</intent-filter>

  每个 < data > 元素都可以指定一个 URI 和一个数据类型(MIME 媒体类型)。 URI 的每个部分都对应有单独的属性 — scheme 、host 、 port 和 path:
< scheme > :// < host > : < port > / < path >
例如:

content://com.example.project:200/folder/subfolder/etc

  在上述 URI 中, Scheme 是 content , Host 是 com.example.project , Port 是 200 , Path 是 folder/subfolder/etc 。
这些属性都是 < data > 元素的可选项,但却有顺序的依赖关系:

  1. 如果未给出 Scheme ,则 Host 将被忽略。
  2. 如果未给出 Host ,则 Port 将被忽略。
  3. 如果 Scheme 和 Host 均未给出,则 Path 将被忽略。

在把 Intent 中的 URI 和过滤器中的 URI 规则进行比较时,只会按照过滤器 URI 的各个部分来进行。 例如:

  1. 如果过滤器只声明了 Scheme ,则所有带有此 Scheme 的 URI 都将是与其匹配的。
  2. 如果过滤器声明了 Scheme 和 Authority ,但没有声明 Path , 则所有带有同样 Scheme 和 Authority的 URI 都会通过该过滤器, Path 怎么样都无所谓。
  3. 如果过滤器同时声明了 Scheme 、 Authority 和 Path , 则只有那些 Scheme 、 Authority 和Path 都符合的 URI 才能通过该过滤器。

注意: Path 规则中可以包含通配符(*),这样只需要匹配部分路径名称即可。

  数据验证将会同时比较 Intent 和过滤器的 URI 和 MIME 类型。 规则如下:

  1. 如果 Intent 即不包含 URI ,也不含 MIME 类型, 则仅当过滤器也未指定任何 URI 和 MIME 类型时,才能通过验证。
  2. 如果 Intent 包含了 URI ,但不含 MIME 类型(既没有显式给出也无法从 URI 中推导出来), 则仅当 URI 与过滤器的
    URI 规则吻合且过滤器未指定 MIME 类型时,才能通过验证。
  3. 如果 Intent 包含了 MIME 类型,但不含 URI , 则仅当过滤器中列出了相同的 MIME 类型且未指定 URI
    规则时,才能通过验证。
  4. 如果 Intent 同时包含了 URI 和 MIME 类型(显式给出或可从 URI 中推导出来), 则当过滤器中列出了相同的 MIME类型时通过 MIME 类型验证。 当 URI 与过滤器中的 URI 相匹配,或者 URI 带有 content: 或file:且过滤器未指定 URI 时,通过 URI 验证。 也就是说,如果某个组件的 Intent 过滤器只给出了 MIME 类型,那么就表示它将支持 content: 和 file: 数据的处理。

最后一条规则说明,系统期望所有组件都能够读取文件或者 Content Provider 中的本地数据。 因此,过滤器只需要列出数据类型即可,不必显式地命名 content: 和 file: 类型的 Scheme。 这是一种典型的应用场景。 例如,下述的 < data > 元素将会通知 Android 系统,该组件可以从 Content Provider 读取图片数据并显示出来:

<intent-filter>    <data android:mimeType="image/*" />    ...</intent-filter>

  因为大部分数据都是由 Content Provider 发布出来的, 所以指定数据类型但不给出 URI 也许是 Intent 过滤器最常见的配置方式。
  Intent 过滤器另一种常见的配置方式就是包含 Scheme 和数据类型。 例如,类似下述的 < data > 元素将会通知 Andorid 系统,为了执行 Action ,该组件可以从网络读取视频数据:

<intent-filter>    <data android:scheme="http" android:type="video/*" />    ...</intent-filter>

Intent 匹配
  Intent 与 过滤器的匹配机制,不仅用于查找需要激活的组件,还用于发现当前设备中所有组件的某些信息。 例如,通过把所有带有 ACTION_MAIN Action 和 CATEGORY_LAUNCHER Category 过滤器的 Activity 找出来,管理主屏幕的应用程序就可以组建应用程序启动器。
  应用程序可以采用统一的方式来使用 Intent 过滤机制。PackageManager 拥有一些 query…() 方法, 这些方法将会返回能够接受某类 Intent 的全部组件, 类似的另一些 resolve…() 方法将会确定响应某个 Intent 的最佳组件。例如, queryIntentActivities() 将返回可执行传入参数 Intent 的 Activity 列表, queryIntentServices() 将返回类似的服务列表。 这两个方法均不会激活组件,而只是列出能够响应 Intent 的组件。 另一个类似的方法,就是列出广播接收器列表的 queryBroadcastReceivers()。

0 0