【android】利用ContentObserver监听短信来获取验证码
我们知道,可以通过注册广播的方法来读取短信,进而获取验证码,但实际应用起来是会有问题的,因为短信的广播是有序广播,假如有其他应用先捕获广播并终止传递,那么我们就永远也收不到这条短信变化的广播了。
所以,本文介绍的是一种更好的办法————————利用ContentObserver监听短信来获取验证码
先来点介绍性文字吧。
“ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。”
下面给出方案3的关键性代码:
1、AndroidManifest.xml文件中配置短信读取权限
2、监听短信变化的类
public class SmsContentObserver extends ContentObserver {private static final String TAG = "SmsContentObserver";//发送验证码的号码private static final String VERIFY_CODE_FROM = "106903331094102";//5位纯数字验证码private static final String PATTERN_CODER = "(?private Context mContext;private Handler mHandler;public SmsContentObserver(Context context, Handler handler) {super(handler);this.mContext = context;this.mHandler = handler;}@Overridepublic void onChange(boolean selfChange) {Uri inBoxUri = Uri.parse("content://sms/inbox");Cursor c = mContext.getContentResolver().query(inBoxUri, null,null, null, "date desc");if (c != null) {//while (c.moveToNext()) {//只取最新的一条短信if (c.moveToNext()) {String number = c.getString(c.getColumnIndex("address"));//手机号Log.d(TAG, "number:"+number);String body = c.getString(c.getColumnIndex("body"));if (number.equals(VERIFY_CODE_FROM)) {String verifyCode = patternCode(body);Message msg = Message.obtain();msg.what = 1;msg.obj = verifyCode;mHandler.sendMessage(msg);//break;}}c.close();}}private String patternCode(String patternContent) {if (TextUtils.isEmpty(patternContent)) {return null;}Pattern p = Pattern.compile(PATTERN_CODER);Matcher matcher = p.matcher(patternContent);if (matcher.find()) {return matcher.group();}return null;}}
当短信有变化时,把短信内容读取出来,并按时间由高到低排序。根据自己项目需要的短信验证码的格式匹配(我这里的匹配方法写的很LOW,-_-||)。找到后,可以不用继续读取短信直接break。这里通过Handler的去更新UI。
3、注册/取消注册监听
通常是在onResum中去注册短信监听,在onStop中取消注册。
@Overrideprotected void onStop() { super.onStop(); unRegisterSmsContentObservers();}@Overrideprotected void onResume() { super.onResume(); registerSmsContentObservers();}private void registerSmsContentObservers() { Uri smsUri = Uri.parse("content://sms"); //smsContentObserver是SmsContentObserver的一个实例,可以在onCreate中初始化 getContentResolver().registerContentObserver(smsUri, true,smsContentObserver);}private void unRegisterSmsContentObservers() { getContentResolver().unregisterContentObserver(smsContentObserver);}
注意,虽然我们监听的是收件箱inbox,但是在注册时需要监听所有短信的变化。这句很重要:
Uri.parse("content://sms")
不能写成
Uri.parse("content://sms/inbox")
其实,通过ContentObserver还能做很多事情。更多功能等待大家去发现。
另外,附sms主要结构:
_id:短信序号,如100
thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的
address:发件人地址,即手机号,如+86138138000
person:发件人,如果发件人在通讯录中则为具体姓名,陌生人为null
date:日期,long型,如1346988516,可以对日期显示格式进行设置
protocol:协议0SMS_RPOTO短信,1MMS_PROTO彩信
read:是否阅读0未读,1已读
status:短信状态-1接收,0complete,64pending,128failed
type:短信类型1是接收到的,2是已发出
body:短信具体内容
service_center:短信服务中心号码编号,如+8613800755500
参考:http://www.jianshu.com/p/5ccdcd9bed89、http://blog.csdn.net/mad1989/article/details/22426415
更多相关文章
- android手机开发课小结
- Android基于监听的事件处理
- Android数据库监听器+Demo
- Android开发实践:WIFI扫描功能的封装
- Android(安卓)自定义View的监听事件
- (迁移)android 上传短信乱码
- android自定义view 右侧字母导航
- 事件处理机制之基于监听的事件处理机制
- Android(安卓)API :SMS短信服务处理和获取联系人