现在的位置: 首页 > 综合 > 正文

Android中Intent详解

2013年10月06日 ⁄ 综合 ⁄ 共 25062字 ⁄ 字号 评论关闭

可以毫不夸张地说:Intent是整个Android应用的脉络与灵魂 。

在一个Android 应用中,主要是由四种组件组成(Activities, Services, Broadcast receivers, Content providers),而这四种组件是独立的,它们之间可以互相调用,协调工作,最终组成一个真正的Android应用。在这些组件之间的通讯,主要是由Intent协助完成的。如果我们把Activity比作积木的话,那么Intent就是胶水,把不同的积木粘起来,构成我们搭建的房子(应用)。
Intent负责对应用中一次操作的动作及动作涉及数据 进行描述,Android则根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦控制。就像我们打电话到出租车公司叫计程车,而不是直接到街道上叫车,我们给出租车公司打电话,表明我们的意图(Intent),当服务员接到此意图,就依据我们的意图去挑选最合适的计程车,然后派遣它来接我们。
例如,在一个联系人 维护的应用中,当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上,点击某个联系人后,希望能够跳到此联系人的详细信息屏幕(假设对应的Activity为detailActivity)。为了实现这个目的,listActivity 需要构造一个Intent,这个Intent用于告诉系统,我们要做“查看”动作,此动作对应的查看对象是“某联系人”,然后调用startActivity (Intent intent),将构造的Intent传入,系统会根据此Intent中的描述,到AndroidManifest.xml中找到满足此Intent要求的Activity,系统会调用找到的Activity-detailActivity,最终传入Intent,detailActivity则会根据此Intent中的描述,执行相应的的操作。
一、抽象描述要描述什么

在Android参考文档 中,对Intent的定义是执行某操作的一个抽象描述。我们先来看看这里的抽象描述,到底描述了什么。
首先,是对要执行的动作(action)的一个简要描述,如 ACTION_ VIEW(查看)、 ACTION_ EDIT(修改)等,Android为我们定义了一套标准动作:

代码:

ACTION_MAIN
ACTION_VIEW
ACTION_ATTACH_DATA
ACTION_EDIT
ACTION_PICK
ACTION_CHOOSER
ACTION_GET_CONTENT
ACTION_DIAL
ACTION_CALL
ACTION_SEND
ACTION_SENDTO
ACTION_ANSWER
ACTION_INSERT
ACTION_DELETE
ACTION_RUN
ACTION_SYNC
ACTION_PICK_ACTIVITY
ACTION_SEARCH
ACTION_WEB_SEARCH
此外,我们还可以根据应用的需要,定义我们自己的动作,并可定义相应的Activity来处理我们的自定义动作。

其次,是执行动作要操作的数据(data),Android中采用指向数据的一个URI来表示,如在联系人应用中,一个指向某联系人的URI可能为:content://contacts/1。这种Uri表示,通过Uri这个类来描述,具体可以参考android.net.Uri类的文档。

以联系人应用为例,以下是一些action/data对,及其它们要表达的意图:

代码:
ACTION_VIEW content://contacts/people/1 -- 显示标识符为“1”的联系人的信息。

ACTION_DIAL content://contacts/people/1 -- 将标识符为“1”的联系人的号码显示在电话的拨号面板上。

ACTION_VIEW tel:123 -- 将号码123显示在电话的拨号面板上。 (与ACTION_DIAL有何区别?只说:Note how the VIEW action does what what is considered the most reasonable thing for a particular URI.)

ACTION_DIAL tel:123 -- 将号码123显示在电话的拨号面板上。

ACTION_EDIT content://contacts/people/1 --编辑标识符为“1”的联系人的信息。

ACTION_VIEW content://contacts/people/ -- 显示所有联系人的列表。

category (类别),是被执行动作的附加信息。例如 LAUNCHER_CATEGORY 表示 Inten t的接受者应该在 Launcher 中作为顶级应用出现;而 ALTERNATIVE_CATEGORY 表示当前的 Intent 是一系列的可选动作中的一个,这些动作可以在同一块数据上执行。
type (数据类型),显式指定 Intent 的数据类型( MIME )。一般 Intent 的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。
component (组件),指定 Intent 的的目标组件的类名称。通常 Android 会根据 Intent 中包含的其它属性的信息,比如 action 、 data/type 、 category 进行查找,最终找到一个与之匹配的目标组件。但是,如果 component 这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后, Intent 的其它所有属性都是可选的。
extras (附加信息),是其它所有附加信息的集合。使用 extras 可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在 extras 里,传给电子邮件发送组件。

      总之, action、data/type、category和extras 一起形成了一种语言。 这种语言使系统能够理解诸如“查看某联系人的详细信息”之类的短语。 随着应用不断的加入到系统中,它们可以添加新的action、 data/type、category来扩展这种语言。 应用也可以提供自己的Activity来处理已经存在的这样的“短语”,从而改变这些“短语”的行为。

二、 Android如何解析Intent

在应用中,我们可以以两种形式来使用Intent:

•直接Intent :指定了component属性的Intent(调用setComponent(ComponentName)或者setClass(Context, Class)来指定)。通过指定具体的组件类,通知应用启动对应的组件。
•间接Intent :没有指定comonent属性的Intent。这些Intent需要包含足够的信息,这样系统才能根据这些信息,在所有的可用组件中,确定满足此Intent的组件。
      对于直接Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些间接Intent,通过解析,将Intent映射给可以处理此Intent的Activity、Broadcaset receiver或Service。
     Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:

•如果Intent指明了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
•如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
•如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme(比如 http: 或者mailto:)进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
•如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。
三、应用例子
        以下,以Android SDK中的便笺例子来说明,Intent如何定义及如何被解析。这个应用可以让用户浏览便笺列表、查看每一个便笺的详细信息。

代码:

+ expand sourceview plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150<manifest xmlns:android="
http://schemas.android.com/apk/res/android
      package="com.android.notepad">  
    <application android:icon="@drawable/app_notes" 
            android:label="@string/app_name">  
        <provider class=".NotePadProvider" 
                android:authorities="com.google.provider.NotePad" />  
        <activity class=".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 class=".NoteEditor" 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" />  
                <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 class=".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> 
 <manifest xmlns:android="
http://schemas.android.com/apk/res/android"
       package="com.android.notepad">
     <application android:icon="@drawable/app_notes"
             android:label="@string/app_name">
         <provider class=".NotePadProvider"
                 android:authorities="com.google.provider.NotePad" />
         <activity class=".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 class=".NoteEditor" 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" />
                 <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 class=".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是com.google.android.notepad.NotesList,它是应用的主入口,提供了三个功能 ,分别由三个intent-filter进行描述:
        1、第一个是进入便笺应用的顶级入口(action为android.intent.action.MAIN)。类型为android.intent.category.LAUNCHER表明这个Activity将在Launcher中列出。
        2、第二个是,当type为vnd.android.cursor.dir/vnd.google.note(保存便笺记录的目录)时,可以查看编辑可用的便笺(action为android.intent.action.VIEW| android.intent.action.EDIT ),或者让用户选择一个便笺并返回给调用者(action为 android.intent.action.PICK)。
        3、第三个是,当type为vnd.android.cursor.item/vnd.google.note时,返回给调用者一个用户选择的便笺(action为android.intent.action.GET_CONTENT),而用户却不需要知道便笺从哪里读取的。有了这些功能,下面的Intent就会被解析到NotesList这个activity:

代码:

{ action=android.app.action.MAIN }:与此Intent匹配的Activity,将会被当作进入应用的顶级入口。

{ action=android.app .action.MAIN, category=android.app.category.LAUNCHER }:这是目前Launcher实际使用的 Intent,用于生成Launcher的顶级列表。

{ action=android.app.action.VIEW data=content://com.google.provider.NotePad/notes }:显示"content://com.google.provider.NotePad/notes"下的所有便笺的列表,使用者可以遍历列表,并且察看某便笺的详细信息。

{ action=android.app.action.PICK data=content://com.google.provider.NotePad/notes }:显示"content://com.google.provider.NotePad/notes"下的便笺列表,让用户可以在列表中选择一个,然后将选择的便笺的URL返回给调用者。

{ action=android.app.action.GET_CONTENT type=vnd.android.cursor.item/vnd.google.note }:和上面的action为pick的Intent类似,不同的是这个Intent允许调用者(在这里指要调用NotesList的某个 Activity)指定它们需要返回的数据类型,系统会根据这个数据类型查找合适的 Activity(在这里系统会找到NotesList这个Activity),供用户选择便笺。
第二个Activity 是com.google.android.notepad.NoteEditor,它为用户显示一条便笺,并且允许用户修改这个便笺。它定义了两个intent-filter,所以具有两个功能。
第一个功能是,当数据类型为 vnd.android.cursor.item/vnd.google.note时,允许用户查看和修改一个便签(action为 android.intent.action.VIEW和android.intent.action.EDIT)。
第二个功能是,当数据类型为 vnd.android.cursor.dir/vnd.google.note,为调用者显示一个新建便笺的界面,并将新建的便笺插入到便笺列表中(action为android.intent.action.INSERT)。
有了这两个功能,下面的Intent就会被解析到NoteEditor这个activity:

代码:

{ action=android.intent.action.VIEW data=content://com.google.provider.NotePad/notes/{ID}} :向用户显示标识为ID的便笺。

{ action=android.intent.action.EDIT data=content://com.google.provider.NotePad/notes/{ID}}:允许用户编辑标识为ID的便笺。

{ action=android.intent.action.INSERT data=content://com.google.provider.NotePad/notes }:在“content://com.google.provider.NotePad/notes”这个便笺列表中创建一个新的空便笺,并允许用 户编辑这个便签。当用户保存这个便笺后,这个新便笺的URI将会返回给调用者。

最后一个Activity 是com.google.android.notepad.TitleEditor,它允许用户编辑便笺的标题。它可以被实现为一个应用可以直接调用(在Intent中明确设置component属性)的类,不过这里我们将为你提供一个在现有的数据上发布可选操作的方法。 在这个Activity的唯一的intent-filter中,拥有一个私有的action: com.google.android.notepad.action.EDIT_TITLE,表明允许用户编辑便笺的标题。
和前面的view和edit动作一样,调用这个Intent 的时候,也必须指定具体的便笺(type为vnd.android.cursor.item/vnd.google.note)。不同的是,这里显示和编辑的只是便笺数据中的标题。 除了支持缺省类别(android.intent.category.DEFAULT),标题编辑器还支持另外两个标准类别: android.intent.category.ALTERNATIVE和 android.intent.category.SELECTED_ALTERNATIVE。实现了这两个类别之后,其它Activity就可以调用queryIntentActivityOptions(ComponentName,
Intent[], Intent, int)查询这个Activity提供的action,而不需要了解它的具体实现; 或者调用 addIntentOptions(int, int, ComponentName, Intent[], Intent, int, Menu.Item[])建立动态菜单。需要说明的是,在这个intent-filter中有一个明确的名称(通过android:label= "@string/resolve_title"指定),在用户浏览数据的时候,如果这个Activity是数据的一个可选操作,指定明确的名称可以为用户提供一个更好控制界面。
有了这个功能,下面的Intent就会被解析到TitleEditor这个Activity:
代码:
{ action=com.google.android.notepad.action.EDIT_TITLE data=content://com.google.provider.NotePad/notes/{ID}}:显示并且允许用户编辑标识为ID的便笺的标题。

可以毫不夸张地说:Intent是整个Android应用的脉络与灵魂 。

在一个Android 应用中,主要是由四种组件组成(Activities, Services, Broadcast receivers, Content providers),而这四种组件是独立的,它们之间可以互相调用,协调工作,最终组成一个真正的Android应用。在这些组件之间的通讯,主要是由Intent协助完成的。如果我们把Activity比作积木的话,那么Intent就是胶水,把不同的积木粘起来,构成我们搭建的房子(应用)。
Intent负责对应用中一次操作的动作及动作涉及数据 进行描述,Android则根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦控制。就像我们打电话到出租车公司叫计程车,而不是直接到街道上叫车,我们给出租车公司打电话,表明我们的意图(Intent),当服务员接到此意图,就依据我们的意图去挑选最合适的计程车,然后派遣它来接我们。
例如,在一个联系人 维护的应用中,当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上,点击某个联系人后,希望能够跳到此联系人的详细信息屏幕(假设对应的Activity为detailActivity)。为了实现这个目的,listActivity 需要构造一个Intent,这个Intent用于告诉系统,我们要做“查看”动作,此动作对应的查看对象是“某联系人”,然后调用startActivity (Intent intent),将构造的Intent传入,系统会根据此Intent中的描述,到AndroidManifest.xml中找到满足此Intent要求的Activity,系统会调用找到的Activity-detailActivity,最终传入Intent,detailActivity则会根据此Intent中的描述,执行相应的的操作。
一、抽象描述要描述什么

在Android参考文档 中,对Intent的定义是执行某操作的一个抽象描述。我们先来看看这里的抽象描述,到底描述了什么。
首先,是对要执行的动作(action)的一个简要描述,如 ACTION_ VIEW(查看)、 ACTION_ EDIT(修改)等,Android为我们定义了一套标准动作:

代码:

ACTION_MAIN
ACTION_VIEW
ACTION_ATTACH_DATA
ACTION_EDIT
ACTION_PICK
ACTION_CHOOSER
ACTION_GET_CONTENT
ACTION_DIAL
ACTION_CALL
ACTION_SEND
ACTION_SENDTO
ACTION_ANSWER
ACTION_INSERT
ACTION_DELETE
ACTION_RUN
ACTION_SYNC
ACTION_PICK_ACTIVITY
ACTION_SEARCH
ACTION_WEB_SEARCH
此外,我们还可以根据应用的需要,定义我们自己的动作,并可定义相应的Activity来处理我们的自定义动作。

其次,是执行动作要操作的数据(data),Android中采用指向数据的一个URI来表示,如在联系人应用中,一个指向某联系人的URI可能为:content://contacts/1。这种Uri表示,通过Uri这个类来描述,具体可以参考android.net.Uri类的文档。

以联系人应用为例,以下是一些action/data对,及其它们要表达的意图:

代码:
ACTION_VIEW content://contacts/people/1 -- 显示标识符为“1”的联系人的信息。

ACTION_DIAL content://contacts/people/1 -- 将标识符为“1”的联系人的号码显示在电话的拨号面板上。

ACTION_VIEW tel:123 -- 将号码123显示在电话的拨号面板上。 (与ACTION_DIAL有何区别?只说:Note how the VIEW action does what what is considered the most reasonable thing for a particular URI.)

ACTION_DIAL tel:123 -- 将号码123显示在电话的拨号面板上。

ACTION_EDIT content://contacts/people/1 --编辑标识符为“1”的联系人的信息。

ACTION_VIEW content://contacts/people/ -- 显示所有联系人的列表。

category (类别),是被执行动作的附加信息。例如 LAUNCHER_CATEGORY 表示 Inten t的接受者应该在 Launcher 中作为顶级应用出现;而 ALTERNATIVE_CATEGORY 表示当前的 Intent 是一系列的可选动作中的一个,这些动作可以在同一块数据上执行。
type (数据类型),显式指定 Intent 的数据类型( MIME )。一般 Intent 的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。
component (组件),指定 Intent 的的目标组件的类名称。通常 Android 会根据 Intent 中包含的其它属性的信息,比如 action 、 data/type 、 category 进行查找,最终找到一个与之匹配的目标组件。但是,如果 component 这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后, Intent 的其它所有属性都是可选的。
extras (附加信息),是其它所有附加信息的集合。使用 extras 可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在 extras 里,传给电子邮件发送组件。

      总之, action、data/type、category和extras 一起形成了一种语言。 这种语言使系统能够理解诸如“查看某联系人的详细信息”之类的短语。 随着应用不断的加入到系统中,它们可以添加新的action、 data/type、category来扩展这种语言。 应用也可以提供自己的Activity来处理已经存在的这样的“短语”,从而改变这些“短语”的行为。

二、 Android如何解析Intent

在应用中,我们可以以两种形式来使用Intent:

•直接Intent :指定了component属性的Intent(调用setComponent(ComponentName)或者setClass(Context, Class)来指定)。通过指定具体的组件类,通知应用启动对应的组件。
•间接Intent :没有指定comonent属性的Intent。这些Intent需要包含足够的信息,这样系统才能根据这些信息,在所有的可用组件中,确定满足此Intent的组件。
      对于直接Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些间接Intent,通过解析,将Intent映射给可以处理此Intent的Activity、Broadcaset receiver或Service。
     Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:

•如果Intent指明了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
•如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
•如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme(比如 http: 或者mailto:)进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
•如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。
三、应用例子
        以下,以Android SDK中的便笺例子来说明,Intent如何定义及如何被解析。这个应用可以让用户浏览便笺列表、查看每一个便笺的详细信息。

代码:

+ expand sourceview plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150<manifest xmlns:android="
http://schemas.android.com/apk/res/android
      package="com.android.notepad">  
    <application android:icon="@drawable/app_notes" 
            android:label="@string/app_name">  
        <provider class=".NotePadProvider" 
                android:authorities="com.google.provider.NotePad" />  
        <activity class=".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 class=".NoteEditor" 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" />  
                <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 class=".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> 
 <manifest xmlns:android="
http://schemas.android.com/apk/res/android"
       package="com.android.notepad">
     <application android:icon="@drawable/app_notes"
             android:label="@string/app_name">
         <provider class=".NotePadProvider"
                 android:authorities="com.google.provider.NotePad" />
         <activity class=".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 class=".NoteEditor" 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" />
                 <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 class=".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是com.google.android.notepad.NotesList,它是应用的主入口,提供了三个功能 ,分别由三个intent-filter进行描述:
        1、第一个是进入便笺应用的顶级入口(action为android.intent.action.MAIN)。类型为android.intent.category.LAUNCHER表明这个Activity将在Launcher中列出。
        2、第二个是,当type为vnd.android.cursor.dir/vnd.google.note(保存便笺记录的目录)时,可以查看编辑可用的便笺(action为android.intent.action.VIEW| android.intent.action.EDIT ),或者让用户选择一个便笺并返回给调用者(action为 android.intent.action.PICK)。
        3、第三个是,当type为vnd.android.cursor.item/vnd.google.note时,返回给调用者一个用户选择的便笺(action为android.intent.action.GET_CONTENT),而用户却不需要知道便笺从哪里读取的。有了这些功能,下面的Intent就会被解析到NotesList这个activity:

代码:

{ action=android.app.action.MAIN }:与此Intent匹配的Activity,将会被当作进入应用的顶级入口。

{ action=android.app .action.MAIN, category=android.app.category.LAUNCHER }:这是目前Launcher实际使用的 Intent,用于生成Launcher的顶级列表。

{ action=android.app.action.VIEW data=content://com.google.provider.NotePad/notes }:显示"content://com.google.provider.NotePad/notes"下的所有便笺的列表,使用者可以遍历列表,并且察看某便笺的详细信息。

{ action=android.app.action.PICK data=content://com.google.provider.NotePad/notes }:显示"content://com.google.provider.NotePad/notes"下的便笺列表,让用户可以在列表中选择一个,然后将选择的便笺的URL返回给调用者。

{ action=android.app.action.GET_CONTENT type=vnd.android.cursor.item/vnd.google.note }:和上面的action为pick的Intent类似,不同的是这个Intent允许调用者(在这里指要调用NotesList的某个 Activity)指定它们需要返回的数据类型,系统会根据这个数据类型查找合适的 Activity(在这里系统会找到NotesList这个Activity),供用户选择便笺。
第二个Activity 是com.google.android.notepad.NoteEditor,它为用户显示一条便笺,并且允许用户修改这个便笺。它定义了两个intent-filter,所以具有两个功能。
第一个功能是,当数据类型为 vnd.android.cursor.item/vnd.google.note时,允许用户查看和修改一个便签(action为 android.intent.action.VIEW和android.intent.action.EDIT)。
第二个功能是,当数据类型为 vnd.android.cursor.dir/vnd.google.note,为调用者显示一个新建便笺的界面,并将新建的便笺插入到便笺列表中(action为android.intent.action.INSERT)。
有了这两个功能,下面的Intent就会被解析到NoteEditor这个activity:

代码:

{ action=android.intent.action.VIEW data=content://com.google.provider.NotePad/notes/{ID}} :向用户显示标识为ID的便笺。

{ action=android.intent.action.EDIT data=content://com.google.provider.NotePad/notes/{ID}}:允许用户编辑标识为ID的便笺。

{ action=android.intent.action.INSERT data=content://com.google.provider.NotePad/notes }:在“content://com.google.provider.NotePad/notes”这个便笺列表中创建一个新的空便笺,并允许用 户编辑这个便签。当用户保存这个便笺后,这个新便笺的URI将会返回给调用者。

最后一个Activity 是com.google.android.notepad.TitleEditor,它允许用户编辑便笺的标题。它可以被实现为一个应用可以直接调用(在Intent中明确设置component属性)的类,不过这里我们将为你提供一个在现有的数据上发布可选操作的方法。 在这个Activity的唯一的intent-filter中,拥有一个私有的action: com.google.android.notepad.action.EDIT_TITLE,表明允许用户编辑便笺的标题。
和前面的view和edit动作一样,调用这个Intent 的时候,也必须指定具体的便笺(type为vnd.android.cursor.item/vnd.google.note)。不同的是,这里显示和编辑的只是便笺数据中的标题。 除了支持缺省类别(android.intent.category.DEFAULT),标题编辑器还支持另外两个标准类别: android.intent.category.ALTERNATIVE和 android.intent.category.SELECTED_ALTERNATIVE。实现了这两个类别之后,其它Activity就可以调用queryIntentActivityOptions(ComponentName,
Intent[], Intent, int)查询这个Activity提供的action,而不需要了解它的具体实现; 或者调用 addIntentOptions(int, int, ComponentName, Intent[], Intent, int, Menu.Item[])建立动态菜单。需要说明的是,在这个intent-filter中有一个明确的名称(通过android:label= "@string/resolve_title"指定),在用户浏览数据的时候,如果这个Activity是数据的一个可选操作,指定明确的名称可以为用户提供一个更好控制界面。
有了这个功能,下面的Intent就会被解析到TitleEditor这个Activity:
代码:
{ action=com.google.android.notepad.action.EDIT_TITLE data=content://com.google.provider.NotePad/notes/{ID}}:显示并且允许用户编辑标识为ID的便笺的标题。

抱歉!评论已关闭.