有以下2种方式
1、手机在接收到短信后,会发送一个广播(BroadCast)
2、可以通过内容观察者(ContentObserver)检测短信URI的变化
第一种广播(BroadCast)方式正在被淘汰 1、广播比较耗性能,如果多软件监听短信 2、会因为优先级无法接收到广播
那么主要讲下第二种方式,有以下3个知识点
1、自定义ContentObserver监听短信URI变化
2、通过LoaderManager异步读取短信内容
a、替换managedQuery(主线程运行,由于耗时查询会出现ANR现象)
b、提供异步加载数据机制
c、对数据源变化进行监听,实时更新数据;
d、在Activity配置发生变化(如横竖屏切换)时不用重复加载数据;
e、适用于任何Activity和Fragment;
3、在LoaderManager中学会用Cursor读取短信内容
完整代码
<!--收短信的权限--> <uses-permission android:name="android.permission.RECEIVE_SMS"/> <!--读取短信信息的权限--> <uses-permission android:name="android.permission.READ_SMS"/> public class MainActivity extends AppCompatActivity { private TextView text_view; private Uri URI_SMS = Uri.parse("content://sms/"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text_view = (TextView) findViewById(R.id.text_view); //注册观察者检测短信URI变化 this.getContentResolver().registerContentObserver(URI_SMS, true, new ReadSmsContentObserver(new Handler())); } //观察者监听短信数据库 class ReadSmsContentObserver extends ContentObserver { public ReadSmsContentObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange); //通过异步数据LoaderManager来读取短信内容 ReadSmsLoaderListener readSmsLoaderListener = new ReadSmsLoaderListener(); LoaderManager loaderManager = MainActivity.this.getLoaderManager(); loaderManager.initLoader(0, null, readSmsLoaderListener); } } //异步数据加载类 class ReadSmsLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { private Uri sms_uri = Uri.parse("content://sms/inbox"); //id, address, person, date, type, body... private final String[] sms_projection = new String[]{"body"}; //按时间降序 private final String sms_order = "date desc"; @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { //读取2分钟内的短信,并不会读取之前的短信 String sms_where = "date >" + (System.currentTimeMillis() - 2*60*1000); return new CursorLoader(MainActivity.this, sms_uri, sms_projection, sms_where, null, sms_order); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { fetchSmsCodeFromCursor(cursor); } @Override public void onLoaderReset(Loader<Cursor> loader) { } //解析短信内容 private void fetchSmsCodeFromCursor(Cursor cursor) { if(cursor != null) { while (cursor.moveToNext()) { String body = cursor.getString(cursor.getColumnIndex("body")); if (!TextUtils.isEmpty(body)) { if (body.contains("验证码")) { String verifyCode = getSmsCode(body); //更新UI,显示短信码 text_view.setText(verifyCode); break; } } } } } //提取验证码 private String getSmsCode(String smsContent){ Pattern pattern = Pattern.compile("[0-9]{4,}"); Matcher m = pattern.matcher(smsContent); while (m.find()) { String group = m.group(); if(group != null && group.length() >= 4){ return group; } } return ""; } } } |