[Android] IntentFilter-->Action、Category屬性詳解

若是一個 Intent 請求在一片數據上執行一個動做, Android 如何知道哪一個應用程序(和組件)能用來響應這個請求呢? Intent Filter就是 用來註冊 Activity 、 Service 和 Broadcast Receiver 具備能在某種數據上執行一個動做的能力。使用 Intent Filter ,應用程序組件告訴 Android ,它們能爲其它程序的組件的動做請求提供服務,包括同一個程序的組件、本地的或第三方的應用程序。java

爲了註冊一個應用程序組件爲 Intent 處理者,在組件的 manifest 節點添加一個 intent-filter 標籤。在 Intent Filter 節點裏使用下面的標籤(關聯屬性),你能指定組件支持的動做、種類和數據。
android

一、動做測試:app

        <activity android:name="com.x210.intentfilters.OneActivity" android:label="oneActivity">   
            <intent-filter>
                <action android:name="myapp.action.test1" />
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>

規則a.一條<intent-filter>元素至少應該包含一個<action>,不然任何Intent請求都不能和該<intent-filter>匹配ide

        <activity android:name="com.x210.intentfilters.OtherActivity" android:label="otherActivity">   
            <intent-filter>  
                <category android:name="cate1"/>
                <category android:name="cate2"/>
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>

以上<intent-filter>元素沒有包含<action>標籤,任何Intent請求都沒法與該<intent-filter>匹配。測試

規則b.若是Intent請求的Action和<intent-filter>中個某一條<action>匹配,那麼該Intent就經過了這條<intent-filter>的動做測試。spa

        <activity android:name="com.x210.intentfilters.OneActivity" android:label="oneActivity">   
            <intent-filter>
                 <action android:name="myapp.action.test1" />
                 <action android:name="myapp.action.test2" />
                 <action android:name="myapp.action.test3" />
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity> <span style="color:#ff0000">
</span>

如下幾種Intent請求均可以經過上述<intent-filter>的動做測試。
code

請求1:xml

Intent intent = new Intent("myapp.action.test1");
startActivity(intent);

請求2:utf-8

Intent intent = new Intent("myapp.action.test2");
startActivity(intent);

若是Intent請求或<intent-filter>中沒有說明具體的Action類型,那麼會出現下面兩種狀況。get

(1) 若是<intent-filter>中沒有包含任何Action類型,那麼不管什麼Intent請求都沒法和這條<intent-filter>匹配;
(2) 反之,若是Intent請求中沒有設定Action類型,那麼只要<intent-filter>中包含有Action類型,這個Intent請求就將順利地經過<intent-filter>的行爲測試。

二、類別測試

  <activity android:name="com.x210.intentfilters.OtherActivity" android:label="otherActivity">   
            <intent-filter>  
                <action android:name="myapp.action.test1" />
                <category android:name="cate1"/>
                <category android:name="cate2"/>
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>

只有當Intent請求中全部的Category與組件中某一個IntentFilter的<category>徹底匹配時,纔會讓該 Intent請求經過測試,IntentFilter中多餘的<category>聲明並不會致使匹配失敗。一個沒有指定任何類別測試的 IntentFilter僅僅只會匹配沒有設置類別的Intent請求。

如下三種Intent請求均可以經過上述<intent-filter>的類別測試。

請求1:

    Intent intent = new Intent("myapp.action.test1");
    intent.addCategory("cate1");
    startActivity(intent);

請求2:

    Intent intent = new Intent("myapp.action.test1");
    intent.addCategory("cate2");
    startActivity(intent);

請求3:

        Intent intent = new Intent("myapp.action.test1");
        intent.addCategory("cate1");
        intent.addCategory("cate2");
        startActivity(intent);

實例部分源碼:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.x210.intentfilters"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="9" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.x210.intentfilters.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.x210.intentfilters.OneActivity" android:label="oneActivity">   
            <intent-filter>
                <action android:name="myapp.action.test1" />
                <action android:name="myapp.action.test2" />
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>
        <activity android:name="com.x210.intentfilters.OtherActivity" android:label="otherActivity">   
            <intent-filter>  
                <action android:name="myapp.action.test1" />
                <category android:name="cate1"/>
                <category android:name="cate2"/>
                <category android:name="android.intent.category.DEFAULT" />  
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.java(核心代碼)

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);    
        actionbutton = (Button) findViewById(R.id.ActionButton);
        categorybutton = (Button) findViewById(R.id.CategoryButton);
        actionbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("myapp.action.test1");
                startActivity(intent);
            }
        });
        categorybutton.setOnClickListener(new View.OnClickListener() {        
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("myapp.action.test1");
                intent.addCategory("cate1");
                intent.addCategory("cate2");
                startActivity(intent);
            }
        });
    }
相關文章
相關標籤/搜索