Android 自动填写验证码

获取验证码几乎是每个应用所必备的,很多应用在用户注册的时候设置一个验证码的功能,根据手机号获取验证码的作用就是防止恶意注册。先来看一下效果图
这里写图片描述
上面的效果就是读取短信的信息,然后根据信息内容将验证码截取出来,赋值到输入框。具体的实现过程如下:
首先就是要读取短信,获取短信的内容,如何获取短信的内容呢,android将所有的短信信息都存入了mmssms.db中,如果要访问短信数据库里面的内容就需要一些协议了

content://sms/inbox        收件箱 
content://sms/sent        已发送 
content://sms/draft        草稿 
content://sms/outbox        发件箱 
content://sms/failed        发送失败 
content://sms/queued        待发送列表

根据上面的协议以及内容我们就知道,我们需要的tent://sms/inbox这个协议,因为我们的验证码是在收件箱里面的

cursor=MainActivity.this.managedQuery(Uri.parse("content://sms/inbox"),
                        new String[]{"_id", "address", "read", "body"},
                        "address=? and read=?", new String[]{"10690XXXXX", "0"}, "_id desc");//按id排序
                if (cursor!=null&&cursor.getCount()>0){
                    ContentValues values=new ContentValues();
                    values.put("read", "1");//修改短信为已读模式
                    cursor.moveToNext();
                    int smsbodyColumn=cursor.getColumnIndex("body");
                    String smsBody=cursor.getString(smsbodyColumn);
                    }

要注意10690XXXXX这个是你接收验证码的号码,也就是发送验证码那一方的号码,而不是本人的手机号码。
这里写图片描述
下面是数据库的字段以及说明

_id               一个自增字段,从1开始 
thread_id    序号,同一发信人的id相同 
address      发件人手机号码 
person        联系人列表里的序号,陌生人为null 
date            发件日期 
protocol      协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO  
read           是否阅读 0未读, 1已读  
status         状态 -1接收,0 complete, 64 pending, 128 failed 
type 
    ALL    = 0; 
    INBOX  = 1; 
    SENT   = 2; 
    DRAFT  = 3; 
    OUTBOX = 4; 
    FAILED = 5; 
    QUEUED = 6; 
body                     短信内容 
service_center     短信服务中心号码编号 
subject                  短信的主题 
reply_path_present     TP-Reply-Path 
locked

根据数据库中的字段以及说明我们就可以知道上面代码的作用了,上面的代码作用就是读取短信内容的。获取到短信内容以后我们还不算完成任务,因为我需要的是验证码,当然了要想获取验证码短信的获取是必不可少的,因为我们的验证码就包含在短信的内容里面的,所以我们要把验证码从短信内容里面分离出来,如何分离呢?

public String getVerificationCode(String str){
        Pattern pattern = Pattern.compile("(\\d{6})");
        Matcher matcher=pattern.matcher(str);
        String verificationCode;
        if (matcher.find()) {
            verificationCode = matcher.group(0);
            return verificationCode;
        }
        return "";
    }

就是根据验证码的位数来判断,Pattern.compile(“(\d{6})”)表示连续6位的数字,可以在这修改成自己想要的格式,如四位验证码就将6替换为4即可。我们还可以看到matcher.find(),这个find()是什么呢?find()方法是部分匹配,是查找输入串中与模式匹配的子串,而我们平时用的matches()则是全部查询匹配。还有就是matcher.group(0)这又是怎么回事呢?这就是正则表达式里面的组,关于组我们来说一下是什么意思

 String str = "name LiuYongxiang Robert!";
        Pattern pattern = Pattern.compile("Liu(Yong)(xiang)");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            System.out.println("matcher.group(0)---------->" + matcher.group(0));
            System.out.println("matcher.group(1)---------->" + matcher.group(1));
            System.out.println("matcher.group(2)---------->" + matcher.group(2));
        }

输出的的内容为
这里写图片描述
想必大家一看便知这组的作用了。Pattern.compile(“Liu(Yong)(xiang)”)这个方法里面的一个()代表一个组。还有就是LiuYongxiang这个内容之间是不能有空格的,除非你匹配的时候也有空格,所要的内容和要匹配的内容完全一致才能匹配成功。前面讲了如何获取短信内容和验证码,但是还要注意,我们要获取的短信的内容可不是之前的,而是我们点击获取验证码后获取的短信内容。这一点想必大家都清楚。这样的话我们就需要一个内容观察者,时时刻刻监视着短信内容的变化,而这个观察者就是ContentObserver。继承ContentObserver要重写onChange这个方法,这个方法的作用就是监听短信内容是否发生了变化。

class SmsContentObserver extends ContentObserver {
        private Cursor cursor;
        public SmsContentObserver(Handler handler) {
            super(handler);
        }
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            //读取收件箱中指定号码的短信
            try {
                cursor=MainActivity.this.managedQuery(Uri.parse("content://sms/inbox"),
                        new String[]{"_id", "address", "read", "body"},
                        "address=? and read=?", new String[]{"10690XXXXX", "0"}, "_id desc");//按id排序
                if (cursor!=null&&cursor.getCount()>0){
                    ContentValues values=new ContentValues();
                    values.put("read", "1");//修改短信为已读模式
                    cursor.moveToNext();
                    int smsBodyColumn=cursor.getColumnIndex("body");
                    String smsBody=cursor.getString(smsBodyColumn);
                    final String code = getVerificationCode(smsBody);
                    Message msg = new Message();
                    msg.what = VERIFICATION_CODE;
                    msg.obj = code;
                    mHandler.sendMessage(msg);
                }
            }catch (Exception e){

            }
            //在用managedQuery的时候,不能主动调用close()方法,否则在Android 4.0+的系统上会发生崩溃
            if (Build.VERSION.SDK_INT<14){
                cursor.close();
            }
        }
    }

有了这些还是不够的,既然是观察者当然少不了注册,下面是注册的代码

 SmsContentObserver smsContentObserver = new SmsContentObserver(mHandler);
 Uri smsUri = Uri.parse("content://sms");
 getContentResolver().registerContentObserver(smsUri, true, smsContentObserver);

点击下载源码

如有疑问欢迎留言,如果感觉对您有帮助还请给个好评再走。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值