Android 监听短信2种方式:Broadcast和ContentObserver

1. 基于Broadcast接受短信

1.1 原理

Android收到短信后系统会发送一个android.provider.Telephony.SMS_RECEIVED广播。把它放在Bundle(intent.Extras)中,Bundle可以理解为一个Map,短信采用"pdus"作为键,pdus应该是protocol description units的简写,也就是一组短信。Android不是一接收到短信就立刻发出广播的,他会有一定的延迟,所以就有可能会有多条短信,所以才会用数组来存放。

1.2 实现方法一

原理已经清楚,那么实现是通过重写BroadcastReceiver.onReceive(Context context, Intent intent)函数,关键代码如下:

Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[messages.length];
smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
sender = smsMessage[n].getOriginatingAddress();// 获取短信的发送者
content = smsMessage[n].getMessageBody();// 获取短信的内容  

完整实现为:

public class EventReceiver extends BroadcastReceiver {
    private Context mContext;
    private static final String TAG = "REC_TEST";

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        SmsMessage[] smsMessages = null;
        Object[] pdus = null;

        if (bundle != null) {
            pdus = (Object[]) bundle.get("pdus");
        }
        if (pdus !=null){
            smsMessages = new SmsMessage[pdus.length];
            String sender = null;
            String content = null;

            for (int i=0; i<pdus.length; i++){
                smsMessages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                sender = smsMessages[i].getOriginatingAddress();
                content = smsMessages[i].getMessageBody();
                Log.v(TAG, "SMS:"+sender+content);
                //ShowToast(sender + " 短信", R.drawable.ic_dialog_email);
                Toast.makeText(context, sender + "," + content, Toast.LENGTH_LONG).show();
            }//for smsMessages
        }//if pdus
    }
}

1.3 注册Receiver

1.3.1 静态注册

在AndroidManifest.xml的application里面定义receiver并设置要接收的action。

receiver需要放在application标签之中

        <receiver android:name=".EventReceiver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

1.3.2 动态注册

在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。

	private BroadcastReceiver receiver;    

        @Override
        protected void onStart() {
                super.onStart(); 

                receiver = new CallReceiver();
                registerReceiver(receiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
        } 

        @Override
        protected void onStop() {
                unregisterReceiver(receiver);
                super.onStop();
        } 

2. 基于ContentObserver监听短信

2.1 原理

原理是通过监听短信数据库,操作短信内容。

下面是文献[3]对ContentObserver的介绍:

“ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。”

先不深究更加底层的内容,从表面上我们可以知道ContentObserver可以获取Uri引起的数据库的变化,短信的Uri为:

发送短信:content://sms/outbox

接收短信:content://sms/inbox

知道Uri后我们就可以获取到短信的内容了。

2.2 实现

实现的方法就是重载ContentObserver.onChange()方法即可

具体代码如下:

private class SmsObserver extends ContentObserver {

	public SmsObserver(Handler handler) {
		super(handler);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onChange(boolean selfChange) {
		// TODO Auto-generated method stub
                    //查询发送箱中的短信(正在发送中的短信放在发送箱中)
		Cursor cursor = getContentResolver().query(
				Uri.parse("content://sms/outbox"), null, null, null, null);

		while(cursor.moveToNext()){
			StringBuilder sb = new StringBuilder();
			sb.append("address="+cursor.getString(cursor.getColumnIndex("address")));
			sb.append(", body="+cursor.getString(cursor.getColumnIndex("body")));
			sb.append(", date="+cursor.getString(cursor.getColumnIndex("date")));

			Log.i("Observer", sb.toString());

		}
		cursor.close();

		super.onChange(selfChange);
	}
}

2.3 注册Listener

getContentResolver().registerContentObserver(
				Uri.parse("content://sms"), true, new SmsObserver(new Handler()));

3. 设置权限

要接收某些action,需要在AndroidManifest.xml里面添加相应的权限。

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

4. 参考文献

[1] BroadCastReceiver 简介 http://www.cnblogs.com/alwaysyouare/archive/2011/11/17/2252397.html

[2] Android电话、短信监听 http://blog.163.com/[email protected]/blog/static/1032422412013112343930567/

[3] Android中内容观察者的使用---- ContentObserver类详解  http://www.cnblogs.com/slider/archive/2012/02/14/2351702.html

时间: 2024-10-22 05:51:51

Android 监听短信2种方式:Broadcast和ContentObserver的相关文章

Android 监听短信 两种方式

1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. AndroidManifest.xml: <uses-permission android:name="android.permission.SEND_SMS"></uses-permission> <uses-permission android:name="android.permission.RECEIVE_SMS"

Android 监听短信(同时监听广播和数据库)

暗扣,强烈谴责这种侵害用户利益的行为... 下面给大家介绍Android暗扣原理.......  Android4.4以下的系统玩游戏就要小心了哈 暗扣方式之一:短信订购,即监听--------拦截------------处理短信. 暗扣方式之二:模拟人为操作(又叫模拟流量),通过后台程序代码模拟人的点击行为,暗自给用户订购业务,由运营商收取你的费用,当然这其中也需要涉及监听/拦截/处理短信.使用这种方式的原理无非是Http处理网页,还涉及接入点切换问题,这里就不详细讲解. 回归正题:有的时候,

android 监听短信并发送到服务器

1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. 2. 应用观察者模式,监听短信数据库,操作短信内容.   实例如下: SystemEventReceiver:收到开机启动OK的广播后,启动BootService服务:收到应用发送短信的INTENT后,调用系统接口发送短信 BootService:开启服务后,打开短信监听器 SMSObserver:数据观察者,监听短信数据库 SMSHandler:短信处理器

Android监听短信到来并自动填充到输入框中

基本原理:通过ContentObserver观察者监听sms数据库的改变,当有变化时检测是否是来自指定号码的短信,如果是的话就通过正则表达式获得需要的内容,然后贴代码 (*^__^*) 嘻嘻……: 1 /** 2 * 3 * @ClassName: SmsContent 4 * @Description: 短信监听类 5 * @author guoyizhe 6 * @email [email protected] 7 * @date 2015-6-9 下午3:30:12 8 * 9 */ 10

(七)android开发中两种方式监听短信的原理和实现

一.监听短信的两种方式的简介 Android程序开发中,有两种方式监听短信内容:一.接收系统的短信广播:二.应用观察者模式,监听短信数据库. 第一种方式接收系统的短信广播: A.这种方式只对新收到的短消息有效,运行代码,并不会读取收件箱中已读或未读的消息,只有当收到新来的短消息时,才会执行onReceive()方法. B.并且这个广播是有序广播,如果当别的程序先读取到了这个广播,然后拦截掉了个这个广播,你将接收不到.当然我们可以通过设置priority的数值,其实有时是不管用的,现在在一些定制的

Android实战简易教程-第三十六枪(监听短信)

一般用户喜欢用手机号作为用户名注册APP账号,这时一般都是通过手机验证码的方式进行验证,下面我们就研究一个非常实用的方法,通过监听短信-实现短信验证码的自动填入,提高用户体验. 首先我们看一下如何监听手机短信. 一.获取短信全部内容 1.新建一个SMSBroadcastReceiver: <code class="hljs java has-numbering"><span class="hljs-keyword">package</s

Android实战简易教程-第三十六枪(监听短信-实现短信验证码自动填入)

一般用户喜欢用手机号作为用户名注册APP账号,这时一般都是通过手机验证码的方式进行验证,下面我们就研究一个非常实用的方法,通过监听短信-实现短信验证码的自动填入,提高用户体验. 首先我们看一下如何监听手机短信. 一.获取短信全部内容 1.新建一个SMSBroadcastReceiver: package com.example.messagecut; import java.text.SimpleDateFormat; import java.util.Date; import android.

android菜鸟学习笔记23----ContentProvider(三)利用内置ContentProvider监听短信及查看联系人

要使用一个ContentProvider,必须要知道的是它所能匹配的Uri及其数据存储的表的结构. 首先想办法找到访问短信及联系人数据的ContentProvider能接受的Uri: 到github上找对应ContentProvider的源码:https://github.com/android 有好多个,哪一个才是短信数据的ContentProvider呢? 在filters输入框:输入telephony. 现在只有一个了,打开: 装有git的话,可以选择clone到本地,没有的话,就选择下载

通过broadcastreceiver 监听短信问题

在mainfest中 订阅   短信到来的广播时候  发现找不到 <action android:name="android.provider.Telephony.SMS_RECEIVED"> 目前未找到原因, 不知道,采用通过代码订阅广播方式 会不会成功 目前尚未验证 在网上人的回答 链接:https://www.zhihu.com/question/28521646/answer/64531805来源:知乎 1   因为这个广播很容易被不法分子拿来使用. google公