Android四大组件学习之BroadcastReceiver
来源:互联网 发布:mac破折号 编辑:程序博客网 时间:2024/05/22 02:00
广播的相关概念
BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度等。
虽然同属Android的四大组件,BroadcastReceiver也有自己独立的声明周期,但是和Activity、Service又不同。当在系统注册一个BroadcastReceiver之后,每次系统以一个Intent的形式发布Broadcast的时候,系统都会创建与之对应的BroadcastReceiver广播接收者实例,并自动触发它的onReceive()方法,当onReceive()方法被执行完成之后,BroadcastReceiver的实例就会被销毁。虽然它独自享用一个单独的进程,但也不是没有限制的,如果BroadcastReceiver.onReceive()方法不能在10秒内执行完成,Android系统就会认为该BroadcastReceiver对象无响应,然后弹出ANR(Application No Response)对话框,所以不要在BroadcastReceiver.onReceive()方法内执行一些耗时的操作。所以在BroadCast中不宜做一些耗时的操作。
Broadcast的注册方法
- 静态注册
静态注册是在AndroidManifest.xml文件中配置的,我们就来为MyReceiver注册一个广播地址
<receiver android:name=".MyReceiver"> <intent-filter> <action android:name="android.intent.action.TEST_BROADCAST"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
通过定义Receiver的action,只要是android.intent.action.XXX这个地址的广播,MyReceiver都能够接收得到,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,MyReceiver也会被系统调用而自动运行。
- 动态注册
动态注册需要在代码中动态的指定广播地址并注册,通常我们是在Activity或Service注册一个广播。
MyReceiver receiver = new MyReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("android.intent.action.TEST_BROADCAST"); registerReceiver(receiver, filter);
registerReceiver是android.content.ContextWrapper类中的方法,Activity和Service都继承了ContextWrapper,所以可以直接调用。在实际应用中,我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,
因此我们通常需要在onDestroy方法里释放广播。
注册完广播接收器后,我们就可以发送一条广播了:
Intent intent = new Intent("android.intent.action.TEST_BROADCAST"); intent.putExtra("msg", "hello receiver."); sendBroadcast(intent); }
这样,action为TEST_BROADCAST的接收器都可以收到这条广播。
广播的种类
上面的例子只是一个接收者来接收广播,如果有多个接收者都注册了相同的广播地址,这就要看广播的种类来安排接受顺序了。
普通广播(Normal Broadcast)
Normal Broadcast,它是完全异步的,也就是说,在逻辑上,当一个Broadcast被发出之后,所有的与之匹配的BroadcastReceiver都同时接收到Broadcast。优点是传递效率比较高,但是也有缺点,就是一个BroadcastReceiver不能影响其他响应这条Broadcast的BroadcastReceiver。有序广播
Ordered Broadcast,它是同步执行的,也就是说有序广播的接收器将会按照预先声明的优先级依次接受Broadcast,是链式结构,优先级越高(-1000~1000),越先被执行。因为是顺序执行,所有优先级高的接收器,可以把执行结果传入下一个接收器中,也可以终止Broadcast的传播(通过abortBroadcast()方法),一旦Broadcast的传播被终止,优先级低于它的接收器就不会再接收到这条Broadcast了。
在接受有序广播时,BroadCastReceiver需要设置优先级, 即 android:priority=”886” 属性,这个属性的范围在-1000到1000,数值越大,优先级越高。
然后使用sendOrderedBroadcast方法来发送有序广播,这个方法需要一个权限参数,如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。
系统常见的广播:
- android.intent.action.TIME_SET:系统时间被修改。
- android.intent.action.DATE_CHANGED:系统日期被修改。
- android.intent.action.BOOT_COMPLETED:系统启动完成。
- android.intent.action.BATTERY_CHANGED:设备电量改变。
- android.intent.action.BATTERY_LOW:设备电量低。
- android.intent.action.ACTION_POWER_CONNECTED:设备连接电源。
- android.intent.action.ACTION_POWER_DISCONNECTED:设备断开电源。
- android.provider.Telephony.SMS_RECEIVED:系统收到短信。
- android.intent.action.NEW_OUTGOING_CALL:拨打电话。
广播使用示例
从上面列举的一些动作会发布的Broadcast,可以找到,当系统接收到一条短信的时候,会发布一个“android.provider.Telephony.SMS_RECEIVED”的Broadcast,之前已经介绍过了,一般系统Broadcast都是有序广播,如果不被高优先级的BroadcastReceiver停止传递,会按照优先级顺序传递下去。
而在这个示例中,通过监听接收短信的广播,当其内容有黑名单中的关键字的话,则阻止Broadcast继续传播,并使用Toast提示,否则正常提示短信信息。从上面列举的一些动作会发布的Broadcast,可以找到,当系统接收到一条短信的时候,会发布一个“android.provider.Telephony.SMS_RECEIVED”的Broadcast,一般系统Broadcast都是有序广播,如果不被高优先级的BroadcastReceiver停止传递,会按照优先级顺序传递下去。
而在这个示例中,通过监听接收短信的广播,当其内容有黑名单中的关键字的话,则阻止Broadcast继续传播,并使用Toast提示,否则正常提示短信信息。
public class MessageBroadcast extends BroadcastReceiver { private final String[] blackKeyWord = new String[] { "Message1", "Message2", "Message3" }; @Override public void onReceive(Context context, Intent intent) { // 判断当前接收到的Broadcast是否是收到短信的action if (intent.getAction() .equals("android.provider.Telephony.SMS_RECEIVED")) { StringBuilder sb = new StringBuilder(); // 获取Broadcast传递的数据 Bundle bundle = intent.getExtras(); if (bundle != null) { Object[] pdus = (Object[]) bundle.get("pdus"); for (Object p : pdus) { byte[] pud = (byte[]) p; // 声明一个SmsMessage,用于解析短信的byte[]数组 SmsMessage message = SmsMessage.createFromPdu(pud); boolean flag = false; for (String str : blackKeyWord) { if (message.getMessageBody().contains(str) ) { // 发现黑名单关键字,则标记为true flag = true; break; } } if (flag) { sb.append("发件人:\n"); sb.append(message.getOriginatingAddress()); sb.append("\n发送时间:\n"); Date date = new Date(message.getTimestampMillis()); SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); sb.append(format.format(date)); sb.append("\n短信内容:\n"); sb.append(message.getMessageBody()); Toast.makeText(context, sb.toString(), Toast.LENGTH_SHORT).show(); else{ // 如果存在黑名单关键字内容,停止Broadcast传播 abortBroadcast(); } } } } } } }
AndroidManifest.xml:
<receiver android:name="cn.bgxt.Broadcastdemo.MessageWarn.MessageBroadcast"> <!-- 设置优先级,短信优先级为0,大于0即可 --> <intent-filter android:priority="200"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
- Android学习笔记--四大组件之BroadcastReceiver
- Android 四大组件学习之BroadcastReceiver一
- Android 四大组件学习之BroadcastReceiver二
- Android 四大组件学习之BroadcastReceiver三
- Android 四大组件学习之BroadcastReceiver四
- Android 四大组件学习之 BroadcastReceiver
- Android学习笔记四大组件之BroadcastReceiver
- Android学习之路--四大组件--BroadCastReceiver
- Android四大组件学习之BroadcastReceiver
- android四大组件之BroadCastReceiver
- android 四大组件之 broadcastreceiver
- android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- android四大组件之BroadcastReceiver
- 磁盘阵列RAID
- 第十三节 高阶函数
- 非常可乐HDU1495
- Differences between L1 and L2 as Loss Function and Regularization
- 模态框 ajax分页
- Android四大组件学习之BroadcastReceiver
- Java Socket close和Shutdown的区别
- systick定时器
- mysql一些常用的语句
- 云计算终将被边缘计算取代
- HTML5触摸界面设计与开发--笔记--javaScript性能优化
- android中的索引列表
- 使用Mingw-w64编译FreeImage
- CommentListTextView 一个TextView实现朋友圈的评论列表