首页 > 代码库 > 6、二、App Components(应用程序组件):1、Intents and Intent Filters(意图和意图过滤器)

6、二、App Components(应用程序组件):1、Intents and Intent Filters(意图和意图过滤器)

1、Intents and Intent Filters(意图和意图过滤器)

1.0、Intents and Intent Filters(意图和意图过滤器)

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:

一个Intent 是一个你能够从其它应用程序组件使用它请求一个操作的信使对象。然而使用Intent便于在几个方面的组件之间进行通信,主要有三个基础的用例:

  • To start an activity:(启动Activity)

    An?Activity?represents a single screen in an app. You can start a new instance of an?Activity?by passing an?Intent?to startActivity(). 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‘s?onActivityResult()callback. For more information, see the?Activities?guide.

    ?

一个?Activity在一个应用程序中描述了一个单独的屏幕。你能够通过给startActivity() 方法传递一个Intent启动一个新的?Activity实例。Intent描述了要启动的Activity以及要传递的必须的数据。

如果当Activity Finish的时候,你想接收一个结果,那么你可以调用startActivityForResult()方法。你的Activity将在onActivityResult()回调方法中得到一个单独的Intent对象结果。如果您想得到更多信息,请查看Activities文档。

?

IN THIS DOCUMENT

Intent Types

Building an Intent

Example explicit intent

Example implicit intent

Forcing an app chooser

Receiving an Implicit Intent

Example filters

Using a Pending Intent

Intent Resolution

Action test

Category test

Data test

Intent matching

SEE ALSO

Interacting with Other Apps

Sharing Content

?

在这个文档中

Intent 类型

建立一个Intent

显式Intent的例子

隐式意图的例子

强制一个应用选择器

接收一个隐式意图

过滤器例子

使用Pending Intent

Intent 解析

Action 测试

Category 测试

Data 测试

Intent 匹配

另请参阅

与其它应用交互

分享内容

?

  • To start a service:(启动Service)

    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?Intentto?bindService(). For more information, see the?Services?guide.

    ????一个?Service是一个在后台执行操作的非用户界面组件。你可以通过把一个?Intent传递给startService()方法启动一个Service执行一个一次性操作(比如下载一个文件)Intent?描述了被启动的Service并传递了必须的数据。

    ????如果Service被设计用于一个"客户端-服务端"接口,你能够在其它组件通过把Intent传递给bindService()方法绑定到服务。想要得到更多的信息,可以参照?Services界面。

  • To deliver a broadcast:(发送广播)

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().

????一个广播是一个可以被任何应用接收的消息。系统发布一系列的系统事件广播,比如说当系统启动完成或者开始充电的时候。你能够通过把Intent传递给?sendBroadcast(),sendOrderedBroadcast()或者?sendStickyBroadcast().方法来给其他应用发送广播。

?

  1. Intent 类型

There are two types of intents:

有两种类型的Intent

  • Explicit intents?specify the component to start by name (the fully-qualified class name). You‘ll typically use an explicit intent to start a component in your own app, because you know the class name of the activity or service you want to start. For example, start a new activity in response to a user action or start a service to download a file in the background.

显式意图 通过组件名称指定要启动的组件(类的全限定名)。在你自己的应用程序之中,你通常可以通过一个显式Intent启动一个组件,因为你可以知道你想要启动的Activity或者Service的类的名称。比如说,启动一个新的Activity来响应用户的动作或者启动一个Service在后台下载文件。

  • Implicit intents?do not name a specific component, but instead declare a general action to perform, which allows a component from another app to handle it. For example, if you want to show the user a location on a map, you can use an implicit intent to request that another capable app show a specified location on a map.

    隐式意图 不指定组件名称,而是一般定义一个要执行的操作的Action,它允许其他应用程序的组件来操作它。比如说,如果你想要在地图中显示一个用户的未知,你可以使用一个隐式Intent去请求另一个能够在地图上显示指定位置的应用。

When you create an explicit intent to start an activity or service, the system immediately starts the app component specified in the?Intent?object.

????当你创建一个显式意图去启动一个Activity或者Service时候,系统立刻启动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 the?Intent object. If multiple intent filters are compatible, the system displays a dialog so the user can pick which app to use.

????当你创建一个隐式意图,Android系统通过比较安装在设备上的应用定义在manifest 文件上的intent?intent filters内容查找适当的组件去启动。如果你的intent匹配一个intent filter,系统启动这个组件,并向他发送这个Intent对象。如果有多个intent filter匹配,系统将显示一个对话框让用户选择使用哪一个应用启动。

Figure 1.?Illustration of how an implicit intent is delivered through the system to start another activity:?[1]?Activity A?creates 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.

图一。插图表示被发送的隐式意图怎样通过系统去启动另外一个Activity[1]Activity A使用action创建一个Intent,并传递给它的startActivity().方法。[2]Android系统搜索所有的应用程序用于匹配intent中的intent filter[3]系统通过把Intent对象传递给它的onCreate()?方法启动匹配的activity(Activity B)

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?not?declare any intent filters for an activity, then it can be started only with an explicit intent.

????一个intent filter是在应用程序的manifest文件中指定组件想要接收的Intent的类型的一个表达式。例如,通过给一个Activity定义一个intent filter,,你有可能使其他应用程序直接使用某种意图的start你的activity。同样的,如果你没有为activity定义任何intent filter,那么只就可以用一个显式意图启动它。

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.

注意:为了确保你的应用是安全的,当启动一个Service?应该总是使用一个显式意图,并且不要为你的Service定义intent filter.使用一个隐式意图启动Service是一个安全隐患,因为你不能确定哪一个Service响应这个intent,而且用户不能看到哪个服务启动。

  1. 建立一个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).

一个Intent对象带有系统确定哪个组件启动的信息(如确切的组件名称或应该接收Intent的组件类别),加上对于接收Intent的组件便于执行正确的操作的信息(如获取和处理数据的action)。

The primary information contained in an?Intent?is the following:

Intent主要包含以下的信息:

Component name

The name of the component to start.

????是将要启动的组件的名称。

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.

这个是可选的,但是它是创建一个显式意图的重要的信息,这意味着通过这个组件名称定义的意图只能够被发送给这个应用程序定义的组件。如果没有一个组件名称,则意味着Intent是隐式的并且系统决定哪一个组件能够基于其他的Intent信息接收这个Intent (比如actiondata、和category——将在下面介绍)。如果你必须要在你的应用中启动一个指定的组件,你可以指定组件名称。

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.

注意:当启动一个?Service的时候,你总是能够指定组件名称。否则,你不能确定哪一个service响应这个Intent,并且用户看到哪个service被启动。

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.

?Intent这个的字段是一个ComponentName?对象,你可以指定使用目标组件使用哪一个类的全限定名,包含这个应用的包名。例如,com.example.ExampleActivity.你能够通过setComponent(),?setClass(),setClassName(),或者使用Intent的构造方法设置组件名。

Action

A string that specifies the generic action to perform (such as?view?or?pick).

一个指定要执行的通用操作的字符串(比如view或者pick).

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.

当用在broadcast Intent的情况下,这是所发生和被报告的动作。该action在很大程度上决定了Intent的其余部分的结构,特别是包含什么数据和附件信息。

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:

你能够在你的应用中指定用于Intent的指定的你自己的action(或者通过其他的应用去调用你的应用程序的组件),但是你通常使用定义在Intent类或者其他framework类的action常量。这里是一些用于启动一个activity的常用action

ACTION_VIEW

Use this action in an intent with?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.

当你有一些信息需要通过一个activity显示,你可以在一个Intent中使用这个action,并传递给?startActivity()方法。比如在gallery应用中查看一个图片,或者在map应用中查看一个地址。

ACTION_SEND

Also known as the "share" intent, you should use this in an intent with?startActivity()?when you have some data that the user can share through another app, such as an email app or social sharing app.

也被称为"share" Intent,当你有一些需要用户通过其他的应用程序分享的数据,你可以通过把包含这个actionIntent传递给?startActivity() 方法。比如说一个Email程序或者社会化分享程序。

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.

查看Intent类引用用可以看到更多定义的通用action常量。其他的action被定义在Android Framework的其他地方,比如在Settings?类定义了很多打开Settings应用中的指定界面的action

You can specify the action for an intent with?setAction()?or with an?Intent?constructor.

你可以通过setAction()?方法或者Intent?的构造方法为Intent对象指定action

If you define your own actions, be sure to include your app‘s package name as a prefix. For example:

如果你定义了你的action,一定要使用你的应用程序包名作为前缀,比如:

static											final													String ACTION_TIMETRAVEL =																	"com.example.action.TIMETRAVEL";																			

Data

The URI (a?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.

URI(一个Uri?对象)引用可以用作于要执行的动作的数据和/或数据的MIME提供的数据的类型一般是由intentaction决定的.比如说,如果action?ACTION_EDIT, 数据应包含编辑文档的URI

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.

当创建一个Intent,它往往重要的是指定附加到它的URI的数据的类型(它的MIME类型)。例如,一个Activity能够显示图像而很有可能不能播放音频文件,即使该URI格式可以是相似的。因此指定你的dataMIME类型有助于Android系统找到接收你的意图的最佳组件。然而,MIME类型有时可以从URI推断出来——尤其是当数据是一个?content:?URI,它指示该数据位于本地设备上,并通过一个?ContentProvider控制,这使得该数据的MIME类型是系统可见的。

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().

要设置只有数据的URI,调用?setData()方法。仅仅要设置MIME类型,调用setType()方法。如果需要的话,你可以使用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.

注意:如果你想要同时设置URIMIME类型,不要调setData()setType()方法,因为它们各自抵消对方的值。应该总是使用setDataAndType()?方法去同时设置URI和MIME类型。

Category

A string containing additional information about the kind of component that should handle the intent. Any number of category descriptions can be placed in an intent, but most intents do not require a category. Here are some common categories:

包含应该处理这个Intent的那种组件的附加信息一个字符串。一个Intent中可以有任何数量的category,但大多数的Intent不必需有一个类别。下面是一些常见的类别:

CATEGORY_BROWSABLE

The target activity allows itself to be started by a web browser to display data referenced by a link—such as an image or an e-mail message.

目标Activity允许它自己允许通过启动一个Web浏览器去显示一个链接的引用数据——比如一张图片或者一条Email信息。

CATEGORY_LAUNCHER

The activity is the initial activity of a task and is listed in the system‘s application launcher.

Activity是一个任务的初始Activity并且在系统的Launcher应用中被列出来。

See the?Intent?class description for the full list of categories.

查看Intent类可以得到category的全部列表。

You can specify a category with?addCategory().

你可以通过addCategory()方法指定一个category

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.

以上被列出来的这些属性(component namedataactioncategory)表示一个Intent的标准定义。通过读取这些属性,Android系统能够分析出应该启动哪个应用程序组件。

However, an intent can carry additional information that does not affect how it is resolved to an app component. An intent can also supply:

然而,一个Intent可以携带其他的附件信息,这并不会影响它解析一个应用程序组件。一个Intent还可以提供:

Extras

Key-value pairs that carry additional information required to accomplish the requested action. Just as some actions use particular kinds of data URIs, some actions also use particular extras.

携带来完成所请求的action所需的附加信息的键 - 值对。正如一些操作使用特定类型的数据的URI,一些action也用特别的extra

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 the Intent?with?putExtras().

你可以使用各种添加附件数据的putExtra()方法,每一个方法都接受两个参数:键名和值。你也可以创建一个Bundle对象来包含所有的附件数据,然后把Bundle对象传递给Intent?对象的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.

比如说,当使用ACTION_SEND创建一个intent去发送一个Email的时候,你能够使用EXTRA_EMAIL?键指定"to"接收人,并通过EXTRA_EMAIL键指定"subject"指定主题。

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:

Intent?类指定了很多用于标准化的数据类型的EXTRA_*?常量。如果你需要定义你自己的extrakey(用于你自己的应用接收者的Intent),应该包含你的应用程序的包名作为前缀,例如:

static											final													String EXTRA_GIGAWATTS =																	"com.example.EXTRA_GIGAWATTS";																			

Flags

Flags defined in the?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).

Flags被定义在?Intent?类中作为Intent的元数据。Flags可以让Android系统知道怎样去启动一个Activity(例如,Activity应该属于哪个task)并且当它启动之后如何对待它(比如说,它是否属于最近的活动列表)

For more information, see the?setFlags()?method.

如果想要得到更多信息,请查看setFlags()方法。

1.0.2.1、显式Intent的例子

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.

显式Intent是指你用它来启动一个指定的应用程序组件的Intent,比如说一个你的应用中的一个特定的Activity或者Service。要创建一个显式Intent,可以使用组件名称定义Intent对象——所有的其他的Intent属性都是可选的。

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:

比如说,如果你在你的应用中构建一个Service,命名为?DownloadService,被设计用于从网页上下载一个文件,你能够通过下面的代码来启动它:

// 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);													

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.

可以向构造方法Intent(Context, Class)?传递应用程序?Context对象和一个组件的Class?对象构造一个显式Intent。同样的,Intent可以明确的启动你的应用中的DownloadService?类。

For more information about building and starting a service, see the?Services?guide.

如果想要获得更多关于构建和启动服务的信息,可以参考Services指南。

1.0.2.2、隐式意图的例子

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.

一个隐式Intent指定了一个action,能够调用在这台设备上能够操纵这个action的任何的应用。当你的应用程序不能处理这个action的时候,使用一个隐式Intent是有用的,但其他应用也许可以并且用户可以选择使用哪个应用程序启动。

For example, if you have content you want the user to share with other people, create an intent with the ACTION_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.

比如说,如果你有一个想要用户分享给其他人的内容,可以使用ACTION_SEND action并且附加指定的分享内容创建一个Intent。当你把Intent传递给startActivity()方法并调用它的时候,用户能够选择通过哪个应用去分享内容。

Caution:?It‘s possible that a user won‘t have?any?apps that handle the implicit intent you send to startActivity(). 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.

注意:用户可能有没有任何能够处理你传递给startActivity()方法的隐式Intent的应用程序。如果发生了这种状况,将调用失败,并且你的应用程序也将要崩溃。通过调用Intent对象的resolveActivity()方法能够验证一个Activity能否接受这个Intent。如果调用结果不是null,那么至少有一个应用能够处理这个Intent,并且它可以安全的调用startActivity()方法。如果结果为null,你可以不使用这个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(HTTP.PLAIN_TEXT_TYPE);																		// "text/plain" MIME type

?

// 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.

提示:在这种情况下,URI没有被使用,但是Intent的数据类型通过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..

startActivity()方法被调用,系统将检查所有被安装的应用去判定哪一个能够处理这种意图(一个IntentactionACTION_SEND,并且携带"text./plain"数据).如果仅有一个应用能够处理它,应用将立即被打开,并把Intent传递给他。如果有多个Activity接受Activity时,系统将显示一个对话框,以便用户可以选择使用哪个应用程序

1.0.2.3、强制一个应用选择器

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) .

当有多于一个应用程序能够响应你的隐式意图的时候,用户能够选择使用哪个应用程序,并可以让这个应用成为这个action的默认选择。用户可能希望从现在开始使用相同的应用程序执行一个action时,例如打开一个网页(用户往往更喜欢只是一个Web浏览器),这是很好的

Figure 2.?A chooser dialog.

2,一个选择对话

?

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.

但是,如果多个应用程序能够响应这个Intent并且用户大概想每次使用不同的应用,你应该明确的显示一个选择对话框。这个选择对话框每次询问用户选择使用哪个应用程序操作这个action(用户不能选择处理这个action的默认程序)。比如说,当你的应用程序通过ACTION_SEND?action执行"share"操作,用户可能想使用一个依赖于现状的不同的应用程序来分享,所以你应该总是使用选择对话框,如图2.

To show the chooser, create an?Intent?using?createChooser()?and pass it to startActivity(). For example:

通过使用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);

}										

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.

这显示一个能够响应传递给createChooser()方法的Intent对象的应用程序列表,并使用传递给该方法的第二个参数作为对话框的标题。

?

  1. 接收一个隐式意图

?

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.

为了通知你的应用程序能够接收哪些隐式Intent,可以在你的manifest文件的应用程序组件的?<intent-filter>元素中定义一个或多个intent filter.每一个intent filter指定了可以接受的基于intentactiondatacategoryintent类型。仅当intent能够通过你的intent filter之一的验证的时候,系统能够发送一个隐式intent到你的应用程序组件。

Note:?An explicit intent is always delivered to its target, regardless of any intent filters the component declares.

注意:一个显式intent总是被发送到它的目标,而不管组件定义的任何intent filter

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).

一个应用程序组件应该给它每一个能做的工作定义不同的intent filter。比如说,一个在图片gallery应用中的activity它能够有两个filter:一个filter用于浏览图片,另外的一个filter用来编辑图片。当activity被启动的时候检查Intent并根据此Intent的信息决定怎样干(比如是否显示编辑控制器)

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:

每一个intent filter都定义在应用的manifest文件的?<intent-filter>元素之内,并嵌套在相应的应用程序组件之中(比如一个<activity>?组件)。在?<intent-filter>中,你能够使用一或者多个下面的三个元素指定intent能够接受的类型:

<action>

Declares the intent action accepted, in the?name?attribute. The value must be the literal string value of an action, not the class constant.

通过name?属性声明intent能够接受的action。这个值必须是一个action的字符串字面值,不是类常量。

<data>

Declares the type of data accepted, using one or more attributes that specify various aspects of the data URI (scheme,?host,?port,?path, etc.) and MIME type.

声明能够接受的数据的类型,使用一个或多个属性指定能够接受的数据的URI的各个方面(scheme,?host,?port,?path, 等等.)MIME类型。

<category>

Declares the intent category accepted, in the?name?attribute. The value must be the literal string value of an action, not the class constant.

声明能够接受的intent category,使用name属性。这个值必须是一个action的字符串字面常量,而不是类常量。

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.

注意:为了接收隐式意图,你在intent filter中必许包含CATEGORY_DEFAULT categorystartActivity()??startActivityForResult()方法对待所有的intent就像他们定义了CATEGORY_DEFAULT category一样。如果你没有在你的intent filter中声明这个category,就没有隐式intent能够解析你的activity。

For example, here‘s an activity declaration with an intent filter to receive an?ACTION_SEND?intent when the data type is text:

举例来讲,这里是一个当数据类型是文本的时候能够接收?ACTION_SEND intent activity的声明:

<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.

创建一个filter包含多于一个的<action>,?<data>, ?<category>的实例是可以的。如果你这么做,你只需要简单地让某些组件可以处理任意组合的这些过滤元素。

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.

当你想要去处理多种类型的intent的时候,但是仅有action、data和category类型的指定组合,你需要创建多个intent filter。

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.

一个隐式意图通过比较intent的三个元素来进行filter的针对性测试。为了被发送给应用程序组件,intent必须通过全部的三个测试。如果他们中的任何一个匹配失败,Android系统不会发送这个intent到应用程序组件。但是,因为一个组件可能有多个intent filter,一个intent不能通过组件的一个filter,但是可能通过另一个filter。更多的关于系统怎样解析intent的信息,清产早下面的关于Intent Resolution.的内容

Restricting access to components

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.

限制访问组

使用Intent filter不是一个让其他的应用启动你的组件的安全的方法。通过Intent filter限制一个组件响应只有某些类型的隐式Intent,其他的应用可能能通过一个显式Intent启动你的应用程序组件,如果开发者知道你的组件名称的话。如果仅有你自己的应用程序启动你的应用程序组件之一是重要的,给该组件设置exported属性值为"false"

?

Caution:?To avoid inadvertently running a different app‘s Service, always use an explicit intent to start your own service and do not declare intent filters for your service.

警告:为了避免在不经意间运行不同的应用程序的?Service,应该总是使用一个明确的意图启动自己的服务并且不给您的服务定义Intent filter

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.

注意:对于所有的activity,你必须在manifest文件中定义你自己的Intent filter。然而,Broadcast Receiver能够通过调用registerReceiver()动态的注册filter。你能够通过调用unregisterReceiver()方法注销Receiver这样做可以让你的应用程序只有在运行时的指定期间监听特定广播。

?

1.0.3.1、过滤器例子

?

Example filters(过滤器例子)

To better understand some of the intent filter behaviors, look at the following snippet from the manifest file of a social-sharing app.

为了更好地理解一些intent filter的行为,请看以下这个社会共享的应用程序清单文件的代码片段。

<activity											android:name="MainActivity">

? ? <!—这个应用程序是主入口,会显示在Launcher											

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:

第一个ActivityMainActivity,是应用程序的主入口点——当用户通过Launcher的图标初始化启动这个应用的时候:

  • The?ACTION_MAIN?action indicates this is the main entry point and does not expect any intent data.

    ACTION_MAIN? action标志着这是一个主入口点,并且不期待任何intent数据。

  • The?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.

    CATEGORY_LAUNCHER? category标志着这个Activity的图标将要显示在系统的Launcher应用上。如果?<activity>元素没有通过icon指定一个图标,那么系统将使用<application>元素的icon图标。

These two must be paired together in order for the activity to appear in the app launcher.

为了让Activity显示在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.

第二个Activity?ShareActivity, 是为了便于分享文本和媒体内容。虽然用户可能会从MainActivity导航到这个Activity,它们也可以直接从其他应用程序通过发出匹配这两个intent filter中的一个的隐式Intent来进入ShareActivity?

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.

注意:MIMI类型application/vnd.google.panorama360+jpg是指全景照片的数据类型,你能够通过Google panorama? APIS来处理这种特殊的格式。

?

?

?

  1. 使用Pending Intent

?

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.

PendingIntent对象是Intent?对象的一个包装器。?PendingIntent的主要目的是给包含?Intent外部应用程序授权,就像是它从你的应用程序本身的进程中执行。

Major use cases for a pending intent include:

Pending Intent的主要用例包括:

  • Declare an intent to be executed when the user performs an action with your?Notification?(the Android system‘s?NotificationManager?executes the?Intent).

    定义一个当用户通过你的Notification执行一个动作的时候可以被执行的Intent(Android 系统的?NotificationManager执行这个Intent)

  • Declare an intent to be executed when the user performs an action with your?App Widget?(the Home screen app executes the?Intent).

    定义一个当用户通过你的App Widget执行一个动作的时候可以被执行的Intent(Home Screen 应用执行这个Intent)

  • Declare an intent to be executed at a specified time in the future (the Android system‘s?AlarmManager?executes the?Intent).

    定义一个在指定了未来的时间可以被执行的Intent(Android 系统的?AlarmManager执行这个Intent)

Because each?Intent?object is designed to be handled by a specific type of app component (either an?Activity, 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 as?startActivity(). You must instead declare the intended component type when you create the?PendingIntent?by calling the respective creator method:

因为每一个Intent对象被设计用于操作指定类型的应用程序组件(Activity,Service或者BroadcastReceiver),因此PendingIntent也必须基于相同的考虑被创建。当使用pending Intent 的时候,你的应用不能通过?startActivity()调用执行Intent。当你通过相应的构造方法创建PendingIntent的时候,您必须声明预期的组件类型:

  • PendingIntent.getActivity()?for an??that starts an?Activity.

    PendingIntent.getActivity()用于启动一个?ActivityIntent

  • PendingIntent.getService()?for an?Intent?that starts a?Service.

    PendingIntent.getService()用于启动?ServiceIntent

  • PendingIntent.getBroadcast()?for a?Intent?that starts an?BroadcastReceiver.

    PendingIntent.getBroadcast()用于启动?BroadcastReceiver一个的Intent?

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.

除非你的应用程序接收其他应用的pending intent,上面的这些创建PendingIntent的方法可能是你需要的创建PendingIntent的唯一的方法。

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).

每个方法都需要当前的应用程序Context、你想要包装的Intent,以及指定一或多个Intent如何使用的Flag(如意图是否可以使用一次以上)。

?

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.

每一个相关的用例都提供了更多的关于使用pending Intent的信息的文档,比如在Notifications??App WidgetsAPI指南中。

?

1.0.5、Intent 解析

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:

当系统接收到一个启动Activity的隐式Intent的时候,它会基于以下的三个层面比较IntentIntent filter来搜索最佳的Activity Intent

  • The intent action

    Intentaction

  • The intent data (both URI and data type)

    Intentdata(URIdata type)

  • The intent category

    Intentcategory

The following sections describe how an intents are matched to the appropriate component(s) in terms of how the intent filter is declared in an app‘s manifest file.

下面的小节描述了一个Intent怎样去匹配指定的组件(components),就怎样在应用程序的Manifest文件中定义的Intent filter而言:

1.0.5.1、Action test (action测试 )

To specify accepted intent actions, an intent filter can declare zero or more?<action>?elements. For example:

Intent Filter能够定义0或者多个<action>元素去指定可被接受的Intent action。比如:

<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.

如果要通过这个filterIntent?action必须匹配filter中列出的action列表中的一个。

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).

如果filter没有列出任何的action,则没有Intent能够匹配,因此所有的Intent都会测试失败。然而,如果一个Intent没有指定action,它能够通过这个测试(只要这个filter包含至少一个action)。

1.0.5.2、Category test(category 测试)

To specify accepted intent categories, an intent filter can declare zero or more?<category>?elements. For example:

一个Intent filter能够定义0或者多个<category>元素去指定能够被接收的Intent category,比如:

<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 the Intent?will still pass. Therefore, an intent with no categories should always pass this test, regardless of what categories are declared in the filter.

对于能够通过category测试的Intent,每一个?Intent中的category必须匹配filter中的一个category。相反是没有必要的—— intent filter 可能定义比指定的Intent?更多的category,并且这个Intent能够通过测试。因此,一个没有categoryIntent总是能够通过这个测试,无论在Manifestfilter中定了什么样的category

Note:?Android automatically applies the the?CATEGORY_DEFAULT?category to all implicit intents passed to startActivity()?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.

注意:Android 自动应用CATEGORY_DEFAULT?category到所有传递到startActivity()??startActivityForResult()方法的隐式Intent。所以,如果你想要你的应用程序能够接受隐式Intent,它必须在它的Intent filter中包含一个"android.intent.category.DEFAULT"category()(比如前面的<intent-filter>?的例子).

1.0.5.3、Data test(data 测试)

To specify accepted intent data, an intent filter can declare zero or more?<data>?elements. For example:

一个Intent filter能够定义0或者多个<data>元素去指定能够被接收的Intent data,比如:

<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:

每一个<data>元素能够指定一个URI结构或者一个数据类型(MIME媒体类型)URI的每一个部分都有单独的属性——scheme,?host,?port,以及?path

<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 is folder/subfolder/etc.

着这个URI中,schema?content,hostcom.example.project,prot是200,path是folder/subfolder/etc

Each of these attributes is optional in a?<data>?element, but there are linear dependencies:

?<data>元素中,这些属性每一个都是可选的,但是也有线性的依赖关系:

  • If a scheme is not specified, the host is ignored.

    如果schema没有指定,host将被忽略。

  • If a host is not specified, the port is ignored.

    如果host没有指定,port将被忽略。

  • If both the scheme and host are not specified, the path is ignored.

    如果schemahost都没有指定,PATH将被忽略。

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:

当一个Intent中的URI和在filter中指定的URI比较的时候,它只比较包含在这个filter中的URI的一部分。比如:

  • If a filter specifies only a scheme, all URIs with that scheme match the filter.

    如果filter只指定了一个schema,所有的URI只是用它的schema匹配这个filter.

  • If a filter specifies a scheme and an authority but no path, all URIs with the same scheme and authority pass the filter, regardless of their paths.

    如果filter指定了schema和一个authority但是没有path,所有的URI通过相同的schemaauthority匹配这个filter,而不管它的path.

  • If a filter specifies a scheme, an authority, and a path, only URIs with the same scheme, authority, and path pass the filter.

    如果filter指定了schemaauthority以及path,仅仅只有和这个filterschemaauthority以及path匹配的才能通过这个测试。

Note:?A path specification can contain a wildcard asterisk (*) to require only a partial match of the path name.

注意:一个path的指定能够包含一个通配字符型号(*)来要求仅匹配path的名称部分。

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:

Data测试通过对比Intent中的URI以及MIMI类型和filter中指定的URIMIMI类型。它们的规则如下:

  1. An intent that contains neither a URI nor a MIME type passes the test only if the filter does not specify any URIs or MIME types.

    一个Intent不包含IntentMIME类型,仅当filter没有指定任何URI或者MIME类型的时候才能通过测试。

  2. An intent that contains a URI but no MIME type (neither explicit nor inferable from the URI) passes the test only if its URI matches the filter‘s URI format and the filter likewise does not specify a MIME type.

    一个Intent包含一个URI但是没有MIME类型(既没有显式指定也不能从URI中推断出来),仅当它的URI匹配filterURI格式并且filter同样没有指定MIME类型的时候才能通过测试。

  3. An intent that contains a MIME type but not a URI passes the test only if the filter lists the same MIME type and does not specify a URI format.

    一个Intent包含一个MIME类型,但是没有URI,仅当filter列出来相同的MIME类型但是没有指定一个URI格式的时候才能通过测试。

  4. An intent that contains both a URI and a MIME type (either explicit or inferable from the URI) passes the MIME type part of the test only if that type matches a type listed in the filter. It passes the URI part of the test either if its URI matches a URI in the filter or if it has a?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.

    一个Intent包含URIMIME类型(明确的指定或者可以从URI中推断出来) ,仅当Intent的MIME类型的部分和filter中列出来的类型相匹配的时候才能通过测试。如果一个IntentURI匹配filterURI,或者如果它有一个content:?file:?URI并且filter没有指定一个URI,那么这个Intent能够通过测试。换句话说,如果一个组件的filter列表中只有一个MIME类型,那么它被假定为?支持content:??file:数据。

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:?and file:?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:

这是最后的规则,规则反应组件能够从一个文件或者content Provider中得到本地数据的期望。因此,它们的filter能够列出仅有一个数据类型而且不需要显示命名的content:? file:?schema。这是一个典型的案例。一个<data>元素像下面这样,比如,告诉Android这个组件能够从content provider得到图片数据并显示它:

<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.

因为大部分可用的数据通过content providerfilter指定数据类型,并不需要一个URI可能是常见的。

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:

另一种常见的配置是filterschema和数据类型.比如说,一个像下面这样的<data>元素告诉Android这个组件能够执行从网络上得到video数据的操作。

<intent-filter>

? ? <data												android:scheme="http"																android:type="video/*"																				/>

? ? ...

</intent-filter>										

1.0.5.4、Intent matching (Intent匹配)

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.

Intent匹配Intent filter不仅能发现一个可被激活的目标组件,也有可能发现多个这个设备上的组件。例如,Home 应用能够找到所有指定ACTION_MAIN? actionCATEGORY_LAUNCHER? categoryintent filter相匹配的Activity,并放置于Launcher中。

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.

你的应用程序能够使用类似的Intent匹配。?PackageManager有一系列的query...()?方法来返回所有的能够接收这个特殊的Intent的组件,还有类似的一系列的resolve...()?方法确定能够响应这个Intent的最佳的组件。例如,queryIntentActivities()返回一个能够执行一个作为参数的IntentActivity列表。queryIntentServices()?返回相似的Service列表。它们都不能激活组件;它们仅仅列出那些可以响应的组件。有一个类似的方法,queryBroadcastReceivers(),用于broadcast receiver.

?