Android——事件过滤策略和 IntentFilter
来源:互联网 发布:lua 5.2 for windows 编辑:程序博客网 时间:2024/05/16 13:58
有一个问题,在网上被频繁的问到,就是为什么自定义的Receiver总是无法接收到SD卡插拔的事件。而此问题大部分情况下可以通过增加一句代码解决: filter.addDataScheme(“file”); // filter是IntentFilter对象
那么为什么增加这句代码就可以解决了呢? 在网上看到一遍比较通俗易懂的文章,觉得不错,摘抄过来做个笔记,供以后复习用。
SD卡插拔的广播事件示例代码
package com.silenceburn; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; public class SdCardTester extends Activity { BroadcastReceiver mReceiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.i("myLoger"," onCreate ......"); mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i("myLoger", "Component: " + intent.getComponent()); Log.i("myLoger", "Aciton: " + intent.getAction()); Log.i("myLoger", "Categories: " + intent.getCategories()); Log.i("myLoger", "Data: " + intent.getData()); Log.i("myLoger", "DataType: " + intent.getType()); Log.i("myLoger", "DataSchema: " + intent.getScheme()); Log.i("myLoger"," Receive SDCard Mount/UnMount!"); } }; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MEDIA_MOUNTED); filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); filter.addDataScheme("file"); registerReceiver(mReceiver, filter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(mReceiver); } }
运行结果:
通过日志输出我们可以得知挂载SD卡事件的 Componet 是null ,因此它是一个隐式事件。因此能否送达,需要看事件的 action, data , category 和 IntentFilter是否匹配。
1、ACTION是 android.intent.action.MEDIA_MOUNTED,和我们定义的IntentFilter的 filter.addAction(Intent.ACTION_MEDIA_MOUNTED); 语句相匹配。
因此action部分是匹配的。
2、Categories是null,而我们定义的 IntentFilter 也没有使用addCategory方法增加category定义,null == null,因此 categories也是匹配的。
3、action, data , category 中的两个要素已经匹配,那么能否匹配成功的关键,就是看data是否匹配了。
data匹配规则
首先务必认识到,data是一个相对复杂的要素。 data由URI来描述和定位,URI由三部分组成:
scheme://host:port/path 模式://主机:端口/路径
例如我们截获的挂载SD卡事件,它的data的URI是 file:///mnt/sdcard
其中模式部分是 file, 主机:端口部分是空的, path部分是mnt/sdcard
此外在事件中,还可以设置data的MIME类型,作为事件的datatype属性。
首先明确一个匹配原则,就是对于URI的匹配,只比较filter中声明的部分。
部分匹配原则:只要filter中声明的部分匹配成功,就认为整个URI匹配成功。
举例来说, content://com.silenceburn.SdCardTester:1000/mydata/private/
和filter定义为 content://com.silenceburn.SdCardTester:1000/ 是可以匹配的。
注意filter中并没有定义path部分,但是依然可以匹配成功,因为filter不声明的部分不进行比较。换句话讲,任何符合content://com.silenceburn.SdCardTester:1000/的事件,无论path是什么,都可以匹配成功。
接下来是真正的data部分的,也就是URI的匹配规则如下:
1. 如果data的URI和datatype为空,则 filter 的URI和type也必须为空,才能匹配成功。
2. 如果data的URI不为空,但是datatype为空,则 filter 必须定义URI并匹配成功,且type为空,才能匹配成功。
3. 如果data的URI为空,但是datatype不为空,则 filter 必须URI为空,定义type并匹配成功,才能匹配成功。
4. 如果data的URI和data都不为空,则 filter 的URI和type都必须定义并匹配成功,才能匹配成功。
对于URI部分,有一个特殊处理,就是即使filter没有定义URI,content和file两种URI也作为既存的URI存在。
(举个例子,对于 content 和 file 两种模式的data,只要filter定义的datatype可以和事件匹配,就认为匹配成功,filter不需要显式的增加 content 和 file 两种模式,这两种模式内置支持 )
针对SD卡插拔事件的分析
SD卡插拔是一个隐式事件,而且 action 和 category 部分和我们的 filter 均可以匹配成功。
其data部分的URI为 file:///mnt/sdcard ,datatype为 null ,因此应用上面比较规则中的 2 号规则,分析如下:
1、我们的filter中没有使用 addtype 方法 ,因此 filter 的type为空, datatype部分匹配成功。
2、data的URI为file:///mnt/sdcard ,我们使用filter.addDataScheme(“file”); 语句定义 schema 为 file,根据部分匹配规则,data匹配成功。
至此,整个事件匹配成功,至此,我们就明白了,为什么必须添加 filter.addDataScheme(“file”); 语句才能收到事件!
我们可以尝试把 filter.addDataScheme(“file”); 后面增加语句:
filter.addDataPath("mnt/sdcard",PatternMatcher.PATTERN_LITERAL);
依然可以匹配成功,收到SD卡插拔事件。因为这样就组成了一个URI的完全匹配。
文章转载于:http://blog.csdn.net/silenceburn/article/details/6083375
- Android——事件过滤策略和 IntentFilter
- android事件过滤策略
- android学习笔记——Intent和IntentFilter
- android--context和intentFilter
- Android Intent 和 Intentfilter
- android IntentFilter 使用之 data过滤
- android IntentFilter 使用之 data过滤
- 通过addDataScheme("file") 浅析android事件过滤策略
- 通过addDataScheme("file") 浅析android事件过滤策略
- 通过addDataScheme("file") 浅析android事件过滤策略
- Android——IntentFilter匹配规则
- Android 之 Intent 和 IntentFilter
- android基础知识:intent和intentfilter
- android Intent和intentFilter详解
- Android 读书笔记---Intent 和 IntentFilter
- Android Intent和IntentFilter详解
- android--Intent和IntentFilter详解
- IntentFilter的过滤规则
- 目录操作
- Android MeasureSpec 探索
- 黑马程序员——Java集合框架
- 转一篇我在简书上的一篇文章关于 navigationBar
- 八大排序代码总结
- Android——事件过滤策略和 IntentFilter
- hdu1305 Immediate Decodability (判断一串是否是另一串的前缀,暴力)
- 单链表的倒置
- KVC的使用
- MYSQL for MAC 的基本操作
- HDU-1505-City Game【dp】【思维】
- php常用函数
- windows常用API函数
- navigationBar 的渐变透明效果