在Android中一个应用(APP1)如果要想调用另一应用的(APP2)的某一个Activity(Activity2),就需要在给Intent设置的参数能够通过Activiy2 在清单文件中声明的<intent-filter>属性验证,才能成功调用到Activity。<intent-filter> 标签中可以使用的验证有:Action验证、Category验证、Data验证,其中Action验证是必须声明的。
- Action 验证:
一个Activity可以声明多个Action,在验证时只要通过一个即通过验证,如果Activity2声明如下3个Action:
<intent-filter> <action android:name="ACTION1"/> <action android:name="ACTION2"/> <action android:name="ACTION3"/> ………… </intent-filter>
其他的应用可以通过给Intent设置Action方法调用到Activity2(如果系统中其他应用也有相同的Action,会进行列表供用户选择),如:
<span style="font-size:18px;">Intent intent=new Intent(); intent.setAction("ACTION1"); startActivity(intent);</span>
- Category验证:
Activity2的<intent-filter>还可以声明多个Category验证,如下(其中DEFAULT那个是系统会自动添加的,及时没声明还是会存在的):
<intent-filter> <action android:name="ACTION1"/> <action android:name="ACTION2"/> <action android:name="ACTION3"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="CATEGORY1"/> <category android:name="CATEGORY2"/> <category android:name="CATEGORY3"/> </intent-filter>
在其他应用中可以为Intent添加Category,当所添加的Category都在Activity2有声明是就会通过验证,如下Intent就能通过验证:
Intent intent=new Intent(); intent.setAction("ACTION1"); intent.addCategory("CATEGORY1"); intent.addCategory("CATEGORY3"); startActivity(intent);
- Data验证:
Data验证比较复杂点,可以验证Intent中设置的Mime Type和Uri。Mime Type可以指定处理的资源类型,如“audio/*”表示所有音频资源,设置MimeType:
<intent-filter> <action android:name="ACTION1"/> <action android:name="ACTION2"/> <action android:name="ACTION3"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="audio/*" /> </intent-filter>
调用的Intent 可以通过setType()或者setTypeAndNormalize()设置Mime Type,
Intent intent=new Intent(); intent.setAction("ACTION1"); intent.setType("audio/*"); // intent.setTypeAndNormalize("audio/*"); startActivity(intent);
Uri比较Url范围广,格式为:scheme://host:port/path,其中scheme为协议标识如:http等,host为IP、域名等,port为端口号,path为路径。在<intent-filter>的<data>中可以对这个几个分别进行设置验证,但是不能跳跃设置,例如设置了scheme,不设置host,直接设置port,这时port的设置将会被忽略,跟没设置port一样。在设置path,可以使用path设置整个路径,也可以使用pathPrefix设置路径以什么开头,还可以使用pathPattern设置带统配符的路径,通配符为“*”和“.*”,其中“*”和正则表达式中的“*”一样,表示前一个字符为0或任意多个,而“.”表示任意字符。如果“abc*d”可以匹配
“abcccd”,“abcd”等,“abc.*d”可以匹配“abced”,“abcfd”等。在<intent-filter>中的<data>设置Uri格式如下:
<intent-filter> <action android:name="ACTION1"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="http" android:path="/abc.jsp" android:host="www.google.com" android:port="8080" android:pathPrefix="/in" android:pathPattern="/i.*n" /> </intent-filter>
相应的调用Intent可以如下:
Intent intent=new Intent(); intent.setAction("ACTION1"); Uri uri=Uri.parse("http://www.google.com:8080/abc.jsp");//匹配path // Uri uri=Uri.parse("http://www.google.com:8080/index.jsp");//匹配pathPrefix // Uri uri=Uri.parse("http://www.google.com:8080/idexn");//匹配pathPattern intent.setData(uri); startActivity(intent);
但是,需要注意的是Intent的setData()方法和setType()会相互覆盖,也就是说,如果先使用setType()设置了Mime Type,之后在使用setData()设置了Uri,那么原先设置的MimeType就会被清空,反之也相同。以下为setData()方法源码,看了就很容易理解了:
public Intent setData(Uri data) { mData = data; mType = null; return this; }
如果一个Activity的<intent-filter>的<data>中mimeType和Uri都设置了,那就需要使用Intent的setDataAndType(Uridata, String type)进行设置咯。
总结下,如果一个Activity在<intent-filter>中声明了Action验证、Category和Data验证,那么另一个应用要想通过隐式调用这个Activity,就必须在给Intent设置正确的参数,只有全部通过验证才能调用到这个Activity。还有一个需要注意的是,被调用的Activity的exported8属性需要设置为true(默认)才能被其他应用调用。