在许多的APP中会涉及到获取短信验证码的选项,如果支持验证码自动填写会帮用户节省一部分操作
下面介绍一种简单的接到短信自动获取验证码填写到验证码输入框的方法
分下面几个步骤
主要是利用观察者模式,向短信服务(Sms),注册一个ContentObserver
创建一个ContentObserver
//可以写一个自定义的类继承自ContentObserver接口,也可以实现一个匿名ContentObserver的实现
public static class SmsObserver extends ContentObserver {
private Context context;
private Handler handler;
/**
* Creates a content observer.
*
* @param handler The handler to run {@link #onChange} on, or null if none.
*/
//构造方法里面传递一个Context和一个Handler,handler是用来更新UI线程
public SmsObserver(Context context, Handler handler) {
super(handler);
this.context = context;
this.handler = handler;
}
//当系统中短信发生变化(接收到短信)时,会调用这个函数,在这个函数中使用handler更新UI
@Override
public void onChange(boolean selfChange, Uri uri) {
// super.onChange(selfChange, uri);
Log.e("tag", uri.toString());
//当接收到短信时,会两次调用onChange函数,第一次数据库并没有发生变化(第一次调用uri为content://sms/raw),所以第二次调用才能取到短信内容,
if (uri.toString().equals("content://sms/raw"))
return;
Uri inbox = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
inbox = Telephony.Sms.Inbox.CONTENT_URI;
}
//取得系统的短信数据库内容,传递回来的是 一个cursor
Cursor c = context.getContentResolver().query(inbox,
null, null, null, null);
if (c != null && c.moveToFirst()) {
//取得短信的发件人
String address = c.getString(c.getColumnIndex(Telephony.Sms.ADDRESS));
//取得短信的内容
String body = c.getString(c.getColumnIndex(Telephony.Sms.BODY));
//使用正则表达式来过滤短信的验证码
Pattern pattern = Pattern.compile("(\\d{6})");
//进行正则表达式过滤
Matcher matcher = pattern.matcher(body);
String validerCode = "";
//如果满足条件,找到了验证码
if (matcher.find())
validerCode = matcher.group(0);
Log.e("tag", validerCode);
//将验证码通过handler传递给UI线程,在UI线程里面进行页面的更新
handler.obtainMessage(1, validerCode).sendToTarget();
}
}
}
在主线程注册短信观察Observer
//新建一个观察者,参数是Context和一个用于更新UI的handler
observer = new SmsObserver(this, handler);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//注册观察者,参数为URI,Flag和观察者对象
getContentResolver().registerContentObserver(CONTENT_URI, true, observer);
}
在Handler中实现主UI的更新
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//取个msg中的obj数据,并显示到TextView中
tv.setText(msg.obj.toString());
//取消注册
getContentResolver().unregisterContentObserver(observer);
}
};
主要过程就是,向系统短信服务注册一个观察者,当接收到短信时,会调用观察者的onChange函数,在该函数中取得系统的第一条短信的信息,可以判断发件人是否正确,然后取出短信的内容进行验证码的提取,最后通过构造函数传递进去的handler发送Message给UI线程,在UI线程中的handler的handleMessage(Message msg)中取出msg.obj进行UI页面的更新。