Android Google官方文档(cn)解析之——Intents and Intent filter

  应用程序核心组件中的三个Activityservice,还有broadcast receiver都是经过一个叫作intent的消息激活的。Intent消息传送是在相同或不一样的应用程序中的组件之间后运行时绑定的一个设施。Intent对象也就是它本身是一个数据结构,这个数据结构持有将要执行操做的抽象描述,或者在broadcast的状况下,是一个已经发生而将要宣布的描述。为传递intent到每一个不一样类型的组件有单独的机制:html

  • 一个Intent对象被传递到Context.startActivity()或是Activity.startActivityForResult()方法来启动一个Activity或是获得一个已经存在的Activity来作一些新的事情。(也能够被传递到Activity.setResult()来返回到一个叫作startActivityForResult()Activity)android

  • 一个Intent对象被传递到Context.startService()来初始化一个service或是传递一个新的指令到一个已经运行的service。一样的,一个Intent也能够被传递到Context.bindService()来创建调用组件与目标服务之间的链接。还能够随意的初始化一个没有运行的service
  • 传递给broadcast的方法中的任意一个方法(例如Context.sendBroadcast(),Context.sendOrderedBroadcast或是Context.sendStickyBroadcast())Intent对象被传送给全部感兴趣的广播接收者。

  在那样的状况下,Android系统将找到适当的Activityservice或是broadcast receiver集合来响应这个Intent,若是有必要的话还会实例化它们。那些消息系统内没有重叠部分:broadcast Intent只对应broadcast receiver,而不会给Activity或是service。一个传递给startActivity()方法的Intent只会被传递给一个Activity,毫不会传递给一个service或是broadcast receiver,等等。浏览器

  这份文档开始于Intent对象的描述。而后会描述Android映射Intent到组件使用的法则,讲述了哪个组件应当接受一个Intent消息。对于Intent来讲并无准确的指明一个目标组件,进程将潜心于检测Intent与关联了潜在的目标组件的Intent filters安全

Intent Objects | Intent对象

  一个Intent对象是一个信息束。它容纳了接受Intent组件感兴趣的信息(例如将要执行的动做还有将要对其起做用的数据)加上Android系统感兴趣的信息(好比应当处理这个Intent的组件的种类还有如何启动目标Activity的指令)。主要地它能包含如下几点:网络

Component name | 组件名数据结构

  应当处理Intent组件的名字。这个字段是一个ComponentName对象,全部有资格的目标组件类名(例如”com.example.project.app.FreneticActivity”)集合还有应用程序manifest文件中应用程序所在的包名(例如”com.example.project”)集合。组件名和包名集合中的包在manifest中不是必须必定要匹配的。app

  组件名是可选的。若是被设置了,Intent对象会被传送给指定类的实例。若是没有设置组件名,Android系统会使用Intent对象中的其余信息来定位一个合适的目标,在后文中请查看关于Intent Resolution.ide

  组件名能够经过setComponent(),setClass,或是setClassName方法来设置,也能够经过getComponent()方法来读取。测试

Action |动做google

  一个字符串命名了将要执行的动做—或者是在broadcast Intent的状况下,已经发生将要报告的动做。

  Intent类定义了一系列的动做常量,包括这些:

 

Constant 

常量

Target component 

目标组件

Action

动做

ACTION_CALL

activity

Initiate a phone call.

初始化一个打电话界面

ACTION_EDIT

activity

Display data for the user to edit.

为用户展现数据来编辑

ACTION_MAIN

activity

Start up as the initial activity of a task, with no data input and no returned output.

做为任务的初始化Activity启动,没有数据输入也没有返回值输出。

ACTION_SYNC

activity

Synchronize data on a server with data on the mobile device.

 

ACTION_BATTERY_LOW

broadcast receiver

A warning that the battery is low.

提示电量太低。

ACTION_HEADSET_PLUG

broadcast receiver

A headset has been plugged into the device, or unplugged from it.

耳机已经被插入设备或是从设备上拔出。

ACTION_SCREEN_ON

broadcast receiver

The screen has been turned on.

屏幕被转向。

ACTION_TIMEZONE_CHANGED

broadcast receiver

The setting for the time zone has changed.

时区设置被改变。

  查看预约义的类内部动做常量列表请看Intent的类描述。其余的action被定义在Android API的其余地方。你也能够在应用程序中为激活组件定义你本身的动做字符串。你创造的action 常量应当包括包名做为前缀-例如:”com.example.project.SHOW_COLOR”。

  动做主要的决定了Intent的其余部分是如何构造的,尤为是”data”还有”extras”字段,做为方法名决定参数列表还有返回值。由于这样,使用尽量特殊的action名还有将他们与Intent中的其余字段名结合的紧一点是一个好主意。换句话来讲,为Intent对象定义一整套协议而不是定义一个孤立action可以使你的组件更易于操做。

  在Intent对象中的动做被”setAction()”方法设置,也能经过”getAction()”方法来获取。

Data | 数据

  被执行数据的URI还有数据的MIME类型。不一样的动做会被不一样种类的数据规格来组成一对。例如,若是动做字段是ACTION_EDIT,数据字段会包含将要被展现编辑文档的URI。若是动做是ACTION_CALL,数据字段将会是包含tel:URI,将要拨打的电话。一样的,若是动做是ACTION_VIEW而数据字段是一个http:URI,那么接收的Activity将会被调用来下载或是展现URI表示的数据。

  当匹配一个Intent到能胜任处理数据的组件的时候,除了URI以外知道数据的类型(MIME type)也是很重要的。例如,展现图像数据的组件不能被用做播放媒体文件调用。

在不少状况下,数据类型能经过URI推断出来尤为是content:URIs,代表了数据是在设备上存放的,被content provider来控制(请查看content provider的分开讨论)。可是类型也能够在Intent对象中准确的设置。setData()方法仅仅指定数据的URIsetType()方法仅仅指定数据的MIME类型,而setDataAndType()方法能够同时指定数据的URIMIME类型。URI能够经过getData()方法获取,类型能够经过getType()获取。

Category | 种类

  包含关于组件种类的额外信息的字符串能够处理Intent。许多种类描述能够放在Intent对象中。就像action同样,Intent类定义了许多category常量,包括如下这些:

 

Constant

常量

Meaning

含义

CATEGORY_BROWSABLE

The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message

目标Activity能够被浏览器安全的调用,经过一个连接来展现数据。例如一张图片或是一条邮件消息。

CATEGORY_GADGET

The activity can be embedded inside of another activity that hosts gadgets.

Activity能够被嵌入到另外一个主机产品的Activity中。

CATEGORY_HOME

The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed.

这个Activity展现了主屏幕,设备被翻转或是HOME键被按下的时候用户看见的第一个界面。

CATEGORY_LAUNCHER

The activity can be the initial activity of a task and is listed in the top-level application launcher.

这个Activity能够是一个任务的启动Activity,在顶级应用程序启动器中被列出。

CATEGORY_PREFERENCE

The target activity is a preference panel.

目标Activity是一个参数面板。

 

  为所有的分类列表,请查看Intent类描述。

  addCategory()方法在Intent对象中任命一个种类,removeCategory()方法来删除以前添加过的种类,getCategories()方法来获取当前对象中的全部种类集合。

Extras | 额外部分

  额外信息的键值对,额外信息应当被分发处处理Intent的组件。正像一些action被特殊种类的URI配对,一些action也经过特殊的额外部分配对。例如,ACTION_TIMEZONE_CHANGED Intent有一个”time-zone”的额外部分,它定义了新的时区,ACTION_HADSET_PLUG有一个”state”额外部分代表了耳机如今是不是插入仍是拔出的状态,也有一个”name”额外部分给耳机的类型。若是你要创造一个SHOW_COLORaction,颜色值将会在一个额外键值对中设置。

  Intent对象中有一系列的put...()方法来插入各类各样的额外数据的类型还有相似的get...()方法集合来读取这些数据。这些方法与Bundle对象中的方法是等价的。实际上,额外部分也能够被安放和读取做为Bundle经过使用putExtras()方法和getExtras()方法。 

Flags | 标记

  不一样种类的标记。不少标记介绍了Android系统如何启动一个Activity(例如,Activity属于哪个任务)还有在启动以后如何对待它(例如,它是否属于最近启动的Activity列表)。全部的标记都定义在Intent类中。

  Android系统和伴随着平台的应用程序都使用Intent对象来发送系统原生广播还有激活系统组件。查看如何构造Intent来激活系统组件,请在参考文献中查阅list of intents.

Intent Resolution | Intent 解析

Intent 能够被分为两大类:

  • 显式的Intent经过组件的名字指定了目标组件(以前提到过的component name字段有值集合)。既然组件名通常来讲不能被其余应用程序的开发者所知道,准确的Intent是为全局应用程序消息所使用的,例如一个Activity启动一个从属的service或是启动一个同类型的Activity
  • 隐式的Intent并不命名目标(组件名字段为空)。隐式的Intent常常用于激活其余应用程序中的组件。

  Android传递显式的Intent给一个指定的目标类的实例。Intent对象中除了组件名没有其余东西关心决定哪一个组件应该获取到该Intent

  隐式的Intent须要不一样的策略。在目标组件缺乏的状况下,Android系统必须找到最好的组件(或是多个组件)来处理该Intent—单个的Activity或是service来执行请求的动做或是响应广播通知的广播接受者集合。它经过比较Intent对象的内容和Intent filter(一个关联了潜在接收Intent的组件的结构)来作到。过滤器通知组件的能力还有划定Intent能够处理的界限。他们打开这样一个组件,这个组件有可能接收已经通知了类型的隐式Intent。若是一个组件没有Intent filters,那么它只接受显示的Intent。一个有过滤器的组件既能够接收显式的也能够接收隐式的Intent

  一个Intent对象中只有三个方面被查阅,当Intent对象是针对于Intent filter测试的时候。ActionData(both URI and data type)Category

  Extra还有flag在解决组件接收Intent的时候并不起做用。

Intent filters

  为了通知系统他们能处理哪个隐式的IntentActivityservicebroadcast receiver能够有一个多更多的Intent filter。每个过滤器描述了组件的一个能力,一个罪案将会接收IntentIntent集合。,实际上,Intent filter在但愿类型的Intent中过滤,当过滤掉不想要的Intent时,但只有不想要的隐式Intent(那些没有指名一个目标类的Intent)。显示Intent老是被传递到他的目标,无论它是否包含Intent filter;过滤器没有被请教。可是隐式Intent传递给一个组件,只有Intent能传递给组件的过滤器之一的组件。

  一个组件中每个能作的工做有单独的过滤器,每个能呈现给用户的外观。例如,记事本应用程序中的NoteEditor Activity有两个过滤器:一个用来启动用户能够查看或编辑的特定便签,另外一个来开始一个新的空白便签,那么用户能够书写和保存。(全部的Note Pad的过滤器将在以后的Note Pad Example部分描述。)

  Intent filterIntentFilter类的实例。然而,既然Android系统必须在启动一个组件以前就得必须了解组件的能力,那么Intent filter通常来讲不在Java代码中设置,而是在应用程序的manifest文件(AndroidManifest.xml)中做为<intent-filter>元素来定义。(有一个例外,经过调用Context.registerReceiver()方法动态注册的广播接收者,他们是做为intentFilter对象直接建立的)

  过滤器有与actiondatacategory字段平行的Intent对象字段。隐式Intent在全部三个方面对过滤器进行测试。为了传递给拥有过滤器的组件,它必须经过全部的三项测试。若是即便没有经过他们中的一个,Android系统都不会传递到组件,至少不在那个过滤器的基础上。然而,即便一个组件有多个Intent filter,没有经过组件过滤器的Intent也可能在另外一个上经过。

  三项测试将在下面被详细的描述:

Action test | 动做测试

manifest文件中的<intent-filter>标签以<action>子标签的方式列出了动做。例如:

<intent-filter . . . >
    <action android:name="com.example.project.SHOW_CURRENT" />
    <action android:name="com.example.project.SHOW_RECENT" />
    <action android:name="com.example.project.SHOW_PENDING" />
    . . .
</intent-filter>

  就像例子中展现的那样,当一个Intent对象只命名了单个的action,过滤器也须要列出多于一个的actionAction列表不能为空,过滤器列表必须包含至少一个<action>标签不然的话它将阻塞全部的Intent

  为了经过这个测试,在Intent对象中指定的action必须与过滤器列表中的某一个action匹配。若是Intent对象或是过滤器没有指定一个action,结果就是如下列出的:

  • 若是过滤器没有列出actionIntent将不会匹配到任何东西,因此全部的Intent都不能经过测试。没有Intent能够经过该过滤器。
  • 另外一方面,没有指定actionIntent对象将自动的经过测试,只要过滤器包含至少一个action

Category test | 种类测试

<intent-filter>元素也列出了category做为子元素。例如:

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

  注意到以前描述的action还有category常量在manifest文件中没有用到。代替的整个字符串值会被用到。例如,在上面的例子中”android.intent.category.BROWSABLE”字符串符合以前文档中提到过的CATEGORY_BROWSABLE常量。相似的字符串”android.intent.action.EDIT”字符串符为”ACTION_EDIT”常量。

  为了Intent能够经过category测试,在Intent对象中的每个种类必须匹配过滤器中的category。过利器能够列出附加的category,可是不能遗漏Intent中的任意一个category

  所以,原则上一个没有种类的Intent对象老是能经过category测试,无论过滤器中有什么。大部分状况下那是对的。然而有一个例外,Android让全部的隐式Intent经过startActivity()方法,好像他们包含至少一个种类:”android.intent.category.DEFAULT”(CATEGORY_DEFAULT常量)。所以,将要接收隐式IntentActivity必须在他们的Intent过滤器中包含”android.intent.category.DEFAULT”。(”android.intent.action.MAIN”还有”android.intent.category.LANCHER”设置的过滤器除外,他们标记了一个开始新任务的Activity而后在启动器中呈现出来。他们能够在category列表中包含”android.intent.category.DEFAULT”,可是不是必须的。)查看更多的那些过滤器的信息能够参见以后提到的Using intent matching

Data test | 数据测试

  就像action还有category同样,一个Intent filter的数据规格也是在一个子元素中包含的。在那些状况下这个子元素能够出现屡次或是不出现。例如:

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

  每个<data>元素能够指定一个URI还有一个数据类型(MIME 媒体类型)。有单独的属性——schemehost,还有path——每个URI的不一样部分:scheme://host:port/path

  例如,在接下来的URI中,content://com.example.project:200/folder/subfolder/etcscheme”content”,host”com.example.project”,port”200”,path”folder/subfolder/etc”。Host还有port在一块儿组成了整个URI,若是一个host没有被指定,那么port就会被忽视。

  那些属性中每个都是可选的,但他们彼此之间互不依赖。authority是有意义的,scheme必须被指定。为了一个地址是有意义的,schemeauthority都必须被指定。

  当Intent对象中的URI被与filter中的URI详述比较时,实际上只会与filter中提到的URI部分比较。例如,若是一个过滤器只指定了scheme,全部拥有该schemeURI将会匹配这个过滤器。若是一个过滤器指定了scheme还有authority可是没有指定path,全部有相同scheme还有authorityURI能匹配,无论他们的path。若是一个过滤器指定了schemeauthority,还有path,只有有相同schemeauthority还有path的能够匹配。然而,在过滤器中path详细会包含通配符,只须要path的局部匹配。

  <data>元素的”type”属性指定了数据的MIME类型。在过滤器中它比URI更常见。Intent对象还有过滤器均可以用”*”做为子类型的万能类型,例如”text/*”或是”audio/*”代表任意子类型的匹配。

数据测试比较URI还有Intent对象中的数据类型和过滤器中的URI还有数据类型。过则以下:

  1. 既没有URI也没有数据类型的Intent对象只有在过滤器没有指明URI还有数据类型的状况下才能经过测试。
  2. URI可是没有数据类型的(URI中也不能推断出类型)Intent对象只有它的URI匹配了过滤器的URI,这个过滤器并无指明一个类型。这将只会是这样的状况,像”mailto:”还有”tel:”同样的URI,它们并不涉及到实际的数据。
  3. 有数据类型可是没有URIIntent对象只有在过利器列出了一样的数据类型一样的也没有指明URI的状况下能经过测试。
  4. 既有URI也有数据类型(或是从URI中可用推断出数据类型)Intent对象,只有在它的类型匹配了过滤器中的一个类型才能经过测试的数据类型部分。若是它的URI匹配了过滤器中的一个URI或者它有”content:”或是”file:”URI而且过滤器没有指明URI的状况才才能公国测试的URI部分。换句话来讲,组件是默认支持”content:”还有”file”数据的若是过滤器值列出了数据类型。

  若是Intent能够经过多于一个的Activity或是service的过滤器,那么用户将会被询问激活哪个组件。若是没有目标组件被找到那么会引起一个异常。

Common cases | 一般状况

  上面提到最后一条数据测试的规则,反应了组件可以从文件或是content provider中获取本地数据的指望。所以,它们的过滤器只须要列出数据类型而没必要要准确的命名”content:”和”file:”scheme.这是一个经典的案例。好比一个<data>元素像下面说的这样告诉Android组件能够从content provider中获取图像数据而且展现它:

<data android:mimeType="image/*" />

  既然大部分的有效数据都是被content provider所提供,那么指明了数据类型可是没有URI的过滤器或许是最多见的。

  另外一个常见的配置是有scheme还有数据类型的过滤器。例如像下面的<data>元素告诉Android塑件能够从网络中获取视频数据而且展现它:

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

  例如考虑当用户跟随了一个网页上的连接,浏览器程序作什么呢。它开始尝试展现数据(若是连接是一个HTML页面)。若是不能展现该数据,它将含有这个scheme的隐式Intent还有数据类型放在一块儿而后尝试打开一个能作这个任务的Activity。若是没有接收者,那么它请求下载管理器来下载该数据。那将把它放在content provider的管理下,那么有大量的Activity(那些只命名了数据类型的过滤器)能够响应。

  大部分的应用程序也只有一种方法来初始启动,在没有任何特殊数据引用的状况下。能初始化应用程序的Activity有被做为action”android.intent.action.MAIN”的过滤器。若是他们要被放在应用程序启动器中,他们也须要指定”android.intent.category.LAUNCHER”category:

<intent-filter . . . >
    <action android:name="code android.intent.action.MAIN" />
    <category android:name="code android.intent.category.LAUNCHER" />
</intent-filter>

Using intent matching | 使用Intent匹配 

  Intent匹配Intent过滤器不只是为了发现目标组件来激活,并且发现一些设备上的组集合的一些东西。好比,Android系统居住于应用程序启动器中,为用户来展现可用的应用程序并启动的顶级视图,经过找到全部定义了”android.intent.action.MAIN”action还有”android.intent.category.LAUNCHER”category过滤器的Activity。而后在启动器中展现那些Activity的图标还有标签,经过查找在过滤器中带有”android.intent.category.HOME”的Activity来展现home屏幕。

  你应用程序使用Intent匹配也是相似的方式。包管理器(PackageManager)有一系列的query...()方法,它返回你能够接收特定Intent的全部组件,还有相似的一系列的resolve...()方法来决定响应Intent的最好组件。例如queryIntentActivities()返回能执行做为参数传过来Intent的全部Activity列表,queryIntentServices()返回一个相似的服务列表。这些方法并不激活组件,他们仅仅列出了能响应Intent的组件列表。对于broadcast receiver来讲也有相似的方法,queryBroadcastReceivers().

 

Note Pad Example | 记事本例子

  记事本示例程序可让用户浏览便签列表,能够查看列表中的单独项的详细信息,编辑项,添加新项到列表中。这个章节将查看这个程序的manifest文件中的Intent filter(若是你在SDK离线状况下工做,你能够查看到这个示例程序的全部源码,包括manifest文件在<sdk>/sample/NotePad/index.html中。若是你是在线浏览这份文档,源文件能够在Tutorials and Sample Code 章节中看到)

  在这份manifest文件中,记事本应用程序定义了三个Activity,每个都拥有至少一个Intent filter。也定义了一个管理Note数据的content provider。这是整个的manifest文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.android.notepad">
    <application android:icon="@drawable/app_notes"
                 android:label="@string/app_name" >

        <provider android:name="NotePadProvider"
                  android:authorities="com.google.provider.NotePad" />

        <activity android:name="NotesList" android:label="@string/title_notes_list">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="android.intent.action.PICK" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>
        
        <activity android:name="NoteEditor"
                  android:theme="@android:style/Theme.Light"
                  android:label="@string/title_note" >
            <intent-filter android:label="@string/resolve_edit">
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="com.android.notepad.action.EDIT_NOTE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.INSERT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>
        </activity>
        
        <activity android:name="TitleEditor" 
                  android:label="@string/title_edit_title"
                  android:theme="@android:style/Theme.Dialog">
            <intent-filter android:label="@string/resolve_title">
                <action android:name="com.android.notepad.action.EDIT_TITLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.ALTERNATIVE" />
                <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>
        
    </application>
</manifest>

  第一个Activity NotesList 与其余Activity区分开来其实是它是在一个Note的文件夹(note列表)上操做而不是单个Note。它通常做为进入应用程序的初始化用户界面。它经过三个Intent过滤器的描述能作三件事情:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

  这个过滤器定义了进入记事本应用程序的主入口。标准的”MAIN” action是一个入口,不须要Intent中的任何其余信息(例如没有数听说明),而后”LAUNCHER”category代表入口点会在应用程序启动器中列出来。

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.PICK" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>

  这个过滤器声明了这个Activity能在一个Note文件夹作的事情。它能够容许用户查看或是编辑文件夹(经过”VIEW”还有”EDIT”动做),或是从文件夹中选择一个特别的Note(经过”PICK”动做)

  <data>元素的”mimeType”属性指明了action操做的数据类型。它代表了Activity能够从持有Note pad数据(vnd.google.note)content provider中获取到一个大于零的游标或是更多的项目(vnd.android.cursor.dir)。启动ActivityIntent对象能够包含一个内容:URI指明了Activity应该打开的这种类型的额外数据。

  在Note”DEFAULT”category在过滤器中也被提供了。它在这是由于Context.startActivity还有Activity.startActivityForResult()方法视全部的Intent都有”DEFAULT”category,可是有两个除外:

  • 显示指出了目标ActivityIntent
  • 包含”MAIN”action还有”LAUNCHER”categoryIntent

  所以,”DEFAULT”category对于全部的过滤器都是须要的,除了那些有”MAIN”action还有”LAUNCHER”category的过滤器。(intent filter 并不为显示Intent咨询)

<intent-filter>
    <action android:name="android.intent.action.GET_CONTENT" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
</intent-filter>

  这个过滤器描述了该Activity的能力来返回一个用户选择的Note,而用户没有要求文件夹中应当选择的任意的详述。”GET_CONTENT”动做相似”PICK”动做。两种状况下,Activity都从用户选择的Note中返回一个URI(在那种状况下,URI被返回给Activity经过一个叫作startActivityForResult()来启动便签列表activity)这里,然而调用者指定了但愿的数据类型而不是用户将要选择的数据文件夹。

  数据类型,”vnd.android.cursor.item/vnd.google.note”,代表了该Activity能够返回的数据类型,单个NoteURI。从返回的URI中,调用者能够从持有Note pad数据(vnd.google.note)content provider中获得一个准确项(vnd.android.cursor.item)的游标。

  换句话说,在以前的filter”PICK”action,数据类型代表了Activity可以展现给用户的数据的类型。在”GET_CONTENT”过滤器中,它代表了Activity也能够返回数据的类型给调用者。

考虑到这些功能,下面的Intent将解决在NotesList activity

Action:android.intent.action.MAIN
启动没有指明数据的Activity

Action:android.intent.action.MAIN
Category:android.intent.category.MAIN
启动没有选择数据指明的Activity。这是被顶级列表中的启动器所使用的实际Intent。全部匹配了这个action还有category的filter的Activity都会被添加到启动器。

Action:android.intent.action.VIEW
Data:content://com.google.provider.NotePad/notes
请求Activity展现”content://com.google.provider.NotePad/notes”下的全部note的列表。用户能够浏览note列表也能够从中获取到项的信息。

Action:android.intent.PICK
Data:content://com.google.provider.NotePad/notes
请求展现在”content://com.google.provider.NotePad/notes”下的note列表。用户能够从列表中选择一项而后Activity会返回该项的URI给启动NoteList Activity的Activity。

Action:android.intent.action.GET_CONTENT
Data type:vnd.android.cursor.item/vnd.google.note
请求Activity提供Note pad数据中的一项数据。

  第二项ActivityNoteEditor,展现用户一个Note实体并且容许用户编辑。它作两件事就像在他的两个Intent filter中描述的那样:

<intent-filter android:label="@string/resolve_edit">
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <action android:name="com.android.notepad.action.EDIT_NOTE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
</intent-filter>

  首先Activity主要的目的是让用户在单个Note上查看或是编辑它。(“EDIT_NOTE category”对于”EDIT”来讲是同义的。)Intent包含匹配了数据的URI,该URI匹配了MIME类型”vnd.android.cursor.item/vnd.google.note”,那就是说这个URI是一个特定noteURI。它会是被NoteList activity”PICK”或是”GET_CONTENT”动做返回的URI

  就像以前说的,过滤器列出”DEFAULT”种类以便于该Activity能够被没有明确指出NoteEditor类的Intent启动。

<intent-filter>
    <action android:name="android.intent.action.INSERT" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>

  该Activity的第二个目的是确保用户能够建立一个新的便签,新的便签将会插入到已有的便签文件夹中。该Intent将会包含匹配了”vnd.android.cursor.dir/vnd.google.note”MIME类型的URI,也就是说,便签将会被放入的文件夹的URI

  考虑到这些功能,Intent将解决NoteEditorActivity以下:

action: android.intent.action.VIEW 
data: content://com.google.provider.NotePad/notes/ID
请求Activity展现被id定义的note的内容。(关于content:URI 如何指定集合中单个的成员,请查看 content provider)

action: android.intent.action.EDIT 
data: content://com.google.provider.NotePad/notes/ID
请求Activity展现没有被id定义的note,而且让用户编辑它。如何用户保存了更改,该Activity将会在content provider中更新note的数据。

action: android.intent.action.INSERT 
data: content://com.google.provider.NotePad/notes
请求Activity建立一个新的空白便签在”content://com.google.provider.NotePad/notes”便签列表中,并且容许用户编辑它。若是用户保存了便签,那么便签的URI将会返回给调用者。

  最后一个ActivityTitleEditor,确保用户能够编辑便签的标题。在没有用Intent filter的状况下经过直接调用Activity(经过在Intent中显示的设置它的组件名)的方式也能被执行。可是这里咱们抓住机会来展现如何在已经存在的数据上发布可选择的操做:

<intent-filter android:label="@string/resolve_title">
    <action android:name="com.android.notepad.action.EDIT_TITLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
</intent-filter>

  该Activity只有一个Intent filter用了一个叫作”com..android.notepad.action.DEIT_TITLE”的用户action.它必须在特定的note(数据类型为”vnd.android.cursor.item/vnd.google.note”)上被调用,就像以前的”VIEW”还有”EDIT”动做同样。然而这里,该Activity展现了note数据中的标题,而不是note的内容自己。

  此外提供了一般的”DEFAULT”category,标题的编辑者也提供了两个其余的categories:”ALTERNATIVE”还有”SELECTED_ALTERNATIVE”。这些categories指出Activity能够在选项菜单中呈现给用户(就像”LAUNCHER”category肯定了应用程序启动器中呈现给用户的Activity)。注意到过滤器也提供了一个明确的标签(经过android:label=”@string/resolve_title”)以更好的控制用户看到的东西,当呈现了这个Activity做为一个对他们正在查看的数据可选的动做。(更多关于那些categories还有建立选项菜单,请查看PackageManager.queryIntentActivityOptions()还有Menu.addIntentOptions()方法)

考虑到这些功能,接下来的Intent将在TitleEditor Activity中解决:

action: com.android.notepad.action.EDIT_TITLE 
data: content://com.google.provider.NotePad/notes/ID
请求Activity展现关联note ID的标题,而且容许用户编辑这个标题。
相关文章
相关标签/搜索