自动填充短信验证码(使用ContentObserver)

来源:互联网 发布:2016网络对战射击游戏 编辑:程序博客网 时间:2024/05/18 09:28

为了减少用户的操作步骤,在获得短信验证码的时候,我们可以监听特殊手机号码的短信,截取信息当中的短信验证码(其实有很多应用都监听短信例如360短信,一些信用卡或者是记账类的应用)。

原理:可以使用一个自定义的BroadcastReceiver来监听短信,在监听结果当中过滤手机号,在需要回填的activity当中实现实例化广播并且实现其回调接口,在接口当中进行回填验证码,在销毁activity时销毁链接。但是这样操作会出现一些问题,由于一些其他的应用也会使用广播监听手机例如QQ通讯录或者是360通讯录等有的时候会被其拦截,即使你修改优先级也会出现不能进行回填的问题。所有这里可以采用另外一种的解决方法:使用ContentProvider来监听短信数据库的变化,在自定义的ContentObserver当中实现onChange的方法进行监听特定手机号的短信,然后进行信息截取在填充到需要填充的位置。

1,在AndroidManifest当中需要的权限:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <!-- 发送短信-->  
  2. lt;uses-permission android:name="android.permission.SEND_SMS" />  
  3. <!-- 阅读消息 -->  
  4. <uses-permission android:name="android.permission.READ_SMS" />  
  5. <!-- 写入消息 -->  
  6. <uses-permission android:name="android.permission.WRITE_SMS" />  
  7. <!-- 接收消息 -->  
  8. <uses-permission android:name="android.permission.RECEIVE_SMS" />  

2,在oncreate()方法中注册短信库的监听:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1.  content = new SmsContent(new Handler());    
  2. //注册短信变化监听    
  3. this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content);  
3,SmsContent自定义的ContentObserver:
[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1.        /*  
  2. * 监听短信数据库  
  3. */  
  4. lass SmsContent extends ContentObserver {  
  5. private Cursor cursor = null;  
  6.   
  7. public SmsContent(Handler handler) {  
  8.     super(handler);  
  9.     // TODO Auto-generated constructor stub  
  10. }  
  11.   
  12. @SuppressWarnings("deprecation")  
  13. @Override  
  14. public void onChange(boolean selfChange) {  
  15.     // TODO Auto-generated method stub  
  16.     super.onChange(selfChange);  
  17.     // 读取收件箱中指定号码的短信  
  18.     cursor = managedQuery(Uri.parse("content://sms/inbox"),  
  19.             new String[] { "_id", "address", "read", "body" },  
  20.             " address=? and read=?",  
  21.             new String[] { "监听的号码", "0" }, "_id desc");  
  22.     // 按id排序,如果按date排序的话,修改手机时间后,读取的短信就不准了  
  23.     if (cursor != null && cursor.getCount() > 0) {  
  24.         ContentValues values = new ContentValues();  
  25.         values.put("read", "1"); // 修改短信为已读模式  
  26.         cursor.moveToNext();  
  27.         int smsbodyColumn = cursor.getColumnIndex("body");  
  28.         String smsBody = cursor.getString(smsbodyColumn);  
  29.         edit1.setText(getDynamicPassword(smsBody));  
  30.   
  31.     }  
  32.     // 在用managedQuery的时候,不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃  
  33.     if (Build.VERSION.SDK_INT < 14) {  
  34.         cursor.close();  
  35.     }  
  36. }  
4,getDynamicPassword(smsBody)截取短信中六位数字验证码的方法

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /**  
  2.      * 从字符串中截取连续6位数字组合 ([0-9]{" + 6 + "})截取六位数字 进行前后断言不能出现数字 用于从短信中获取动态密码  
  3.      *   
  4.      * @param str  
  5.      *            短信内容  
  6.      * @return 截取得到的6位动态密码  
  7.      */  
  8.     public static String getDynamicPassword(String str) {  
  9.         // 6是验证码的位数一般为六位  
  10.         Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{"  
  11.                 + 6 + "})(?![0-9])");  
  12.         Matcher m = continuousNumberPattern.matcher(str);  
  13.         String dynamicPassword = "";  
  14.         while (m.find()) {  
  15.             System.out.print(m.group());  
  16.             dynamicPassword = m.group();  
  17.         }  
  18.   
  19.         return dynamicPassword;  
  20.     }  

如果验证码的位数变化只要将6修改为想要的位数,过验证不只为数字直接修改正则为想要的内容即可。

5,在Activity销毁的时候要记得关闭数据库监听:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.     protected void onDestroy() {  
  3.         // TODO Auto-generated method stub  
  4.         super.onDestroy();  
  5.         this.getContentResolver().unregisterContentObserver(content);  
  6.     }  
这样既可以实现短信监听自动回填,在回填的位置一般使用EditText不要使用TextView,因为android手机用户可能会禁止应用访问短信的权限应该支持手动填写。

0 0
原创粉丝点击