如果您的應用程式可以執行有助於其他應用程式的動作,那麼您應在活動中指定適當的意圖篩選器,以備應用程式回應動作要求。
舉例來說,假設您建立的社交應用程式可以與使用者的好友分享訊息或相片,請支援 ACTION_SEND
意圖。這樣一來,當使用者透過其他應用程式開始執行「分享」動作時,您的應用程式就會顯示為選擇器對話方塊 (又稱為「釐清差異對話方塊」) 當中的選項,如圖 1 所示。
如要讓其他應用程式以此方式啟動活動,您需要在資訊清單檔案中為相應的 <activity>
元素新增 <intent-filter>
元素。
應用程式安裝在裝置上時,系統會找出您的意圖篩選器,然後將相關資訊加進所有已安裝應用程式所支援的內部意圖目錄。
當應用程式以隱含意圖呼叫 startActivity()
或 startActivityForResult()
時,系統會檢查可回應該意圖的活動。
新增意圖篩選器
為了正確定義活動可以處理的意圖,您新增的每個意圖篩選器都要盡可能詳細指定活動接受的動作和資料類型。
如果活動擁有的意圖篩選器符合 Intent
物件的下列條件,系統可能會將特定 Intent
傳送至活動:
- 動作
- 為要執行的動作命名的字串,通常是平台定義的其中一個值,例如
ACTION_SEND
或ACTION_VIEW
。請在意圖篩選器中使用
<action>
元素指定此條件。 您在此元素中指定的值必須是動作的完整字串名稱,而非 API 常數 (如本頁範例所示)。 - 資料
- 與意圖相關的資料說明。
請在意圖篩選器中使用
<data>
元素指定此條件。透過這個元素中的一或多個屬性,您可以指定 MIME 類型、URI 前置字元、URI 配置,或者同時指定這些屬性與其他代表可接受資料類型的屬性。注意:如果不需要宣告資料的特定
Uri
,例如活動處理代碼時 另一種「額外」類型資料,而非 URI,請只指定android:mimeType
屬性來宣告 活動資料,例如text/plain
或image/jpeg
。 - 類別
- 提供另一種方式來說明處理意圖的活動特徵,通常與啟動該活動的使用者手勢或位置有關。系統支援幾種不同的類別,但多數很少使用。不過,所有隱含意圖均預設以
CATEGORY_DEFAULT
定義。請在意圖篩選器中使用
<category>
元素指定此條件。
在意圖篩選器中,您可以利用 <intent-filter>
元素中相應的巢狀 XML 元素,逐一宣告活動接受哪些條件。
舉例來說,以下活動的意圖篩選器會在資料類型為文字或圖片時處理 ACTION_SEND
意圖:
<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> </activity>
提示:如果您希望在選擇器對話方塊中顯示不同於活動預設的圖示,請在 <intent-filter>
元素中加入 android:icon
。
每個傳入的意圖只能指定一個動作和一種資料類型,但每個 <intent-filter>
都可以宣告多個 <action>
、<category>
和 <data>
的例項。
如有任兩對動作與資料搭配時所表現的行為彼此互斥,請建立不同的意圖篩選器,以指定搭配哪些資料類型時可接受哪些動作。
舉例來說,假設活動會同時處理 ACTION_SEND
和 ACTION_SENDTO
意圖的文字和圖片。在這種情況下,您必須針對這兩項動作定義兩個不同的意圖篩選器,因為 ACTION_SENDTO
意圖必須使用 Uri
的資料來指定使用 send
或 sendto
URI 配置的收件者地址。例如:
<activity android:name="ShareActivity"> <!-- Filter for sending text; accepts SENDTO action with sms URI schemes --> <intent-filter> <action android:name="android.intent.action.SENDTO"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="sms" /> <data android:scheme="smsto" /> </intent-filter> <!-- Filter for sending text or images; accepts SEND action and text or image data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="image/*"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
注意:如要接收隱含意圖,您必須在意圖篩選器中加入 CATEGORY_DEFAULT
類別。startActivity()
和 startActivityForResult()
方法會將所有意圖視為宣告 CATEGORY_DEFAULT
類別。如果您未在意圖篩選器中完成宣告,系統就不會將任何隱含意圖解析至您的活動。
如要進一步瞭解如何傳送及接收執行社群媒體分享行為的 ACTION_SEND
意圖,請參閱「接收其他應用程式傳送的簡單資料」。您也可以參閱「分享簡單資料」和「分享檔案」這兩篇文章,取得有關如何分享資料的實用資訊。
處理活動中的意圖
如要決定活動要採取哪些動作,請參考用於啟動活動的 Intent
。
只要在活動啟動時呼叫 getIntent()
,即可擷取用於啟動活動的 Intent
。在活動的生命週期中,您隨時可以這麼做,但一般做法是在早期回呼 (例如 onCreate()
或 onStart()
) 進行這項操作。
例如:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) val data: Uri? = intent?.data // Figure out what to do based on the intent type if (intent?.type?.startsWith("image/") == true) { // Handle intents with image data } else if (intent?.type == "text/plain") { // Handle intents with text } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get the intent that started this activity Intent intent = getIntent(); Uri data = intent.getData(); // Figure out what to do based on the intent type if (intent.getType().indexOf("image/") != -1) { // Handle intents with image data } else if (intent.getType().equals("text/plain")) { // Handle intents with text } }
傳回結果
如果您想將結果傳回叫用您活動的活動,只要呼叫 setResult()
即可指定結果代碼和 Intent
結果。作業執行完畢且使用者返回原始活動後,請呼叫 finish()
來關閉並刪除活動,例如:
Kotlin
// Create intent to deliver some kind of result data Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result -> setResult(Activity.RESULT_OK, result) } finish()
Java
// Create intent to deliver some kind of result data Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")); setResult(Activity.RESULT_OK, result); finish();
您一律必須與結果同時指定結果代碼,這個代碼通常是 RESULT_OK
或 RESULT_CANCELED
。如有需要,您可以透過 Intent
提供其他資料。
注意:結果已預設為 RESULT_CANCELED
。因此,如果使用者在動作完成或您設定結果前輕觸「返回」按鈕,原始活動就會收到「已取消」結果。
如果只想傳回代表數個結果選項之一的整數,則可將結果代碼設為大於 0 的任何值。如果您使用結果代碼傳送整數且不需要加入 Intent
,則可呼叫 setResult()
並僅傳遞結果代碼。
Kotlin
setResult(RESULT_COLOR_RED) finish()
Java
setResult(RESULT_COLOR_RED); finish();
在這種情況下,也許只有少數幾個可能的結果,因此結果代碼是本機定義的整數 (大於 0)。當您將結果傳回到自家應用程式中的活動時,這項功能非常實用,原因是接收結果的活動可以參照公用常數來判定結果代碼的值。
注意:您不需要檢查活動是透過 startActivity()
還是 startActivityForResult()
啟動。如果啟動活動的意圖可能會預期收到結果,只要呼叫 setResult()
即可。如果原始活動已呼叫 startActivityForResult()
,系統會將您提供給 setResult()
的結果傳送給原始活動;否則系統會忽略這個結果。