关于短信的读取以及新短信到达时如何触发事件去处理自己的逻辑

转载请注明:http://blog.csdn.net/binbinqq86/article/details/47154117


关于短信的获取已经是个老话题了,最近项目中需要用到这个功能,就是在用户注册的时候,当获取验证码后能自动填入输入框,网上找了一大堆,无非都是注册短信到达的广播,这种方式在虚拟机上是没有问题的,可是一到真机上,是根本行不通的。网上一搜,大把大把的这种方式,都是重复内容,为什么就不自己跑一遍呢???

经过自己的研究,解决了这个问题,主要思路就是通过反射,来调用系统的获取短信的方法,下面看代码:

Cursor cur = null;  
		try {
			clazz = Class.forName("android.provider.Telephony$Sms");
//			Object object = clazz.newInstance();
			Method[] ms=clazz.getMethods();
			Method me=clazz.getMethod("query", ContentResolver.class,String[].class,String.class,String.class);
			cur=(Cursor) me.invoke(null, getContentResolver(),null,"type=1 and protocol=0","date desc");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        if (null == cur)  
            return;  
        while (cur.moveToNext()) {  
        	Msg msg=new Msg();
            String number = cur.getString(cur.getColumnIndex("address"));//手机号  
            String date = cur.getString(cur.getColumnIndex("date"));
            String body = cur.getString(cur.getColumnIndex("body"));  
            msg.body=body;
            msg.date=date;
            msg.num=number;
        }  
 看着很简单吧,

android.provider.Telephony$Sms这个内部类下的query方法被置为hide标记,所以无法调用,通过反射就能很简单的获取系统的短信,那么当短信到达时怎么能立刻得知呢?这里就要用到内容观察者ContentObserver这个类,下面看代码:

class SmsObserver extends ContentObserver {  
  
        public SmsObserver(Context context, Handler handler) {  
            super(handler);  
        }  
  
        @Override  
        public void onChange(boolean selfChange) {  
            super.onChange(selfChange);  
            //每当有新短信到来时,会触发这个方法,可以在这里处理自己的逻辑,比如读取短信内容,自动填入验证码到输入框
        }  
    }  

注意:此时想要获得自己需要的短信的话,查询语句需要加些条件,具体短信数据库的主要字段的含义如下:

content://sms/inbox         收件箱  
content://sms/sent           已发送  
content://sms/draft          草稿  
content://sms/outbox      发件中 
content://sms/failed         失败  
content://sms/queued     待发送
 
数据库中sms相关的字段如下:    
 
_id                         primary key     integer                  与words表内的source_id关联
thread_id              会话id,一个联系人的会话一个id,与threads表内的_id关联      integer
address                 对方号码          text
person                  联系人id           integer             
date                      发件日期           integer
protocol               通信协议,判断是短信还是彩信     integer       0:SMS_RPOTO, 1:MMS_PROTO
read                      是否阅读           integer       default 0             0:未读, 1:已读  
status                   状态                  integer       default-1           -1:接收,
                                                                                                  0:complete,
                                                                                                64: pending,
                                                                                               128: failed 
type                     短信类型           integer                                   1:inbox
                                                                                                   2:sent
                                                                                                   3:draft56
                                                                                                   4:outbox
                                                                                                   5:failed
                                                                                                   6:queued            
body                      内容 
service_center      服务中心号码
subject                  主题 
reply_path_present 
locked
error_code
seen                    是否在通知栏显示通知  integer 0:显示,1:不显示


如果需要过滤特定的短信,只需要加上号码和未读条件即可。。。

注册下这个观察者:


        smsObserver = new SmsObserver(this, smsHandler);  
        getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, smsObserver); 

到此,我们在一开始的那个问题就完美的解决了大笑,心里那个酸爽~

想要完整代码的朋友可以留下邮箱,当然,主要核心代码就那么几行,相信大家自己也能写出来,最后不要忘记在mainfest中加入读取短信的权限。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值