关闭

Android开发:实现APP自动填写注册验证码功能

标签: android广播接收者内容观察者验证码自动填写自动填写验证码
5313人阅读 评论(6) 收藏 举报
分类:

前言

此技术的实现原理是“广播接收者”和“内容观察者”。
利用接收到短信时的系统发出的广播进行短信的读取,并利用正则表达式解析出短信中的验证码。
在部分手机上,该广播被禁用,所以需要使用到内容观察者,在短信收件箱发生变化时,对短信数据库进行读取,得到相应验证码短信,并利用正则表达式解析出短信中的验证码。本文内容请使用于正规用途,请勿用于非法监听用户短信等恶意行为。谢谢合作!

本文原创作者xiong_it,本文原创链接:http://blog.csdn.net/Xiong_IT/article/details/50997084

本篇文章已授权微信公众号 guolin_blog(郭霖)独家发布.


使用广播接收者获取验证码

  • 广播接收者一般用法

    1. 继承BroadcastReceiver
    2. 重写onReceive(Context context, Intent intent);
    3. 注册自定义广播接收者(1.代码动态注册;2.清单文件注册)

使用广播接收者获取验证码实现代码如下:

public class ReadSmsCodeReceiver extends BroadcastReceiver {
    private static final String SMS_RECEIVED_ACTION =Telephony.Sms.Intents.SMS_RECEIVED_ACTION;// 接收到短信时的action

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SMS_RECEIVED_ACTION)) {
            getSmsCodeFromReceiver(intent);
        }
    }

    /**
     * 从接收者中得到短信验证码
     *
     * @param intent
     */
    private void getSmsCodeFromReceiver(Intent intent) {
        KJLoger.log(TAG, "getSmsCodeFromReceiver");
        SmsMessage[] messages = null;
        if (Build.VERSION.SDK_INT >= 19) {
            messages = android.provider.Telephony.Sms.Intents.getMessagesFromIntent(intent);
            if (messages == null) return;
        } else {
            messages = getSmsUnder19(intent);
            if (messages == null) return;
        }

        if (messages.length > 0) {
            SmsMessage sms = messages[0];
            // 短信发送人
            String smsSender = sms.getOriginatingAddress();
            // 短信内容
            String smsBody = sms.getMessageBody();

            // 检查短信发送者,和短信内容
            if (checkSmsSender(smsSender) && checkSmsBody(smsBody)) {
                // 解析短信内容,得到验证码
                String smsCode = parseSmsBody(smsBody);
                // 自定义的方法,用来发送验证码给Handler,进行填写
                sendMsg2Register(OBSERVER_SMS_CODE_MSG, smsCode);
            }
        }
    }

    /**
     * 当API低于19时的做法
     * @param intent
     * @return 短信实例
     */
    private SmsMessage[] getSmsUnder19(Intent intent) {
        SmsMessage[] messages;
        Bundle bundle = intent.getExtras();
        // 相关链接:https://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html#SMS_DELIVER_ACTION
        Object[] pdus = (Object[]) bundle.get("pdus");

        if ((pdus == null) || (pdus.length == 0)) {
            return null;
        }

        messages = new SmsMessage[pdus.length];
        for (int i = 0; i < pdus.length; i++) {
            if (Build.VERSION.SDK_INT >= 23) {
                String format = bundle.getString("format");
                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format);
            } else {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            }
        }
        return messages;
    }
}

以上,从短信广播中得到了Message实例,并得到短信。验证码获取方法为parseSmsBody(String smsBody),最后会统一讲解。

使用内容观察者得到短信验证码

  • 内容观察者的一般用法

    1. 继承内容观察者ContentObserver
    2. 重写onChange(boolean selfChange)方法
    3. 注册内容观察者
context.getContentResolver().registerContentObserver(uri, true, mReadSmsObserver);

使用内容观察者获取验证码实现代码如下:

public class ReadSmsObserver extends ContentObserver {
        private static final String SMS_INBOX_URI = "content://sms/inbox";//API level>=23,可直接使用Telephony.Sms.Inbox.CONTENT_URI,用于获取cusor
        private static final String SMS_URI = "content://sms";//API level>=23,可直接使用Telephony.Sms.CONTENT_URI,用于注册内容观察者
        private static final String[] PROJECTION = new String[]{
                Telephony.Sms._ID,
                Telephony.Sms.ADDRESS,
                Telephony.Sms.BODY,
                Telephony.Sms.DATE
        };
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            // 读取短信收件箱,只读取未读短信,即read=0,并按照默认排序
            Cursor cursor = getContentResolver().query(Uri.parse(SMS_INBOX_URI), PROJECTION,
                    Telephony.Sms.READ + "=?", new String[]{"0"}, Telephony.Sms.Inbox.DEFAULT_SORT_ORDER);
            if (cursor == null) return;

            while (cursor.moveToNext()) {
                // 读取短信发送人
                String address = cursor.getString(cursor.getColumnIndex(Telephony.Sms.ADDRESS));
                // 读取短息内容
                String smsBody = cursor.getString(cursor.getColumnIndex(Telephony.Sms.BODY));
                // 检查短信发送者,和短信内容
                if (checkSmsSender(address) && checkSmsBody(smsBody)) {
                    // 解析短信内容,得到验证码
                    String smsCode = parseSmsBody(smsBody);
                    // 自定义的方法,用来发送验证码给Handler,进行填写
                    sendMsg2Register(RECEIVER_SMS_CODE_MSG, smsCode);
                    // 关闭cursor的方法
                    closeCursor(cursor);
                    return;
                }
            }
            // 关闭cursor的方法
            closeCursor(cursor);
        }
    }

注意:注册短信观察者的Uri和获取Cursor的Uri不相同,如果使用获取Cursor的Uri进行注册,则得不到onChange回调。

正则表达式解析短信得到验证码

    /**
     * 解析短信得到验证码
     *
     * @param smsBody
     * @return 验证码
     */
    private String parseSmsBody(String smsBody) {
        String regex = new String("(\\d{4})");// 匹配规则为短信中的连续4位数字
        String smsCode = "";// 验证码

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(smsBody);

        while (matcher.find()) {// 如果匹配到了
            smsCode = matcher.group(0);
        }
        Log.w(TAG, "smsCode = " + smsCode);
        return smsCode;
    }

配置权限

    <!--用于读取短信验证码,缺一不可-->
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />

多说一句:笔者当时只配置了android.permission.READ_SMS权限,结果定义的短信广播接收者死活不回调onReceive(Context context, Intent intent);

本文原创作者xiong_it,本文原创链接:http://blog.csdn.net/Xiong_IT/article/details/50997084

填写验证码

将上述从广播接收者,内容观察者中得到的smsCode填入EditText输入框中即可。

笔者开源了一个AutoInputAuthCode类库,用于帮助开发者快速实现该功能,博客地址:http://blog.csdn.net/xiong_it/article/details/71451922

Github:https://github.com/xiong-it/AutoInputAuthCode

参考链接

Java正则表达式教材:http://www.runoob.com/java/java-regular-expressions.html
Android短信说明:https://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html#SMS_DELIVER_ACTION

5
0
查看评论

android app 自动填写短信验证码

public class SmsContentObserver extends ContentObserver { private Context mContext; private Handler mHandler;//更新UI线程 private String c...
  • sweetzhangxue
  • sweetzhangxue
  • 2017-04-06 17:20
  • 382

Android使用mob实现手机号验证注册

现在很多的app都采用首次进入使用手机号码快速注册成功,然后登入设置各种用户信息。这里使用mob第三方sdk实现手机号码的快速注册,实现起来也很简单,集成文档也有说明,这里把实现的过程和结果都记录下来,方便以后查用! 注册一个有效的mob账号 进入mob后台,使用短信验证SDK,然后添加一个应用(...
  • linxi7
  • linxi7
  • 2016-09-23 11:34
  • 3898

Android 开发第一步 短信验证码登录

目前的安卓开发中,常规的用户名+密码的登录方式已渐渐被账户+短信验证码替换掉。这主要是出于对用户信息安全的保证。现在和大家分享下关于短信验证码的使用。 首先,需要一个电话号码,目前很多账户都是将账户名设置成手机号,然后点击按钮获取手机验证码。 其次,你需要后台给你手机短信的验证接口,各个公司用的...
  • momoThree
  • momoThree
  • 2016-06-27 11:01
  • 5754

android 短信验证码自动填写的两种方式

实际应用开发中,会经常用到短信验证的功能,这个时候如果再让用户就查看短信.然后再回到界面进行短信的填写,难免有多少有些不方便,作为开发者.本着用户至上的原则我们也应该来实现验证码的自动填写功能,实现短信验证码自动填写有两种方式: 第一种,实现ContentObserver,把我们自己的Observ...
  • u010399316
  • u010399316
  • 2015-09-28 10:23
  • 2371

android获取短信验证码并自动填写

参考资料如下,亲测很好用,哈哈: http://blog.csdn.net/kaloda2011/article/details/21032829代码如下: MainActivitypublic class MainActivity extends AppCompatActivity { ...
  • jane1229
  • jane1229
  • 2016-09-12 17:11
  • 3347

各大APP注册时发送短信验证码是怎么实现的?

回答这个问题可以从多个角度来回答,比如商务角度和技术角度,为了快速清晰的让广大的读者了解这个过程,本文我们从商务角度来深入分析。   实现原理     现各大APP发送短信的服务一般是由第三方短信服务商提供的,他们整合了移动,联通、电信三方资源...
  • kaifaer
  • kaifaer
  • 2016-09-27 10:52
  • 7366

Android组件自动注册方案

今日快讯昨天向大家推送了我这个公众号的第一篇推广文章,最后的反响算是褒贬不一吧。我后来自己有反思一下,觉得还是应该给大家道个歉,这毕竟是我所接的第一篇推广,很多方面都考虑不周。其中最大的失误就是只做了宣传,没有做福利。仅仅向大家介绍了这样一个付费的面试专栏,却忘记申请优惠折扣了,这样的话大家虽说从我...
  • c10WTiybQ1Ye3
  • c10WTiybQ1Ye3
  • 2018-01-09 00:00
  • 55

Android短信验证码自动填写功能的实现

android应用经常会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,通常,用户收到短信需要最小化应用去查看短信再填入验证码,必然比较麻烦,因此有必要能够自动获得下发的短信验证码,方便了用户的操作,用户体验更好。
  • u014343528
  • u014343528
  • 2016-03-15 20:08
  • 2979

Android短信息验证码自动填写详细介绍

Android短信息验证码自动填写详细介绍 最新发现安卓验证码在获取验证码自动填写这块比较火,今天很好奇的去研究了一下,所以马上写博客将这块和大家一起分享,在自己的真机上面测试 通过 1、下面是获取验证码的整个流程图 接下面我就不多说废话了,直接贴我这块的代码了...
  • wangliang198901
  • wangliang198901
  • 2015-09-09 14:59
  • 961

Android开发:使用AutoInputAuthCode快速实现自动填写验证码

AutoInputAuthCode是一个帮助Android开发者快速实现自动填写验证码的类库
  • Xiong_IT
  • Xiong_IT
  • 2017-05-09 13:47
  • 1810
    个人资料
    • 访问:350029次
    • 积分:3487
    • 等级:
    • 排名:第11297名
    • 原创:60篇
    • 转载:5篇
    • 译文:3篇
    • 评论:171条
    我的Github
    博客专栏
    最新评论