Android中的 Intent 是非常重要的一个组件。"intent"在英语中的意思是"意图、目的",也就是说,Intent类也是一种用来表达某种意图的工具。
举个例子来说的话:比如你的界面有一个按钮,你希望如果点击了这个按钮就可以启动系统中的另一个相机程序进行拍照。在这里,"启动一个相机程序"就是你所要表达的意图(目的),这种意图就可以用一个 Intent 对象来实现。也就是说,Intent 是用来连接一个操作和一个响应结果的纽带,如果你触发了这个操作,那么就会出现相应的响应结果。
一个 Intent 对象可以用来做这样3件事情:
(1) 启动一个Activity,可以通过startActivity(Intent intent) 来实现。
(2) 启动一个Service,可以通过startService(Intent intent) 来实现。
(3) 分发广播
Intent的种类:
(1) 明确的意图(explicit intent) :指定某个确定的组件来达成意图。下面是一个使用明确意图的实例代码:
Intent intent = new Intent(this, SnifferService.class); //SnifferService是你自己定义的一个Activity
startService(intent);
(2) 含蓄的意图(implicit intent) :不指定具体由哪个组件来达成意图,而是把用户做出的的操作分发出去,如果某个组件能够处理这种操作就由这个组件来处理,但是如果有多个组件都能处理这个操作,那么将会弹出对框框让用户选择使用哪个组件来处理。下面是一个使用含蓄意图的实例代码:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
//如果没有能够处理该Intent的组件,那么程序将会崩溃,所
//以应该在调用startActivity()之前通过Intent.resolveActivity方
//法检查一下有没有能处理该Intent的组件
if (intent.resolveActivity(getPackageManager()) != null)
startActivity(intent);
Intent对象的组成:
1. 组件名称(Component name){
能够达成意图的组件的名称。通过setComponent()、setClass()、setClassName() 或着通过
Intent类的构造器来设定。
组件名称的设定是可选的,如果你设定了一个组件名称,那这个 Intent 就是一个明确意图,
当你执行了这个 Intent 绑定的 Action时,那么就会由组件名称中设定的那个组件来达成意图
。如果你不设定这个值,那这个Intent就是一个含蓄意图。
注意:出于安全性的考虑,你最好设置这个值使用明确意图,因为你无法确定有没有哪些危
险的服务会回应这个Intent。
}
2. 触发意图的行为(Action) {
触发该意图的操作。通过 setAction() 或 Intent类的构造器来设定。
}
3. 数据(Data) {
将要被处理的数据和数据的MIME类型。可以通过 setData() 来设定数据,通过setType()
来设定数据的MIME类型,如果要同事设置两项,可以使用 setDataAndType() 。
注意:如果要同时设定数据和MIMIE,请不要分别使用setData() 和setType() ,因为他们
会让各自的设定无效化。只能使用setDataAndType() 。
例如:如果设定的 Action 为 ACTION_EDIT,那么 Data 中就包含了要被编辑的那个文档的
URI。
}
4. 响应程序的类别(Category) {
用来描述哪类组件可以处理这个 Intent。通过 addCategory() 来设定。
}
一个Intent对象还可以携带额外的信息:
5. 额外信息(Extras) {
Intent附带的额外信息,是一组键值对(key/value),可以通过putExtra(key, value) 来添加额
外信息。
} 6.标记(flag) {
这种标记告诉系统该如何加载一个 activity(活动)并且在加载完毕后该怎么办。通过setFlag()
来设定。
}
如何处理含蓄的意图与意图过滤器:
我们之前提到如果一个 Intent 是一个明确的意图,那么如果我们触发了其 Action 就会引发这个 Intent对象所绑定的组件来做出相应的处理。那么如果一个含蓄的意图被触发了,将会由那些组件来处理这个意图呢?
这时候就要通过使用意图过滤器来抓取我们的程序想要处理的意图了。
这个问题就举个例子来说明吧:
比如现在有个程序A广播了一个含蓄意图,如果现在你希望你的程序B能够处理这个意图,那么就应该在B程序的工程目录
的 AndroidManifest.xml 文件中的<activity> 标签中添加如下代码:
<intent-filter>
<action android:name="android.intent.action.****" /> <!-- ****可以添加要处理的action -->
<data android:mimeType="****" /> <!-- ****可以为"text/html"、"text/plain"等 -->
<category android:name="android.intent.category.****" /> <!-- ****可以添加响应的category -->
</intent-filter>
含蓄意图的匹配规则:
当一个含蓄意图被广播后,系统会根据下列三个要素来决定由哪个 activity 来处理这个意图:
(1) 触发意图的行为(action)
(2) 数据(data)
(3) 响应程序的类别(category)
Action的匹配 {
如果一个 Intent 指定的 action 想要被通过过滤,那么这个 action 必须与过滤器中的某一
个<action>标签中的内容相匹配。
◇ 如果过滤器为空,那么所有的 Intent 都不能通过过滤。
◇ 但是如果 Intent 的 action 为空,那么 Intent 将通过过滤。
} Category的匹配 {
如果一个 Intent 中指定的 category 想要通过过滤,那么这个 Intent 中的每个 category
都必须对应一个过滤器中的<category>标签才可。
但是反过来则没有关系,过滤器中定义的<category>数量可以多余你的 Intent 中所指定
的 category 的数量。
◇ 一个没有指定 category 的 Intent 可以通过任何针对 category 的过滤。
} Data的匹配 {
过滤器中的每个<data>标签都可指定一个URI和一个MIME文件类型。
URI 的组成:<scheme>://<host>:<port>/<path>
每个URI的组成部分都是可选的,但是这几部分之间有这样一种依赖关系 {
<1> 如果 <scheme> 是空的,那么 <host> 就会被忽略
<2> 如果 <host> 是空的,那么 <port> 就会被忽略
<3> 如果 <scheme> 和 <host> 都是空的,那么 <path> 就会被忽略
}
当要对一个设置了 URI 的 Intent 进行过滤的时候,只是按照你的匹配器中<data>的URL
定义的部分进行匹配,比如:如果你只在匹配器的<data>的URI 中指定了 <scheme> ,那
么只要被检查 Intent 的 URI 的 <scheme> 部分通过了匹配就可以。如果你在匹配器的
<data>的URL 中指定了 <scheme> 和<host> ,那么被检查的 Intent 的URI 的这两个部分
必须都能通过过滤才可以。
过滤器中的<data>标签如果设定了 URI 和 MIME类型,那么被检查的 Intent 要想通过过滤
,那么它的URI 和 MIME 也必须全部通过过滤。反之,如果<data>标签中只指定的某一项
,那么被检查的 Intent 也同样只需要匹配指定的那一项即可通过过滤。
}
官方资料:
Interacting With Other Apps(与其他App的互动)
Intents And Intent Filters(意图和意图过滤器)
如果转载请注明出处:http://blog.csdn.net/gophers/article/details/21610647