Android获取短信验证码并自动填充的两种方式「建议收藏」

Android获取短信验证码并自动填充的两种方式「建议收藏」有些项目为了方便客户操作,减去客户输入短信验证码的时间,会要求安卓app能够获取收到的短信验证码并自动填充到输入框。所以,我整理了安卓获取短信验证码并自动填充输入框的两种方法,而且正式在项目中使用并无bug。      一:监听短信库的变化,获取收到的短信内容,并通过正则表达式取出数字验证码填充到输入框中。代码如下:      publicclassObtainSmsVerifyC

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

       有些项目为了方便客户操作,减去客户输入短信验证码的时间,会要求安卓app能够获取收到的短信验证码并自动填充到输入框。所以,我整理了安卓获取短信验证码并自动填充输入框的两种方法,而且正式在项目中使用并无bug。

       一:监听短信库的变化,获取收到的短信内容,并通过正则表达式取出数字验证码填充到输入框中。代码如下:

       public class ObtainSmsVerifyCode {

 private Uri SMS_INBOX = Uri.parse(“content://sms/”);
 private Context context = null;
 private Handler handler = new Handler();
 private SmsObserver smsObserver;
 private SmsCodeReceivedListener listener = null;
 private String patternCoder = “(?<!\\d)\\d{6}(?!\\d)”;
 private ApplicationContext application = new ApplicationContext();

 /**
  * @Description: 获取到短信验证码监听
  */
 public interface SmsCodeReceivedListener {

  public void onSmsCodeReceived(String code);
 }

 public ObtainSmsVerifyCode(Context context) {

  this.context = context;
  ContentResolver cr = context.getContentResolver();
  smsObserver = new SmsObserver(handler);
  cr.registerContentObserver(SMS_INBOX, true, smsObserver);
 }

 public void setOnSmsCodeReceivedListener(SmsCodeReceivedListener lis) {

  listener = lis;
 }

 public void unRegisterContentObserver() {

  ContentResolver cr = context.getContentResolver();
  cr.unregisterContentObserver(smsObserver);
 }

 /**
  * @Description: 获取验证码
  */
 private void getVerifyCodeFromSms() {

  ContentResolver cr = context.getContentResolver();
  /**
   * address:发件人手机号码
   * date:发件日期
   * read:是否阅读
   * status:状态,-1接受
   * body:短信内容
   */
  String[] projection = new String[] { “address”, “body”, “date”, “type”,
    “read” };
  Cursor cursor;
  try {

   cursor = cr
     .query(SMS_INBOX, projection, null, null, “date desc”);
   if (cursor != null) {

    if (cursor.moveToFirst()) {

     SimpleDateFormat dateFormat = new SimpleDateFormat(
       “yyyy-MM-dd hh:mm:ss”);
     Date d = new Date(cursor.getLong(cursor.getColumnIndex(“date”)));
     String date = dateFormat.format(d);
     StringBuilder sb = new StringBuilder();
     sb.append(
       “发件人手机号码:”
         + cursor.getString(cursor
           .getColumnIndex(“address”)))
       .append(“信息内容:”
         + cursor.getString(cursor
           .getColumnIndex(“body”)))
       .append(“是否查看:”
         + cursor.getString(cursor
           .getColumnIndex(“read”)))
       .append(“类型:”
         + cursor.getInt(cursor.getColumnIndex(“type”)))
       .append(date);
     LogUtil.i(“sb=======” + sb);
     if (listener != null) {

      if (SmsServiceUtils.smsPhoneNum(application.getSegmentId())
        .contains(
          cursor.getString(cursor
            .getColumnIndex(“address”)))) {

       LogUtil.i(“here is it=====”
         + cursor.getString(cursor
           .getColumnIndex(“address”)));
       if (hasSixNumOrNot(cursor.getString(cursor
         .getColumnIndex(“body”)))
         && cursor
           .getString(
             cursor.getColumnIndex(“body”))
           .contains(
             “BOC Online Electronic Services”)) {

        listener.onSmsCodeReceived(patternCode(cursor
          .getString(cursor.getColumnIndex(“body”))));
       }
      }
     }

    }
    cursor.close();
   }
  } catch (Exception e) {

   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 /**
  * 匹配短信中间的6个数字(验证码等)
  *
  * @param patternContent
  * @return
  */
 private String patternCode(String patternContent) {

  if (TextUtils.isEmpty(patternContent)) {

   return “”;
  }
  Pattern p = Pattern.compile(patternCoder);
  Matcher matcher = p.matcher(patternContent);
  if (matcher.find()) {

   return matcher.group();
  }
  return “”;
 }
 /**
  * 判断短信中间是否包含6位数字(验证码等)
  * true:包含;false:不包含
  * @param patternContent
  * @return
  */
 private boolean hasSixNumOrNot(String patternContent) {

  if (TextUtils.isEmpty(patternContent)) {

   return false;
  }
  Pattern p = Pattern.compile(patternCoder);
  Matcher matcher = p.matcher(patternContent);
  if (matcher.find()) {

   return true;
  }
  return false;
 }

 /**
  * @Description: 监听短信数据
  */
 class SmsObserver extends ContentObserver {

  public SmsObserver(Handler handler) {

   super(handler);
  }

  @Override
  public void onChange(boolean selfChange) {

   super.onChange(selfChange);
   LogUtil.i(“selfChange===” + selfChange);
   getVerifyCodeFromSms();
  }
 }
}

     其中,SmsObserver是监听短信库变化的类,当短信库发生变化的时候会走OnChange的回调,此时遍历短信库,取出最近一条信息,信息包含的内容已经标记在代码的文档注释中,通过限制条件判断收到短信是否是工程所需发件人发过来的信息,同时根据正则表达式取出数字验证码,并通过SmsCodeReceivedListener接口,对外暴露所取出的短信验证码,在外面输入框就可以接收短信验证码。在关闭页面的时候,要调用unRegisterContentObserver()方法,取消对短信库的监听,以防内存泄露。

       二:通过自定义广播接收器,接收短信发过来的广播内容。代码如下

       public class SMSReceiver extends BroadcastReceiver {

 public static final String SMS_RECEIVED_ACTION = “android.provider.Telephony.SMS_RECEIVED”;
 private Context context;
 private EditText editText;
 private String patternCoder = “(?<!\\d)\\d{4}(?!\\d)”;

 public SMSReceiver(Context context, EditText editText) {

  super();
  this.context = context;
  this.editText = editText;
 }

 @Override
 public void onReceive(Context context, Intent intent) {

  if (intent.getAction().equals(SMS_RECEIVED_ACTION)) {

   SmsMessage[] messages = getMessagesFromIntent(intent);
   for (SmsMessage message : messages) {

    LogUtil.i(message.getOriginatingAddress() + ” : “
      + message.getDisplayOriginatingAddress() + ” : “
      + message.getDisplayMessageBody() + ” : “
      + message.getTimestampMillis());
    String smsContent = message.getDisplayMessageBody();
    LogUtil.i(smsContent);
    editText.setText(patternCode(smsContent));
   }
  }
 }

 public final SmsMessage[] getMessagesFromIntent(Intent intent) {

  Object[] messages = (Object[]) intent.getSerializableExtra(“pdus”);
  byte[][] pduObjs = new byte[messages.length][];
  for (int i = 0; i < messages.length; i++) {

   pduObjs[i] = (byte[]) messages[i];
  }
  byte[][] pdus = new byte[pduObjs.length][];
  int pduCount = pdus.length;
  SmsMessage[] msgs = new SmsMessage[pduCount];
  for (int i = 0; i < pduCount; i++) {

   pdus[i] = pduObjs[i];
   msgs[i] = SmsMessage.createFromPdu(pdus[i]);
  }
  return msgs;
 }

 /**
  * 匹配短信中间的4个数字(验证码等)
  *
  * @param patternContent
  * @return
  */
 private String patternCode(String patternContent) {

  if (TextUtils.isEmpty(patternContent)) {

   return null;
  }
  Pattern p = Pattern.compile(patternCoder);
  Matcher matcher = p.matcher(patternContent);
  if (matcher.find()) {

   return matcher.group();
  }
  return null;
 }

}

       SmsMessage的详细用法可以参考API或者网上搜索一下具体用法。至于广播的注册和解绑都是基本知识,也不再赘述。

       其他还要注意在清单配置文件中加上短信读写和接收权限

<uses-permission android:name=”android.permission.READ_SMS” />
   <uses-permission android:name=”android.permission.RECEIVE_SMS” />
   <uses-permission android:name=”android.permission.WRITE_SMS” />

另外,所谓的短信获取并自动填充,是在发送的短信格式是合法格式的前提下才成立,测试在短信平台发送的不合法的短信模板应该是不可能完全限制并拦截的。比如交易短信只包含6位数字,那合法短信本身就应该只会包含六位连续数字,不会在短信中出现几个连续六位数字,这是不合理的。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/160022.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Cover Letter实用指南

    Cover Letter实用指南1、什么是CoverLetter?指的是投稿信2、coverletter的内容主要包括那些?应该简述所投稿件的核心内容、主要发现和意义,拟投期刊,对稿件处理有无特殊要求等(如“nottoreview”list)。另外,请附上主要作者的中文姓名、通讯地址、电话、传真和e-mail地址。此外有的杂志要求推荐几位审稿人及其联系方式。以及谁已经阅读过该文(当然是牛人)。

    2022年5月1日
    51
  • vue使用axios解决跨域_vue前端解决跨域的方法

    vue使用axios解决跨域_vue前端解决跨域的方法工具版本:【vue-V】:2.9.6ide工具:VSCode/Idea前提:我们前端vue工程需要单独部署一、本地使用命令运行跨域问题。外网访问的地址:https://www.runoob.com/try/ajax/json_demo.json本地springboot接口访问的地址:http://192.168.3.12:8081/register/getSmsCode/1234567891、axios访问的代码: created(){ const_this=this

    2025年10月28日
    4
  • 2021 idea激活码最新(破解版激活)

    2021 idea激活码最新(破解版激活),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月17日
    75
  • iPhone 开发分辨率 持续更新

    iPhone4s:320*480iPhone5s/SE:320*568iPhone6/6s/7/8:375*667iPhone6/6s/7/8Plus414*736iPhoneX375*812以上是开发分辨率,不是物理分辨率。

    2022年4月8日
    112
  • 全网最全python爬虫精进

    全网最全python爬虫精进4.25(第一天)**第0关认识爬虫**1、初始爬虫爬虫,从本质上来说,就是利用程序在网上拿到对我们有价值的数据。2、明晰路径2-1、浏览器工作原理(1)解析数据:当服务器把数据响应给浏览器之后,浏览器并不会直接把数据丢给我们。因为这些数据是用计算机的语言写的,浏览器还要把这些数据翻译成我们能看得懂的内容;(2)提取数据:我们就可以在拿到的数据中,挑选出对我们有用的数据;(3)存储数据:将挑选出来的有用数据保存在某一文件/数据库中。2-2、爬虫工作原理(1)获取数据:爬虫程序会根据

    2022年5月27日
    34
  • Linux镜像最全版本下载网站

    Linux镜像最全版本下载网站Linux镜像下载Linux镜像下载地址(国内)网易开源镜像站:http://mirrors.163.com/阿里云官方镜像站:http://mirrors.aliyun.comLinux网站https://www.linux.org/.1.CentOSCentOS官网:https://www.centos.org/.CentOS各个版本下载:https://www.centos.org/.CentOS版本选择:1.DVD版:这个是常用版本,就是普通安装版了,推荐大家安装。里面包

    2022年6月28日
    57

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号