DCloud_UNI_CHB
DCloud_UNI_CHB
  • 发布:2016-06-07 10:14
  • 更新:2024-03-04 14:34
  • 阅读:43757

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

分类: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);
24 关注 分享
赵梦欢 明峰 埃文 smileboyi wfc1870 草原狼 1***@qq.com 2***@qq.com 帅帅的让我疯狂 Trust lhyh 菜鸡 水灵退散 潇洒哥gg 老哥教教我 1***@qq.com 3***@qq.com 忘记我是谁 l***@gmail.com aliang888 袁述 asdasdsad 龙宗毅 小枫同学

要回复文章请先登录注册

1***@qq.com

1***@qq.com

回复 r***@163.com :
这个问题解决了吗,我也碰到了
2024-03-04 14:34
1***@qq.com

1***@qq.com

回复 coffey :
这个问题你解决了吗,好像用vivo的手机是才有这种问题
2024-03-04 14:34
1***@163.com

1***@163.com

回复 m***@vip.qq.com :
兄弟,你解决这个问题了吗
2022-09-26 14:53
踏江行

踏江行

权限"<uses-permission android:name=\"android.permission.READ_SMS\"/>"也加了 进不去onReceiveCallback
2022-06-16 18:55
m***@163.com

m***@163.com

貌似解决了
1 给足权限
2 imiu系统要给 通道栏短信权限
3 收到短信使用得时候要合并 短信太长会分段
2022-04-11 19:56
m***@163.com

m***@163.com

偶尔失败
2022-04-08 15:26
Aerial

Aerial

小米手机监听短信有的可以平台可以监听到短信内容,有的平台就不行,这是什么问题
2022-01-10 19:30
素来妆

素来妆

msg: "短信发送失败:other error"
这是什么错啊,太模糊了
2021-12-28 15:31
coderhhan

coderhhan

小米手机 监听不得到额
2021-12-07 11:33
coderhhan

coderhhan

监听不到 验证码的短信 但是能见听到10086的短信 这是为啥
2021-12-06 16:25