在上⼀篇博客中讲到通过⼴播获取短信验证码,但是存在缺陷。这⾥讲⼀下如何通过ContentObserver来实现这个功能。关于
ContentObserver这⾥就不再介绍了,主要是利⽤ContentObserver能监控到⼿机短信箱内容变化的原理来实现,实现过程如下⽂。⾸先写⼀个类继承ContentObserver,重写onChange⽅法:
public class SmsContentObserver extends ContentObserver { private String smsInboxUri = \"content://sms/inbox\"; private Context ctx; private String sortOrder;
private String address = \"10001\";// 发送短信地址
public SmsContentObserver(Context ctx, Handler handler) { super(handler); this.ctx = ctx;
sortOrder = Sms.DATE + \" desc\"; }
@Override
public void onChange(boolean selfChange) { super.onChange(selfChange); Uri uri = Uri.parse(smsInboxUri);
Cursor cursor = ctx.getContentResolver().query(uri, null, null, null, sortOrder);
if (cursor != null) {
while (cursor.moveToNext()) { if (cursor.moveToNext()) {
String number = cursor.getString(cursor
.getColumnIndex(Sms.ADDRESS));// ⼿机号 String smsbody = cursor.getString(cursor .getColumnIndex(Sms.BODY));
Log.e(\"smsbody\ if (number.equals(address)) {
Log.e(\"smsbody\ String regEx = \"\\\\d{4}$\";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(smsbody.toString()); String msgContent = \"\"; while (m.find()) {
msgContent = m.group();
Log.e(\"msgContent\ break; } } } }
cursor.close(); } }}
然后注册ContentObserver:
smsContentObserver = new SmsContentObserver(this, new Handler()); Uri smsUri = Uri.parse(\"content://sms\");
getContentResolver().registerContentObserver(smsUri, true, smsContentObserver);
最后,使⽤完不要忘了释放资源:
getContentResolver().unregisterContentObserver(smsContentObserver);
MainActivity完整代码如下:
public class MainActivity extends Activity { SmsContentObserver smsContentObserver;
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
@Override
protected void onResume() {
// TODO Auto-generated method stub super.onResume();
smsContentObserver = new SmsContentObserver(this, new Handler()); Uri smsUri = Uri.parse(\"content://sms\");
getContentResolver().registerContentObserver(smsUri, true, smsContentObserver); }
@Override
protected void onStop() {
// TODO Auto-generated method stub super.onStop();
getContentResolver().unregisterContentObserver(smsContentObserver); }}
输出⽇志:
注意点:
1. 在使⽤ctx.getContentResolver().query()查询的时候,加上查询条件可以提⾼查询效率。 2. 通过正则表达式对发送短信的号码进⾏匹配,可以只读取某个号码发送的短信。
试着读取⼿机收到的摩拜短信验证码,结果有时候能读到,有时候不⾏,后来发现是发送短信的号码不同,真是坑爹!
所以实际使⽤的时候,要注意address是否与实际发送短信的号码相⼀致。同⼀⼿机运营商发送短信的号码都不同,如果是不同的运营商,号码也会不同。
因篇幅问题不能全部显示,请点此查看更多更全内容