Intent有兩種,一種是顯式意圖,一種是隱式意圖。顯式意圖指定了具體要啟動(dòng)的Activity的類晴圾,所以當(dāng)你打算用顯式意圖啟動(dòng)某個(gè)Activity的時(shí)候,設(shè)置intent-filter是完全沒(méi)有用的噪奄。
對(duì)于每一個(gè)activity死姚,可以有任意數(shù)量的intent-filter,在隱式意圖的匹配過(guò)程當(dāng)中勤篮,只要匹配上了任意一個(gè)intent-filter都能啟動(dòng)這個(gè)Activity都毒。
intent-filter過(guò)濾intent根據(jù)三樣?xùn)|西,action碰缔,category和data账劲。
action
action是區(qū)分大小寫的字符串,一個(gè)intent-filter可以包含一個(gè)或多個(gè)action金抡。當(dāng)然瀑焦,一個(gè)action都沒(méi)有也是可以的,但是沒(méi)有action的intent-filter是無(wú)法被成功匹配的竟终。無(wú)論intent-filter里面有一個(gè)還是多個(gè)actions蝠猬,intent的action只要和intent-filter里面這些actions有一個(gè)完全相同就行切蟋。
category
category是區(qū)分大小寫的字符串统捶,一個(gè)intent-filter可以包含任意數(shù)量的category。但是如果希望intent-filter被成功匹配柄粹,category必須至少包含"android.intent.category.DEFAULT"喘鸟。category的匹配規(guī)則是intent的category一定是intent-filter里面列舉的幾個(gè)category之一,或者說(shuō)intent的category不能超出intent-filter所列舉的幾個(gè)category范圍之外驻右。
data
一個(gè)intent-filter里面可以有任意數(shù)量的data什黑,一個(gè)intent只能攜帶一個(gè)data(和type),我們認(rèn)為堪夭,只要intent的data愕把,完全符合intent-filter里面的任意一個(gè)data拣凹,就被認(rèn)為是匹配的岖寞。
<data
android:host="sdcard"
android:mimeType="video/mp4"
android:path="/sdcard/1.MP4"
android:pathPattern=".*\\.mp4"
android:pathPrefix="/sdcard/"
android:port="-2"
android:scheme="file" />
data的結(jié)構(gòu)里面主要包含了兩個(gè)東西刹悴,mimeType和URI。
mimeType
mimeType是指媒體類型辰狡,是一個(gè)區(qū)分大小寫的字符串橘蜜。比如image/jpeg菊匿,video/mpeg等等。
URI
URI由許多元素組成计福,下面是URI的結(jié)構(gòu):
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
具體的跌捆,比如:
file://sdcard/1.mp4
http://www.reibang.com/p/0321f33dff7f
- scheme
例如http、content象颖、file佩厚。 - host
URI的主機(jī)名,比如www.reibang.com说订。 - port
端口號(hào)可款。 - path/pathPattern/pathPrefix
path表示完整的路徑。pathPattern是判定完整路徑是否匹配用的正則表達(dá)式克蚂。pathPrefix也是正則表達(dá)式闺鲸,它匹配的是路徑的前綴信息。
匹配規(guī)則
intent的data完全符合intent-filter的data埃叭,意味著
- 默認(rèn)的URI
當(dāng)data當(dāng)中沒(méi)有配置任何的關(guān)于URI的參數(shù)的時(shí)候摸恍,scheme默認(rèn)為file或者content。
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/mp4" />
<data android:mimeType="image/*" />
</intent-filter>
上面的這段代碼的作用是:當(dāng)前的Activity可以用于打開MP4赤屋,或者是任意圖片立镶。如果你有興趣可以去試一下,當(dāng)你點(diǎn)擊打開一張圖片的時(shí)候类早,系統(tǒng)會(huì)彈出多個(gè)應(yīng)用讓你來(lái)選擇用哪個(gè)應(yīng)用來(lái)打開這張圖片媚媒,這時(shí)候除了系統(tǒng)自帶的相冊(cè),我們的應(yīng)用也會(huì)赫然出現(xiàn)在列表中涩僻。
intent.setDataAndType(Uri.parse("file://sdcard/1.mp4"), "video/mp4");
intent.setDataAndType(Uri.parse("file://sdcard/1.jpeg"), "image/jpeg");
這是啟動(dòng)目標(biāo)Activity的intent的配置方法缭召。
隱式意圖匹配失敗的處理
隱式意圖一個(gè)很大的問(wèn)題就是我們并不知道系統(tǒng)里面是否有Activity能被匹配,比如如果你的手機(jī)里面一個(gè)查看圖片的Activity都沒(méi)有逆日,那么用相應(yīng)的intent隱式啟動(dòng)注定會(huì)失敗并且拋出異常嵌巷。所以在實(shí)際啟動(dòng)activity之前,最好是先做一下判斷室抽,比如:
intent.resolveActivity(getPackageManager());
如果返回的是null搪哪,則表示匹配失敗,否則會(huì)返回最佳匹配的Activity坪圾。除此之外我們還有一種方法晓折,可以返回所有成功匹配的Activity惑朦,像這樣:
getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
getPackageManager().queryIntentActivities(intent, PackageManager.GET_INTENT_FILTERS);
getPackageManager().queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
最后說(shuō)一下一類特殊的intent-filter
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
它們組合出現(xiàn)代表程序會(huì)出現(xiàn)在系統(tǒng)的應(yīng)用列表中,單獨(dú)出現(xiàn)沒(méi)有任何意義漓概。如果想獲得所有出現(xiàn)在應(yīng)用列表中的應(yīng)用行嗤,那么可以定義一個(gè)intent,用queryIntentActivities來(lái)獲取到匹配的所有Activit