DCloud_UNI_CHB
DCloud_UNI_CHB
  • 发布:2016-06-07 10:14
  • 更新:4 小时前
  • 阅读:31111

手机端监听短信验证码并自动提交表单

分类:Native.js

重要说明

鉴定短信验证码仅能在App端实现,其他端无法使用。但在App端,更为合理的方式其实是使用一键登录。即无需短信验证码,一键登录获取真实的手机号。
一键登陆的体验比短信验证码好很多,不需等待验证码、输入验证码,并且一键登陆的费用比短信便宜不少。
所以强烈推荐改用一键登陆,uni一键登陆的文档另见:https://uniapp.dcloud.net.cn/univerify

----------------------------------如不使用一键登陆,请继续阅读下文----------------------------------

目前很多App都选择使用手机号注册或手机号加动态验证码登录的方式,此时用户需要等待短信验证码,然后手动填写,再点击注册或登录按钮,完成注册登录操作。

本文介绍如何利用native.js,实现系统监听短信验证码并帮助用户自动填写验证码输入框,自动提交登录表单。

备注:目前仅支持Android平台

代码主要分为两个部分:

  • 标准短信监听部分
  • 个性短信内容及登录界面适配部分

标准短信监听部分
该部分为标准函数,开发者基本无需修改;

var callbacks = [];  
var receiver;  
var filter;  
var main;  
var isInit = false;  
var isRegistered = false;  
var isOlderVersion = false;  

//plusReady封装,若使用mui,可直接使用mui.plusReady()方法;  
var plusReady = function(){  
     if (window.plus) {  
        callback();  
    } else {  
        document.addEventListener("plusready", function() {  
            callback();  
        }, false);  
    }  
}  

/**  
* 初始化  
*/  
var init = function(callback) {  
    //仅支持Android版本  
    if (plus.os.name !== 'Android') {  
        return;  
    }  
    try {  
        var version = plus.runtime.innerVersion.split('.');  
        isOlderVersion = parseInt(version[version.length - 1]) < 22298;  
        main = plus.android.runtimeMainActivity();  
        var Intent = plus.android.importClass('android.content.Intent');  
        var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
        var SmsMessage = plus.android.importClass('android.telephony.SmsMessage');  
        var receiverClass = 'io.dcloud.feature.internal.reflect.BroadcastReceiver';  
        if (isOlderVersion) {  
            receiverClass = 'io.dcloud.feature.internal.a.a';  
        }  
        filter = new IntentFilter();  
        var onReceiveCallback = function(context, intent) {  
            try {  
                var action = intent.getAction();  
                if (action == "android.provider.Telephony.SMS_RECEIVED") {  
                    var pdus = intent.getSerializableExtra("pdus");  
                    var msgs = [];  
                    for (var i = 0, len = pdus.length; i < len; i++) {  
                        msgs.push(SmsMessage.createFromPdu(pdus[i]));  
                    }  
                    for (var i = 0, len = callbacks.length; i < len; i++) {  
                        callbacks[i](msgs);  
                    }  
                }  
            } catch (e) {}  
        }  
        receiver = plus.android.implements(receiverClass, {  
            a: onReceiveCallback,  
            onReceive: onReceiveCallback  
        });  
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");  
        callback && callback();  
    } catch (e) {}  
}  

//注册短信监听  
var register = function(callback) {  
    callbacks.push(callback);  
    if (!isInit) {  
        isInit = isRegistered = true;  
        plusReady(function() {  
            init(function() {  
                setTimeout(function() {  
                    //                  console.log('registerReceiver');  
                    try {  
                        if (isOlderVersion) {  
                            main.a(receiver, filter);  
                        } else {  
                            main.registerReceiver(receiver, filter); //注册监听  
                        }  
                    } catch (e) {}  
                }, 300);  
            });  
        });  
    } else if (!isRegistered) {  
        //      console.log('registerReceiver');  
        try {  
            if (isOlderVersion) {  
                main.a(receiver, filter);  
            } else {  
                main.registerReceiver(receiver, filter); //注册监听  
            }  
        } catch (e) {}  
    }  
};  
//注销监听,在登录成功或从登录页跳转到其它页面后调用  
var unregister = function(callback, remove) {  
    for (var i = 0, len = callbacks.length; i < len; i++) {  
        if (callbacks[i] === callback) {  
            callbacks.splice(i, 1);  
        }  
    }  
    if (remove && !callbacks.length) {  
        if (main && isRegistered) {  
            try {  
                if (isOlderVersion) {  
                    main.a(receiver);  
                } else {  
                    main.unregisterReceiver(receiver);  
                }  
            } catch (e) {}  
            isRegistered = false;  
            //          console.log('unregisterReceiver');  
        }  
    }  
};

个性短信内容及登录界面适配部分
这部分开发者需要根据具体App或登录页面,修改短信匹配内容和验证码输入框选择器,参考如下注释

//验证码匹配规则,需要根据实际站点匹配  
var codeRegex = /[0-9]{6}/g;  

var handleSMS = function(msgs) {  
    for (var i = 0, len = msgs.length; i < len; i++) {  
        var content = msgs[i].getDisplayMessageBody();  
        //匹配短信内容,若短信内容包含“XX网”,则认为初步匹配成功  
        if (~content.indexOf('XX网')) {  
            //匹配验证码规则,比如包含6位数字  
            var matches = content.match(codeRegex);  
            if (matches && matches.length) {  
                var code = matches[0];  
                //验证码输入框控件,需根据实际页面修改选择器  
                var codeElem = document.querySelector('.login-view form input[type="password"]');  
                if (codeElem) {  
                    codeElem.value = code;  

                    //TODO 这里可以取消短信监听  

                    //模拟表单提交,需根据实际页面修改选择器  
                    document.querySelector('.login-view form button[type="submit"]').click();  
                    plus.nativeUI.toast('获取短信验证码成功,自动登录..');  

                }  
                break;  
            }  
        }  
    }  
};  

//登录页面注册短信监听事件  
register(handleSMS);
23 关注 分享
赵梦欢 明峰 埃文 smileboyi wfc1870 草原狼 1***@qq.com 2***@qq.com 帅帅的让我疯狂 Trust lhyh 菜鸡 水灵退散 潇洒哥gg 老哥教教我 1***@qq.com 3***@qq.com 忘记我是谁 l***@gmail.com aliang888 袁述 asdasdsad 龙宗毅

要回复文章请先登录注册

coderhhan

coderhhan

小米手机 监听不得到额
4 小时前
coderhhan

coderhhan

监听不到 验证码的短信 但是能见听到10086的短信 这是为啥
23 小时前
coderhhan

coderhhan

为啥 真机调试有效果,打包之后就没生效了
4 天前
9***@qq.com

9***@qq.com

回复 谭小谭 :
ios不需要支持直接提供了
2021-10-28 09:23
谭小谭

谭小谭

我天,不支持ios,简直太不友好了吧
2021-10-18 10:28
m***@vip.qq.com

m***@vip.qq.com

双卡双待手机如何判断是哪个手机号来的短信?
2021-09-03 13:16
n***@163.com

n***@163.com

回复 n***@163.com :
用 plus.android.requestPermissions 去申请得到读取短信授权
2021-07-21 11:13
n***@163.com

n***@163.com

manifest.json写入了对应权限,真机连线调试正常,打包以后就失效了,请问是不是权限的问题?
2021-07-20 14:55
龙宗毅

龙宗毅

请问在调试模式下可以读取,打包后不能读取是什么问题?
2021-07-16 11:17
3***@qq.com

3***@qq.com

基座调试 报错了 Error in onLoad hook: "TypeError: Cannot read property 'plus' of undefined", 请问有谁遇到过吗?求指导!
2021-05-29 18:22