[intent-filter] 之 data 「scheme, host, port, mim...

以前一直搞不很明白 AndroidManifest.xml 中 activity 標籤下的 intent-filter 中 data 標籤的屬性含義,今天認真看了 Dev Guide,又在網上查詢了大量相關資料,現把 data 標籤中的屬性含義作一個總結。
 html

1、定義
 
android

scheme, host, port, path, pathPrefix, pathPattern 是用來匹配 Intent 中的 Data Uri 的。具體規則以下:
 瀏覽器

  scheme://host:port/path or pathPrefix or pathPattern
 
網絡

這裏須要注意的是這裏的 scheme 不是 schema,也許你記得 xmlns:android="http://schemas.android.com/apk/res/android" 這段聲明,你就會想起其中的 schema (至少我是這樣想到了...- -!),但這裏的 scheme 不是 schema。雖然在寫 AndroidManifest.xml 的時候,有智能提示,可是但願你們仍是能注意到。ide

上面那句最後的 「path or pathPrefix or pathPattern」 是指後面的 path 驗證可使用 data 屬性中的 android:path、android:pathPrefix 或 pathPattern,你能夠添加任意個 data 標籤,因爲是 「or」 ,所以,只要其中任意一個 data 匹配,系統就會選擇你的 Activity 啓動,固然,若是別的 Activity 也有相同的 data 標籤,系統就會給用戶彈出一個 Chooser Dialog。ui


mimeType 也是是用來匹配 Intent 的。好比,當你使用 Intent.setType("text/plain") ,那麼系統將會匹配到全部註冊 android:mimeType="text/plain" 的 Activity,想獲取更多有關 mimeType 的知識請參考:【轉】備份:Android 經常使用 mimeType 表google

這裏須要十分注意的是 Intent.setType(), Intent.setData,Intent.setDataAndType() 這三個方法!
 
spa

  • setType 調用後設置 mimeType,而後將 data 置爲 null;
  • setData 調用後設置 data,而後將 mimeType 置爲 null;
  • setDataAndType 調用後纔會同時設置 data 與 mimeType。
     
另外須要注意的是,若是你在 data 標籤,既設置了 mimeType 又設置了 scheme 以內的,那麼你的 Intent 須要同時設置匹配的 data 與 mimeType 即調用 setDataAndType ,系統才能匹配到這個 Activity(即使你 mimeType 設置爲 "*/*" 也是如此)。固然,若是你沒有設置 mimeType,那麼調用 setData 進行匹配,若是你設置了任何的 mimeType 將不會匹配到該 Activity。

2、區別

  這裏主要說的區別是  pathpathPrefixpathPattern 之間的區別
 
  • path 用來匹配完整的路徑,如:http://example.com/blog/abc.html,這裏將 path 設置爲 /blog/abc.html 纔可以進行匹配;
  • pathPrefix 用來匹配路徑的開頭部分,拿上面的 Uri 來講,這裏將 pathPrefix 設置爲 /blog 就能進行匹配了;
  • pathPattern 用表達式來匹配整個路徑,這裏須要說下匹配符號與轉義。
匹配符號:
  1. 「*」 用來匹配0次或更多,如:「a*」 能夠匹配「a」、「aa」、「aaa」...
  2. 「.」 用來匹配任意字符,如:「.」 能夠匹配「a」、「b」,「c」...
  3. 所以 「.*」 就是用來匹配任意字符0次或更多,如:「.*html」 能夠匹配 「abchtml」、「chtml」,「html」,「sdf.html」...
轉義:
由於當讀取 Xml 的時候,「\」 是被看成轉義字符的(當它被用做 pathPattern 轉義以前),所以這裏須要兩次轉義,讀取 Xml 是一次,在 pathPattern 中使用又是一次。如:「*」 這個字符就應該寫成 「\\*」,「\」 這個字符就應該寫成 「\\\\」。


3、一些例子

   例子1:若是咱們想要匹配 http 以 「.pdf」 結尾的路徑,使得別的程序想要打開網絡 pdf 時,用戶可以能夠選擇咱們的程序進行下載查看。

咱們能夠將 scheme 設置爲 「http」,pathPattern 設置爲 「.*\\.pdf」,整個 intent-filter 設置爲:
View Code
1 <intent-filter> 2  <action android:name="android.intent.action.VIEW"></action> 3  <category android:name="android.intent.category.DEFAULT"></category> 4  <data android:scheme="http" android:pathPattern=".*\\.pdf"></data> 5 </intent-filter>

若是你只想處理某個站點的 pdf,那麼在 data 標籤裏增長  android:host="yoursite.com" 則只會匹配 http://yoursite.com/xxx/xxx.pdf,但這不會匹配 www.yoursite.com,若是你也想匹配這個站點的話,你就須要再添加一個 data 標籤,除了 android:host 改成 「www.yoursite.com」 其餘都同樣。
 code

例子2:若是咱們作的是一個IM應用,或是其餘相似於微博之類的應用,如何讓別人經過 Intent 進行調用分享出如今選擇框裏呢?
 
咱們只用註冊 android.intent.action.SEND 與 mimeType 爲 「text/plain」 或 「*/*」 就能夠了,整個 intent-filter 設置爲:
View Code
1 <intent-filter> 2  <action android:name="android.intent.action.SEND" /> 3  <category android:name="android.intent.category.DEFAULT" /> 4  <data mimeType="*/*" /> 5 </intent-filter>

這裏設置 category 的緣由是,建立的 Intent 的實例默認 category 就包含了 Intent.CATEGORY_DEFAULT ,google 這樣作的緣由是爲了讓這個 Intent 始終有一個 category。xml


例子3:若是咱們作的是一個音樂播放軟件,當文件瀏覽器打開某音樂文件的時候,使咱們的應用可以出如今選擇框裏?
 
這相似於文件關聯了,其實作起來跟上面同樣,也很簡單,咱們只用註冊 android.intent.action.VIEW 與 mimeType 爲 「audio/*」 就能夠了,整個 intent-filter 設置爲:
View Code
1 <intent-filter> 2  <action android:name="android.intent.action.VIEW" /> 3  <category android:name="android.intent.category.DEFAULT" /> 4  <data android:mimeType="audio/*" /> 5 </intent-filter>

參考:
【2】備份:Android 經常使用 mimeType 表  http://www.cnblogs.com/newcj/archive/2011/08/10/2134305.html
相關文章
相關標籤/搜索