自動填充短信驗證碼(使用ContentObserver)


為了減少用戶的操作步驟,在獲得短信驗證碼的時候,我們可以監聽特殊手機號碼的短信,截取信息當中的短信驗證碼(其實有很多應用都監聽短信例如360短信,一些信用卡或者是記賬類的應用)。

原理:可以使用一個自定義的BroadcastReceiver來監聽短信,在監聽結果當中過濾手機號,在需要回填的activity當中實現實例化廣播並且實現其回調接口,在接口當中進行回填驗證碼,在銷毀activity時銷毀鏈接。但是這樣操作會出現一些問題,由於一些其他的應用也會使用廣播監聽手機例如QQ通訊錄或者是360通訊錄等有的時候會被其攔截,即使你修改優先級也會出現不能進行回填的問題。所有這里可以采用另外一種的解決方法:使用ContentProvider來監聽短信數據庫的變化,在自定義的ContentObserver當中實現onChange的方法進行監聽特定手機號的短信,然后進行信息截取在填充到需要填充的位置。

1,在AndroidManifest當中需要的權限:

01.<!-- 發送短信-->
02. <uses-permission android:name="android.permission.SEND_SMS" />
03. <!-- 閱讀消息 -->
04. <uses-permission android:name="android.permission.READ_SMS" />
05. <!-- 寫入消息 -->
06. <uses-permission android:name="android.permission.WRITE_SMS" />
07. <!-- 接收消息 -->
08. <uses-permission android:name="android.permission.RECEIVE_SMS" />
 復制代碼

2,在oncreate()方法中注冊短信庫的監聽:

 

1 content = new SmsContent(new Handler());
2 //注冊短信變化監聽
3  this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content);
4  復制代碼

3,SmsContent自定義的ContentObserver:

 

/*
02. * 監聽短信數據庫
03. */
04. class SmsContent extends ContentObserver {
05. private Cursor cursor = null;
06. 
07. public SmsContent(Handler handler) {
08. super(handler);
09. // 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. }
37. 
38. }
 復制代碼

 

4,getDynamicPassword(smsBody)截取短信中六位數字驗證碼的方法

 

/**
02. * 從字符串中截取連續6位數字組合 ([0-9]{" + 6 + "})截取六位數字 進行前后斷言不能出現數字 用於從短信中獲取動態密碼
03. *
04. * @param str
05. * 短信內容
06. * @return 截取得到的6位動態密碼
07. */
08. public static String getDynamicPassword(String str) {
09. // 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銷毀的時候要記得關閉數據庫監聽:

 

@Override
02. protected void onDestroy() {
03. // TODO Auto-generated method stub
04. super.onDestroy();
05. this.getContentResolver().unregisterContentObserver(content);
06. }
 復制代碼

 

這樣既可以實現短信監聽自動回填,在回填的位置一般使用EditText不要使用TextView,因為android手機用戶可能會禁止應用訪問短信的權限應該支持手動填寫。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM