http://blog.csdn.net/dlutbrucezhang/article/details/8917774
http://developer.android.com/guide/components/intents-filters.html
Intent对象可以向操作系统描述我们需要处理的任务。使用显式Intent,我们需要指定具体的类名;而使用隐式Intent,我们只需要向操作系统描述清楚我们的工作意图,操作系统会去启动那些对外宣称能够完成任务的activity(即能匹配成功intent-filter的)。如果操作系统找到多个activity,那么用户将会看到可选列表,然后看用户自己如何选择了。通过隐式意图启动一些组件时,必须满足该组件所对应的<intent-filter>。
虽然隐式意图也可以带extra数据,但操作系统在寻找合适的activity时并不会使用任何附加在隐式意图上的extra信息。这并不意味着隐式意图上的extra信息没有用,同显式意图一样,intent一样会将它所带的extra信息带到寻找到的activity中。
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> <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>。
它指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" />它是不会被隐式意图启动的。
要操作的数据及数据类型。可以通过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的值。
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时才能匹配成功。
在安卓系统中本身就含有许多应用,可以通过查看源码获得隐式意图的设置,从而启动相应的组件,常见的如:启动系统的相机、图库等。
在使用隐式意图调用别的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()中即可。