ContentObserver监听媒体库变化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ContentObserver监听媒体库变化相关的知识,希望对你有一定的参考价值。
参考技术A 在android中,我们可以使用ContentObserver监听ContentProvider数据的变化。我们试下拍照的事件响应:
当数据发生变化的时候,会通知到onChange方法。在API 16以上,可支持返回变化的Uri对象,在此之前,不会返回具体变化的对象,需要自己去找出被改变的对象。
在上面的例子中,Handler其实是基本没起到作用的,直接传null也不会影响使用。
所以在删除时,没有返回具体的Uri对象。
自动填充短信验证码(使用ContentObserver)
为了减少用户的操作步骤,在获得短信验证码的时候,我们可以监听特殊手机号码的短信,截取信息当中的短信验证码(其实有很多应用都监听短信例如360短信,一些信用卡或者是记账类的应用)。
原理:可以使用一个自定义的BroadcastReceiver来监听短信,在监听结果当中过滤手机号,在需要回填的activity当中实现实例化广播并且实现其回调接口,在接口当中进行回填验证码,在销毁activity时销毁链接。但是这样操作会出现一些问题,由于一些其他的应用也会使用广播监听手机例如QQ通讯录或者是360通讯录等有的时候会被其拦截,即使你修改优先级也会出现不能进行回填的问题。所有这里可以采用另外一种的解决方法:使用ContentProvider来监听短信数据库的变化,在自定义的ContentObserver当中实现onChange的方法进行监听特定手机号的短信,然后进行信息截取在填充到需要填充的位置。
1,在AndroidManifest当中需要的权限:
01.<!-- 发送短信--> 02. <uses-permission android:name="android.permission.SEND_SMS" /> 03. <!-- 阅读消息 --> 04. <uses-permission android:name="android.permission.READ_SMS" /> 05. <!-- 写入消息 --> 06. <uses-permission android:name="android.permission.WRITE_SMS" /> 07. <!-- 接收消息 --> 08. <uses-permission android:name="android.permission.RECEIVE_SMS" /> 复制代码
2,在oncreate()方法中注册短信库的监听:
1 content = new SmsContent(new Handler()); 2 //注册短信变化监听 3 this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content); 4 复制代码
3,SmsContent自定义的ContentObserver:
/* 02. * 监听短信数据库 03. */ 04. class SmsContent extends ContentObserver { 05. private Cursor cursor = null; 06. 07. public SmsContent(Handler handler) { 08. super(handler); 09. // TODO Auto-generated constructor stub 10. } 11. 12. @SuppressWarnings("deprecation") 13. @Override 14. public void onChange(boolean selfChange) { 15. // TODO Auto-generated method stub 16. super.onChange(selfChange); 17. // 读取收件箱中指定号码的短信 18. cursor = managedQuery(Uri.parse("content://sms/inbox"), 19. new String[] { "_id", "address", "read", "body" }, 20. " address=? and read=?", 21. new String[] { "监听的号码", "0" }, "_id desc"); 22. // 按id排序,如果按date排序的话,修改手机时间后,读取的短信就不准了 23. if (cursor != null && cursor.getCount() > 0) { 24. ContentValues values = new ContentValues(); 25. values.put("read", "1"); // 修改短信为已读模式 26. cursor.moveToNext(); 27. int smsbodyColumn = cursor.getColumnIndex("body"); 28. String smsBody = cursor.getString(smsbodyColumn); 29. edit1.setText(getDynamicPassword(smsBody)); 30. 31. } 32. // 在用managedQuery的时候,不能主动调用close()方法, 否则在Android 4.0+的系统上, 会发生崩溃 33. if (Build.VERSION.SDK_INT < 14) { 34. cursor.close(); 35. } 36. } 37. 38. } 复制代码
4,getDynamicPassword(smsBody)截取短信中六位数字验证码的方法
/** 02. * 从字符串中截取连续6位数字组合 ([0-9]{" + 6 + "})截取六位数字 进行前后断言不能出现数字 用于从短信中获取动态密码 03. * 04. * @param str 05. * 短信内容 06. * @return 截取得到的6位动态密码 07. */ 08. public static String getDynamicPassword(String str) { 09. // 6是验证码的位数一般为六位 10. Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{" 11. + 6 + "})(?![0-9])"); 12. Matcher m = continuousNumberPattern.matcher(str); 13. String dynamicPassword = ""; 14. while (m.find()) { 15. System.out.print(m.group()); 16. dynamicPassword = m.group(); 17. } 18. 19. return dynamicPassword; 20. } 复制代码
如果验证码的位数变化只要将6修改为想要的位数,过验证不只为数字直接修改正则为想要的内容即可。
5,在Activity销毁的时候要记得关闭数据库监听:
@Override 02. protected void onDestroy() { 03. // TODO Auto-generated method stub 04. super.onDestroy(); 05. this.getContentResolver().unregisterContentObserver(content); 06. } 复制代码
这样既可以实现短信监听自动回填,在回填的位置一般使用EditText不要使用TextView,因为android手机用户可能会禁止应用访问短信的权限应该支持手动填写。
以上是关于ContentObserver监听媒体库变化的主要内容,如果未能解决你的问题,请参考以下文章
如何在不打开应用程序的情况下使 ContentObserver 工作?