怎么设置手机自动读取验证码短信验证码这个功能

Android实现短信验证码获取自动填写功能(详细版)
作者:灰太狼
字体:[ ] 类型:转载 时间:
这篇文章主要为大家详细介绍了Android实现短信验证码获取自动填写功能,很实用的功能分享给大家,感兴趣的小伙伴们可以参考一下
现在的应用在注册登录或者修改密码中都用到了短信验证码,那在android中是如何实现获取短信验证码并自动填写的呢?
首先,需要要在manifest中注册接收和读取短信的权限:&
&uses-permission android:name="android.permission.RECEIVE_SMS"&&/uses-permission&
&uses-permission android:name="android.permission.READ_SMS"/&&
实现一个广播SMSBroadcastReceiver来监听短信:
package com.example.
import java.text.SimpleDateF
import java.util.D
import android.content.BroadcastR
import android.content.C
import android.content.I
import android.telephony.SmsM
* 短信监听
public class SMSBroadcastReceiver extends BroadcastReceiver {
private static MessageListener mMessageL
public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
public SMSBroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED_ACTION)) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for(Object pdu:pdus) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte [])pdu);
String sender = smsMessage.getDisplayOriginatingAddress();
//短信内容
String content = smsMessage.getDisplayMessageBody();
long date = smsMessage.getTimestampMillis();
Date tiemDate = new Date(date);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = simpleDateFormat.format(tiemDate);
//过滤不需要读取的短信的发送号码
if ("+3".equals(sender)) {
mMessageListener.onReceived(content);
abortBroadcast();
//回调接口
public interface MessageListener {
public void onReceived(String message);
public void setOnReceivedMessageListener(MessageListener messageListener) {
this.mMessageListener = messageL
在需要填写验证码的Activity中,生产SMSBroadcastReceiver的实例,实现onReceived的回调接口。为了节约系统资源,我们使用动态注册注销广播的方法。&
package com.example.
import com.example.receive.SMSBroadcastR
import android.os.B
import android.app.A
import android.content.IntentF
import android.view.M
import android.widget.EditT
public class MainActivity extends Activity {
private EditText edtP
private SMSBroadcastReceiver mSMSBroadcastR
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtPassword = (EditText) findViewById(R.id.password);
protected void onStart() {
super.onStart();
//生成广播处理
mSMSBroadcastReceiver = new SMSBroadcastReceiver();
//实例化过滤器并设置要过滤的广播
IntentFilter intentFilter = new IntentFilter(ACTION);
intentFilter.setPriority(Integer.MAX_VALUE);
//注册广播
this.registerReceiver(mSMSBroadcastReceiver, intentFilter);
mSMSBroadcastReceiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.MessageListener() {
public void onReceived(String message) {
edtPassword.setText(message);
protected void onDestroy() {
super.onDestroy();
//注销短信监听广播
this.unregisterReceiver(mSMSBroadcastReceiver);
上面提供了一种获取短信息验证码并自动填写的实现方式,就是直接通过短信广播监听短信。但是,这种方式有它的缺陷:当你的手机安装了其他一些短信应用(例如QQ通讯录)或者手机本身限制了权限的情况下,这种方式有可能会不起作用,无法做到自动填写,而且就算把优先级设高,也不能保证不会被别的应用“抢先”。
后来查资料知道,可以通过监听短信数据库的方式实现。监听短信数据库主要是通过ContentObserver这个类来完成。ContentObserver主要是通过Uri来监测特定的Databases的表,当ContentObserver所观察的Uri发生变化时,便会触发它。思路就是监听短信数据库中特定号码的未读短信。我们可以通过百度找到许多demo,但是我发现很多demo中存在着Bug,在接收到短信后引起崩溃。还有一种情况,当真机连接着电脑,电脑装有类似豌豆荚之类的软件的时候,手机收到短信后,豌豆荚之类的可能会把该短信的状态改成“已读”,这样也会导致崩溃。
通过调试,终于把Bug修复了,布局和短信权限就不再赘述。在MainActivity中增加一个内部类SmsContent。
* 监听短信数据库
class SmsContent extends ContentObserver {
private Cursor cursor =
public SmsContent(Handler handler) {
super(handler);
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//读取收件箱中指定号码的短信
cursor = managedQuery(Uri.parse("content://sms/inbox"), new String[]{"_id", "address", "read", "body"},
" address=? and read=?", new String[]{"", "0"}, "_id desc");//按id排序,如果按date排序的话,修改手机时间后,读取的短信就不准了
MyLog.l("cursor.isBeforeFirst() " + cursor.isBeforeFirst() + " cursor.getCount() " + cursor.getCount());
if (cursor != null && cursor.getCount() & 0) {
ContentValues values = new ContentValues();
values.put("read", "1");
//修改短信为已读模式
cursor.moveToNext();
int smsbodyColumn = cursor.getColumnIndex("body");
String smsBody = cursor.getString(smsbodyColumn);
MyLog.v("smsBody = " + smsBody);
edtPassword.setText(MatchesUtil.getDynamicPassword(smsBody));
//在用managedQuery的时候,不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃
if(Build.VERSION.SDK_INT & 14) {
cursor.close();
记得在onCreate中注册短信变化监听&
SmsContent content = new SmsContent(new Handler());
//注册短信变化监听
this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content);
记得注销监听
&this.getContentResolver().unregisterContentObserver(content);
其中,下发的验证码短信一般都是一个字符串,其中包含6位数字,我们需要把这6位数字提取出来,我们可以用正则表达式写一个静态方法。&
* 从字符串中截取连续6位数字
* 用于从短信中获取动态密码
* @param str 短信内容
* @return 截取得到的6位动态密码
public static String getDynamicPassword(String str) {
Pattern continuousNumberPattern = pile("[0-9\\.]+");
Matcher m = continuousNumberPattern.matcher(str);
String dynamicPassword = "";
while(m.find()){
if(m.group().length() == 6) {
System.out.print(m.group());
dynamicPassword = m.group();
return dynamicP
至此,android获取短信验证码并自动填写的功能就实现了。
补充:对于上面短信数据库监听中有个直接关闭游标的操作(现在已经更正):cursor.close();&&
但是,如果这样直接关闭的话,会引起崩溃。例如,当获取了短信密码,自动填写上了之后,按home键返回桌面,然后再进入应用,会引起应用崩溃。报的错是:
android.database.StaleDataException: Attempted to access a cursor after it has been closed
后来通过查资料得知,是用managedQuery的时候, 不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃。对版本进行一个判断再执行关闭游标的操作。&
//在用managedQuery的时候,不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃
if(Build.VERSION.SDK_INT & 14) {
cursor.close();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具您的举报已经提交成功,我们将尽快处理,谢谢!
还是那个 秘书你只要直接按 回车好了就不用输了 `我现在就这么用``可是TX错喀的地方是限制了留言数目`22条过后就必须自己输入代码!给我分吧!
百度浏览器抢票学生版 6.0.19就不错的
你好朋友现在只能是手动输入验证码了,目前最新的360浏览器抢票专版比较不错,建议你安装用用。
大家还关注亲爱的开发者朋友:我们很高兴和大家分享一个消息,团队正式启用顶级域名,Mob即Mobile缩写,全面转型为移动
1、可以到AndroidManifest.xml文件中将下面的两个权限删除掉
& && &&&&uses-permission android:name=&android.permission.READ_CONTACTS& /&
& & & & &uses-permission android:name=&android.permission.READ_PHONE_STATE& /&
2、如果删除部分机型还不行的话,更新下新的版本就可以了。
免费咨询 | 24小时在线android读取短信内容&自动填充验证码
public class SmsContent extends ContentObserver {
&public static final String SMS_URI_INBOX =
"content://sms/inbox";
&private Activity activity =
&private String smsContent = "";
&private EditText verifyText =
&public SmsContent(Activity activity, Handler
handler, EditText verifyText) {
&&super(handler);
&&this.activity =
&&this.verifyText =
&@Override
&public void onChange(boolean selfChange) {
&&super.onChange(selfChange);
&&Cursor cursor =//
&&// 读取收件箱中指定号码的短信
&&cursor =
activity.managedQuery(Uri.parse(SMS_URI_INBOX), new String[] {
"_id", "address", "body", "read" }, "address=? and read=?",
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
new String[] { "5554", "0" }, "date desc");
&&if (cursor != null) {//
如果短信为未读模式
&&&cursor.moveToFirst();
(cursor.moveToFirst()) {
&&&&String
smsbody = cursor.getString(cursor.getColumnIndex("body"));
&&&&System.out.println("smsbody======================="
+ smsbody);
&&&&String
regEx = "[^0-9]";
&&&&Pattern
p = pile(regEx);
&&&&Matcher
m = p.matcher(smsbody.toString());
&&&&smsContent
= m.replaceAll("").trim().toString();
&&&&verifyText.setText(smsContent);
掉用该方法的地方的代码:
SmsContent content = new SmsContent(LoginActivity.this, new
Handler(), verifyText);
&&// 注册短信变化监听
&&this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"),
true, content);
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。android自动填写短信验证码功能_Android每日干货_传送门
你是真实用户吗(Are you a robot)?
我们怀疑你不是真实用户,已对你的访问做了限制。如果您是真实用户,非常抱歉我们的误判对您造成的影响,您可以通过QQ()或电子邮件()反馈给我们,并在邮件和QQ请求信息里注明您的IP地址:220.177.198.53,我们会尽快恢复您的正常访问权限。另外,如果您不是在访问的当前页面,我们建议您移步
或者 在浏览器中输入以下地址:http://chuansong.me/n/ 访问,您所访问的网站是从抓取的数据,请直接访问,会有更好的体验和更及时的更新。We suspect you are a robot.We are really sorry if you are not,and you can email us () with your current IP address: 220.177.198.53 to get full access to .If you are not accessing
for the current page,you'd better visit
for better performance,as the current website you are accessing is just spam.
觉得不错,分享给更多人看到
Android每日干货 微信二维码
分享这篇文章
7月19日 22:33
Android每日干货 最新头条文章
Android每日干货 热门头条文章

我要回帖

更多关于 短信验证码自动填写 的文章

 

随机推荐