部分內容參考了:https://blog.csdn.net/iispring/article/details/48481793
<intent-filter> <action android:name="com.lenovo.calendar.ACTION_SETTINGS_CHANGED" /> <data android:scheme="content" /> <data android:host="com.lenovo.calendar" /> <data android:mimeType="vnd.lenovo.data/update" />
</intent-filter>
也可寫成這樣
<intent-filter> <action android:name="com.lenovo.calendar.ACTION_SETTINGS_CHANGED" /> <data android:scheme="content" android:host="com.lenovo.calendar" android:mimeType="vnd.lenovo.data/update" /> </intent-filter>
也可以只包含android:scheme 和android:host android:mimeType一個屬性
每個<data />
標籤都可以指定一個URI結構以及data的MIME類型。一個完整的URI由scheme
、host
、port
和path
組成,其結構如下所示:
<scheme>://<host>:<port>/<path>
其中scheme既可以是Android中常見的協議,也可以是我們自定義的協議。Android中常見的協議包括content協議、http協議、file協議等,自定義協議可以使用自定義的字符串。
如下是一個content協議的URI:
content://com.example.project:200/folder/subfolder/etc
在該URI中,scheme是content,host是com.example.project,port是200,path是folder/subfolder/etc。如下是一個自定義協議的URI:
ispring://blog.csdn.net/sunqunsunqun
在該URI中,scheme是ispring,host是blog.csdn.net,沒有明確設定port,path是sunqunsunqun。
組成URI的這些屬性在<data />
標籤中都是可選的 ,但存在如下的依賴關係:
- 如果沒有指定scheme,那麼host參數會被忽略
- 如果沒有指定host,那麼port參數會被忽略
- 如果scheme和host都沒有指定,path參數會被忽略
當我們將intent對象中的Uri參數與intent-filter中的<data />
標籤指定的URI格式進行對別時,我們我們只對比intent-filter的<data />
標籤指定的部分,例如:
- 如果intent-filter中只指定了scheme,那麼所有帶有該sheme的URI都能匹配到該intent-filter。
- 如果intent-filter中只指定了scheme和authority(authority包括host和port兩部分)而沒有指定path,那麼所有具有相同scheme和authority的URI都能匹配到該intent-filter,而不用考慮path爲何值。
- 如果intent-filter中同時指定了scheme、authority和path,那麼只有具有相同scheme、authority和path的URI才能匹配到該intent-filter。
需要注意的是,intent-filter的<data />
標籤在指定path的值時,可以在裏面使用通配符*
,起到部分匹配的效果。
data測試需要同時將intent對象中的URI、MIME類型與intent-filter的<data />
標籤中指定的URI、MIME類型進行對比。
我們知道一個intent-filter下可以有多個<data />
標籤,intent對象無需通過所有的<data />
標籤測試,一般情況下,我們的intent對象只需通過了其中一個<data />
標籤的測試並滿足某些特定情形下的一些條件,那麼該intent對象就通過了該intent-filter的data測試。
進行對比的規則分以下幾種情況:
intent對象不包含URI和MIME類型
這種情況下,只有當intent-filter也沒有指定任何URI和MIME類型的時候才能通過data測試。
例如我們有如下intent對象:Intent intent = new Intent(); intent.setAction("com.ispring.action.ACTION_TEST1");
- 1
- 2
上面的intent對象可以通過下面的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
- 1
- 2
- 3
- 4
上面的intent對象無法通過下面的intent-filter測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
intent對象包含URI但不包含MIME類型
這種情況下,只有當intent對象的URI匹配到了intent-filter中的URI格式,並且intent-filter沒有指定MIME類型的時候才能通過data測試。需要注意的是,這裏所說的intent-filter沒有指定MIME類型的情形指的是intent-filter中所有的<data />
標籤都沒有指定MIME類型,即整個intent-filter中完全沒有android:mimeType
這幾個字,理解這點很重要,大家在下面的幾個示例中可以體會到這點。
例如有如下intent對象:Intent intent = new Intent(); intent.setAction("com.ispring.action.ACTION_TEST1"); Uri uri = Uri.parse("ispring://blog.csdn.net/sunqunsunqun"); intent.setData(uri);
- 1
- 2
- 3
- 4
上面的intent能通過如下的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" android:host="blog.csdn.net" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
上面的intent對象可以通過以下intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" android:host="blog.csdn.net" /> <data android:scheme="sunqun" android:host="8080" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
intent對象雖然不能通過scheme爲sunqun的
<data />
標籤測試,但是可以通過scheme爲ispring的data標籤測試,且intent對象和intent-filter中的兩個<data />
標籤都沒有指定MIME,所以上面的intent對象可以通過該intent-filter測試。上面的intent對象無法通過以下intent-filter的
<data />
標籤測試:<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" android:scheme="ispring" android:host="blog.csdn.net" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
上面的intent對象之所以不能通過intent-filter中唯一的一個
<data />
標籤測試是因爲我們的intent對象沒有指定MIME類型,但是上面的<data />
標籤通過android:mimeType="text/plain"
設置了MIME類型。上面的intent對象無法通過以下intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" android:host="blog.csdn.net" /> <data android:mimeType="text/plain" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
上面的intent對象之所以無法通過該intent-filter中的data測試,是因爲intent對象沒有設置MIME類型,但是intent-filter中第二個data標籤通過
android:mimeType="text/plain"
設置了MIME類型。
intent對象包含MIME類型但不包含URI
這種情況下,只有當intent中的MIME類型與intent-filter中列出的MIME類型相同,並且intent-filter沒有指定任何的URI格式的時候才能通過data測試。需要注意的是,這裏所說的intent-filter沒有指定任何的URI格式的情形指的是intent-filter中所有<data />
標籤都沒有指定URI,即整個intent-filter中完全沒有android:scheme
、android:host
、android:port
以及android:path
,理解這點很重要,大家在下面的幾個示例中可以體會到這點。
例如有如下intent對象:Intent intent = new Intent(); intent.setAction("com.ispring.action.ACTION_TEST1"); intent.setType("text/plain");
- 1
- 2
- 3
上面的intent對象可以通過以下intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
上面的intent對象可以通過下面的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> <data android:mimeType="text/plain" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
上面的intent對象雖然沒有通過MIME類型爲
image/*
的第一個data標籤測試,但能通過第二個data標籤測試,並且intent對象和intent-filter都沒有指定任何的URI格式。上面的intent對象不能通過以下intent-filter中的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" android:scheme="ispring" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
上面的intent對象中沒有設置URI信息,但是在該intent-filter中設置了URI中的scheme值,所以intent無法通過intent-filter的data測試。
上面的intent對象無法通過以下intent-filter中的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> <data android:scheme="ispring" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
上面的intent對象沒有指定URI信息,但是上面的intent-filter中第二個
<data />
標籤設置了URI中的scheme信息,所以intent對象無法通過該intent-filter的data測試。
intent對象同時包含URI和MIME類型
這種情況下,要分別測試URI以及MIME類型測試是否通過,只有URI以及MIME測試都通過了,data測試才能通過。- 對於MIME測試:如果intent的MIME類型能夠匹配intent-filter中列出的某一個
<data />
標籤中的MIME類型值,那麼MIME類型測試就通過了。 - 對於URI測試:
又細分兩種情況,滿足下面的任何一種情況都可以通過URI測試。- 如果intent的URI格式能夠匹配intent-filter中列出的某一個
<data />
中的URI,那麼URI測試就通過了。 - 如果intent的URI是
content:
協議或file:
協議,並且整個intent-filter的所有<data />
標籤中都沒有指定URI,那麼該intent也能通過URI測試。換句話說,如果一個intent-filter只列出了MIME類型,沒有列出任何URI相關的格式的話,那麼這個intent-filter就默認是支持content:
協議或file:
協議的。
- 如果intent的URI格式能夠匹配intent-filter中列出的某一個
下面舉幾個例子大家自己體會一下。
假設有如下協議爲自定義協議
ispring:
的intent對象:Intent intent = new Intent(); intent.setAction("com.ispring.action.ACTION_TEST1"); Uri uri = Uri.parse("ispring://blog.csdn.net/sunqunsunqun"); String type = "text/plain"; intent.setDataAndType(uri, type);
- 1
- 2
- 3
- 4
- 5
上面的intent對象可以通過下面的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" android:host="blog.csdn.net" /> <data android:mimeType="text/plain" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
上面的intent對象無法通過下面的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" android:host="blog.csdn.net" android:port="8080" /> <data android:mimeType="text/plain" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
port不滿足,URI測試不通過,導致data測試失敗。
上面的intent對象無法通過下面的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" android:host="blog.csdn.net" /> <data android:mimeType="image/*" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
android:mimeType
不滿足,MIME類型測試不通過,導致data測試失敗。
假設有如下協議爲
content:
的intent對象:Intent intent = new Intent(); intent.setAction("com.ispring.action.ACTION_TEST1"); Uri uri = Uri.parse("content://com.ispring.test"); String type = "text/plain"; intent.setDataAndType(uri, type);
- 1
- 2
- 3
- 4
- 5
上面的intent對象無法通過下面的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="ispring" /> <data android:mimeType="text/plain" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
- 6
URI中的scheme不匹配,導致URI測試不通過,導致data測試失敗。
上面的intent對象可以通過下面的intent-filter的data測試:
<intent-filter> <action android:name="com.ispring.action.ACTION_TEST1" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
- 1
- 2
- 3
- 4
- 5
intent中使用的是
content:
協議,並且整個intent-filter中都沒有定義URI格式,所以URI測試是可以通過的,並且MIME類型能找到匹配項,所以可以通過data測試。
- 對於MIME測試:如果intent的MIME類型能夠匹配intent-filter中列出的某一個