官方解释:一个意图是
可以使用
一个消息传递对象向另一个应用程序组件请求一个动作。intent
在几个方面
促进组件之间的通信,有三个基本用例:
- 启动一个Activity
- startActivity()
- startActivityForResult() 你的activity将在onActivityResult()回调方法中接收到一个Intent。
- 启动一个Service
- startService()
- bindService()
- 发送一个广播
- sendBroadcast()、sendOrderedBroadcast()或者sendStickyBroadcast()
Intent分类
- 显式意图指定组件开始的名字(完全限定类名)。你通常在您自己的应用程序 使用一个显式意图启动一个组件,因为你知道你想启动的activity或service类名。例如,启动一个新的activity来响应用户操作或启动一个service在后台下载一个文件。
- 隐式意图不指定一个特定的组件的名字,而是声明一个通用执行的行动,它允许一个组件从另一个应用程序来处理它。举个例子,如果你想让用户打开在地图上的位置,您可以使用隐式意图来请求另一个能够显示一个地图上的指定位置的应用程序 。
当你启动一个显示意图的时候,系统立即会直接启动它
当你创建一个隐式意图,安卓系统会在其他app的manifest文件中IntentFilters找到与之匹配的组件,然后启动。如果有多个匹配选项,会提供给你选择。
你为一个组件在清单中设置了IntentFilters其他的APP就可以隐式启动你的组件,而如果没有IntentFilters就只能显式启动。
隐式启动组件的步骤:
- activity创建一个意图的action描述并将其传递到startActivity()
- 安卓系统在系统所有app清单文件中组件的IntentFilters中搜索与之匹配的。
- 系统启动一个匹配的activity,通过Intent唤醒它的onCreate()方法,进入ActivityB的生命周期。
警告:确保你的应用程序是安全的,开始时总是使用显式意图服务,不为你的服务声明意图过滤器。使用隐式意图启动一个服务是一个安全隐患,因为你无法确定服务响应的目的,用户无法看到哪个服务开启。从Android 5.0(API级别21)开始,
如果你用隐式Intent 调用bindService(),
系统会抛出异常。
创建一个Intent
Intent包含的主要信息:
- Component name(启动组件的name)
适用情况:显式启动一个指定的组件。启动服务必须以该方式(当我们用
实际上就是在源代码中创建ComponentName对象,为启动组件做准备
)
- Action 一个字符串,用来指定执行的action(例如视图或选择)。
特别是Broadcast Intent,report广播的时候适用action,这个action起着决定性因素的作用。如何组织其余的参数——特别是包含了data和extras。
你可以
在您的应用程序
指定自己的行动意图(或
在应用程序
使用其他应用程序来调用你的组件),但是你应该通常使用常量定义的行动意图类或其他框架类。下面是一些常用来启动activity的action:见
http://developer.android.com/reference/android/content/Intent.html
你也可以自定义一个action,例如:
static
final
String
ACTION_TIMETRAVEL
=
"com.example.action.TIMETRAVEL"
;
。需要在清单文件的IntentFilters中指定action,一般用于注册广播(也可以在逻辑文件中动态注册)。
- Data
URI(对象)代表被执行的data或者MIME类型的data。通常由intent的action决定提供data。
当创建一个intent,除了URI指定一个data(MIME)类型时非常重要的。例如,一个能够显示图片activity可能不能播放audio,即使它们的URI格式是相似的。我们可以从URI中推断出MIME类型——特别是当你的data是content:URI这种格式。这是有ContentProvicer提供的本地数据。 只设置数据URI,用setData()。只设置MIME类型,调用setType()。如果有必要,可以显式地设置两个setDataAndType()。
注意: 警告:如果你想设置URI和MIME类型,不叫setData()和setType(),因为他们的值是互斥的。总是使用setDataAndType()来设置URI和MIME类型。
- Category
一个包含你应该处理的intent的组件类型的额外信息的字符串,一个intent中可以添加任意个Category,但是大多数intent不需要category。category可以用来标记你应用的类型如:浏览器、图库、日历、联系人.....
- Extras
为了需要完成的操作携带额外的键值对信息,就像一些需要使用特殊类型数据URI的action,一些action也需要额外的extras。
你可以使用putExtra()方法,可以插入键值对,也可以put一个Bundle对象。
- Flags
Flags为intent起到元数据(metadata)的作用。他可以设置怎样启动一个activity(activity属于哪个task)和当它启动后怎么处理它(例如,他是否属于最新的activity列表)。
接收一个隐式intent
隐式intent需要在你们清单文件里面添加intent filters.
应用程序组件应该宣布独立的过滤器为每一个独特的工作可以做。例如,一个活动在一个图片库应用程序有两个过滤器:一个过滤器来查看图像,另一个过滤器来编辑图像。当活动开始时,它检查意图和决定如何基于行为意图的信息(如显示编辑器控件)。
Declares the intent action accepted, in the
name
attribute. The value must be the literal string value of an action, not the class constant.
Declares the type of data accepted, using one or more attributes that specify various aspects of the data URI (
scheme
,
host
,
port
,
path
, etc.) and MIME type.
<category>
Declares the intent category accepted, in the
name
attribute. The value must be the literal string value of an action, not the class constant.
注意:为了得到隐含的intent,你必须包括CATEGORY_DEFAULT类别的intent过滤器
例子:
<activity
android:name
=
"ShareActivity"
>
<intent-filter>
<action android:name = "android.intent.action.SEND" />
<category android:name = "android.intent.category.DEFAULT" />
<data android:mimeType = "text/plain" />
</intent-filter>
<intent-filter>
<action android:name = "android.intent.action.SEND" />
<category android:name = "android.intent.category.DEFAULT" />
<data android:mimeType = "text/plain" />
</intent-filter>
</activity>
如果有多重不同的需求,可以指定多个过滤器(这个东西以后再继续搞)。
使用Pending Intent
PendingIntent对象是用来包装一个意图对象。PendingIntent的主要目的是允许外来应用程序来执行所包含的意图就像从你的应用程序执行的过程。
用途主要包括:
- 声明一个intent当执行Notification上一个动作的时候调用(安卓系统的NotificationManager去执行Intent)
- 声明一个intent当执行App Widget上一个动作的时候调用(主屏幕app执行Intent)
- 声明一个intent在指定的时间执行(安卓系统的AlarmManager执行intent)
PendingIntent.getActivity()
for anIntent
that starts anActivity
.PendingIntent.getService()
for anIntent
that starts aService
.PendingIntent.getBroadcast()
for aIntent
that starts anBroadcastReceiver
.
注意:意图必须明确,这个不存在隐式意图