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

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

分类: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 龙宗毅 小枫同学

要回复文章请先登录注册

r***@163.com

r***@163.com

求助,请问双卡的情况下 ,如何判断是哪个卡槽收到的短信?
2021-01-05 16:22
r***@163.com

r***@163.com

请问如何删除获取到的短信?求助! ... 急...
2020-12-08 20:06
你很精神

你很精神

回复 靖墨如霖 :
大佬你成功了吗,这个该怎么调用到uniapp上啊,完全没有头绪,方便的话帮我讲解下吧,万谢
2020-09-12 09:59
靖墨如霖

靖墨如霖

回复 178251115 :
我成功过,改天我写个专栏吧,这个监听不清楚的,还是会碰到坑的。
2020-08-28 20:24
靖墨如霖

靖墨如霖

回复 6***@qq.com :
这位兄弟,还在研究这项目吗?不是全部代码都放在onReady里,上面那个plusReady方法放在mui.plusReady()方法内,其它代码都封装调用的。哈哈这位楼主有空得来回复回复下问题了。@DCloud_UNI_CHB
2020-08-28 20:21
靖墨如霖

靖墨如霖

回复 1***@163.com :
是的 IOS不支持,init 上有写
//仅支持Android版本
if (plus.os.name !== 'Android') {
return;
}
2020-08-28 20:18
1***@163.com

1***@163.com

回复 raise :
ios不支持
2020-08-26 10:26
178251115

178251115

有人成功吗,贴下代码可以吗,一次都没有成功
2020-08-21 15:10
6***@qq.com

6***@qq.com

回复 靖墨如霖 :
这个应该怎么用啊 我直接把所有代码粘贴复制了 放在onReady里面 但是 没有用
2020-07-08 13:39
6***@qq.com

6***@qq.com

这个应该怎么使用啊 把代码都粘贴到短信验证码的页面吗
2020-07-08 11:51