Table of contents


Intents是Android應用程式內部或應用程式與應用程式間溝通的一個機制。你可以簡單把Intents的視為是一種事件處理系統。

Intents的使用可分顯式啟動或隱式啟動,當一個隱式的Intent啟動時,Intent可以不知道會由誰來處理這個Intent,一般都是由系統決定什麼樣的Intent會由那一個Component處理。這樣可以達到應用上的解耦。 讓不同程式的Activity可以交互使用。例如,如果客製的程式需要一個發mail的功能,你可以直接使用系統現有的mail功能(含mail的UI),不用自已再重寫一個mail activity.

Intent可以包含以下內容:

  1. Component name : 要處理Intent的元件名稱,選擇性的屬性,如果有設定,就會由該元件處理這個intent,元件名稱是像這樣的格式: com.example.project.app.FreneticActivity
  2. Action : 執行什麼樣的動作
  3. Data : content uri
  4. Type : MIME type,用來識別資料型別
  5. Category : action category
  6. Extras : intent間溝通用的容器(Key-Value pair)
  7. Flags

典型的Intent的使用方式如下:

Intent intent = new Intent(MyActivity.this, MyOtherActivity.class);
startActivity(intent);

startActivity(intent);被呼叫時,新的Activity(MyOtherActivity.class)會被帶到目前(MyActivity)的上面。

component設定可透過以下幾種方式

  1. setComponent(String name)
  2. setClass(Class cls)
  3. 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的結果

  1. action
  2. data (both URI and data type)
  3. 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 actionLAUNCHER category外的activity 都應該要設定DEFAULT category