700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android 应用中使用ContentObserver自动填写短信验证码

Android 应用中使用ContentObserver自动填写短信验证码

时间:2021-01-29 00:52:48

相关推荐

Android 应用中使用ContentObserver自动填写短信验证码

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

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

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

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

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

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

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

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

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

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

在你的Activity中进行注册监听短信数据库,c为Activity的对象注册代码为getContentResolver().registerContentObserver(Uri.parse("content://sms"),true,c); 关于各种类型的uri请参考/kf/03/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); }/** *从短信字符窜提取验证码 * *@parambody短信内容 *@paramcodelength验证码的长度 一般4位 *@return接取出来的验证码 */ public String getyzm(String body, int codelength) {Pattern p = pile("(?<![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; }}

首先([a-zA-Z0-9]{4})是得到一个连续的4位数字字母组合(?<![a-zA-Z0-9])负向断言([0-9]{YZMLENGTH})前面不能有数字(?![a-zA-Z0-9])断言([0-9]{YZMLENGTH})后面不能有数字出现 有些验证码是纯数字的那么直接用这个就可以了

//Pattern p = pile("(?<![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就不写了呵呵这里很清楚也很简单..不喜勿喷,有错回帖

来一句 弘洋大神 的名言

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。