天天看點

Intents and Intent Filters概述

轉載請标注原文位址:http://blog.csdn.net/uranus_wm/article/details/10196777

 Intents and Intent Filters概述

Android應用三大核心元件-activities,services和broadcast receivers都是通過intents消息來驅動的。Intent是一種存在延時的動态綁定消息機制,可以在相同或不同應用間通訊。一個執行個體化的Intent消息,其資料結構包含了需要完成的操作的抽象描述,常在廣播情況下,描述了某件事情已經發生并且對外廣播。對于不同的元件有不同的intent發送機制。

  • 将intent對象傳給Context.startActivity() 或 Activity.startActivityForResult()來啟動一個activity. 使用 Activity.setResult()時傳遞傳入一個intent來從activity中傳回結果給調用startActivityForResult()的視窗。
  •  将intent對象傳給Context.startService()來初始化service或者發送intent指令給service。同樣,可以通過傳給Context.bindService()一個intent來建立用戶端與服務之間的連接配接。并可選是否啟動服務。
  • 通過Context.sendBroadcast(),Context.sendOrderedBroadcast(), 或者 Context.sendStickyBroadcast()發送intent,該intent會被發送給所有感興趣的廣播接收者。源碼中有很多廣播存在。

不管哪種情況,Android系統會尋找最合适的activitiy,service或者broadcast receivers來響應intent,如有必要還會對相應目标執行個體化。Intent消息系統在各元件間沒有重疊,就broadcast intent隻會發送給broadcast receiver,絕不會發給activity或者services。而startActivity()中帶的intent隻會發送給activity,也絕不會發送給broadcast receiver。

這篇文章從intent對象開始說起,然後說明Android如果将intent發送給對應的元件—如何解決哪個元件應該接受目前intent。對intent來說并沒有明确指定目标元件的名字,這個過程涉及判斷intent對象與潛在目标元件的intent filters是否比對的問題。

Intent 對象

________________________________________

一個Intent對象是一組資訊的集合。包含目标元件感興趣的資訊(例如要執行的動作和資料)加上Android系統感興趣的資訊(例如哪類元件應該接受該intent或者打開目标視窗的指令)。主要來說包括如下:

元件名稱(Component name)

能夠處理目前intent的元件名稱是一個ComponentName對象—包含兩段資訊:一個完全合格的目标元件的類名(例如"com.example.project.app.FreneticActivity")加上相應應用manifest檔案中的包名稱(例如"com.example.project")。包名部分是不要求完全比對的。

元件名稱項是可選的,如果設定了,Intent對象會發送給特定的元件。如果沒有設定,Android會通過Intent對象中的其他資訊來确定誰是合适的接收者—請看後面Intent Resolution部分介紹。

元件名稱通過setComponent(), setClass(), 或者 setClassName()設定,通過getComponent()方法讀取。

Action

需要完成的動作(action)由一個字元串表示—在廣播中被發送的intent也是這樣。Intent類中定義了一系列的action類,包括如下:

Intents and Intent Filters概述

可以參考Intent類内部一系列預定義的通用actions的描述。其他的actions定義在各個Android API中。你也可以定義自己的action字元串用來驅動你自己的應用部分元件。你自己發明的action需要包含包名作為字首—例如:"com.example.project.SHOW_COLOR"。

Action域(屬性)極大地影響了intent其他域(屬性)的結構化—特别是data域和extras域—就像方法名稱決定了參數和傳回值一樣。是以,建議action名稱盡可能具體化,使得它和intent其他域耦合度高。換句話說,不要定義一些不相關看不明白的名稱。然後在元件内部定義完整的intent處理方法。

Intent對象action域通過setAction()方法設定,通過getAction()方法讀取。

Data

Data包括資料的URI和資料的MIME類型。不同的action對應有不同類型的data規範。例如:如果action域為ACTION_EDIT,則data域包含需要顯示編輯文檔的URI。如果action為ACTION_CALL, 則data域為tel:URI,URI為被呼叫的電話号碼。如果action為ACTION_VIEW則data域為http:URI,被請求到的接收視窗會根據URI指定的位址下載下傳内容并顯示。

在比對intent資料域的時候,通常要考慮資料域中URI的資料類型(MIME type)。例如,一個圖檔浏覽器不能響應音頻檔案播放這樣請求。(action都為PLAY)

多數情況下,資料類型可以通過URI推斷出來—尤其是content: URIs這種表示資料存儲在裝置本地,并有content provider管理(參考 separate discussion on content providers)。但資料類型也能在intent對象中明确指定。setData()方法用于設定URI,setType()方法用于設定MIME類型,setDataAndType()既可設定URI也可設定MIME類型,getData()用于讀取URI,getType()讀取MIME類型。

Category

Intent内部還有一個字元串稱作Category,作為附加資訊用于元件的比對。任意多個category Intent對象中可以放置任意多個category類型說明。和action一樣,Intent類内部預定義了多個category常量,包括:

Intents and Intent Filters概述

請參考Intent類内對所有categories的描述。

addCategory()方法用于在Intent内部設定category,removeCategory()用于删除先前添加的category,而getCategories()用于擷取目前Intent中所有設定的category。

Extras

Extras以key-value鍵值對的形式作為附加資訊被傳送給潛在的Intent處理元件。就像某些actions配備了某些特定類型的資料的URIs,某些actions也配備了特定的extras附加字段。舉例:intent ACTION_TIMEZONE_CHANGED有一個"time-zone"的附加字段用于表示新的時區,而ACTION_HEADSET_PLUG有一個"name"附加字段耳機的類型。如果你創造了一個SHOW_COLOR的action,則應該設定一個"value"附加字段作為顔色值的表示。

Intent對象有一系列put...()方法用于插入各種類型的附加資料,也有一系列對應的的get...()方法用于讀取資料。這些方法傳遞的資料可以通過Bundle 合并為一個對象。實際上我們可以通過putExtras() 和 getExtras()方法合并附加資料的安裝和讀取。

Flags

各種類型的Flag,主要用于輔助告知Android系統如何選中一個activity(例如,這個activity應該屬于哪個任務)以及當它被打開後如何處理它(例如,這個activity是否應屬于最近打開的activities清單)。所有flag都定義在Intent類中。

Intent Resolution

________________________________________

Intent可以被分成兩個群體:

  •  一類明确,顯示的指定了目标元件的名稱(component name有被指派)。由于開發者通常不知道其他應用中的元件名稱,顯示intent通常用于應用程式内部消息通訊—例如打開一個從屬的service或者打開一個姐妹activity。
  • 一類隐式,含蓄的并未指定目标元件名稱(component name字段為空)。隐式intent通常用于激活不同應用中的元件。

Android發送一個顯示intent給一個指定的目标。除了component name,intent其他域都和比對目标元件不相關。

隐式intent必須要有其他政策。在缺少目标元件名稱情況下,Andriod系統必然要尋找最合适的目标來處理intent。通過intent和潛在元件關聯的intent filter作比較。過濾器filter聲明了元件可以處理的intent能力,同時限定了它可處理的intent。然後系統會打開隐式比對成功的元件。如果一個元件沒有聲明任何intent filter,那麼它隻能被顯示方式打開。具有intent filter的元件既可被隐式打開也可被顯示打開。Intent對象中隻有action,data(包括URI和type)和category三個對象參與和intent filter的比對測試。Extras和flags不參加比對測試。

Intent filters

用于告知系統能處理哪些隐式的intent。Activities,services和broadcast receivers都可以有多個intent filter。每一個intent filter都描述了元件擁有的一種能力。實際中,過濾器隻過濾那些不必要的隐含意圖。顯示意圖總是直接發給目标,不管intent其他域包含什麼;過濾器甚至不被咨詢。隐式intent隻有在過濾器比對通過後才會發給元件。

一個元件有多個獨立的filter,呈現給使用者其種功能。例如,事例應用程式Note Pad的NoteEditor視窗有兩個過濾器—一個用于啟動時呈現給使用者一個指定的通知,另一個用于啟動一個空的note給使用者編輯,儲存。(Note Pad的所有過濾器在後面的Note Pad Example中有描述)

Filters and security

不能依賴過濾器起到安全保護作用,雖然過濾器可以過濾掉非特定類型的隐式調用,但是對于顯示調用不起作用,某些人可以用顯示方法指定元件名稱,然後加上不同的action和data源。

過濾器是IntentFilter類的執行個體。然而,由于Android系統必須在元件被打開之前就知道元件的能力,但過濾器通常不在java源碼中,其作為<intent-filter>元素位于應用程式的manifest檔案中(AndroidManifest.xml)。(這些被broadcast receivers使用到的元素會通過Context.registerReceiver()方法動态注冊,然後直接被建立成IntentFilter對象)

過濾器針對Intent對象也有action,data和category三個字段。一個隐式intent必須要者三個字段完全測試比對才能通過。有一個不成功,Android系統都不會将該intent發給元件。當然一個元件可以有多個過濾器,一個不通過,也許另一個可以通過。

三個字段的比對測試描述如下:

Action test

如下manifest檔案中列出了多個<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字段,過濾器可以有多個action。過濾器内部不能為空,至少要有一個 <action>元素,否則将會阻止所有的intent。

要測試通過,Intent内部的action必須要和過濾器中列出的一個action比對。如果intent或者過濾器有一個沒有指定任何action,有兩種情況:

  • 過濾器沒有聲明action,沒有任何intent能通過比對,所有的intent都不會通過。
  • 另方面,intent對象沒有指定任何action,這時卻可以通過測試—隻要過濾器至少包含一個action。

Category test

如下manifest檔案中列出了多個categories子元素:

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

請注意manifest中聲明action和category時使用的是完整字元串,而不是前面描述的字元串常量。例如例子中"android.intent.category.BROWSABLE"對應的CATEGORY_BROWSABLE,字元串"android.intent.action.EDIT"對應的ACTION_EDIT。

Intent要通過category測試,其内部添加的每一個category都必須和一個filter中聲明的category比對。Filter可以有多餘的category,但是intent中的category一個也不能漏過。

原則上如果intent不包含任何category,則總能通過category測試,不用考慮filter的情況。大多情況下這種說法是對的,但有一種情況例外:Android允許通過隐式intent調用startActivity()方法時,該intent至少要包含一個category:"android.intent.category.DEFAULT" (常量定義為CATEGORY_DEFAULT )。于是,希望能被隐式調用的activity必須在intent filter中包含聲明"android.intent.category.DEFAULT"。(聲明包含"android.intent.action.MAIN"和"android.intent.category.LAUNCHER"的過濾器除外。他們表明視窗會在新任務中打開和視窗會在launcher中呈現出來。他們已經包含了"android.intent.category.DEFAULT"的定義,是以不需要重複寫出。)看後面的Using intent matching有更多過濾器的介紹。

Data test

和action和category一樣,data也作為子元素在過濾器中被列出。而且,data子元素可以出現多個,也可以一個也沒有。舉例如下:

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

每一個data可以指定一個URI位址和一個資料類型(MIME類型)。URI包括scheme, host, port, 和path各個獨立字段。

scheme://host:port/path
           

舉例:如下 URI,

content://com.example.project:200/folder/subfolder/etc
           

scheme字段是"content", host是 "com.example.project", port 字段是"200", path字段是"folder/subfolder/etc". host和port共同構成了URI認證位址,如果隻有port沒有host是沒用的。

這些屬性字段都是可選的,但他們之間并不是獨立的:要認證位址有效,scheme字段就必須指定。要path路徑有效,scheme和認證位址(host,port)都必須指定。

當Intent和過濾器中的URI做比對上,系統僅比對過濾器中提到的部分,如果一個過濾器隻指定了scheme,所有scheme比對的URI都可以比對通過。如果一個filter指定了scheme和認證位址,沒有指定path路徑,則所有scheme和認知位址相同的URI可以比對通過,不考慮path路徑。如果filter指定了schme,authori(認證位址)和path,則必須進行URI全比對。當然path字段内部可以使用通配符來要求隻做部分比對。

<data>字段的type屬性指定data為某種MIME類型。在fitler中它比URI更常見。Intent對象和過濾器裡面都可以使用通配符"*"來指定子類型—例如"text/*" 或者"audio/*"表明任意子類型都可以比對。

Data測試包含URI和資料類型測試。規則如下:

a. 既沒有URI也沒有data type的Intent能通過測試當且僅當過濾器也沒有指定任何URI和data types

b. Inten指定URI但沒有data type(且type類型不能由URI推斷出)能通過測試當且僅當過濾器同樣也沒有指定type字段.舉例URIs為mailto: 或者 tel:沒有指定任何資料.

c. Intent有data type字段但沒有URI字段能通過測試當切僅當過濾器列出了同樣的資料類型并且同樣沒有指定URI。

d. Intent既有URI字段又有data type字段(或者data type可由URI推斷出來)能通過測試當且僅當a)data type能與過濾器中的type清單比對上b)URI部分也能完全比對或者intent聲明了content: 或者 file:這樣的URI,而過濾器沒有指定URI。換句話說,元件隻指定了data type則被認為支援content: 和 file:兩種形式的資料。

如果一個intent能通過多個activity或service比對,則系統會詢問使用者打開哪個元件。如果沒有目标元件被比對找到,則會産生一個異常。

通常情況

上面最後關于資料比對測試的規則,規則(d)提到元件能夠從本地檔案或content provider中擷取資料。于是,過濾器可以隻列出data type字段而不明确指定scheme字段為content: 或者 file。這是一個典型的情況。下面的例子中的<data>元素告訴Android系統該元件可以打開content provider中的image資料并顯示出來。

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

由于大多數有效資料由content providers配置設定提供,過濾器隻指定data type字段而沒有URI字段也許是通用做法。

另外一種通用配置是過濾器隻包含scheme和data type。例如下面例子中<data>元素告訴系統改元件能夠從網路上擷取video類型的資料并播放。

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

考慮一下這個例子,當使用者在網頁上點選一個連結時,浏覽器做了什麼?首先是嘗試去顯示頁面資料(如果這個連結指向一個HTML頁面)。如果它不能直接顯示該類型資料,它會發送一個隐式intent,包含scheme和data type啟動一個activity來完成這個工作。如果沒人接招,浏覽器會要求下載下傳管理器把資料下載下傳下來儲存在content provider裡面,然後就會有大量潛在的activity(那些過濾器隻有名稱和data type字段的)可以響應這個請求。

大多數應用程式不需要指定資料就可以啟動運作。Activity可以作為一個應用程式的初始視窗,通過在過濾器中添加"android.intent.action.MAIN"到action。如果應用可以呈現在launcher中,則也可以添加"android.intent.category.LAUNCHER"到action中。

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

使用Intent比對(Using intent matching)

通過Intent比對不光是找到一個目标元件去激活,也可以是一個元件集合。例如Android系統中的launcher應用,啟動後顯示給使用者的最上一層視窗,它要找到所有的過濾器包含"android.intent.action.MAIN" action 和 "android.intent.category.LAUNCHER" category的activity。然後在launcher中把圖示和标簽字段顯示出來。類似的它還要為首頁面視窗尋找所有過濾器包含"android.intent.category.HOME"的activity。

你的應用程式可以用類似的方式做intent比對。PackageManager提供了一系列query...()方法用于查詢接受了指定的intent的所有元件。類似還有一系列resolve...()方法用于幫助判定最合适的接收元件。例如queryIntentActivities()傳回所有比對通過的activity清單,而queryIntentServices()傳回類似的Services清單。這兩個方法都不激活(打開)元件,他們隻是列出所有的響應者。對于broadcast receivers有一個類似的方法queryBroadcastReceivers()。

NotePad的例子(Note Pad Example)

________________________________________

示例應用程式Note Pad提供了使用者浏覽一個note筆記清單,檢視清單中每條note的詳情,編輯note。這一段我們先看他manifest檔案的聲明。(在<sdk>/samples/NotePad/index.html中你可以找到這個例子。網站上源碼檔案位于Tutorials and Sample Code章節中)

在這個manifest中申明了三個activity視窗,每一個至少包含一個intent filter過濾器。還聲明了一個content provider來管理note筆記的資料。下面是源檔案定義:

<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>
           
Intents and Intent Filters概述

 第一個activity,NotesList和其他視窗不同,它操作的是note目錄(note清單)而不是單一一條note記錄。它通常會作為應用的初始接口。它有三個過濾器表明它能完成三件事情。

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

這個過濾器為應用程式聲明了主入口。Action中MAIN值表明該activity是主入口,這時不需要Intent中的其他資訊(例如資料),category中的LAUNCHER值表明這個應用應該列在launcher應用中。

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

這個filter聲明該activity可以對一個note目錄進行操作。同時它允許使用者對目錄進行檢視和編輯(通過action VIEW和EDIT的聲明),還允許使用者從目錄中挑選一條note記錄(通過action PICK聲明)

<data>的mimeType 屬性字段指定了這個action可以操作的資料類型。它顯示該activity可以從管理Note Pad資料(vnd.google.note)的content provider那裡獲得一個包含0條或多條資料的Cursor遊标。能夠激活這個視窗的Intent應該包含content:URI這樣形式的data,其中URI指明了這種類型的資料要求被打開。

注意這個filter也指明了category為DEFAULT 。因為Context.startActivity() 和Activity.startActivityForResult()兩個方法預設為所有的intent都包含DEFAULT category這個屬性--隻有兩種例外:顯示指定activity名稱的intent和包含action為MAIN和category為LAUNCHER的intent。除此之外基本所有的過濾器基本都需要聲明category為DEFAULT。

<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這個action和前面提到的PICK這個action有點類似。兩種情況下,activity都會傳回使用者選擇的item的URI。(資料傳回給通過startActivityForResult()方法調用NoteList的activity。)這裡,調用者隻需指定所需資料的類型而不是所需資料的目錄路徑。

資料類型vnd.android.cursor.item/vnd.google.note訓示了activity可以傳回的資料類型—一個URI針對每一條note。從這個傳回的RUI,調用者可以從content provider(管理vnd.google.note資料)得到一個确切的item(vnd.android.cursor.item)的遊标。換句話說,對于前面過濾器中的PICK action,data type字段表明視窗可以顯示給使用者的資料類型。而對于GET_CONTENT這個過濾器,data type字段表明使用者可以拿到的資料類型。

給出這些能力聲明後,下面的intent會被NotesList這個activity解析到:

action: android.intent.action.MAIN
           

打開這個activity沒有附帶任何資料

action: android.intent.action.MAIN 
category: android.intent.category.LAUNCHER
           

打開這個視窗無任何附帶資料。這是Launcher應用的實際用到的例子,用于查找所有的頂級視窗清單。

action: android.intent.action.VIEW 
data: content://com.google.provider.NotePad/notes
           

要求activity清單形式顯示content://com.google.provider.NotePad/notes裡面所有的notes。然後使用者可以浏覽并取得item資訊。

action: android.intent.action.PICK 
data: content://com.google.provider.NotePad/notes
           

要求activity顯示content://com.google.provider.NotePad/notes裡面的一個note清單,然後使用者可以從清單中選中一條記錄,那條記錄對應的URI會傳回給原來的調用視窗。

action: android.intent.action.GET_CONTENT 
data type: vnd.android.cursor.item/vnd.google.note
           

要求activity提供一條Note Pad資料記錄。

第二個視窗NoteEditor展示給使用者單條記錄并允許使用者編輯。從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能夠讓使用者檢視,編輯單條記錄。(EDIT_NOTE 是EDIT的代名詞。)請求intent需要包含一個URI比對MIME類型vnd.android.cursor.item/vnd.google.note。通常就是從NoteList activity中通過PICK 或者 GET_CONTENT傳回得到的URI。

這個filter包含一個DEFAULT屬性,說明這個視窗可以被隐式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>
           

這個視窗第二個功能是允許使用者建立一條記錄插入到目前目錄中。請求intent需要包含一個URI比對MIME類型vnd.android.cursor.dir/vnd.google.note--該URI告訴該視窗該記錄該存在什麼位置。

給出這個功能聲明後,下面的intent對應可以通路NoteEditor activity:

action: android.intent.action.VIEW 
data: content://com.google.provider.NotePad/notes/ID
           

要求序列槽顯示指定ID的note記錄

action: android.intent.action.EDIT 
data: content://com.google.provider.NotePad/notes/ID
           

要求序列槽顯示指定ID的note記錄,并允許使用者編輯。如果儲存修改,則将修改資料儲存到content provider中。

action: android.intent.action.INSERT 
data: content://com.google.provider.NotePad/notes
           

要求視窗在content://com.google.provider.NotePad/notes建立一個新的空紀錄,并允許使用者編輯它,如果使用者儲存,傳回URI給調用者。

最後一個視窗TitleEditor允許使用者編輯note記錄的标題。這個視窗原本應該通過直接調用的方式實作(顯示調用),不需要指定filter。但在此我們借此機會展示如何對現有資料進行替換編輯操作。

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

這個視窗隻有一個filter,action為"com.android.notepad.action.EDIT_TITLE"。類似之前的VIEW 和EDIT action它隻能針對一條指定的記錄操作(資料類型vnd.android.cursor.item/vnd.google.note)。當然這個視窗顯示的是note記錄内部的标題資料,而不是note記錄本身。

另外該filter使用了DEFAULT屬性,還支援另外兩個标準categories:ALTERNATIVE 和SELECTED_ALTERNATIVE。這兩個屬性辨別視窗可以從option menu打開(類似LAUNCHER 屬性辨別視窗可以被放在launcher應用中一樣)。這個filter還提供了一個顯示的标簽(viaandroid:label="@string/resolve_title")當該視窗作為一個菜單操作呈現給使用者時,我猜測用來作為OptionMenu的菜單标題(更多的資訊請檢視

如下intent可以針對通路TitleEditor視窗:

action: com.android.notepad.action.EDIT_TITLE 
data: content://com.google.provider.NotePad/notes/ID
           

要求視窗顯示指定ID note的關聯标題,并允許使用者編輯标題。

繼續閱讀