實現自動讀取短信驗證碼功能
使用觀察者模式監聽短信的變化
/**
* 監聽短信數據庫變化
* @author Jeff
* @describe
* @date 2018/5/24.
*/
public class SmsDatabaseObserver extends ContentObserver {
// 只檢查收件箱
public static final Uri MMSSMS_ALL_MESSAGE_URI = Uri.parse("content://sms/inbox");
public static final String SORT_FIELD_STRING = "_id asc"; // 排序
public static final String DB_FIELD_ID = "_id";
public static final String DB_FIELD_ADDRESS = "address";
public static final String DB_FIELD_PERSON = "person";
public static final String DB_FIELD_BODY = "body";
public static final String DB_FIELD_DATE = "date";
public static final String DB_FIELD_TYPE = "type";
public static final String DB_FIELD_THREAD_ID = "thread_id";
public static final String[] ALL_DB_FIELD_NAME = {
DB_FIELD_ID, DB_FIELD_ADDRESS, DB_FIELD_PERSON, DB_FIELD_BODY,
DB_FIELD_DATE, DB_FIELD_TYPE, DB_FIELD_THREAD_ID };
public static int mMessageCount = -1;
private static final long DELTA_TIME = 60 * 1000;
private ContentResolver mResolver;
private OnSmsDatabaseChangedListener onSmsDatabaseChangedListener;
public SmsDatabaseObserver(ContentResolver resolver, Handler handler) {
super(handler);
mResolver = resolver;
}
@Override
public void onChange(boolean selfChange) {
onReceiveSms();
}
private void onReceiveSms() {
Cursor cursor = null;
// 添加異常捕捉
try {
cursor = mResolver.query(MMSSMS_ALL_MESSAGE_URI, ALL_DB_FIELD_NAME,
null, null, SORT_FIELD_STRING);
final int count = cursor.getCount();
if (count <= mMessageCount) {
mMessageCount = count;
return;
}
// 發現收件箱的短信總數目比之前大就認爲是剛接收到新短信---如果出現意外,請神保佑
// 同時認爲id最大的那條記錄爲剛剛新加入的短信的id---這個大多數是這樣的,發現不一樣的情況的時候可能也要求神保佑了
mMessageCount = count;
if (cursor != null) {
cursor.moveToLast();
final long smsdate = Long.parseLong(cursor.getString(cursor.getColumnIndex(DB_FIELD_DATE)));
final long nowdate = System.currentTimeMillis();
// 如果當前時間和短信時間間隔超過60秒,認爲這條短信無效
if (nowdate - smsdate > DELTA_TIME) {
return;
}
final String strAddress = cursor.getString(cursor.getColumnIndex(DB_FIELD_ADDRESS)); // 短信號碼
final String strbody = cursor.getString(cursor.getColumnIndex(DB_FIELD_BODY)); // 在這裏獲取短信信息
final int smsid = cursor.getInt(cursor.getColumnIndex(DB_FIELD_ID));
if (TextUtils.isEmpty(strAddress) || TextUtils.isEmpty(strbody)) {
return;
}
// 得到短信號碼和內容之後進行相關處理
if (onSmsDatabaseChangedListener!=null)
onSmsDatabaseChangedListener.onSmsDatabaseChanged(strbody);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
try { // 有可能cursor都沒有創建成功
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void setOnSmsDatabaseChangedListener(OnSmsDatabaseChangedListener onSmsDatabaseChangedListener) {
this.onSmsDatabaseChangedListener = onSmsDatabaseChangedListener;
}
//短信數據庫發生變化時的回調接口
public interface OnSmsDatabaseChangedListener{
void onSmsDatabaseChanged(String content);
}
}
註冊/註銷Observer
private void registerSmsDatabaseChangeObserver(ContextWrapper contextWrapper) {
//因爲,某些機型修改rom導致沒有getContentResolver
try {
mSmsDBChangeObserver = new SmsDatabaseObserver(contextWrapper.getContentResolver(), new Handler());
contextWrapper.getContentResolver().registerContentObserver(SMS_MESSAGE_URI, true, mSmsDBChangeObserver);
} catch (Throwable b) {
}
}
private void unregisterSmsDatabaseChangeObserver(ContextWrapper contextWrapper) {
try {
contextWrapper.getContentResolver().unregisterContentObserver(mSmsDBChangeObserver);
} catch (Exception e) {
e.printStackTrace();
}
}
注意權限的聲明
<!--讀取接收短信-->
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>