通过ContentObserver自动获取短信验证码
在上一篇博客中讲到通过广播获取短信验证码,但是存在缺陷。这里讲一下如何通过ContentObserver来实现这个功能。关于ContentObserver这里就不再介绍了,主要是利用ContentObserver能监控到手机短信箱内容变化的原理来实现,实现过程如下文。
首先写一个类继承ContentObserver,重写onChange方法:
public class SmsContentObserver extends ContentObserver {
private String smsInboxUri = "content://sms/inbox";
private Context ctx;
private String sortOrder;
private String address = "10001";// 发送短信地址
public SmsContentObserver(Context ctx, Handler handler) {
super(handler);
this.ctx = ctx;
sortOrder = Sms.DATE + " desc";
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Uri uri = Uri.parse(smsInboxUri);
Cursor cursor = ctx.getContentResolver().query(uri, null,
null, null, sortOrder);
if (cursor != null) {
while (cursor.moveToNext()) {
if (cursor.moveToNext()) {
String number = cursor.getString(cursor
.getColumnIndex(Sms.ADDRESS));// 手机号
String smsbody = cursor.getString(cursor
.getColumnIndex(Sms.BODY));
Log.e("smsbody", number + "-->" + smsbody);
if (number.equals(address)) {
Log.e("smsbody", "10001" + "-->" + smsbody);
String regEx = "\\d{4}$";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(smsbody.toString());
String msgContent = "";
while (m.find()) {
msgContent = m.group();
Log.e("msgContent", "-->" + msgContent);
break;
}
}
}
}
cursor.close();
}
}
}
然后注册ContentObserver:
smsContentObserver = new SmsContentObserver(this, new Handler());
Uri smsUri = Uri.parse("content://sms");
getContentResolver().registerContentObserver(smsUri, true,
smsContentObserver);
最后,使用完不要忘了释放资源:
getContentResolver().unregisterContentObserver(smsContentObserver);
MainActivity完整代码如下:
public class MainActivity extends Activity {
SmsContentObserver smsContentObserver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
smsContentObserver = new SmsContentObserver(this, new Handler());
Uri smsUri = Uri.parse("content://sms");
getContentResolver().registerContentObserver(smsUri, true,
smsContentObserver);
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
getContentResolver().unregisterContentObserver(smsContentObserver);
}
}
输出日志:
注意点:
1. 在使用ctx.getContentResolver().query()查询的时候,加上查询条件可以提高查询效率。
2. 通过正则表达式对发送短信的号码进行匹配,可以只读取某个号码发送的短信。
试着读取手机收到的摩拜短信验证码,结果有时候能读到,有时候不行,后来发现是发送短信的号码不同,真是坑爹!
所以实际使用的时候,要注意address是否与实际发送短信的号码相一致。
同一手机运营商发送短信的号码都不同,如果是不同的运营商,号码也会不同。
如何判断手机运营商?可以看这个里面的方法:
http://blog.csdn.net/ceovip/article/details/77069789