/**稀土掘金,时光不老**/

大家好,最近做项目时,加了一个小功能,手机登录应用或注册时自动填写短信验证码,当然,网上有很多很棒的demo,我也来和大家分享一下,同时也作为一下个人笔记吧。

因为比较简单,就不上效果图了,为什么不用广播(BroadcastReceiver)来接收系统收到短信时候的广播。可是这个广播是有序广播,就是当别的程序先获取到了这个广播再传递给你,当然它也可以干掉这个广播,让你接收不到,这样你的程序肯定是接收不到这个广播的了。网上有很多这样的例子,什么提高广播接收器的优先级又是1000又是10000的。这里提到了把intent-filter中的android:priority的值设置为1000,但是在实时中你设置1000一样是接受不到广播的,除非你把手机中的其他接受了这个广播的短信卸载,比如360 GO短信,飞信神马的。他们的优先级总是要比你的高。你可以继续BAIDU,有的人会设置它为10000 9999等等,你会发现设置为10000的时候偶尔可以接收到,仅仅是偶尔。那肿么办呢。

大家可以看看这个广播的基本介绍:http://wenku.baidu.com/view/226f9dd5b14e852458fb57ba.html

好了,来说说几个核心点吧

1. 使用ContentObserver(使用的观察者模式)监听手机短信动态数据库,当收到短信数据库变化了的时候    去取得最新的那条短信即可。或者你想别的什么操作也可以。

2. 可指定一个号码,只读取与它有关短信,避免提取来源错误 。

3.  可过滤掉与我们不需要的短信

4. 利用正则表达式,可匹配各种类型验证码。

哈哈 ,激动人心的时刻来了,看代码--------------

  1. 在你的Activity中进行注册监听短信数据库,c为Activity的对象
  2. 注册代码为getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, c);
  3. 关于各种类型的uri请参考http://www.2cto.com/kf/201203/123797.html博客。

这是获取短信验证码的工具类

public class SmsReciverUtil extends ContentObserver {private Activity c;
    private int codelength;
    private Handler handler;

    public SmsReciverUtil(Handler handler, Activity c, int codelength) {super(handler);
        this.c = c;
        this.codelength = codelength;//截取验证码的长度
        this.handler = handler;
    }// 收到短信一般来说都是执行了两次onchange方法.第一次一般都是raw的这个.这个时候虽然收到了短信.但是短信还没有写入   到收件箱里面
    // 然后才是另外一个,后面的数字是该短信在收件箱中的位置
    @Override
    public void onChange(boolean selfChange, Uri uri) {super.onChange(selfChange, uri);
        if (uri.toString().equals("content://sms/raw")) {return;
        }String code = getsmsCode(c, codelength);
        if (!TextUtils.isEmpty(code)) {// 利用handler将得到的验证码发送给主界面
            Message msg = Message.obtain();
            msg.what =0;
            msg.obj = code;
            handler.sendMessage(msg);
        }}public String getsmsCode(Activity c, int codelength) {ContentResolver contentresolver = c.getContentResolver();
        // 设置一个uri来查看收件箱中短信内容
        Uri uri = Uri.parse("content://sms/inbox");
        //需要查询的字段 address 号码,read 0未读 1已读,body短信内容
        String[] projection = new String[]{"_id", "address", "read", "body"};
        //需要查询未读短信
//        String selection = "address=? and read=?";                                   //注意这里填写的号码如何是公司里固定的号码可以是 (xxxxxxx)但是测试使用的号码时看有没有(+86xxxxxxx)别 写错了,代码没问题,好好检查O(∩_∩)O哈哈~,当然你可以不写需要查询的号码,查询收件箱数据库中的短信
//        String [] selections = new String[]{"这里填写需要查询的号码","0"};
        // 按短信id倒序排序,如果按date排序的话,修改手机时间后,读取的短信就不准了
        String sortOrder = "_id desc";
        // 读取收件箱中指定号码的短信
        Cursor cur = contentresolver.query(uri, projection, null, null, sortOrder);
        if (null == cur) {            return null;
        }if (cur.getCount() <= 0) {            return null;
        }if (!cur.moveToFirst()) {            return null;
        }String number = cur.getString(cur.getColumnIndex("address"));// 手机号
        String body = cur.getString(cur.getColumnIndex("body"));//短信类容
        // 最后用完游标千万记得关闭
        cur.close();
        // 在这里我们的短信提供商的号码如果是固定的话.我们可以再加一个判断,这样就不会受到别的短信应用的验证码的影响了
        if (!number.startsWith("这里填写你的号码以xxxx开头的数字")) {return null;
        }if (!body.contains("这里填写你的过滤的名称"){return null;
        }return getyzm(body, codelength);
    }/**
     * 从短信字符窜提取验证码
     *
     * @param body       短信内容
     * @param codelength 验证码的长度 一般4     * @return 接取出来的验证码
     */

    public String getyzm(String body, int codelength) {Pattern p = Pattern.compile("(?<![0-9])([0-9]{" + codelength + "})(?![0-9])");
        Matcher matcher = p.matcher(body);
        if (matcher.find()) {
//            ContentValues values = new ContentValues();
//            values.put("read", "1"); // 修改短信为已读模式
            return matcher.group(0);
        }return null;
    }
}
  1. 首先([a-zA-Z0-9]{4})是得到一个连续的4位数字字母组合
  2. (?<![a-zA-Z0-9])负向断言([0-9]{YZMLENGTH})前面不能有数字
  3. (?![a-zA-Z0-9])断言([0-9]{YZMLENGTH})后面不能有数字出现

有些验证码是纯数字的那么直接用这个就可以了
//Pattern p = Pattern.compile("(?<![0-9])([0-9]{" + 验证码的长度可自定义+ "})(?![0-9])");
监听完成后记得在你的Activity中getContentResolver().unregisterContentObserver(c);注销监听

哇 差点忘了,相信很多小伙伴们犯过这样的错误吧O(∩_∩)O哈哈~

<!-- 阅读消息 -->
    <uses-permission android:name="android.permission.READ_SMS" />

<!-- 接收消息 -->
    <uses-permission android:name="android.permission.RECEIVE_SMS" />

如果你还有其他操作还要加上一些权限

<!-- 发送短信-->

<uses-permission android:name="android.permission.SEND_SMS" />

<!-- 写入消息 -->
    <uses-permission android:name="android.permission.WRITE_SMS" />

就是这么简单对不demo就不写了呵呵这里很清楚也很简单..不喜勿喷,有错回帖

来一句 弘洋大神 的名言

生命不息,奋斗不止,万事起于忽微,量变引起质变

Android 应用中使用ContentObserver自动填写短信验证码相关推荐

  1. android短信接收器的实现,可以实现自动填写短信验证码功能

    项目介绍 项目地址: SmsObserverForAndroid 介绍 这是一个用于拦截android实时短信的库,可以进行短信过滤,得到自己想要的内容,可以用于需要自动填写短信验证码的app项目 功 ...

  2. 如何让我的应用自动填写短信验证码?

    问题分享 华为开发者论坛上有开发者向我们咨询:想要实现应用自动填写短信验证码,但如果将手机短信"验证码保护"功能打开,app就不能自动填写验证码,有没有什么方法能获取到短信验证码? ...

  3. 自动填充短信验证码实现方式

    自动填充短信验证码 短信验证码是大部分软件里面都存在的功能,同时为了避免用户自己输入导致的繁琐操作,有一部分app设计者将其设置成了自动填充的方式,方便用户操作那么这种方式是什么实现的呢. 利用广播接 ...

  4. autojs自动获取短信验证码

    AutoJS 是一种基于 JavaScript 的自动化脚本语言,可以用于在 Android 设备上自动化操作. 如果你想使用 AutoJS 自动获取短信验证码,你可以使用 Android 的短信 A ...

  5. 抓取html表单验证码,如何在jquery中利用表单获取短信验证码

    如何在jquery中利用表单获取短信验证码 发布时间:2021-02-18 15:42:54 来源:亿速云 阅读:88 作者:Leah 这期内容当中小编将会给大家带来有关如何在jquery中利用表单获 ...

  6. Android自动填充短信验证码

    自动拦截短信实际上就是在系统注册一个BroadcastReceiver,然后通过设置拦截短信的: filter.addAction("android.provider.Telephony.S ...

  7. Android Studio精彩案例(五)《JSMS短信验证码功能实现》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 很多应用刚打开的时候,让我们输入手机号,通过短信验证码来登录该应用.那么,这个场景是怎么实现的呢?其实是很多开放平台提供了短信验证功能 ...

  8. web: 手机键盘自动获取短信验证码,点击自动填充输入框

    一.展示效果: IOS手机: autocomplete="one-time-code" <van-field:class="$style.code"v-m ...

  9. App开发(Android与php接口)之:短信验证码

    最近和同学们一起开发一个自主项目,要用到短信验证码,在网上搜索了很久,看到一个推荐贴,提到了很多不错的短信服务商.经过测试,帖子中提到的服务商他们的短信到达率和到达速度也都不错.最后,由于经费问题,我 ...

  10. uni-app中使用uniCloud实现发送短信验证码(开通、配置、使用)

    登录dcloud开发者中心,通过以下几个步骤,即可实现发送短信功能.注意是,这里讲解的是通过uniCloud实现调用功能,如需使用REST API调用,请查看官方文件. 一.开通服务 地址:DClou ...

最新文章

  1. WSAGetLastError()部分常见返回值
  2. java 学习(一)冒泡排序
  3. HDU - 1251 统计难题(字典树)
  4. prev php,PHP prev() 函数 ——jQuery中文网
  5. Spring Boot 前端传json数组,后台接收处理
  6. php折半查找算法,PHP如何实现折半查找算法
  7. 基于 Groovy 的自动化构建工具 Gradle 入门(转)
  8. 如何终止线程的运行(C/C++)
  9. sqlserver的坑
  10. 6. Magento2 --- 创建主题
  11. Html5用户注册页面
  12. 站群php自动地图,Discuz自动采集-DZ站群系统自动更新-Discuz站群管理系统
  13. 单片机c语言轻松入门 完整版,单片机C语言轻松入门
  14. 规则引擎Drools简述
  15. SM2证书的鉴定方法——续上文国密算法
  16. java的json解析_java中json的使用和解析
  17. 简单图(simple graph)原理及实现(Java)
  18. win10电脑没有声音(电脑放音乐没声音怎么回事)
  19. 移动端H5页面关于软键盘的一些踩坑记录
  20. JAVA经典垃圾收集器与内存分配策略

热门文章

  1. 体验数学之美——泛函
  2. TTL反相器 电路分析
  3. echarts最简单的南丁格尔玫瑰图+图例
  4. 10 个用于 Linux 的开源轻量级 Web 浏览器
  5. 论文查重不能超过多少?
  6. 苹果系统虚拟机无usb服务器,Mac上Vmware虚拟机无法识别USB Key怎么办?Mac虚拟机无法识别USB Key解决方法...
  7. PDF图纸怎么导入CAD中?尝试这样操作一下
  8. “中华酷联米”第一阵营形成 小米梦如何继续
  9. java图形界面美化_在Java中使用图片实现GUI的美化.doc
  10. 枚举类中的valueOf用法