Android 短信监听及用途分析
监听系统短信这个只能作为一个技术点来研究下,读者可能在工作中可能不会哦涉及到,一般的应用软件也不会有这个需求
但是作为程序员呢,多了解一下也是好的。
Android 监听系统短信有什么用?
1、对系统接收到的短信进行识别,是广告或者是诈骗等
2、对短信内容进行过滤或者是对内容进行提取,比如验证码提取
3、对系统短信进行拦截,连系统自己都不让收到了(不会出现在系统数据里面,也不会有系统短信的通知栏提示)
监听系统短信广播有什么坑?
1、系统短信广播为有序广播,要拦截的话,需要在注册广播的时候设置广播优先级为最大,不过这种也有风险,如果被其他的应用先拦截了,那么我们将不再收到,使用时需注意。
2、要接到系统短信广播,那么应用必须具备短信读取权限,这对使用者来说可能是一个限制
3、除了短信读取权限,有些手机需要同时具备彩信读取权限(小米手机),这个就有点苛刻了
4、如果不能够接受第3点,那么要使用另外一种方式获取短信内容了,那就是:通过监听系统短信数据库数据变化,这个单独写了一篇文章介绍http://www.cnblogs.com/popfisher/p/5455980.html
5、系统短信数据库也是通过监听短信广播的方式得到短信内容数据的,只是系统自己的东西它有默认权限允许,不担心因为权限问题收不到短信广播
第5点可以这样验证:自己写一个短信广播的接收者,把短信广播给拦截了,会发现系统自己也收不到短信内容了。
如果是上面几种场景你都可是通过监听系统短信广播,然后解析出系统短信的内容, 进而对短信内容进行其他相关处理
监听系统短信广播代码如下
private static class SmsReceiver extends BroadcastReceiver {
SmsReceiverProcessor mSmsReceiverProcessor;
SmsReceiver() {
mSmsReceiverProcessor = new SmsReceiverProcessor();
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
String action = intent.getAction();
if (SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED.equals(action)
|| SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED2.equals(action)
|| SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED_2.equals(action)
|| SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_GSM_SMS_RECEIVED.equals(action)){
mSmsReceiverProcessor.handleSms(intent);
}
// 如果需要拦截广播,调用下面语句
abortBroadcast();
}
}
public class SmsReceiverProcessor {
public static final String ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
public static final String ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED2 = "android.provider.Telephony.SMS_RECEIVED2";
public static final String ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED_2 = "android.provider.Telephony.SMS_RECEIVED_2";
public static final String ANDROID_PROVIDER_TELEPHONY_GSM_SMS_RECEIVED = "android.provider.Telephony.GSM_SMS_RECEIVED";
public SmsReceiverProcessor() {
}
public void handleSms(Intent intent) {
SmsMessage[] smss = SmsUtils.getMessagesFromIntent(intent);
if (smss != null && smss.length >= 1) {
StringBuilder bodyBuf = new StringBuilder();
String phoneNumber = ""; // 电话号码
long time = 0;
for (SmsMessage msg : smss) {
try {
bodyBuf.append(msg.getDisplayMessageBody());
phoneNumber = msg.getDisplayOriginatingAddress();
time = msg.getTimestampMillis();
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
final String smsContent = bodyBuf.toString(); // 短信内容
if (TextUtils.isEmpty(phoneNumber) || TextUtils.isEmpty(smsContent)) {
return;
}
// 获得短信号码和内容之后可以进行相关处理
System.out.println("phoneNumber: " + phoneNumber + " smsContent: " + smsContent);
}
}
}
// SmsUtils.java代码
public class SmsUtils {
public static SmsMessage[] getMessagesFromIntent(Intent intent) {
// moto的双模手机
if (isMotoTwoMode()) {
return getMessagesFromIntentInMotoXT800(intent);
}
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
if (messages == null) {
return null;
}
final int pduCount = messages.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
try {
for (int i = 0; i < pduCount; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[]) messages[i]);
}
} catch (Throwable e) {
return null;
}
return msgs;
}
private static SmsMessage[] getMessagesFromIntentInMotoXT800(Intent intent) {
String strFrom = intent.getStringExtra("from");
boolean bCDMA;
if (strFrom == null)
return null;
if (strFrom.equals("GSM")) {
bCDMA = false;
} else if (strFrom.equals("CDMA")) {
bCDMA = true;
} else {
return null;
}
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
byte[][] pduObjs = new byte[messages.length][];
for (int i = 0; i < messages.length; i++) {
pduObjs[i] = (byte[]) messages[i];
}
byte[][] pdus = new byte[pduObjs.length][];
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i++) {
pdus[i] = pduObjs[i];
SmsMessageBase obj = XT800CreateFromPdu(pdus[i], bCDMA);
try {
msgs[i] = SmsMessage.class.newInstance();
Field f = SmsMessage.class.getField("mWrappedSmsMessage");
f.set(msgs[i], obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return msgs;
}
// MOTO xt800上面的短信解析
private static SmsMessageBase XT800CreateFromPdu(byte[] pdu, boolean bCDMA) {
SmsMessageBase wrappedMessage = null;
if (bCDMA) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
}
return wrappedMessage;
}
// 判断是否是摩托的双模手机
public static boolean isMotoTwoMode() {
final String strXT800 = "XT800";
final String strXT800plus = "XT800+";
final String strXT806 = "XT806";
final String strXT882 = "XT882";
String model = Build.MODEL;
if (model != null) {
String upper = model.toUpperCase();
if (upper.equals(strXT800) || upper.equals(strXT800plus)
|| upper.equals(strXT806) || upper.equals(strXT882)) {
return true;
}
}
return false;
}
}
上面的代码需要导入两个类如下:
import android.telephony.SmsMessage;
import com.android.internal.telephony.SmsMessageBase;
接下来是注册广播,这里使用动态注册的方式,广播的注册与反注册结合Activity或者Service的生命周期来使用,具体不再详述。
广播的使用
private static BroadcastReceiver mSmsReceiver = null;
private static void registerSmsReceiver(ContextWrapper contextWrapper) {
try {
mSmsReceiver = new SmsReceiver();
IntentFilter filter = new IntentFilter(SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED);
filter.addAction(SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED2);
filter.addAction(SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_SMS_RECEIVED_2);
filter.addAction(SmsReceiverProcessor.ANDROID_PROVIDER_TELEPHONY_GSM_SMS_RECEIVED);
filter.setPriority(Integer.MAX_VALUE); // 这里虽然这是为整数最大值,但是实际上应该不允许超过系统运行的最大值1000,没验证
contextWrapper.registerReceiver(mSmsReceiver, filter, Manifest.permission.BROADCAST_SMS, null);
} catch(Throwable e) { }
} private static void unregisterSmsReceiver(ContextWrapper contextWrapper) {
try {
contextWrapper.unregisterReceiver(mSmsReceiver);
} catch(Exception e) { }
}
如果是简单的一点应用,使用上面的方式获取短信内容能够满足需求,但是如果对覆盖率要求高一点的需求可能就不行了,特别是对彩信权限或者其他权限的依赖会很不方便,所以多数时候使用监听系统短信数据库内容变化的方式来获取短信内容。
Android 短信监听及用途分析的更多相关文章
- Android短信监听软件
本案例是在android手机中运行,是一个没有界面的短信监听软件.主要是用BroadcastReceiver来接受短信广播,当接收到短信后就跳转到service中来转发短信.哈哈,不是用来干坏事的.这 ...
- Android短信监听(二)——利用ContentObserver实现短信监听
MainActivity例如以下: package cc.testsmslistener; import cc.testsmslistener.SMSContentObserver.MessageLi ...
- wemall app商城源码Android短信监听接收器
wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...
- Android短信监听实现,及Android4.4之后短信机制变更
前阵子公司有一个项目,简单的监听短信应用,功能只有如下两个: 1.监听短信并获取短信内容上传服务器: 2.从服务器获取短信内容,发送出去 按照传统的思路,监听短信我们有两种方式:第一种是使用广播 ...
- Android实战简易教程-第四十枪(窃听风云之短信监听)
近期在做监听验证码短信自己主动填入的功能,无意间想到了一个短信监听的办法. 免责声明:短信监听本身是一种违法行为,这里仅仅是技术描写叙述.请大家学习技术就可以.(哈哈) 本实例是基于bmob提供的后台 ...
- Android 编程下短信监听在小米手机中失效的解决办法
相信很多人写的短信监听应用在小米手机上是拦截不到短信的,这是因为小米对短信的处置权优先分给了系统.我们可以在短信的[设置]→[高级设置]→[系统短信优先]中发现短信的优先处理权默认是分给系统的,只要关 ...
- Android实现短信监听并且转发到指定的手机号,转发后不留痕
转载:http://blog.csdn.net/swqqcs/article/details/7252419 通过这些代码也可以对远程手机实现短信控制.有兴趣的可以自己改一下,说一下简单的原理,要实现 ...
- 赵雅智_BroadcastReceiver短信监听
AndroidManifest.xml 注冊广播接收者 加入权限 <?xml version="1.0" encoding="utf-8"?> &l ...
- Android短信收到,语音播报
发送短信功能界面 /** * 发送短信Demo * * @description: * @author ldm * @date 2016-4-22 上午9:07:53 */ public class ...
随机推荐
- JSP内置对象及常用方法
jsp九大内置对象及四个作用域: 何为作用域 先让我们看看效果: 大概流程是这样的,我们访问index.jsp的时候,分别对pageContext, request, session,applicat ...
- C++基础_总结
(1)多态性都有哪些?(静态和动态,然后分别叙述了一下虚函数和函数重载) 多态分为两种:静态和动态.静态主要包括函数重载和模板:动态主要是依靠虚函数实现的. 静态联编:重载函数不加virtual关键字 ...
- js生成二维码 中间有logo
描述: jquery.qrcode.js 是一个能够在客户端生成矩阵二维码QRCode 的jquery插件 ,使用它可以很方便的在页面上生成二维条码.此插件是能够独立使用的,体积也比较 ...
- 移动开发可能用到的css单位
众所周知CSS技术我们虽然很熟悉,在使用的过程却很容易被困住,这让我们在新问题出现的时候变得很不利.随着web继续不断地发展,对于新技术新 解决方案的要求也会不断增长.因此,作为网页设计师和前端开发人 ...
- 1 background(复合属性)与font(复合属性) 2 行内块的间距问题 3 行内元素的margin 4 清除浮动 5定位的元素的层级 6 Border-radius: 边框半径
1 background(复合属性)与font(复合属性): background: 颜色 图片的链接 是否平铺 背景位置 是否滚动.(可以随意调动或省略) Font: 粗度 字体风格 字体大小 ...
- CSS选择器小结
在CSS3中是提倡使用选择器来将样式与元素直接绑定在一起的. 网页开发过程中,我们需要定义很多class来应用到不同的元素上,由于class本身是没有语义而且是可以复用的,所以过度使用class会使得 ...
- 一种让 IE6/7/8 支持 media query 响应式设计的方法
在不同的浏览器宽度下使用不同的 CSS 声明,常见的方案是使用 media query,但这个方案不支持 IE9 以下浏览器. 国外比较流行的 UI 框架 bootstrap v3 版本中使用 med ...
- 简单一招实现json数据可视化
开发一个内部功能时碰到的需求,要把json数据在页面上展示出来,平时浏览器会安装jsonView这样的扩展来看json数据,但是程序要用到的话该怎么办呢?今天在网上搜索的时候,发现了这个小技巧,分享一 ...
- 【Paddy】数据库监控系列(一) - 监控理念
很多时候,都和身边朋友聊两个问题,DBA的日常工作都是哪些?什么才是数据库方面最重要的? 我相信这两个问题的答案每个人都不会完全一样,我也是,所以这里只代表我的个人观点,并且以下的内容将围绕我的思路展 ...
- iOS-----写一个规范的单例--->
1.集成了一个宏 2.两句代码集成单例 3.一句代码调用单例 -------------> 1.集成了一个宏 //这里就要注意了,因为每个单例中,方法名可以不一样,那么我们就不能把名字写死,要灵 ...