An Intent
is a messaging object you can use to request an action from another app component. Although intents facilitate communication between components in several ways, there are three fundamental use-cases:
An Activity
represents a single screen in an app. You can start a new instance of an Activity
by passing an Intent
tostartActivity()
. The Intent
describes the activity to start and carries any necessary data.
If you want to receive a result from the activity when it finishes, call startActivityForResult()
. Your activity receives the result as a separate Intent
object in your activity'sonActivityResult()
callback. For more information, see theActivities guide.
A Service
is a component that performs operations in the background without a user interface. You can start a service to perform a one-time operation (such as download a file) by passing an Intent
to startService()
. The Intent
describes the service to start and carries any necessary data.
If the service is designed with a client-server interface, you can bind to the service from another component by passing an Intent
to bindService()
. For more information, see the Services guide.
A broadcast is a message that any app can receive. The system delivers various broadcasts for system events, such as when the system boots up or the device starts charging. You can deliver a broadcast to other apps by passing an Intent
to sendBroadcast()
, sendOrderedBroadcast()
, or sendStickyBroadcast()
.
There are two types of intents:
When you create an explicit intent to start an activity or service, the system immediately starts the app component specified in the Intent
object.
Figure 1. Illustration of how an implicit intent is delivered through the system to start another activity: [1] Activity Acreates an Intent
with an action description and passes it to startActivity()
. [2] The Android System searches all apps for an intent filter that matches the intent. When a match is found, [3] the system starts the matching activity (Activity B) by invoking its onCreate()
method and passing it the Intent
.
When you create an implicit intent, the Android system finds the appropriate component to start by comparing the contents of the intent to the intent filters declared in the manifest file of other apps on the device. If the intent matches an intent filter, the system starts that component and delivers it theIntent
object. If multiple intent filters are compatible, the system displays a dialog so the user can pick which app to use.
An intent filter is an expression in an app's manifest file that specifies the type of intents that the component would like to receive. For instance, by declaring an intent filter for an activity, you make it possible for other apps to directly start your activity with a certain kind of intent. Likewise, if you do notdeclare any intent filters for an activity, then it can be started only with an explicit intent.
Caution: To ensure your app is secure, always use an explicit intent when starting a Service
and do not declare intent filters for your services. Using an implicit intent to start a service is a security hazard because you cannot be certain what service will respond to the intent, and the user cannot see which service starts. Beginning with Android 5.0 (API level 21), the system throws an exception if you call bindService()
with an implicit intent.
An Intent
object carries information that the Android system uses to determine which component to start (such as the exact component name or component category that should receive the intent), plus information that the recipient component uses in order to properly perform the action (such as the action to take and the data to act upon).
The primary information contained in an Intent
is the following:
This is optional, but it's the critical piece of information that makes an intent explicit, meaning that the intent should be delivered only to the app component defined by the component name. Without a component name, the intent is implicit and the system decides which component should receive the intent based on the other intent information (such as the action, data, and category—described below). So if you need to start a specific component in your app, you should specify the component name.
Note: When starting a Service
, you should always specify the component name. Otherwise, you cannot be certain what service will respond to the intent, and the user cannot see which service starts.
This field of the Intent
is a ComponentName
object, which you can specify using a fully qualified class name of the target component, including the package name of the app. For example,com.example.ExampleActivity
. You can set the component name with setComponent()
, setClass()
,setClassName()
, or with the Intent
constructor.
In the case of a broadcast intent, this is the action that took place and is being reported. The action largely determines how the rest of the intent is structured—particularly what is contained in the data and extras.
You can specify your own actions for use by intents within your app (or for use by other apps to invoke components in your app), but you should usually use action constants defined by the Intent
class or other framework classes. Here are some common actions for starting an activity:
ACTION_VIEW
startActivity()
when you have some information that an activity can show to the user, such as a photo to view in a gallery app, or an address to view in a map app.
ACTION_SEND
startActivity()
when you have some data that the user can share through another app, such as an email app or social sharing app.
See the Intent
class reference for more constants that define generic actions. Other actions are defined elsewhere in the Android framework, such as in Settings
for actions that open specific screens in the system's Settings app.
You can specify the action for an intent with setAction()
or with an Intent
constructor.
If you define your own actions, be sure to include your app's package name as a prefix. For example:
static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
Uri
object) that references the data to be acted on and/or the MIME type of that data. The type of data supplied is generally dictated by the intent's action. For example, if the action is
ACTION_EDIT
, the data should contain the URI of the document to edit.
When creating an intent, it's often important to specify the type of data (its MIME type) in addition to its URI. For example, an activity that's able to display images probably won't be able to play an audio file, even though the URI formats could be similar. So specifying the MIME type of your data helps the Android system find the best component to receive your intent. However, the MIME type can sometimes be inferred from the URI—particularly when the data is a content:
URI, which indicates the data is located on the device and controlled by a ContentProvider
, which makes the data MIME type visible to the system.
To set only the data URI, call setData()
. To set only the MIME type, call setType()
. If necessary, you can set both explicitly with setDataAndType()
.
Caution: If you want to set both the URI and MIME type, do not call setData()
and setType()
because they each nullify the value of the other. Always use setDataAndType()
to set both URI and MIME type.
CATEGORY_BROWSABLE
CATEGORY_LAUNCHER
See the Intent
class description for the full list of categories.
You can specify a category with addCategory()
.
These properties listed above (component name, action, data, and category) represent the defining characteristics of an intent. By reading these properties, the Android system is able to resolve which app component it should start.
However, an intent can carry additional information that does not affect how it is resolved to an app component. An intent can also supply:
You can add extra data with various putExtra()
methods, each accepting two parameters: the key name and the value. You can also create a Bundle
object with all the extra data, then insert the Bundle
in theIntent
with putExtras()
.
For example, when creating an intent to send an email with ACTION_SEND
, you can specify the "to" recipient with the EXTRA_EMAIL
key, and specify the "subject" with the EXTRA_SUBJECT
key.
The Intent
class specifies many EXTRA_*
constants for standardized data types. If you need to declare your own extra keys (for intents that your app receives), be sure to include your app's package name as a prefix. For example:
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
Intent
class that function as metadata for the intent. The flags may instruct the Android system how to launch an activity (for example, which task the activity should belong to) and how to treat it after it's launched (for example, whether it belongs in the list of recent activities).
For more information, see the setFlags()
method.
An explicit intent is one that you use to launch a specific app component, such as a particular activity or service in your app. To create an explicit intent, define the component name for the Intent
object—all other intent properties are optional.
For example, if you built a service in your app, named DownloadService
, designed to download a file from the web, you can start it with the following code:
// 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);
The Intent(Context, Class)
constructor supplies the app Context
and the component a Class
object. As such, this intent explicitly starts the DownloadService
class in the app.
For more information about building and starting a service, see the Services guide.
An implicit intent specifies an action that can invoke any app on the device able to perform the action. Using an implicit intent is useful when your app cannot perform the action, but other apps probably can and you'd like the user to pick which app to use.
For example, if you have content you want the user to share with other people, create an intent with theACTION_SEND
action and add extras that specify the content to share. When you call startActivity()
with that intent, the user can pick an app through which to share the content.
Caution: It's possible that a user won't have any apps that handle the implicit intent you send tostartActivity()
. If that happens, the call will fail and your app will crash. To verify that an activity will receive the intent, call resolveActivity()
on your Intent
object. If the result is non-null, then there is at least one app that can handle the intent and it's safe to call startActivity()
. If the result is null, you should not use the intent and, if possible, you should disable the feature that issues the 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); }
Note: In this case, a URI is not used, but the intent's data type is declared to specify the content carried by the extras.
When startActivity()
is called, the system examines all of the installed apps to determine which ones can handle this kind of intent (an intent with the ACTION_SEND
action and that carries "text/plain" data). If there's only one app that can handle it, that app opens immediately and is given the intent. If multiple activities accept the intent, the system displays a dialog so the user can pick which app to use..
Figure 2. A chooser dialog.
When there is more than one app that responds to your implicit intent, the user can select which app to use and make that app the default choice for the action. This is nice when performing an action for which the user probably wants to use the same app from now on, such as when opening a web page (users often prefer just one web browser) .
However, if multiple apps can respond to the intent and the user might want to use a different app each time, you should explicitly show a chooser dialog. The chooser dialog asks the user to select which app to use for the action every time (the user cannot select a default app for the action). For example, when your app performs "share" with the ACTION_SEND
action, users may want to share using a different app depending on their current situation, so you should always use the chooser dialog, as shown in figure 2.
To show the chooser, create an Intent
using createChooser()
and pass it to startActivity()
. For example:
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); }
This displays a dialog with a list of apps that respond to the intent passed to the createChooser()
method and uses the supplied text as the dialog title.
To advertise which implicit intents your app can receive, declare one or more intent filters for each of your app components with an <intent-filter>
element in your manifest file. Each intent filter specifies the type of intents it accepts based on the intent's action, data, and category. The system will deliver an implicit intent to your app component only if the intent can pass through one of your intent filters.
Note: An explicit intent is always delivered to its target, regardless of any intent filters the component declares.
An app component should declare separate filters for each unique job it can do. For example, one activity in an image gallery app may have two filters: one filter to view an image, and another filter to edit an image. When the activity starts, it inspects the Intent
and decides how to behave based on the information in the Intent
(such as to show the editor controls or not).
Each intent filter is defined by an <intent-filter>
element in the app's manifest file, nested in the corresponding app component (such as an <activity>
element). Inside the <intent-filter>
, you can specify the type of intents to accept using one or more of these three elements:
<action>
name
attribute. The value must be the literal string value of an action, not the class constant.
<data>
scheme
,
host
,
port
,
path
, etc.) and MIME type.
<category>
name
attribute. The value must be the literal string value of an action, not the class constant.
Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT
category in the intent filter. The methods startActivity()
and startActivityForResult()
treat all intents as if they declared the CATEGORY_DEFAULT
category. If you do not declare this category in your intent filter, no implicit intents will resolve to your activity.
For example, here's an activity declaration with an intent filter to receive an ACTION_SEND
intent when the data type is text:
<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>
It's okay to create a filter that includes more than one instance of <action>
, <data>
, or <category>
. If you do, you simply need to be certain that the component can handle any and all combinations of those filter elements.
When you want to handle multiple kinds of intents, but only in specific combinations of action, data, and category type, then you need to create multiple intent filters.
Using an intent filter is not a secure way to prevent other apps from starting your components. Although intent filters restrict a component to respond to only certain kinds of implicit intents, another app can potentially start your app component by using an explicit intent if the developer determines your component names. If it's important that only your own app is able to start one of your components, set the exported
attribute to "false"
for that component.
An implicit intent is tested against a filter by comparing the intent to each of the three elements. To be delivered to the component, the intent must pass all three tests. If it fails to match even one of them, the Android system won't deliver the intent to the component. However, because a component may have multiple intent filters, an intent that does not pass through one of a component's filters might make it through on another filter. More information about how the system resolves intents is provided in the section below about Intent Resolution.
Caution: To avoid inadvertently running a different app'sService
, always use an explicit intent to start your own service and do not declare intent filters for your service.
Note: For all activities, you must declare your intent filters in the manifest file. However, filters for broadcast receivers can be registered dynamically by calling registerReceiver()
. You can then unregister the receiver with unregisterReceiver()
. Doing so allows your app to listen for specific broadcasts during only a specified period of time while your app is running.
To better understand some of the intent filter behaviors, look at the following snippet from the manifest file of a social-sharing app.
<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>
The first activity, MainActivity
, is the app's main entry point—the activity that opens when the user initially launches the app with the launcher icon:
ACTION_MAIN
action indicates this is the main entry point and does not expect any intent data.CATEGORY_LAUNCHER
category indicates that this activity's icon should be placed in the system's app launcher. If the <activity>
element does not specify an icon with icon
, then the system uses the icon from the <application>
element.These two must be paired together in order for the activity to appear in the app launcher.
The second activity, ShareActivity
, is intended to facilitate sharing text and media content. Although users might enter this activity by navigating to it from MainActivity
, they can also enter ShareActivity
directly from another app that issues an implicit intent matching one of the two intent filters.
Note: The MIME type, application/vnd.google.panorama360+jpg
, is a special data type that specifies panoramic photos, which you can handle with the Google panorama APIs.
A PendingIntent
object is a wrapper around an Intent
object. The primary purpose of a PendingIntent
is to grant permission to a foreign application to use the contained Intent
as if it were executed from your app's own process.
Major use cases for a pending intent include:
NotificationManager
executes the Intent
).Intent
).AlarmManager
executes the Intent
). Because each Intent
object is designed to be handled by a specific type of app component (either anActivity
, a Service
, or a BroadcastReceiver
), so too must a PendingIntent
be created with the same consideration. When using a pending intent, your app will not execute the intent with a call such asstartActivity()
. You must instead declare the intended component type when you create thePendingIntent
by calling the respective creator method:
PendingIntent.getActivity()
for an Intent
that starts an Activity
.PendingIntent.getService()
for an Intent
that starts a Service
.PendingIntent.getBroadcast()
for a Intent
that starts an BroadcastReceiver
. Unless your app is receiving pending intents from other apps, the above methods to create a PendingIntent
are the only PendingIntent
methods you'll probably ever need.
Each method takes the current app Context
, the Intent
you want to wrap, and one or more flags that specify how the intent should be used (such as whether the intent can be used more than once).
More information about using pending intents is provided with the documentation for each of the respective use cases, such as in the Notifications and App Widgets API guides.
When the system receives an implicit intent to start an activity, it searches for the best activity for the intent by comparing the intent to intent filters based on three aspects:
The following sections describe how intents are matched to the appropriate component(s) in terms of how the intent filter is declared in an app's manifest file.
To specify accepted intent actions, an intent filter can declare zero or more <action>
elements. For example:
<intent-filter> <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.VIEW" /> ... </intent-filter>
To get through this filter, the action specified in the Intent
must match one of the actions listed in the filter.
If the filter does not list any actions, there is nothing for an intent to match, so all intents fail the test. However, if an Intent
does not specify an action, it will pass the test (as long as the filter contains at least one action).
To specify accepted intent categories, an intent filter can declare zero or more <category>
elements. For example:
<intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> ... </intent-filter>
For an intent to pass the category test, every category in the Intent
must match a category in the filter. The reverse is not necessary—the intent filter may declare more categories than are specified in the Intent
and theIntent
will still pass. Therefore, an intent with no categories should always pass this test, regardless of what categories are declared in the filter.
Note: Android automatically applies the the CATEGORY_DEFAULT
category to all implicit intents passed tostartActivity()
and startActivityForResult()
. So if you want your activity to receive implicit intents, it must include a category for "android.intent.category.DEFAULT"
in its intent filters (as shown in the previous <intent-filter>
example.
To specify accepted intent data, an intent filter can declare zero or more <data>
elements. For example:
<intent-filter> <data android:mimeType="video/mpeg" android:scheme="http" ... /> <data android:mimeType="audio/mpeg" android:scheme="http" ... /> ... </intent-filter>
Each <data>
element can specify a URI structure and a data type (MIME media type). There are separate attributes — scheme
, host
, port
, and path
— for each part of the URI:
<scheme>://<host>:<port>/<path>
For example:
content://com.example.project:200/folder/subfolder/etc
In this URI, the scheme is content
, the host is com.example.project
, the port is 200
, and the path isfolder/subfolder/etc
.
Each of these attributes is optional in a <data>
element, but there are linear dependencies:
When the URI in an intent is compared to a URI specification in a filter, it's compared only to the parts of the URI included in the filter. For example:
Note: A path specification can contain a wildcard asterisk (*) to require only a partial match of the path name.
The data test compares both the URI and the MIME type in the intent to a URI and MIME type specified in the filter. The rules are as follows:
content:
or file:
URI and the filter does not specify a URI. In other words, a component is presumed to support content:
and file:
data if its filter lists only a MIME type. This last rule, rule (d), reflects the expectation that components are able to get local data from a file or content provider. Therefore, their filters can list just a data type and do not need to explicitly name the content:
andfile:
schemes. This is a typical case. A <data>
element like the following, for example, tells Android that the component can get image data from a content provider and display it:
<intent-filter> <data android:mimeType="image/*" /> ... </intent-filter>
Because most available data is dispensed by content providers, filters that specify a data type but not a URI are perhaps the most common.
Another common configuration is filters with a scheme and a data type. For example, a <data>
element like the following tells Android that the component can retrieve video data from the network in order to perform the action:
<intent-filter> <data android:scheme="http" android:type="video/*" /> ... </intent-filter>
Intents are matched against intent filters not only to discover a target component to activate, but also to discover something about the set of components on the device. For example, the Home app populates the app launcher by finding all the activities with intent filters that specify the ACTION_MAIN
action and CATEGORY_LAUNCHER
category.
Your application can use intent matching in a similar way. The PackageManager
has a set of query...()
methods that return all components that can accept a particular intent, and a similar series of resolve...()
methods that determine the best component to respond to an intent. For example, queryIntentActivities()
returns a list of all activities that can perform the intent passed as an argument, and queryIntentServices()
returns a similar list of services. Neither method activates the components; they just list the ones that can respond. There's a similar method, queryBroadcastReceivers()
, for broadcast receivers.
一个意图
是一个消息对象,你可以用它来 请求另一个动作的应用程序组件。虽然意图促进在几个方面组件之间的通信中,有三个基本的用例:
一个活动
代表了一个应用程序的单一屏幕。您可以启动的新实例活动
传递一个意图
到startActivity()
。的意图
描述了启动活动并进行任何必要的数据。
如果你想从当它完成活动收到结果,调用startActivityForResult()
。您的活动得到的结果作为一个单独的意图
在活动的对象的onActivityResult()
回调。欲了解更多信息,请参见活动指南。
一个服务
是没有用户界面在后台执行操作的组件。您可以启动一个服务传递一个执行一次性操作(如下载文件),意图
给startService()
。该意向书
介绍启动该服务,并进行任何必要的数据。
如果服务被设计与一个客户-服务器接口,可以通过使结合于来自另一组件的服务意图
到bindService()
。欲了解更多信息,请参阅服务指南。
广播是,任何应用程序可以接收消息。该系统提供了系统事件的各种节目,比如当系统启动或设备开始充电的。你可以通过传递一个提供给其他应用广播意向
到sendBroadcast()
, sendOrderedBroadcast()
,或sendStickyBroadcast()
。
有两种类型的意图的:
当你创建一个明确的意图开始一项活动或服务时,系统立即开始在指定的应用程序组件意图
对象。
图1.怎样一个隐含的意图是通过系统提供的启动另一个活动说明:[1] 活动A创建了一个 意图
与动作的描述和它传递给startActivity()
。[2] Android系统搜索的所有应用程序意图过滤器的意图相匹配。当找到一个匹配,[3]系统启动配对活动(活动B通过调用它)的onCreate()
方法,并传递给它的意图
。
当你创建一个隐含的意图,Android系统找到合适的组件通过意图的内容进行比较以启动意图过滤器在申报清单文件设备上的其他应用程序。如果意图相匹配的意图过滤器,系统将启动该组件,并提供它的意图
对象。如果有多个意图过滤器是兼容的,系统会显示一个对话框,以便用户可以选择要使用的应用程序。
一个意图过滤器是在应用的清单文件,指定该组件希望收到意图的类型的表达式。例如,通过声明为活动的意图过滤器,你有可能使其他应用程序直接与某种意图开始您的活动。同样的,如果你不是为了游玩声明任何的意图过滤器,那么就只能用明确意图开始。
注意:为了确保您的应用程序是安全的,开始时请务必使用明确意图服务
,不为你服务声明意图过滤器。使用一个隐含的意图是启动一个服务是一个安全隐患,因为你不能确定什么样的服务将向意图做出回应,并且用户无法看到哪些服务启动。采用Android 5.0(API级别21)开始,系统投如果你调用一个异常bindService()
有一个隐含的意图。
一个意图
对象携带了Android系统用于确定要启动的组件(如确切的组件名称或应接收的意图组件类别),以及信息接收者组件,以便正确执行操作使用信息(如要采取的行动和数据要遵循)。
包含在主信息意图
是以下内容:
这是可选的,但它的信息的关键部分,使得一个意图 明确,这意味着意图应仅递送到由组件名称中定义的应用程序组件。没有一个组件名称,目的是隐式,系统决定哪个组件应接收基于其它意图信息的意图(如动作,数据和下面类别描述的)。所以,如果你需要在你的应用程序来启动某个特定组件,您应该指定组件名称。
注意:当启动一个服务
,你应该 始终指定组件名称。否则,你无法确定什么样的服务将向意图做出回应,并且用户无法看到哪些服务启动。
在这一领域的意图
是一个 组件名
对象,您可以指定使用目标组件的完全限定类名,其中包括应用程序的包名。例如, com.example.ExampleActivity
。您可以设置与该组件名称setComponent()
,setClass()
,setClassName()
,或使用 意向
构造。
在广播意图的情况下,这是发生的,并且所报告的动作。操作在很大程度上决定了意图的其余部分所采用的结构,尤其中包含的内容数据,并附加功能。
您可以通过意图您的应用程序(或其他应用使用来调用你的应用程序组件)中指定使用自己的行为,但你通常应该使用已定义的动作常量意图
类或其他框架类。下面是启动活动的一些常规操作:
ACTION_VIEW
startActivity()
时,你有一些信息,一个活动可以显示给用户,如要查看的照片在画廊的应用程序,或查看在地图应用程序的地址。
ACTION_SEND
startActivity()
,当你有一些数据,用户可以通过其他应用程序,共享,如电子邮件应用或社交共享应用程序。
见意向
的定义通用的行为更多的常量类引用。其他的动作在Android框架其他地方定义,比如在设置
为打开系统中的设置应用特定画面的动作。
您可以指定与意图的动作的setAction()
或与意向
构造。
如果您定义自己的操作,一定要包括你的应用程序的包名作为前缀。例如:
静态 最终 字符串ACTION_TIMETRAVEL = “com.example.action.TIMETRAVEL” ;
开放的
引用的数据对象)可以作用于和/或MIME类型的数据。类型提供的数据通常由意图的动作决定的。例如,如果动作是
ACTION_EDIT
,数据应包含编辑文档的URI。
当创建一个意图,它指定数据的除了它的URI的类型(它的MIME类型)往往重要。例如,这能够大概显示图像的活动将不能够播放音频文件,即使该URI格式可能是相似的。因此指定MIME类型的数据有助于Android系统发现收到你的意图的最佳组件。然而,MIME类型,有时可以从推断的URI的,特别是当数据是一个 内容:
URI,其指示数据所在的设备上,并且通过受控 的ContentProvider
,这使得数据的MIME类型的系统是可见的。
要设置只有数据的URI,调用使用setData()
。要设置只MIME类型,调用的setType()
。如果有必要,你可以同时设置明确setDataAndType()
。
注意:如果你要同时设置URI和MIME类型, 不要调用使用setData()
和 的setType()
,因为它们各自抵消对方的价值。始终使用setDataAndType()
同时设置URI和MIME类型。
CATEGORY_BROWSABLE
CATEGORY_LAUNCHER
见意向
进行分类的完整列表类的描述。
您可以指定与类别addCategory()
。
上述(组件名称,动作,数据,和类别)中列出这些性质表示意图的限定特征。通过阅读这些特性,Android系统能解决哪些应用组件它应该开始。
然而,意图可以携带不影响它是如何解析为应用程序组件的其他信息。一个意图还可以提供:
可以使用各种添加额外的数据putExtra()
方法,每个方法接受两个参数:键名和值。您还可以创建一个捆绑
的所有额外的数据对象,然后将包
中的意图
与putExtras()
。
例如,在创建意图时,与发送电子邮件 ACTION_SEND
,您可以指定用的“到”收件人 EXTRA_EMAIL
键,并指定“主体”与 EXTRA_SUBJECT
键。
该意图
类指定许多EXTRA_ *
常量标准化的数据类型。如果您需要声明自己的附加 键(对于您的应用程序接收意图),一定要包括你的应用程序的包名作为前缀。例如:
静态 最终 字符串EXTRA_GIGAWATTS = “com.example.EXTRA_GIGAWATTS” ;
意图
类作为意图元数据功能。这些标志可指示Android系统如何启动一个活动(例如,它 的任务活动应该属于)和它的发射后如何对待它(例如,它是否属于在最近的活动的列表)。
欲了解更多信息,请参见setFlags()
方法。
一个明确的意图是让你用来启动特定的应用程序组件,比如在你的应用程序特定的活动或服务之一。要创建一个明确的意图,对于定义组件名意向
对象的所有其他意图属性都是可选的。
例如,如果你建你的应用程序服务,命名为下载服务
,旨在从网络上下载一个文件,可以用下面的代码开始吧:
//在活动执行,因此“这”是上下文
//该fileUrl是一个字符串的URL,如"http://www.example.com/image.png" Intent downloadIntent = new Intent ( this , DownloadService . class ); downloadIntent . setData (Uri . parse
( fileUrl )); startService ( downloadIntent );
该意向书(背景下,A类)
构造函数提供应用程序上下文
和组件类
对象。因此,这种意图明确开始下载服务
中的应用程序类。
有关构建和启动服务的详细信息,请参阅 服务指南。
隐式意图指定可以调用该设备能够执行行动的任何应用程序的操作。使用一个隐含的意图时,你的应用程序无法执行的操作,但其他应用程序也许可以和你想的用户选择使用哪个应用是非常有用的。
例如,如果你有内容,您希望用户与其他人共享,创建具有意图ACTION_SEND
行动,并添加指定内容共享临时演员。当你调用 startActivity()
与意图,用户可以选择通过共享的内容的应用程序。
注意:这是可能的,用户不会有任何 的处理您发送到隐含意图应用startActivity()
。如果发生这种情况,调用将失败,您的应用程序会崩溃。要验证活动将收到的意图,调用resolveActivity()
您的意向
对象。如果结果不为null,则至少有一个应用程序能够处理的意图和它的安全调用 startActivity()
。如果结果为空,你不应该使用的意图,可能的话,你应该禁用发出意图的功能。
//创建一个文本消息 验证意图将解析为一个活动 ,如果 (sendIntent 。resolveActivity (getPackageManager ()) != 空) { startActivity (sendIntent ); }
注意:在这种情况下,一个URI是不使用,但意图的数据类型声明来指定由额外携带的内容。
当startActivity()
被调用时,系统会检查所有已安装的应用程序,以确定哪些可以处理这种意图(与意图ACTION_SEND
行动,并携带“text / plain的”数据)。如果只有一个应用程序可以处理它,该应用程序会立即打开,并给出意图。如果有多个活动接受的意图时,系统会显示一个对话框,以便用户可以选择要使用的应用程序..
图2.一个选择器对话框。
当有多个应用程序,响应你的意图隐含的,用户可以选择哪些应用程序来使用,让该应用程序的操作的默认选择。为执行该用户可能希望使用相同的应用程序从现在起,一个动作时,这是很好的,例如打开一个网页时,如(用户往往更喜欢只是一个网络浏览器)。
但是,如果多个应用程序可以向意向作出回应,用户可能希望每次都使用不同的应用程序,你应该明确地显示一个选择对话框。在选择对话框要求用户选择哪些应用每次使用的操作(用户不能选择为操作的默认应用)。例如,当您的应用程序进行“共享”与ACTION_SEND
动作,用户可能想利用这取决于他们目前的状况不同的应用分享,所以你应该始终使用选择对话框,如图2。
要显示选择器,创建一个意图
使用createChooser()
并将它传递给startActivity()
。例如:
意图sendIntent = 新 意图(意图。ACTION_SEND ); ... //总是使用字符串资源的UI文本 //这是说像“分享这张照片。” 字符串标题= getResources ()。的getString (ř 。字符串。chooser_title ); //创建意图显示选择对话框 意图选择器= 意图。createChooser (sendIntent ,标题); //验证原意将解决至少一个活动 ,如果 (sendIntent 。resolveActivity (getPackageManager ()) != 空) { startActivity (选配); }
这将显示与传递给意图响应的应用程序列表的对话框createChooser()
方法,并使用所提供的文本作为对话框的标题。
为了宣传其隐含的意图您的应用程序可以接收,与申报为每个应用程序组件的一个或多个意图过滤器<意图过滤器>
在你的元素清单文件。每一个意图过滤指定它接受基于意图的动作,数据和类别意图的类型。该系统将提供一个隐含的意图,你的应用程序组件只有意图可以通过你的意图过滤器之一。
注:一个明确意图总是传递到其目标,无论任何意图过滤组件声明。
一个应用程序组件应为每一个独特的工作可以做单独声明过滤器。例如,在一个图片库应用一个活动可能有两个过滤器:一个过滤器来查看图像,另一个过滤器来编辑图像。当活动启动时,它检查该意图
,并决定基于在所述信息如何表现意图
(例如,以显示编辑控件或不是)。
每一个意图过滤器是由一个定义的<意向过滤器>
在应用程序的清单文件中的元素,嵌套在相应的应用程序组件(如<活动>
元素)。里面的<意向过滤器>
,您可以指定意图的方式,通过这三个要素中的一个或多个接受:
<动作>
名称
属性。该值必须是一个行动的文本字符串值,而不是类常量。
<资料>
方案
,
主机
,
端口
,
路径
等)和MIME类型。
<category>中
名称
属性。该值必须是一个行动的文本字符串值,而不是类常量。
注:为了获得隐含的意图,你 必须包括在 CATEGORY_DEFAULT
的意图过滤类别。方法startActivity()
和 startActivityForResult()
把所有的意图,如果他们宣布CATEGORY_DEFAULT
类别。如果没有这一类的意图过滤器声明,没有隐含意图将解析为您的活动。
例如,这里是与意图过滤器来接收活动的声明 ACTION_SEND
意图时,数据类型为文本:
<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>
, <数据>
或 <category>中
。如果你这样做,你只是需要确定该组件可以处理任何与这些过滤元件的所有组合。
当你要处理多个种类的意图,但只有在行动中,数据和类别类型的特定组合,那么你需要创建多个意图过滤器。
使用意图过滤器是不是为了防止你开始组件的其他应用程序的安全方式。虽然意图过滤器来限制只有某些类型的隐含意图的响应一个组成部分,其他应用程序可以通过如果开发商决定了你的组件名称使用一个明确的意图可能会启动您的应用程序组件。如果重要的是,只有你自己的应用程序能够启动您的组件之一,设置出口
属性为“假”
该组件。
隐式意图由意图比较每三要素的对一个过滤器进行测试。被传递到该组件,意图必须通过所有三个测试。如果失败,甚至其中的一个匹配,Android系统将无法实现意图的组件。但是,由于组件可以具有多个意图过滤器,即不通过的部件的过滤器之一的意图可能使其通过另一个过滤器。下面对部分提供了有关该系统如何解决意图的更多信息意向分辨率。
注意:为避免意外运行不同的应用程序的 服务
,始终使用明确意图开始自己的服务,并没有为您服务声明意图过滤器。
注意: 对于所有的活动,您必须在清单文件中声明你的意图过滤器。然而,对于广播接收机滤波器可以动态地由调用注册 registerReceiver()
。然后,您可以注销与接收机unregisterReceiver()
。这样做使您的应用程序到你的应用程序正在运行,而只在指定的时间段监听特定广播。
为了更好地理解一些意图过滤器的行为,看看从共享的社会应用程序的清单文件中的片断。
<活动 安卓:名称= “MainActivity” > <! -这个活动是主入口,应该出现在应用程序启动 本次活动以处理文本数据的“发送”行动 本次活动还处理“发送”和“SEND_MULTIPLE”与媒体数据
第一项活动,MainActivity
,是应用程序的主入口点活动,当用户最初启动的启动器图标应用程序打开:
ACTION_MAIN
行动表明这是主要的入口点,并且不期待任何意图的数据。CATEGORY_LAUNCHER
类别表示,本次活动的图标应放置在系统的应用启动。如果<活动>
元素没有指定一个图标图标
,则系统将使用该图标<应用程序>
元素。这两个必须一起才能配对的活动出现在应用程序启动器。
第二活动,ShareActivity
,是为了便于共用的文本和媒体内容。虽然用户可以通过导航到它进入这个活动MainActivity
,他们也可以进入ShareActivity
直接从其他应用程序,发出一个隐含的意图匹配两个意图过滤器中的一个。
注: MIME类型, 应用程序/ vnd.google.panorama360 + JPG
,是指定的全景照片,您可以在处理特殊的数据类型谷歌全景的API。
一个的PendingIntent
对象是周围的包装意图
对象。一个最主要的目的的PendingIntent
是将权限授予外国申请使用包含的意图
,就好像它是从你的应用程序自身的进程中执行。
主要用例挂起的意图包括:
NotificationManager
执行意图
)。意向
)。AlarmManager
执行意图
)。 因为每个意图
对象旨在由特定类型的应用程序组件(无论是一个的处理活动
,一个服务
,或广播接收器
),因此,也必须一的PendingIntent
用相同的考虑创建。当使用挂起的意图,你的应用程序将无法执行与诸如呼叫的意图startActivity()
。当您创建您必须声明,而不是预期的组件类型 的PendingIntent
致电各创作者的方法:
PendingIntent.getActivity()
一个 意向
启动的活动
。PendingIntent.getService()
一个 意向
启动一个服务
。PendingIntent.getBroadcast()
的 意图
启动的广播接收器
。 除非你的应用程序是接收从其他应用程序挂起的意图,上面的方法来创建的PendingIntent
是唯一 的PendingIntent
你可能永远需要的方法。
每个方法对当前应用背景
中, 意图
要包裹指定如何意图应被使用,并且一个或多个标记(例如是否意图可以使用一次以上)。
关于使用未决意图详细信息设有用于每个各自的使用情况下,如在该文档的通知 和应用的窗口小部件的API指南。
当系统收到一个隐含的意图开始活动,它将搜索通过比较意图基于以下三个方面的意图过滤器意图的最佳活动:
以下各节描述意图是如何的意图过滤器是如何在一个应用程序的清单文件中声明的条款匹配到合适的组件(S)。
要指定接受的意图行动,意图过滤器可以声明零个或更多 的<action>
元素。例如:
<intent-filter> <action android:name = "android.intent.action.EDIT" /> <action android:name = "android.intent.action.VIEW" /> ... </intent-filter>
打通这个过滤器,在指定的操作意图
必须匹配过滤器中列出的操作之一。
如果过滤器没有列出任何动作,没有任何一个意图匹配,所以所有的意图失败的考验。但是,如果意图
不指定一个动作,它将通过测试(只要该过滤器包含至少一个动作)。
要指定接受意向类别,一个意图过滤器可以声明零个或更多 的<category>
元素。例如:
<intent-filter> <category android:name = "android.intent.category.DEFAULT" /> <category android:name = "android.intent.category.BROWSABLE" /> ... </intent-filter>
对于意图传递类试验中,对每一个类别意图
必须在过滤器的类别相匹配。相反的是没有必要的,意图过滤器可以宣告多个类别比指定意图
和 意图
仍然会通过。因此,没有类别的意图应该总是通过这个测试,无论在过滤器中声明哪些类别。
注: Android的自动的应用CATEGORY_DEFAULT
类别传递给所有的隐含意图startActivity()
和startActivityForResult()
。所以如果你想你的活动接受隐含意图,它必须包括一个类别“android.intent.category.DEFAULT”
其意图过滤器(如在以前<意图过滤器>
的例子。
要指定接受意图数据,一个意图过滤器可以声明零个或多个 <数据>
元素。例如:
<intent-filter> <data android:mimeType = "video/mpeg" android:scheme = "http" ... /> <data android:mimeType = "audio/mpeg" android:scheme = "http" ... /> ... </intent-filter>
每个<数据>
元素可以指定一个URI结构和数据类型(MIME媒体类型)。有单独的属性- 模式
,主机
,端口
和路径
-为URI的各个部分:
<方案>:// <主机>:<端口> / <路径>
例如:
内容://com.example.project:200 /文件夹/子文件夹中的/ etc
在此URI,该方案的内容
,主机是com.example.project
,端口是200
,和路径是文件夹/子/等
。
每个属性是一个可选的<数据>
元素,但也有线性的依赖关系:
当在意图的URI被相比,在过滤器中的URI规范,它相比仅包括在过滤器URI的部分。例如:
注:路径规范可以包含通配符星号(*),以只需要路径名的一个部分匹配。
数据测试比较两者的URI和在意图在滤波器中指定的URI和MIME类型的MIME类型。的规则如下:
内容:
或文件:
URI和过滤器没有指定一个URI。换句话说,组件被假定为支持内容:
与文件:
数据如果其过滤列表仅一个MIME类型。 这最后一条规则,规则(四),反映了期望组件能够从文件或内容提供商获取本地数据。因此,他们的过滤器可以列出只是一个数据类型,并不需要显式地命名内容:
和文件:
方案。这是一个典型的案例。一个<数据>
像下面这样的元素,例如,告诉Android组件可以从内容提供商获取图像数据并显示它:
<意图过滤器> <数据 的android:mime类型= “图像/ *” /> ... </意图过滤器>
由于大多数可用的数据是由内容提供者,过滤器,用于指定一个数据类型而不是一个URI也许是最常用的分配。
另一种常见的配置是一个方案和一个数据类型的过滤器。例如,<数据>
像下面的元素告诉Android组件可以从网络检索视频数据以执行的操作:
<意图过滤器> <数据 的android:计划= “HTTP” 机器人:类型= “视频/ *” /> ... </意图过滤器>
意图是针对意图过滤器匹配,不仅发现一个目标组件激活,同时也发现一些关于设备上的组件集合。例如,家庭应用填充通过查找所有与指定意向过滤器的活动应用启动 ACTION_MAIN
行动和 CATEGORY_LAUNCHER
类别。
应用程序可以以类似的方式使用意图匹配。该软件包管理系统
具有一组查询...()
返回,可以接受的特定意图的所有组件的方法,以及类似的一系列解决...()
确定对意图响应最佳组分的方法。例如,queryIntentActivities()
返回一个可以执行作为参数传递的意图所有活动的列表,以及queryIntentServices()
返回一个类似的服务列表。无论方法激活的组件; 他们只是列出了可以响应的人。有一个类似的方法, queryBroadcastReceivers()
,对于广播接收机。