如何去理解BroadcastReceiver(广播)?其实可以这样想,首先我们要有一个发送广播的“媒体”,在这个例子中,我们暂且用activity组件作为这个媒体,当然以后会用到service,或者随机启动方式来发送广播,这看业务需求来决定。在这个例子中,当点击按钮的时候,一条广播就发送了出去,同样用到了意图对象Intent。和启动activity和service一样,我们需要为意图对象设置“标记”和“包裹”,它就像个基站,向世界发送信号。而对于广播自身而言,他就像一个监听器,一个系统级别的监听器,当然他也有他所监听的内容,不是什么都监听的,那么如何确定广播到底在监听什么呢?

    上面提到,意图这个基站被激活后向外发送信号,这个信号是带着“标记(action)”的,比如,基站发送了一条标记为 setAction("wuchen.broadcastReceiver.MY_RECEIVER")的信号,而在世界中监听的广播君,如果想要监听到这条信号,就需要让世界知道自己的存在,并且告诉世界自己要监听的信号的标记是什么,都要记录在案。这就需要在Manifest清单文件中进行注册:

    <receiver android:name=".MyBroadcastReceiver" ><intent-filter><action android:name="wuchen.broadcastReceiver.MY_RECEIVER" /></intent-filter></receiver>

    一但注册完成功后,每当有基站发送的信号同广播君向世界注册的标记匹配时,广播君就会启动并截获信息。其实广播接听的这个过程,上面的比喻需要调整一下,更严谨的说法是广播并不是随时都保持在一个监听的状态,而是在接收到Intent发出的广播和自己本身注册的信息匹配时,才会被触发,而且由于自身属于系统级别监听和程序级别监听不同的是:程序级别监听在程序终止后就没有监听作用了,而系统级别监听在被激活后会有自己的进程,比如当一个程序打开,并激活了一个系统级别监听,当这个程序关闭后,系统级别监听并不会随着这个激活他的程序的关闭而停止处理业务的作用,还会继续运行,除非他自己本身处理完业务需求后生命周期结束。

    严格上讲,系统级别监听的broadcastReceiver激活后也只能最多运行10秒钟,如果10秒内还没有处理完业务,Android会认为该程序无响应,并弹出ANR(application No Response)对话框。对于这种”限制“,我们处理这种限制的方式,也是项目中用到的最多一种方法:启动service。最可靠的方式是在广播中启动一个service,让service在后台去处理数据,这样就算广播生命周期结束,service也不会被销毁,因为用startService这种方式启动的service,就算访问者(广播)销毁自己也不会销毁,而且本来在广播中处理数据的耗时操作,交给了service去做,同时避免了ANR问题的出现。用启动新线程的方式也不可靠,广播的生命周期,就是内部onReceive方法的周期,当onReceiver方法结束,也就意味着广播的结束。

    虽然我们可以在onReceiver内执行启动一个新线程执行耗时的业务,由于onReceiver方法周期很短暂,可能出现的情况是:子线程还没有结束广播就关闭了,广播一旦关闭,虽然子线程还可以运行,但系统会认为广播处于无组件活动的状态,在内存紧张的时候优先结束该进程,这样可能会导致子线程不能执行完任务。所以最好的方式是启动service。

    需要注意的是,世界中接收同一个标记信号的广播君不局限只能存在一个,也许广播君A和广播君B监听的是同一个信号这是决不冲突的。但究竟是广播君A先接收到信号还是广播君B先接收到,这就涉及到了有序广播,和有序广播相对应的是普通广播。

    普通广播:普通广播可以让所有的广播君一起接收到信号(逻辑上),如果有10个广播君,那么是个都可以接收到,无法停止信号的传播。

    有序广播:有序广播传播的方式如同传递,比如有10个广播君,A传到B,B再到C,以此类推,如果传到D后,D想终止信号的传播,那么D以后的广播君就接收不到信号了。虽然这10个广播君都在等待接收同一个信号,但在D这里,就有权利终止信号的传输。 有序广播还有一个特点,广播君可以将自己的内容传给下一位唯一需要确定的是,到底是广播君A先接收到还是广播君B先接收到,这就需要在广播君们在注册时,考虑到”优先级“的问题了。在配置文件的每个receiver中的intent-filter标签中添加一个属性android:priority="100",数字越高优先级越大。

    <receiver android:name=".MyBroadcastReceiver" ><intent-filter android:priority="11" ><action android:name="wuchen.broadcastReceiver.MY_RECEIVER" /></intent-filter></receiver><receiver android:name=".MyBroadcastReceiver_B" ><intent-filter android:priority="10" ><action android:name="wuchen.broadcastReceiver.MY_RECEIVER" /></intent-filter></receiver>

普通广播(Normal Broadcast):

一,优缺点:和有序广播的优缺点相反!

二,发送广播的方法:sendBroadcast()

 

有序广播(Ordered Broadcast):

一,优缺点

优点:1,按优先级的不同,优先Receiver可对数据进行处理,并传给下一个Receiver

             2,通过abortBroadcast可终止广播的传播  

缺点:效率低  

二,发送广播的方法:sendOrderedBroadcast()   

三,优先接收到Broadcast的Receiver可通过setResultExtras(Bundle)方法将处理结果存入Broadcast中,下一个Receiver 通过 Bundle bundle=getResultExtras(true)方法获取上一个 Receiver传来的数据     

上面讲了很多关于广播的很多基础概念,那么BroadcastReceiver在实际的应用中到底会起到样的作用呢?

因为广播是一个系统级别的监听器,所以它可以将不同进程间通信的一个“纽带”。举个简单的例子,我们知道在我们启动service是如果用startService这种方式启动时,访问者和service之间是不能进行数据的“互动”的,但是有了BroadcastReceiver就一样可以进行互动,方法我大致说一下,在activity端创建一个broadcast,同样在service端也创建一个broadcast,相互监听对方的动作,这样就可以达到进程间通信的目的了。

短信拦截

BroadcastReceiver还可以监听系统进程,比如android的收短信,电量低,电量改变,系统启动,等……只要BroadcastReceiver监听了这些进程,就可以实现很多有趣的功能,比如,接收短信的这条广播是一条有序广播,所以我们可以监听这条信号,在传递给真正的接收程序时,我们将自定义的广播接收程序的优先级大于它,并且取消广播的传播,这样就可以实现拦截短信的功能了。

我们只需要一个BroadcastReceiver类,就可以实现这个功能,不需要activity,也不需要布局文件。当然如果需要更加的商业化,需要改进的地方还有很多。比如我们可以做一个界面让用户从联系人中指定一个号码进行短信拦截,也可以自定义。

public class SmsReceiver extends BroadcastReceiver {// 当接收到短信时被触发@Overridepublic void onReceive(Context context, Intent intent) {// 如果是接收到短信if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {// 取消广播(这行代码将会让系统收不到短信)abortBroadcast();StringBuilder sb = new StringBuilder(); // 接收由SMS传过来的数据 Bundle bundle = intent.getExtras(); // 判断是否有数据 if (bundle != null) { // 通过pdus可以获得接收到的所有短信消息 Object[] pdus = (Object[]) bundle.get("pdus"); // 构建短信对象array,并依据收到的对象长度来创建array的大小 SmsMessage[] messages = new SmsMessage[pdus.length]; for (int i = 0; i < pdus.length; i++) { messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); } // 将送来的短信合并自定义信息于StringBuilder当中 for (SmsMessage message : messages) { sb.append("短信来源:"); // 获得接收短信的电话号码  sb.append(message.getDisplayOriginatingAddress()); sb.append("\n------短信内容------\n"); // 获得短信的内容  sb.append(message.getDisplayMessageBody()); } } Toast.makeText(context, sb.toString(), 5000).show(); } } }

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="wuchen.broadcastReceiver"android:versionCode="1"android:versionName="1.0" ><applicationandroid:icon="@drawable/icon"android:label="@string/app_name" ><receiver android:name=".SmsReceiver" ><intent-filter android:priority="800" ><action android:name="android.provider.Telephony.SMS_RECEIVED" /></intent-filter></receiver></application><!-- 授予程序接收短信的权限 --><uses-permission android:name="android.permission.RECEIVE_SMS" /></manifest>

转载于:https://www.cnblogs.com/chenxibobo/p/6136689.html

Android的BroadcastReceiver 广播 短信拦截相关推荐

  1. android实现接收短信,Android 使用 BroadcastReceiver 接收短信

    在 Android 6.0 或者之后的版本中要主动请求用户授权,具体方法,可以参考我之前写的这篇文章 <Android 6.0+ SMSManager 使用示例 发送短信> 广播中接收并处 ...

  2. android手机短信拦截的实现

    以前刚开始接触android时对诸如短信拦截之类的功能很感兴趣,网上很多文章都介绍了使用广播接收android.provider.Telephony.SMS_RECEIVED的动作,从而接收到SMS信 ...

  3. 关于Android短信拦截

           今天参加了培训公司筹划的面试,主要是关于安卓客户端的技术面试,总结这次面试我决定写一些总结,首先就是关于我所写的手机通讯录的短信拦截功能的介绍:手机在接收到短信后会发出一段广播,我们只需 ...

  4. 关于Android短信拦截(二)

    题外话:因为这是一篇来自百度的文章,并且在好多网站中都有转载,但却没有标明出处,所以我也搞不清作者是何人,特在此声.另外,关于这个例子的实现,一定要注意权限的设置,我在这里例子的实验中,由于没有找到S ...

  5. Android短信拦截机制适配的坑(下)--4.4以上系统,主要是6.0

    前一篇文章,Android短信拦截机制适配的坑(上)--4.4以下系统 介绍了广播接收的顺序,但是我明确说明在4.4以下系统,那么4.4及以上系统会遇到说明问题呢? 首先我们要来了解4.4系统短信的机 ...

  6. Android 短信拦截及用途分析

    监听系统短信这个只能作为一个技术点来研究下,读者可能在工作中可能不会哦涉及到,一般的应用软件也不会有这个需求 但是作为程序员呢,多了解一下也是好的. Android 监听系统短信有什么用? 1.对系统 ...

  7. Android 动态注册短信拦截

    前段时间研究短信拦截.涉及广播动态注册这一快. 一点心得,记录下来. 短信拦截原理: android系统在接收到短信后,会进行判读有没有应用监听着短信接收广播,有的话则先传给用户应用进行处理,应用处理 ...

  8. android 黑名单 短信拦截

    上一篇讲了电话拦截,现在讲一下短信拦截. 由于android4.4以上,提高了系统的安全性,同时,也对短信的处理进行了保护 先来讲一下在android4.4以下的短信拦截机制 在android4.4一 ...

  9. Android 来电(包括铃声),短信拦截的实现方法

    关于拦截的文章我之前写过拦截Back按键和Home按键的处理方法,今天就开发过程中关于电话,短信的拦截做一个总结. 一:拦截来电的功能实现 现在的Android版本已经把Phone类的相关API给隐藏 ...

最新文章

  1. 利用.NET的XML序列化解决系统配置问题
  2. 机器学习模型越来越大,开发者应该如何部署?
  3. 检测生成.xml文件的效果:以人脸xml为例
  4. Customer Material Info in CRM and C4C
  5. java cpu io高_服务器负载过高问题分析-不是cpu高负载也不是IO负载如何处理(阿里 几乎是必考题)...
  6. ubuntu14.04安装hadoop2.7.1伪分布式和错误解决
  7. java如何多表断网,java Web如何离线使用并进行数据同步
  8. Guava库学习:学习Concurrency(九)RateLimiter
  9. python迭代器_Python迭代器
  10. 关于WM下创建和删除GPRS接入点
  11. 【Axure图标库】单线形图标元件库 细线矢量图标1000+
  12. Android系统 ——高通平台刷机流程(qfil)
  13. LANDrop局域网文件传输神器
  14. Android 7.0 抓包
  15. Linux学习基础一 【安装 目录 系统命令 常用vim操作】
  16. Spring Boot 2020 官方基础68课程第十六个 Securing a Web Application
  17. 原研哉:设计是什么?
  18. 蹩脚的程序员们,我们来谈谈你的未来!
  19. (CVPR-2018)Non-local Neural Networks
  20. 《你好,放大器》----学习记录(三)

热门文章

  1. 最近一月的娱乐生活:看电影,玩游戏
  2. MDK调试错误之assert_failed
  3. 如何在 Windows Server 2003 中创建漫游用户配置文件
  4. 怎么做逆向geocoding?
  5. Upma Xmac 测试 03
  6. shell之常用脚本
  7. 5G时代 我国在通信技术领域弯道超车指日可待
  8. Java 代码的基本知识
  9. windows 下Android的开发准备
  10. Interference Signal 第八届