标签:
这是可选项,但也是构建显式 Intent 的一项重要信息,这意味着 Intent 应当仅传递给由组件名称定义的应用组件。如果没有组件名称,则 Intent 是隐式的,且系统将根据其他 Intent 信息(例如,以下所述的操作、数据和类别)决定哪个组件应当接收 Intent。因此,如需在应用中启动特定的组件,则应指定该组件的名称。
注意:启动 Service
时,您应 始终指定组件名称。否则,您无法确定哪项服务会响应 Intent,且用户无法看到哪项服务已启动。
Intent
的这一字段是 ComponentName
对象,您可以使用目标组件的完全限定类名指定此对象,其中包括应用的软件包名称。例如,com.example.ExampleActivity
。您可以使用 setComponent()
、setClass()
、setClassName()
或 Intent
构造函数设置组件名称。
对于广播 Intent,这是指已发生且正在报告的操作。操作在很大程度上决定了其余 Intent 的构成,特别是数据和 extra 中包含的内容。
您可以指定自己的操作,供 Intent 在您的应用内使用(或者供其他应用在您的应用中调用组件)。但是,您通常应该使用由 Intent
类或其他框架类定义的操作常量。以下是一些用于启动 Activity 的常见操作:
ACTION_VIEW
startActivity()
结合使用。ACTION_SEND
startActivity()
结合使用。有关更多定义通用操作的常量,请参阅Intent
类引用。 其他操作在 Android 框架中的其他位置定义。例如,对于在系统的设置应用中打开特定屏幕的操作,将在 Settings
中定义。
您可以使用 setAction()
或 Intent
构造函数为 Intent 指定操作。
如果定义自己的操作,请确保将应用的软件包名称作为前缀。 例如:
static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
Uri
对象)。提供的数据类型通常由 Intent 的操作决定。例如,如果操作是 ACTION_EDIT
,则数据应包含待编辑文档的 URI。
创建 Intent 时,除了指定 URI 以外,指定数据类型(其 MIME 类型)往往也很重要。例如,能够显示图像的Activity可能无法播放音频文件,即便 URI 格式十分类似时也是如此。因此,指定数据的 MIME 类型有助于 Android 系统找到接收 Intent 的最佳组件。但有时,MIME 类型可以从 URI 中推断得出,特别当数据是 content:
URI 时尤其如此。这表明数据位于设备中,且由 ContentProvider
控制,这使得数据 MIME 类型对系统可见。
要仅设置数据 URI,请调用 setData()
。要仅设置 MIME 类型,请调用 setType()
。如有必要,您可以使用 setDataAndType()
同时显式设置二者。
警告:若要同时设置 URI 和 MIME 类型,请勿调用 setData()
和 setType()
,因为它们会互相抵消彼此的值。请始终使用 setDataAndType()
同时设置 URI 和 MIME 类型。
CATEGORY_BROWSABLE
CATEGORY_LAUNCHER
有关类别的完整列表,请参阅 Intent
类描述。
您可以使用 addCategory()
指定类别。
以上列出的这些属性(组件名称、操作、数据和类别)表示 Intent 的既定特征。通过读取这些属性,Android 系统能够解析应当启动哪个应用组件。
但是,Intent 也有可能会一些携带不影响其如何解析为应用组件的信息。Intent 还可以提供:
您可以使用各种 putExtra()
方法添加附加数据,每种方法均接受两个参数:键名和值。您还可以创建一个包含所有附加数据的 Bundle
对象,然后使用 putExtras()
将 Bundle
插入 Intent
中。
例如,使用 ACTION_SEND
创建用于发送电子邮件的 Intent 时,可以使用 EXTRA_EMAIL
键指定“目标”收件人,并使用 EXTRA_SUBJECT
键指定“主题”。
Intent
类将为标准化的数据类型指定多个 EXTRA_*
常量。如需声明自己的附加数据 键(对于应用接收的 Intent ),请确保将应用的软件包名称作为前缀。例如:
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
Intent
类中定义的、充当 Intent 元数据的标志。标志可以指示 Android 系统如何启动 Activity(例如,Activity 应属于哪个 任务 ),以及启动之后如何处理(例如,它是否属于最近的 Activity 列表)。
setFlags()
方法。显式 Intent 是指用于启动某个特定应用组件(例如,应用中的某个特定 Activity 或服务)的 Intent。要创建显式 Intent,请为 Intent
对象定义组件名称。Intent 的所有其他属性均为可选属性。
例如,如果在应用中构建了一个名为 DownloadService
、旨在从 Web 中下载文件的服务,则可使用以下代码启动该服务:
// Executed in an Activity, so ‘this‘ is theContext
// 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 指定能够在可以执行相应操作的设备上调用任何应用的操作。如果您的应用无法执行该操作而其他应用可以,且您希望用户选取要使用的应用,则使用隐式 Intent 非常有用。
例如,如果您希望用户与他人共享您的内容,请使用 ACTION_SEND
操作创建 Intent,并添加指定共享内容的 Extra。使用该 Intent 调用startActivity()
时,用户可以选取共享内容所使用的应用。
警告:用户可能没有任何应用处理您发送到 startActivity()
的隐式 Intent。如果出现这种情况,则调用将会失败,且应用会崩溃。要验证 Activity 是否会接收 Intent,请对 Intent
对象调用 resolveActivity()
。如果结果为非空,则至少有一个应用能够处理该 Intent,且可以安全调用startActivity()
。如果结果为空,则不应使用该 Intent。如有可能,您应禁用发出该 Intent 的功能。
// Create the text message with a string
Intent 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 activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
注意:在这种情况下,系统并没有使用 URI,但已声明 Intent 的数据类型,用于指定 Extra 携带的内容。
startActivity()
时,系统将检查已安装的所有应用,确定哪些应用能够处理这种 Intent(即:含 ACTION_SEND
操作并携带“文本/纯”数据的 Intent )。如果只有一个应用能够处理,则该应用将立即打开并提供给 Intent。如果多个 Activity 接受 Intent,则系统将显示一个对话框,使用户能够选取要使用的应用。如果有多个应用响应隐式 Intent,则用户可以选择要使用的应用,并将其设置为该操作的默认选项。 如果用户可能希望今后一直使用相同的应用执行某项操作(例如,打开网页时,用户往往倾向于仅使用一种 Web 浏览器),则这一点十分有用。
但是,如果多个应用可以响应 Intent,且用户可能希望每次使用不同的应用,则应采用显式方式显示选择器对话框。选择器对话框要求用户选择每次操作要使用的应用(用户无法为该操作选择默认应用)。 例如,当应用使用ACTION_SEND
操作执行“共享”时,用户根据目前的状况可能需要使用另一不同的应用,因此应当始终使用选择器对话框,如图 2 中所示。
要显示选择器,请使用 createChooser()
创建 Intent
,并将其传递给 startActivity()
。例如:
Intent sendIntent = 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 the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);
// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
createChooser()
方法的 Intent 的应用列表,并使用提供的文本作为对话框标题。例如,以下是一个使用 Intent 过滤器进行的 Activity 声明,当数据类型为文本时,系统将接收 ACTION_SEND
Intent :
如需仅以操作、数据和类别类型的特定组合来处理多种 Intent,则需创建多个 Intent 过滤器。
使用 Intent 过滤器时,无法安全地防止其他应用启动组件。尽管 Intent 过滤器将组件限制为仅响应特定类型的隐式 Intent,但如果开发者确定您的组件名称,则其他应用有可能通过使用显式 Intent 启动您的应用组件。如果必须确保只有您自己的应用才能启动您的某一组件,请针对该组件将 exported
属性设置为 "false"
。
系统通过将 Intent 与所有这三个元素进行比较,根据过滤器测试隐式 Intent。隐式 Intent 若要传递给组件,必须通过所有这三项测试。如果 Intent 甚至无法匹配其中任何一项测试,则 Android 系统不会将其传递给组件。但是,由于一个组件可能有多个 Intent 过滤器,因此未能通过某一组件过滤器的 Intent 可能会通过另一过滤器。如需了解有关系统如何解析 Intent 的详细信息,请参阅下文的 Intent 解析部分。
警告:为了避免无意中运行不同应用的 Service
,请始终使用显式 Intent 启动您自己的服务,且不必为该服务声明 Intent 过滤器。
registerReceiver()
动态注册。稍后,您可以使用 unregisterReceiver()
注销该接收器。这样一来,应用便可仅在应用运行时的某一指定时间段内侦听特定的广播。PendingIntent.getActivity()
,适用于启动 Activity
的 Intent
。PendingIntent.getService()
,适用于启动 Service
的 Intent
。PendingIntent.getBroadcast()
,适用于启动 BroadcastReceiver
的 Intent
。除非您的应用正在从其他应用中接收待定 Intent,否则上述用于创建 PendingIntent
的方法可能是您所需的唯一 PendingIntent
方法。
每种方法均会提取当前的应用 Context
、您要包装的 Intent
以及一个或多个指定应如何使用该 Intent 的标志(例如,是否可以多次使用该 Intent)。
当系统收到隐式 Intent 以启动 Activity 时,它根据以下三个方面将该 Intent 与 Intent 过滤器进行比较,搜索该 Intent 的最佳 Activity:
下文根据如何在应用的清单文件中声明 Intent 过滤器,描述 Intent 如何与相应的组件匹配。
要指定接受的 Intent 操作, Intent 过滤器既可以不声明任何 <action>
元素,也可以声明多个此类元素。例如:
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
...
</intent-filter>
要通过此过滤器,您在 Intent
中指定的操作必须与过滤器中列出的某一操作匹配。
如果该过滤器未列出任何操作,则 Intent 没有任何匹配项,因此所有 Intent 均无法通过测试。但是,如果 Intent
未指定操作,则会通过测试(只要过滤器至少包含一个操作)。
要指定接受的 Intent 类别, Intent 过滤器既可以不声明任何 <category>
元素,也可以声明多个此类元素。例如:
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
...
</intent-filter>
若要 Intent 通过类别测试,则 Intent
中的每个类别均必须与过滤器中的类别匹配。反之则未必然,Intent 过滤器声明的类别可以超出 Intent
中指定的数量,且 Intent
仍会通过测试。因此,不含类别的 Intent 应当始终会通过此测试,无论过滤器中声明何种类别均是如此。
注意: Android 会自动将 CATEGORY_DEFAULT
类别应用于传递给 startActivity()
和 startActivityForResult()
的所有隐式 Intent。因此,如需 Activity 接收隐式 Intent,则必须将 "android.intent.category.DEFAULT"
的类别包括在其 Intent 过滤器中(如上文的 <intent-filter>
示例所示)。
要指定接受的 Intent 数据, Intent 过滤器既可以不声明任何 <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 中,架构是 content
,主机是 com.example.project
,端口是 200
,路径是 folder/subfolder/etc
。
在 <data>
元素中,上述每个属性均为可选,但存在线性依赖关系:
将 Intent 中的 URI 与过滤器中的 URI 规范进行比较时,它仅与过滤器中包含的部分 URI 进行比较。例如:
注意:路径规范可以包含星号通配符 (*),因此仅需部分匹配路径名即可。
数据测试会将 Intent 中的 URI 和 MIME 类型与过滤器中指定的 URI 和 MIME 类型进行比较。规则如下:
content:
或 file:
URI 且过滤器未指定 URI,则 Intent 会通过测试的 URI 部分。换而言之,如果过滤器仅列出 MIME 类型,则假定组件支持 content:
和 file:
数据。
最后一条规则,即规则 (d),反映了期望组件能够从文件中或内容提供商处获得本地数据。因此,其过滤器可以仅列出数据类型,而不必显式命名 content:
和 file:
架构。这是一个典型的案例。例如,下文中的 <data>
元素向 Android 指出,组件可从内容提供商处获得并显示图像数据:
<intent-filter>
<data android:mimeType="image/*" />
...
</intent-filter>
由于大部分可用数据均由内容提供商分发,因此指定数据类型(而非 URI)的过滤器也许最为常见。
另一常见的配置是具有架构和数据类型的过滤器。例如,下文中的 <data>
元素向 Android 指出,组件可从网络中检索视频数据以执行操作:
<intent-filter>
<data android:scheme="http" android:type="video/*" />
...
</intent-filter>
通过 Intent 过滤器匹配 Intent,这不仅有助于发现要激活的目标组件,还有助于发现设备上组件集的相关信息。例如,主页应用通过使用指定 ACTION_MAIN
操作和 CATEGORY_LAUNCHER
类别的 Intent 过滤器查找所有 Activity,以此填充应用启动器。
PackageManager
提供了一整套 query...()
方法来返回所有能够接受特定 Intent 的组件。此外,它还提供了一系列类似的 resolve...()
方法来确定响应 Intent 的最佳组件。例如,queryIntentActivities()
将返回能够执行那些作为参数传递的 Intent 的所有 Activity 列表,而 queryIntentServices()
则可返回类似的服务列表。这两种方法均不会激活组件,而只是列出能够响应的组件。对于广播接收器,有一种类似的方法: queryBroadcastReceivers()
。我的Android笔记--Intent上(我是文档的搬运工)
标签:
原文地址:http://www.cnblogs.com/wdh-blog/p/5720946.html