實現自動讀取短信驗證碼功能

實現自動讀取短信驗證碼功能

使用觀察者模式監聽短信的變化

/**
 * 監聽短信數據庫變化
 * @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"/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章