首页 > 代码库 > Android Activity intent-flilter过滤机制

Android Activity intent-flilter过滤机制

       在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 = http://www.mamicode.com/data;>

 如果一个Activity的<intent-filter>的<data>中mimeType和Uri都设置了,那就需要使用Intent的setDataAndType(Uridata, String type)进行设置咯。

 

        总结下,如果一个Activity在<intent-filter>中声明了Action验证、Category和Data验证,那么另一个应用要想通过隐式调用这个Activity,就必须在给Intent设置正确的参数,只有全部通过验证才能调用到这个Activity。还有一个需要注意的是,被调用的Activity的exported8属性需要设置为true(默认)才能被其他应用调用。

















Android Activity intent-flilter过滤机制