实现自动读取短信验证码功能
使用观察者模式监听短信的变化
/**
* 监听短信数据库变化
* @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"/>