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

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

分类: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