隐式Intent,IntentFilter与Uri

参考

        http://blog.csdn.net/dlutbrucezhang/article/details/8917774

        http://developer.android.com/guide/components/intents-filters.html

Intent

概述

        Intent对象可以向操作系统描述我们需要处理的任务。使用显式Intent,我们需要指定具体的类名;而使用隐式Intent,我们只需要向操作系统描述清楚我们的工作意图,操作系统会去启动那些对外宣称能够完成任务的activity(即能匹配成功intent-filter的)。如果操作系统找到多个activity,那么用户将会看到可选列表,然后看用户自己如何选择了。通过隐式意图启动一些组件时,必须满足该组件所对应的<intent-filter>。

        虽然隐式意图也可以带extra数据,但操作系统在寻找合适的activity时并不会使用任何附加在隐式意图上的extra信息。这并不意味着隐式意图上的extra信息没有用,同显式意图一样,intent一样会将它所带的extra信息带到寻找到的activity中

flag

        FLAG_ACTIVITY_NEW_TASK:例如现在栈1的情况是:A B C。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK标记,如果D这个Activity在Manifest.xml中的声明中添加了Task affinity,系统首先会查找有没有和D的Task affinity相同的task栈存在,如果有,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Task affinity默认没有设置,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK标记效果是一样的了。(参见http://blog.csdn.net/berber78/article/details/7278408)。注意:从非activity开启activity的话,必须为intent设置该标签

        FLAG_ACTIVITY_NO_HISTORY:当前启动的activity不会在栈中存在,也就是说,按返回键的时候是没有办法返回到该activity的。和<activity>中的noHistory=true是一样的效果。

<intent-filter>

下面是一个清单文件中的intent-filter
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="inline" />
                <data android:mimeType="text/html"/>
                <data android:mimeType="text/plain"/>
                <data android:mimeType="application/xhtml+xml"/>
                <data android:mimeType="application/vnd.wap.xhtml+xml"/>
            </intent-filter>
可以看出<intent-filter>有三个子结点<action>,<category>,<data>。

<action>

        它指的是intent要执行的操作,比如当前的intent想获取某个内容(比如照相等) 可以通过Intent.setAction()来为intent对象设置action,它会自动匹配<intent-filter>中的<action>结点。
<type>
        设置当前的数据类型。如image/*表示图片,video/*表示视频。

<category>

        它指intent的可选类别,常用来描述我们何时、何地甚至如何使用某个activity。通过Intent.addCategory()为Intent对象设置category。它会自动匹配<intent-filter>中的<category>结点。

此处需注意一点

        如果该intent传入到startActivity()中当作参数,系统会默认的加上一个值为android.intent.category.DEFAULT的category。因此,如果<intent-filter>没有设置<category android:name="android.intent.category.LAUNCHER" />它是不会被隐式意图启动的。

<data>

        要操作的数据及数据类型。可以通过Intent.setType(),Intent.setData()和Intent.setDataAndType()为Intent对象设置数据和数据类型。前两个方法分别用来设置类型和数据,但由于setType()与setData()两个方法互斥,后写的方法会清空掉前写的方法所设置的值,所以如果同时要设置type与data应调用Intent.setDataAndType(),而不是分别调用前两个方法。

它的具体属性值如下:

        android:mimeType,应该通过intent.setType(type)来匹配mimeType的值,表示数据类型。

        android:scheme:指向的是Uri中的scheme的值。

        android:path:指向的是Uri中的path的值。

        android:port:指向的是Uri中的port的值。

        android:host:指向的是Uri中的host的值。

Uri

        Intent.setData()中的参数是一个Uri,而对于一个Uri来说,它的标准样式如下:

scheme://host:port/path

        当没有设置host的值时,port,path的值是无效的,并且data并不是完全匹配的。只要传入的Uri中的scheme,host,port,path分别满足<intent-filter>中的对应的值,该activity就会启动。假如:一个<intent-filter>中设置了scheme,host,port。而一个Uri中的scheme,host,port匹配相应的值,而且该Uri中还有path,那么这个<intent-filter>对应的activity也会启动。例如下面的intent是可以匹配下面的intent-filter,虽然intent比<intent-filter>在data上多了host值

Intent对象

Intent intent = new Intent("xx");
intent.addCategory("xxxx");
intent.setData(Uri.parse("ab://dafdaf"));
startActivity(intent);
intent-filter
<intent-filter>
                <action android:name="xx" />
                <category android:name="xxxx" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="ab"/>
            </intent-filter>

        如果Intent中没有传入Uri,也没有传入type,只有filter中同样没有指定uri和type时才能匹配成功。

配置隐式Intent

        在安卓系统中本身就含有许多应用,可以通过查看源码获得隐式意图的设置,从而启动相应的组件,常见的如:启动系统的相机、图库等。

注意事项

        在使用隐式意图调用别的activity时,如果没有activity满足该intent对象,那么程序就会崩溃。因此,在调用隐式意图之前需要判断有没有activity能满足当前的隐式意图。判断的代码如下:

	public boolean hasActivities(Intent intent) {
		PackageManager pm = getPackageManager();
		List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
		return activities.size() > 0;
	}

        当系统中有多个应用可以响应当前的intent,默认情况下会弹出一个dialog,让用户进行选择,并且在选择的时候设置成默认的打开应用。一旦将某个应用设置成默认的打开应用,那么下次该种类型的intent会直接使用该应用打开,而不会再弹出dialog让用户进行选择。如果想每一次都让用户进行选择,那么可以使用Intent.createChooser(Intent,String),其中第二个参数为弹出dialog中的title,每一个参数为要响应的intent。该方法也会返回一个intent对象,将该对象直接使用到startActivity或者startActivityForResult()中即可。










你可能感兴趣的:(隐式Intent,IntentFilter与Uri)