Android 之Intent,Filter和IntentFilter

Android 之Intent,Filter和IntentFilter

Intent(意圖)/Filter(過濾器)

Android意圖(Intent)是一個要執行的操作的抽象描述。它可以通過 startActivity 來啓動一個活動,broadcastIntent 來發送廣播到任何對它感興趣的廣播接受器組件,startService(Intent) 或者bindService(Intent, ServiceConnection, int) 來與後臺服務通訊。
意圖本身(一個 Intent 對象)是一個被動的數據結構,保存着要執行操作的抽象描述。

接收意圖(Intent)等方法
  1. Context.startActivity():意圖傳遞給該方法,用於啓動一個新的活動或者讓已存在的活動做一些新的事情。
  2. Context.startService():意圖傳遞給該方法,將初始化一個服務,或者新的信息到一個持續存在的服務。
  3. Context.sendBroadcast():意圖傳遞給該方法,信息將傳遞到所有對此感興趣的廣播接收器。

意圖對象
意圖對象是一包的信息,用於組件接收到的意圖就像 Android 系統接受到的信息。

意圖對象包括如下的組件,具體取決於要通信或者執行什麼。

動作(Action)

這是意圖對象中必須的部分,被表現爲一個字符串。在廣播的意圖中,動作一旦發生,將會被報告。動作將很大程度上決定意圖的其他部分如何被組織。Intent 類定義了一系列動作常量對應不同的意圖。這裏是一份Android意圖標準動作 列表。

意圖對象中的動作可以通過 setAction() 方法來設置,通過 getAction() 方法來讀取。

數據(Data)

添加數據規格到意圖過濾器。這個規格可以只是一個數據類型(如元類型屬性),一條 URI ,或者同時包括數據類型和 URI 。 URI 則由不同部分的屬性來指定。

這些指定 URL 格式的屬性是可選的,但是也相互獨立 -

  • 如果意圖過濾器沒有指定模式,所有其他的 URI 屬性將被忽略。
  • 如果沒有爲過濾器指定主機,端口屬性和所有路徑屬性將被忽略。

setData() 方法只能以 URI 來指定數據,setType() 只能以元類型指定數據,setDataAndType() 可以同時指定 URI 和元類型。URI 通過 getData() 讀取,類型通過 getType() 讀取。

動作/數據組的一些實例

  • ACTION_VIEW content://contacts/people/1:顯示ID爲1的用戶的信息。
  • ACTION_DIAL content://contacts/people/1:顯示電話撥號器,並填充用戶1的數據。
  • ACTION_VIEW tel:123:顯示電話撥號器,並填充給定的號碼。
  • ACTION_DIAL tel:123:顯示電話撥號器,並填充給定的號碼。
  • ACTION_EDIT content://contacts/people/1:編輯ID爲1的用戶信息。
  • ACTION_VIEW content://contacts/people/:顯示用戶列表,以便查看。
  • ACTION_SET_WALLPAPER:顯示選擇壁紙設置。
  • ACTION_SYNC:同步數據,默認的值爲:android.intent.action.SYNC
  • ACTION_SYSTEM_TUTORIAL:開啓平臺定義的教程(默認教程或者啓動教程)
  • ACTION_TIMEZONE_CHANGED:當時區被改變時通知
  • ACTION_UNINSTALL_PACKAGE:運行默認的卸載器

意圖的類型

Android 支持兩種類型的意圖,顯示意圖,隱式意圖。

顯式意圖

顯式意圖用於連接應用程序的內部世界,假設你需要連接一個活動到另外一個活動,我們可以通過顯示意圖,下圖顯示通過點擊按鈕連接第一個活動到第二個活動。
這些意圖通過名稱指定目標組件,一般用於應用程序內部信息 - 比如一個活動啓動一個下屬活動或者啓動一個兄弟活動。舉個例子:

// 通過指定類名的顯式意圖
Intent i = new Intent(FirstActivity.this, SecondAcitivity.class);

// 啓動目標活動
startActivity(i);

隱式意圖

這些意圖沒有爲目標命名,組件名稱的域爲空。隱式意圖經常用於激活其他應用程序的組件。舉個例子:

Intent read1=new Intent();
read1.setAction(android.content.Intent.ACTION_VIEW);
read1.setData(ContactsContract.Contacts.CONTENT_URI);
startActivity(read1);

目標組件接收到意圖,可以使用getExtras()方法來獲取由源組件發送的附加數據。例如:

// 在代碼中的合適位置獲取包對象
Bundle extras = getIntent().getExtras();

// 通過鍵解壓數據
String value1 = extras.getString("Key1");
String value2 = extras.getString("Key2");

IntentFilter

IntentFilter就是“意圖過濾器”,主要用來過濾隱式意圖。當用戶進行一項操作的時候,Android系統會根據配置的 “意圖過濾器” 來尋找可以響應該操作的組件,服務。

例子

Android系統就會通過設定好的意圖過濾器,進行匹配測試,找到能夠打開PDF文件的APP程序代碼如下:

<activity android:name="com.example.testmain.ShowActivity" >
      <intent-filter>
            <action android:name="test.update.mydata" />
            <category android:name="my.test.show" />
            <data android:pathPattern=".*\\.jpg" android:scheme="http" />
      </intent-filter>
 </activity>
IntentFilter 如何過濾隱式意圖

Android系統會根據我們配置的Intent Filter(意圖過濾器),來進行匹配測試。匹配的時候,只會考慮三個方面:動作、數據(URI以及數據類型)和類別。也就是說Android系統會進行“動作測試”,“數據測試”,“類別測試”,來尋找可以響應隱式意圖的組件或服務。

另外,當對其他App程序開放組件和服務的時候也需要配置Intent Filter(意圖過濾器),一個Activity可以配置多個< intent-filter >。

動作測試:

對應中的標籤;
(1) 如果標籤中有多個,那麼Intent請求的Action,只要匹配其中的一條就可以通過了這條的動作測試。

(2) 如果中沒有包含任何,那麼無論什麼Intent請求都無法和這條匹配。

(2) 如果Intent請求中沒有設定Action(動作),那麼這個Intent請求就將順利地通過的動作測試(前提是中必須包含有,否則與第二條衝突)。

類別測試:

對應< intent-filter>中的< category />標籤;

Intent中的類別必須全部匹配< intent-filter>中的< category />,但是< intent-filter>中多餘的< category />將不會導致匹配失敗。

例如:Intent中有3個類別,而意圖過濾器中定義了5個,如果Intent中的3個類別都與過濾器中的匹配,那麼過濾器中的另外2個,將不會導致類別測試失敗。

數據測試:

對應< intent-filter>中的< data>標籤;

< data>元素指定了可以接受的Intent傳過來的數據URI和數據類型,當一個意圖對象中的URI被用來和一個過濾器中的URI比較時,比較的是URI的各個組成部分。

例如:

如果過濾器僅指定了一個scheme,所有該scheme的URIs都能夠和這個過濾器相匹配;

如果過濾器指定了一個scheme、主機名但沒有路經部分,所有具有相同scheme和主機名的URIs都可以和這個過濾器相匹配,而不管它們的路經;

如果過濾器指定了一個scheme、主機名和路經,只有具有相同scheme、主機名和路經的URIs纔可以和這個過濾器相匹配。

當然,一個過濾器中的路徑規格可以包含通配符,這樣只需要部分匹配即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章