如何去理解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 {
// 当接收到短信时被触发
@Override
public 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" > <application
android: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>

Android的BroadcastReceiver 广播 短信拦截的更多相关文章

  1. Android广播——短信拦截

    MainActivity.java package com.example.broadcasttest; import android.content.Intent; import android.c ...

  2. Android -- 怎么发出和接收广播, Broadcast, 电话拨号拦截,短信拦截

    1. 发送广播 使用以下三个API可以发送广播 public void click(View view){ Intent intent = new Intent(); intent.setAction ...

  3. android之短信拦截器

    下面通过短信拦截器来介绍短信中的广播 布局文件 在布局文件中可以设置需要拦截的号码 <?xml version="1.0" encoding="utf-8" ...

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

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

  5. [android] 手机卫士黑名单功能(短信拦截)

    前面我们把需要拦截的手机号都存储和展示出来了,接下来是使用广播接收者拦截短信了,这个广播接收者需要和一个服务绑定,服务开启的时候,接收者存在,服务停掉时,接收者关闭 在service包下定义一个类Ca ...

  6. Android应用源码安卓短信拦截木马项目源码

    温馨提示:本资源由源码天堂整理提供下载转载时请留下链接说明:http://code.662p.com/view/9174.html安卓短信拦截木马源码主要功能就是开机后台启动,拦截本机收到的短信并且转 ...

  7. android: 接收和发送短信

    8.2    接收和发送短信 收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这 项功能,而 Android 作为出色的智能手机操作系统,自然也少不了在这方面的支持.每个 A ...

  8. Android监听系统短信数据库变化-提取短信内容

    由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...

  9. 向android模拟器打电话发短信的简单方法

    在开发android应用程序时,有时候需要测试一下向android手机拨打电话发送短信时该应用程序的反应.譬如编写一个广播接收器,来提示用户有短信收到或者处理短信,就需要向该手机发送短信来进行测试.这 ...

随机推荐

  1. fzu 2111 Min Number

      http://acm.fzu.edu.cn/problem.php?pid=2111  Problem 2111 Min Number Accept: 572    Submit: 1106Tim ...

  2. Java基础(38):Calendar类的应用(优于Date类)

    Calendar 类的应用 Date 类最主要的作用就是获得当前时间,同时这个类里面也具有设置时间以及一些其他的功能,但是由于本身设计的问题,这些方法却遭到众多批评,不建议使用,更推荐使用 Calen ...

  3. android_demo01

    /layout/activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/ ...

  4. BackgroundWorker的使用

    一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能.   基本操作: bgw.RunWorkerAsync ...

  5. centos的用户管理相关命令所在的包

    用户管理命令是指:useradd userdel  groupadd groupdel 这些 这些命令出自一个叫 shadow-utils 的包. 对于配置文件 /etc/shadow ,则来自一个叫 ...

  6. zw版【转发·台湾nvp系列Delphi例程】HALCON ObjToInteger1-4

    zw版[转发·台湾nvp系列Delphi例程]HALCON ObjToInteger1 procedure TForm1.Button1Click(Sender: TObject);var img, ...

  7. Inside TSQL Querying - Chapter 3. Query Tuning

    Tuning Methodology When dealing with performance problems, database professionals tend to focus on t ...

  8. 关于 ActiveMQ

    今天玩了下 ActiveMQ,希望实现服务器的消息可以通知到各个客户终端. 安装: 1.安装 ActiveMQ 之前必须安装 Java 的 jdk , 可以从此下载:   http://www.ora ...

  9. HTML5之WebSocket

    在HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket API.WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术.这个新的API提供了一个方法 ...

  10. Ubuntu12.04 安装Samba

    Ubuntu12.04 安装Samba Ubuntu12.04 安装Samba 本教程介绍了在Ubuntu12.04安装Samba文件服务器,以及如何配置它通过SMB协议共享文件,以及如何将用户添加. ...