参考网址:http://developer.android.com/intl/zh-cn/guide/components/intents-filters.html
1. intent 与intent filter的关系
intent的作用是启动目标组件,intent filter包含了被启动组件的配置信息,在清单文件中设置。
组件可在<intent-filter />中配置一些信息,表示自身被启动的条件。
当一个组件启动另一个组件时,可通过intent对象设置一些信息,符合这些信息条件的组件将会被启动。
2. 显式intent与隐式intent
比如一个组件想启动另一个组件,有两种情况:
①该组件知道目标组件的名称,通过intent告诉Android系统需要启动的组件名称是XXX,则是显式intent;
②该组件不知道目标组件的名称,却知道所要启动组件的条件信息,则通过 intent告诉Android系统需要启动的组件条件有哪些,则是隐式intent。
注意:启动Service组件应该使用显式intent,若使用隐式intent,则不知道有哪些Service被启动,有可能造成安全隐患。
3.intent可设置的条件
①组件名称
通过setClass(),setClassName(),setComponent()或者intent的构造方法设置组件名称。
②ACTION
通过setAction()或者intent的构造方法设置启动组件的动作。
ACTION有系统ACTION与自定义ACTION,自定义ACTION可以是任意字符串,一般写成“包名+动作名”。
③Data
setData():设置数据URI,格式为<scheme>://<host>:<port>/<path>
setType():设置MIME类型,MIME类型有“text/plain”,“image/*”,“video/*”等
setDataAndType():同时设置数据URI与MIME类型时,setData()与setType()不能一起同时使用,会覆盖彼此的数据。
应用场景:比如我们现在需要启动一个能够显示图片的组件,有一个组件在清单文件中在<data />中设置了MIME类型是"image/*",则会启动MIME类型是"image/*"的组件。
e.g.
<activity android:name="MainActivity">
<!-- This activity is the main entry, should appear in app launcher -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="ShareActivity">
<!-- This activity handles "SEND" actions with text data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
<!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/vnd.google.panorama360+jpg"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
</intent-filter>
</activity>
④Category (略,日后使用了解)
⑤Extra (略,日后使用了解)
⑥Flag (Activity专用)
setFlags():用来指定Activity如何被启动,与Activity的加载模式相对应
各参数详解:http://ivoter.iteye.com/blog/1596397
注意:若没有符合隐式Intent的Activity,则应用会崩溃,为了避免此情况发生,应在startActivity(intent)之前,判断Intent.resolveActivity(getPackageManager())是否为空。若为空,则不调用startActivity(intent)。
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
Intent.resolveActivity(getPackageManager())的源码如下:
public ComponentName resolveActivity(PackageManager pm) {
if (mComponent != null) {
return mComponent;
}
ResolveInfo info = pm.resolveActivity(
this, PackageManager.MATCH_DEFAULT_ONLY);
if (info != null) {
return new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
}
return null;
}