Intents and Intent Filters
Table of contents
Intents是Android應用程式內部或應用程式與應用程式間溝通的一個機制。你可以簡單把Intents的視為是一種事件處理系統。
Intents的使用可分顯式啟動或隱式啟動,當一個隱式的Intent啟動時,Intent可以不知道會由誰來處理這個Intent,一般都是由系統決定什麼樣的Intent會由那一個Component處理。這樣可以達到應用上的解耦。 讓不同程式的Activity可以交互使用。例如,如果客製的程式需要一個發mail的功能,你可以直接使用系統現有的mail功能(含mail的UI),不用自已再重寫一個mail activity.
Intent可以包含以下內容:
- Component name : 要處理Intent的元件名稱,選擇性的屬性,如果有設定,就會由該元件處理這個intent,元件名稱是像這樣的格式: com.example.project.app.FreneticActivity
- Action : 執行什麼樣的動作
- Data : content uri
- Type : MIME type,用來識別資料型別
- Category : action category
- Extras : intent間溝通用的容器(Key-Value pair)
- Flags
典型的Intent的使用方式如下:
Intent intent = new Intent(MyActivity.this, MyOtherActivity.class);
startActivity(intent);
當startActivity(intent);
被呼叫時,新的Activity(MyOtherActivity.class)會被帶到目前(MyActivity)的上面。
component設定可透過以下幾種方式
- setComponent(String name)
- setClass(Class cls)
- setClassName(String name)
setClass因為對重構比基於字串為主的另外幾個method友善,所以,通常都用這個。
典型的隱式呼叫(適合用在跟其他app溝通):
private static final int PICK_CONTACT_SUBACTIVITY = 2;
Uri uri = Uri.parse("content://contacts/people");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(intent, PICK_CONTACT_SUBACTIVITY);
跟顯式呼叫的差別在,intent認的是事件的代碼,而不是activity本身。
Action Name的名稱為
<your-package-name >.intent.action.YOUR_ACTION_NAME
Intent filters
Intent filters是activities, services, and broadcast receivers用來過濾隱式intent的機制,只有intent有指定component name就會直接送到該compnent處理(顯式),不受intent filter的管理。 而如果沒有指定component name(隱式),就得看是否有通過附加在元件(activities, services, and broadcast receivers)上的intent filter的測試。 Intent裡的只有以下三個屬性會被intent filter拿來做測試用的條件,其他的不會影響intent filter的結果
- action
- data (both URI and data type)
- category
這三個測試條件要完全通過,元件才會處理該intent,只有一個不符合,就算測試失敗,一般應用上,如果會擔心無法接收到想處理的intent,可以設定多個intent filters來處理。
<intent-filter>
tag至少要包含action,如果<intent-filter>
是空的tag,那會收到所有的intent
如果三個都是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>
如果兩者都是category,只有符合其中一個就通過,或者,如果intent本身沒設定任何category,也會通過測試
<intent-filter . . . >
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
. . .
</intent-filter>
Context.startActivity() 及 Activity.startActivityForResult()需要有DEFAULT category(android.intent.category.DEFAULT)的intent filter才能接收得到,所以除了MAIN action跟LAUNCHER category外的activity 都應該要設定DEFAULT category