通过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

posted on 2017-08-27 23:00  lishbo  阅读(732)  评论(0编辑  收藏  举报