前言

  上一篇博客,讲了BroadcastReceiver的一些基础内容,如何注册以及发送一个广播,那是基础,不清楚的可以先看看:Android--BroadcastReceiver。但是在实际开发当中,大部分情况下是不需要自己发布一个Broadcast或者接收自己定义的Broadcast的,一般而言,都是拦截系统在做某个操作而发布的Broadcast,对其进行相应的处理。这篇博客就以两个示例来讲讲Android系统中,如何拦截系统Broadcast并对其进行处理。

系统中的广播

  在Android系统中,内置了很多Action产量,在触发这些Action的时候,均会发布相应的Broadcast。一般而言,查看Android的API文档中,关于Intent的说明即可找到对应Action的Broadcast,但是列举的还不是很全,最好还是下载Android的源代码,通过查看源代码的方式查看需要拦截的Broadcast。

  下面列举一些常用的广播:

  • 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:拨打电话。

  下面通过两个例子,来讲解如何在Android下,拦截系统Broadcast并对其进行处理。

  1. 通过关键字拦截短信
  2. IP拨号

通过关键字拦截短信

  从上面列举的一些动作会发布的Broadcast,可以找到,当系统接收到一条短信的时候,会发布一个“android.provider.Telephony.SMS_RECEIVED”的Broadcast,之前已经介绍过了,一般系统Broadcast都是有序广播,如果不被高优先级的BroadcastReceiver停止传递,会按照优先级顺序传递下去。

  而在这个示例中,通过监听接收短信的广播,当其内容有黑名单中的关键字的话,则阻止Broadcast继续传播,并使用Toast提示,否则正常提示短信信息。

  通过上一篇博客了解到,onReceive方法的Intent参数包含了这条广播传递的参数,对于短信信息而言,需要获取key为"pdus"的数组,取出数组中每一项,它的每一项代表了一个byte[]格式的短信,需要使用SmsMessage类解析短信内容。

  当然,拦截短信的Broadcast侵犯了隐私,需要注册接收短信的权限:

 <uses-permission android:name="android.permission.RECEIVE_SMS"/>

  下面直接展示源代码了,关键注释已经写的很清楚了,这里不再累述:

  MessageBroadcast.java:

 package cn.bgxt.Broadcastdemo.MessageWarn;

 import java.text.SimpleDateFormat;
import java.util.Date;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast; public class MessageBroadcast extends BroadcastReceiver {
// 在模拟器上,通过DDMS发送短信会产生乱码,所以使用拼音代替
//在真机上不存在乱码的问题
private final String[] blackKeyWord = new String[] { "baoxian", "chuxiao",
"jiangjia" }; @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();
// 如果存在黑名单关键字内容,停止Broadcast传播
abortBroadcast();
} }
}
} } }

  在AndroidManifest.xml中配置Receiver。

         <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>

  效果展示,先发送一个包含黑名单中关键字的短信,再发送一个正常的短信。

IP拨号

  再来看看IP拨号的示例,在Android中,如果触发拨打电话的Action,则会发布一个"android.intent.action.NEW_OUTGOING_CALL"的Broadcast出来,只需要针对它进行拦截即可,然后在加上IP前缀,把处理过的号码添加到数据传递给下一个Receiver。

  处理接收拨打电话的Broadcast,需要对Android增加权限:

 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

 下面直接上代码了,注释写的很清楚,这里不再累述了。

  IpCallPhone.java:

 package cn.bgxt.Broadcastdemo.IpCall;

 import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent; public class IpCallPhone extends BroadcastReceiver {
private final String STARTS="17951";
@Override
public void onReceive(Context context, Intent intent) {
// 获取当前拨号的号码
String number=getResultData();
// 此号码没有被加IP拨号的前缀
if(!number.startsWith(STARTS)){
// 设置加了IP号码的号码
String newnumber=STARTS+number;
// 把新号码增加到返回结果数据中,用于传递给后面的Receiver
setResultData(newnumber);
}
}
}

  AndroidManifest.xml配置Receiver:

         <receiver android:name="cn.bgxt.Broadcastdemo.IpCall.IpCallPhone">
<intent-filter android:priority="200">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>

  效果展示:

  源码下载

总结

  Android系统中内置了非常多的Broadcast,用于对系统事件的响应、拦截、操作,这里只是介绍了两个比较典型的例子。在实际开发中,可以根据需要,查找Android源代码中相应的应用中的代码找到需要的Broadcast,以及如何处理的例子,这里就不一一介绍了。

Android--拦截系统BroadcastReceiver的更多相关文章

  1. 实现android手机来电拦截系统页面弹出自定义页面特效

    如何实现android手机来电拦截系统页面弹出自定义页面特效, 首先:    我们需要注册一个监听来电的广播PhoneStateReceiver 类:其次:    在onReceive里面我们获取an ...

  2. Android的系统体系结构

    目录: Android的系统体系结构 Android的四种常用组件 Activity的启动流程 Android的系统体系结构 在入门了一个简单的Android的Hello World以后,我们首先来看 ...

  3. Android系统架构-----Android的系统体系架构

    一.Android的系统体系结构 在入门了一个简单的Android的Hello World以后,我们首先来看一下我们Android的整体系统架构图: 这个就是我们Android的整体系统架构图了,我们 ...

  4. Android核心分析之十五Android输入系统之输入路径详解

       Android用户事件输入路径 1 输入路径的一般原理 按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题.按键,鼠标等用户消息 ...

  5. Android动画学习(一)——Android动画系统框架简介

    2015-11-09补充:Drawable Animation极有可能是Frame Animation 这几天在找工作,面试的时候被问到了Android动画,之前完全没接触过这部分,直接给懵了,当然其 ...

  6. HDU 1257 最少拦截系统【LIS】

    题意:类似于套娃娃,问最少需要多少个拦截系统. 思路: 假设已经有m个导弹拦截序列 r1:x11>=x12>=x13>=...>=x1n r1:x21>=x22>= ...

  7. Android入门(二):Android的系统架构

    android的系统架构和其操作系统一样,采用了分层的架构.从架构图看,android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和linux核心层.   从技术方面看,An ...

  8. HDU-1257 导弹拦截系统 http://acm.hdu.edu.cn/showproblem.php?pid=1257

    Problem Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高 ...

  9. 【HDU1257】最少拦截系统(贪心)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

随机推荐

  1. Ducci 队列 -基础queue,set

    https://vjudge.net/contest/185301#problem/B 用队列记录,set的不重复性来判断 //#include<bits/stdc++.h> #inclu ...

  2. python文件的路径问题补充上一篇内容

    上次的路径问题还没解决就被勒索病毒的木马器给搞了两周多, 拖拖拖到现在又开始纠结路径问题...还是学习能力不足啊... 补充一下路径问题的知识, 毕竟jupyter notebook跟IDE测试的时候 ...

  3. Open-Domain QA -paper

    Open-domain QA Overview The whole system is consisted with Document Retriever and Document Reader. T ...

  4. selenium 打开新标签页(非窗口)

    如何利用webdriver打开多个标签页和链接呢,到处查找得到的往往只是如何打开标签页. 打开标签页很简单,浏览器打开标签页的快捷键是ctrl+t,那把ctrl+t的按键事件传入即可,很多种实现方式, ...

  5. 用ttBulkCp把excel中的数据导入到timesten数据库中

    最近要做数据预处理,需要用到数据库.而且是以前从来没听说过的TimesTen. 首要目标是要把Excel里的数据,导入到TimesTen数据库中.而TimesTen在win10里用不了,于是我就在虚拟 ...

  6. URI ,URL 和 URN

    URI : 统一资源标识符,用来唯一标识互联网资源,包括URL和URN URL:统一资源定位器 包含: 协议,域名,端口,路由,参数,hash https://i.cnblogs.com/EditPo ...

  7. C#中添加log4net(日志文件)

    1.先下载引用“log4net” 2.然后再App.config配置 3.添加一个LogHandler类 4.在Assemblyinfo类中添加配置的读取文件 5.运用日志文件 6.显示结果

  8. tmux使用中出现的问题和解决方式

    常用操作: tmux ls 看当前都有哪些sessiontmux new -s my1 创建窗口,名为my1ctrl+B,D 退出窗口 (这个就是同时按ctrl和B,然后松开后再按D键)tmux at ...

  9. NOIP-火柴棒等式

    题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 1. 加号与等 ...

  10. Java_集合

    定义: 是一种工具,就像是容器,能存储任意数量的具有共同属性的对象. 与数组比较优点: (1)数组定义后长度不可变,集合长度可变: (2)数组只能通过下标访问,且下标类型只能是数字型,而有的集合(ma ...