Android的Intent過濾

2018-08-02 17:27 更新

編寫:kesenhoo - 原文:http://developer.android.com/training/basics/intents/filters.html

前兩節(jié)課主要講了從一個(gè)app啟動另外一個(gè)app。但如果我們的app的功能對別的app也有用,那么其應(yīng)該做好響應(yīng)的準(zhǔn)備。例如,如果創(chuàng)建了一個(gè)social app,它可以分享messages 或者 photos 給好友,那么最好我們的app能夠接收ACTION_SEND 的intent,這樣當(dāng)用戶在其他app觸發(fā)分享功能的時(shí)候,我們的app能夠出現(xiàn)在待選對話框。

通過在manifest文件中的<activity>標(biāo)簽下添加<intent-filter>的屬性,使其他的app能夠啟動我們的activity。

當(dāng)app被安裝到設(shè)備上時(shí),系統(tǒng)可以識別intent filter并把這些信息記錄下來。當(dāng)其他app使用implicit intent執(zhí)行 startActivity() 或者 startActivityForResult()時(shí),系統(tǒng)會自動查找出那些可以響應(yīng)該intent的activity。

添加Intent Filter

為了盡可能確切的定義activity能夠handle的intent,每一個(gè)intent filter都應(yīng)該盡可能詳盡的定義好action與data。

若activity中的intent filter滿足以下intent對象的標(biāo)準(zhǔn),系統(tǒng)就能夠把特定的intent發(fā)送給activity:

  • Action:一個(gè)想要執(zhí)行的動作的名稱。通常是系統(tǒng)已經(jīng)定義好的值,如ACTION_SENDACTION_VIEW。 在intent filter中通過<action>指定它的值,值的類型必須為字符串,而不是API中的常量(看下面的例子)

  • Data:Intent附帶數(shù)據(jù)的描述。在intent filter中通過<data>指定它的值,可以使用一個(gè)或者多個(gè)屬性,我們可以只定義MIME type或者是只指定URI prefix,也可以只定義一個(gè)URI scheme,或者是他們綜合使用。

Note: 如果不想handle Uri 類型的數(shù)據(jù),那么應(yīng)該指定 android:mimeType 屬性。例如 text/plain or image/jpeg.

  • Category:提供一個(gè)附加的方法來標(biāo)識這個(gè)activity能夠handle的intent。通常與用戶的手勢或者是啟動位置有關(guān)。系統(tǒng)有支持幾種不同的categories,但是大多數(shù)都很少用到。而且,所有的implicit intents都默認(rèn)是 CATEGORY_DEFAULT 類型的。在intent filter中用<category>指定它的值。

在我們的intent filter中,可以在<intent-filter>元素中定義對應(yīng)的XML元素來聲明我們的activity使用何種標(biāo)準(zhǔn)。

例如,這個(gè)有intent filter的activity,當(dāng)數(shù)據(jù)類型為文本或圖像時(shí)會處理ACTION_SEND的intent。

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

每一個(gè)發(fā)送出來的intent只會包含一個(gè)action與data類型,但handle這個(gè)intent的activity的 <intent-filter>可以聲明多個(gè)<action><category><data> 。

如果任何的兩對action與data是互相矛盾的,就應(yīng)該創(chuàng)建不同的intent filter來指定特定的action與type。

例如,假設(shè)我們的activity可以handle 文本與圖片,無論是ACTION_SEND還是ACTION_SENDTO 的intent。在這種情況下,就必須為兩個(gè)action定義兩個(gè)不同的intent filter。因?yàn)?code>ACTION_SENDTO intent 必須使用 Uri 類型來指定接收者使用 send 或 sendto 的地址。例如:

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

Note:為了接受implicit intents, 必須在我們的intent filter中包含 CATEGORY_DEFAULT 的category。startActivity()和startActivityForResult()方法將所有intent視為聲明了CATEGORY_DEFAULT category。如果沒有在的intent filter中聲明CATEGORY_DEFAULT,activity將無法對implicit intent做出響應(yīng)。

更多sending 與 receiving ACTION_SEND intents執(zhí)行social sharing行為的,請查看上一課:接收Activity返回的結(jié)果(Getting a Result from an Activity)

在Activity中Handle發(fā)送過來的Intent

為了決定采用哪個(gè)action,我們可以讀取Intent的內(nèi)容。

可以執(zhí)行getIntent() 來獲取啟動我們activity的那個(gè)intent。我們可以在activity生命周期的任何時(shí)候去執(zhí)行這個(gè)方法,但最好是在onCreate()或者onStart()里面去執(zhí)行。

@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 ...
    }
}

返回Result

如果想返回一個(gè)result給啟動的那個(gè)activity,僅僅需要執(zhí)行setResult(),通過指定一個(gè)result code與result intent。操作完成之后,用戶需要返回到原來的activity,通過執(zhí)行finish() 關(guān)閉被喚起的activity。

 // 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();

我們必須總是指定一個(gè)result code。通常不是RESULT_OK就是RESULT_CANCELED。我們可以通過Intent 來添加需要返回的數(shù)據(jù)。

Note:默認(rèn)的result code是RESULT_CANCELED.因此,如果用戶在沒有完成操作之前點(diǎn)擊了back key,那么之前的activity接受到的result code就是"canceled"。

如果只是純粹想要返回一個(gè)int來表示某些返回的result數(shù)據(jù)之一,則可以設(shè)置result code為任何大于0的數(shù)值。如果我們返回的result只是一個(gè)int,那么連intent都可以不需要返回了,可以調(diào)用setResult()然后只傳遞result code如下:

setResult(RESULT_COLOR_RED);
finish();

Note:我們沒有必要在意自己的activity是被用startActivity() 還是 startActivityForResult()方法所叫起的。系統(tǒng)會自動去判斷該如何傳遞result。在不需要的result的case下,result會被自動忽略。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號