部分内容参考了:https://blog.csdn.net/iispring/article/details/48481793
android:name="com.lenovo.calendar.ACTION_SETTINGS_CHANGED" /> android:scheme="content" /> android:host="com.lenovo.calendar" /> android:mimeType="vnd.lenovo.data/update" />
也可写成这样
android:name="com.lenovo.calendar.ACTION_SETTINGS_CHANGED" /> android:scheme="content" android:host="com.lenovo.calendar" android:mimeType="vnd.lenovo.data/update" />
也可以只包含android:scheme 和android:host android:mimeType一个属性
每个标签都可以指定一个URI结构以及data的MIME类型。一个完整的URI由
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的这些属性在标签中都是可选的 ,但存在如下的依赖关系:
当我们将intent对象中的Uri参数与intent-filter中的标签指定的URI格式进行对别时,我们我们只对比intent-filter的
标签指定的部分,例如:
需要注意的是,intent-filter的标签在指定path的值时,可以在里面使用通配符
*
,起到部分匹配的效果。
data测试需要同时将intent对象中的URI、MIME类型与intent-filter的标签中指定的URI、MIME类型进行对比。
我们知道一个intent-filter下可以有多个标签,intent对象无需通过所有的
标签测试,一般情况下,我们的intent对象只需通过了其中一个
标签的测试并满足某些特定情形下的一些条件,那么该intent对象就通过了该intent-filter的data测试。
进行对比的规则分以下几种情况:
intent对象不包含URI和MIME类型
这种情况下,只有当intent-filter也没有指定任何URI和MIME类型的时候才能通过data测试。
例如我们有如下intent对象:
Intent intent = new Intent();
intent.setAction("com.ispring.action.ACTION_TEST1");
上面的intent对象可以通过下面的intent-filter的data测试:
<intent-filter>
<action android:name="com.ispring.action.ACTION_TEST1" />
<category android:name="android.intent.category.DEFAULT" />
intent-filter>
上面的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>
intent对象包含URI但不包含MIME类型
这种情况下,只有当intent对象的URI匹配到了intent-filter中的URI格式,并且intent-filter没有指定MIME类型的时候才能通过data测试。需要注意的是,这里所说的intent-filter没有指定MIME类型的情形指的是intent-filter中所有的标签都没有指定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);
上面的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>
上面的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>
intent对象虽然不能通过scheme为sunqun的标签测试,但是可以通过scheme为ispring的data标签测试,且intent对象和intent-filter中的两个
标签都没有指定MIME,所以上面的intent对象可以通过该intent-filter测试。
上面的intent对象无法通过以下intent-filter的标签测试:
<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>
上面的intent对象之所以不能通过intent-filter中唯一的一个标签测试是因为我们的intent对象没有指定MIME类型,但是上面的
标签通过
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>
上面的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中所有标签都没有指定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");
上面的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>
上面的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>
上面的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>
上面的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>
上面的intent对象没有指定URI信息,但是上面的intent-filter中第二个标签设置了URI中的scheme信息,所以intent对象无法通过该intent-filter的data测试。
intent对象同时包含URI和MIME类型
这种情况下,要分别测试URI以及MIME类型测试是否通过,只有URI以及MIME测试都通过了,data测试才能通过。
标签中的MIME类型值,那么MIME类型测试就通过了。
中的URI,那么URI测试就通过了。content:
协议或file:
协议,并且整个intent-filter的所有
标签中都没有指定URI,那么该intent也能通过URI测试。换句话说,如果一个intent-filter只列出了MIME类型,没有列出任何URI相关的格式的话,那么这个intent-filter就默认是支持content:
协议或file:
协议的。下面举几个例子大家自己体会一下。
假设有如下协议为自定义协议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);
上面的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>
上面的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>
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>
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);
上面的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>
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>
intent中使用的是content:
协议,并且整个intent-filter中都没有定义URI格式,所以URI测试是可以通过的,并且MIME类型能找到匹配项,所以可以通过data测试。