IntentFilter到底是什么 - UserWang/Android-Notes GitHub Wiki

语法:

 <intent-filter android:icon="drawable resource"
                android:label="string resource"
                android:priority="integer" >
   . . .
</intent-filter>

包含于:

<activity> 
<activity-alias> 
<service> 
<receiver>

描述:

指定activity、service或broadcast receiver可以响应的Intent类型。一个IntentFilter声明了它所在组件的能力,比如一个activity或service可以做什么,或者说一个广播接收者可以接收什么类型的广播等。它可以在启动一个组件来接收意图的时候过滤掉不相关的组件。 应用的核心组件(其 Activity、服务和广播接收器)由 Intent 激活。Intent 是一系列用于描述所需操作的信息(Intent 对象),其中包括要执行操作的数据、应执行操作的组件类别以及其他相关说明。 Android 会找到合适的组件来响应 Intent,根据需要启动组件的新实例,并将其传递到 Intent 对象。

组件将通过“Intent Filter”公布其功能,即它们可响应的 Intent 类型。 由于 Android 系统在启动某组件之前必须了解该组件可以处理哪些 Intent,因此 Intent 过滤器在清单文件中被指定为 元素。 一个组件可能有任意数量的过滤器,其中每个过滤器描述一种不同的功能。

显式命名目标组件的 Intent 将激活该组件;过滤器不起作用。但是,不按名称指定目标的 Intent 只有在能够通过组件的一个过滤器时才可激活该组件。

属性:

android:icon
android:label
android:priority

官方文档:http://developer.android.com/intl/zh-cn/guide/topics/manifest/intent-filter-element.html

看了上边这些描述,还是不知道IntentFilter到底什么鬼?那我们就继续:

首先我们需要了解一下什么是Intent:

Intent 是一个消息传递对象,您可以使用它从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信,但其基本用例主要包括以下三个:

启动activity
通过将 Intent 传递给 startActivity(),您可以启动新的 Activity 实例。Intent 描述了要启动的 Activity,并携带了任何必要的数据。
如果您希望在 Activity 完成后收到结果,请调用 startActivityForResult()。在 Activity 的 onActivityResult() 回调中,您的   Activity 将结果作为单独的 Intent 对象接收。

启动service
通过将 Intent 传递给 startService(),您可以启动服务执行一次性操作(例如,下载文件)。Intent 描述了要启动的服务,并携带了任何必      要的数据。
如果服务旨在使用客户端-服务器接口,则通过将 Intent 传递给 bindService(),您可以从其他组件绑定到此服务。

传递广播
广播是任何应用均可接收的消息。系统将针对系统事件(例如:系统启动或设备开始充电时)传递各种广播。通过将 Intent 传递给       sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast(),您可以将广播传递给其他应用。

Intent 分为两种类型:

显式 Intent :按名称(完全限定类名)指定要启动的组件。通常,您会在自己的应用中使用显式 Intent 来启动组件,这是因为您知道要启动的   Activity 或服务的类名。例如,启动新 Activity 以响应用户操作,或者启动服务以在后台下载文件。
隐式 Intent :不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。例如,如需在地图上向用户显示位置,则可以使用隐式 Intent,请求另一具有此功能的应用在地图上显示指定的位置。 

创建显式 Intent 启动 Activity 或服务时,系统将立即启动 Intent 对象中指定的应用组件。 创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent Filter进行比较,从而找到要启动的相应组件。如果 Intent 与 Intent Filter匹配,则系统将启动该组件,并将其传递给对象。如果多个 Intent Filter兼容,则系统会显示一个对话框,支持用户选取要使用的应用。

Intent Filter是应用清单文件中的一个表达式,它指定该组件要接收的 Intent 类型。例如,通过为 Activity 声明 Intent Filter,您可以使其他应用能够直接使用某一特定类型的 Intent 启动 Activity。同样,如果您没有为 Activity 声明任何 Intent Filter,则 Activity 只能通过显式 Intent 启动。

警告:为了确保应用的安全性,启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应 Intent,且用户无法看到哪些服务已启动。从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用 bindService(),系统会抛出异常。

要公布应用可以接收哪些隐式 Intent,请在清单文件中使用 元素为每个应用组件声明一个或多个 Intent 过滤器。每个 Intent 过滤器均根据 Intent 的操作、数据和类别指定自身接受的 Intent 类型。仅当隐式 Intent 可以通过 Intent 过滤器之一传递时,系统才会将该 Intent 传递给应用组件。

注意:显式 Intent 始终会传递给其目标,无论组件声明的 Intent 过滤器如何均是如此。

应用组件应当为自身可执行的每个独特作业声明单独的过滤器。例如,图像库应用中的一个 Activity 可能会有两个过滤器,分别用于查看图像和编辑图像。 当 Activity 启动时,它将检查 Intent 并根据 Intent 中的信息决定具体的行为(例如,是否显示编辑器控件)。 每个 Intent Filter均由应用清单文件中的 元素定义,并嵌套在相应的应用组件(例如, 元素)中。在 内部,您可以使用以下三个元素中的一个或多个指定要接受的 Intent 类型:

<action>(必须包含)
在 name 属性中,声明接受的 Intent 操作。该值必须是操作的文本字符串值,而不是类常量。

<data>(可以包含)
使用一个或多个指定 数据 URI(scheme、host、port、path 等)各个方面和 MIME 类型的属性,声明接受的数据类型。

<category> (可以包含)
在 name 属性中,声明接受的 Intent 类别。该值必须是操作的文本字符串值,而不是类常量。

注意:为了接收隐式 Intent,必须将 CATEGORY_DEFAULT 类别包括在 Intent Filter中。方法 startActivity() 和 startActivityForResult() 将按照已申明 CATEGORY_DEFAULT 类别的方式处理所有 Intent。 如果未在 Intent Filter中声明此类别,则隐式 Intent 不会解析为您的 Activity。

例如,以下是一个使用 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>

您可以创建一个包括多个 、 或 实例的过滤器。创建时,仅需确定组件能够处理这些过滤器元素的任何及所有组合即可。 如需仅以操作、数据和类别类型的特定组合来处理多种 Intent,则需创建多个 Intent Filter。

系统通过将 Intent 与所有这三个元素进行比较,根据过滤器测试隐式 Intent。隐式 Intent 若要传递给组件,必须通过所有这三项测试。如果 Intent 甚至无法匹配其中任何一项测试,则 Android 系统不会将其传递给组件。但是,由于一个组件可能有多个 Intent 过滤器,因此未能通过某一组件过滤器的 Intent 可能会通过另一过滤器。

限制对组件的访问
使用 Intent Filter时,无法安全地防止其他应用启动组件。尽管 Intent Filter将组件限制为仅响应特定类型的隐式 Intent,
但如果开发者确定您的组件名称,则其他应用有可能通过使用显式 Intent 启动您的应用组件。如果必须确保只有您自己的应用才
能启动您的某一组件,请针对该组件将 exported 属性设置为 "false"。

警告:为了避免无意中运行不同应用的 Service,请始终使用显式 Intent 启动您自己的服务,且不必为该服务声明 Intent 过滤器。

注意: 对于所有 Activity,您必须在清单文件中声明 Intent 过滤器。但是,广播接收器的过滤器可以通过调用 registerReceiver() 动态注册。稍后,您可以使用 unregisterReceiver() 注销该接收器。这样一来,应用便可仅在应用运行时的某一指定时间段内侦听特定的广播。

⚠️ **GitHub.com Fallback** ⚠️