允許其他應用程式啟動您的活動

如果您的應用程式可以執行有助於其他應用程式的動作,則應用程式應在活動中指定適當的意圖篩選器,以便回應動作要求。

舉例來說,假設您建立的社交應用程式可以與使用者的好友分享訊息或相片,則應支援 ACTION_SEND 意圖。這樣一來,當使用者透過其他應用程式啟動「分享」動作時,您的應用程式就會顯示為選擇器對話方塊 (又稱為「釐清差異對話方塊」) 當中的選項,如圖 1 所示。

圖 1. 選擇器對話方塊

如要允許其他應用程式以這種方式啟動您的活動,您必須在資訊清單檔案中為相應的 <activity> 元素新增 <intent-filter> 元素。

應用程式安裝在裝置上時,系統會找出您的意圖篩選器,然後將相關資訊加進所有已安裝應用程式所支援的內部意圖目錄。 當應用程式以隱含意圖呼叫 startActivity()startActivityForResult() 時,系統會找出可回應該意圖的一或多項活動。

新增意圖篩選器

為了正確定義活動可以處理的意圖,您新增的每個意圖篩選器都應盡可能詳細指定活動接受的動作和資料類型。

如果活動擁有的意圖篩選器符合 Intent 物件的下列條件,系統就會將特定 Intent 傳送至活動:

動作
為要執行的動作命名的字串,通常是平台定義的其中一個值,例如 ACTION_SENDACTION_VIEW

請在意圖篩選器中使用 <action> 元素指定此條件。 您在此元素中指定的值必須是動作的完整字串名稱,而非 API 常數 (請參閱下方範例)。

資料
與意圖相關的資料說明。

請在意圖篩選器中使用 <data> 元素指定此條件。透過這個元素中的一或多個屬性,您可以單單指定 MIME 類型、URI 前置字元、URI 配置,或者同時指定這些屬性與其他代表可接受資料類型的屬性。

注意:如果不需要宣告 Uri 資料的相關細節 (例如,在活動會處理其他類型的「額外」資料而不是 URI 的情況下),請僅指定 android:mimeType 屬性,以宣告活動處理的資料類型 (例如 text/plainimage/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_SENDACTION_SENDTO 意圖的文字和圖片。在這種情況下,您必須針對這兩項動作定義兩個不同的意圖篩選器,因為 ACTION_SENDTO 意圖必須使用 Uri 的資料來指定使用 sendsendto 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_OKRESULT_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() 的結果傳送給原始活動;否則系統會忽略這個結果。