[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
相关文章
相关标签/搜索