当前位置: 移动技术网 > IT编程>移动开发>Android > 详解Android开发中ContentObserver类的使用

详解Android开发中ContentObserver类的使用

2019年07月24日  | 移动技术网IT编程  | 我要评论

冰超兽冰龙,白光透视眼镜,第一财经周刊 pdf

contentobserver——内容观察者,目的是观察(捕捉)特定uri引起的数据库的变化,继而做一些相应的处理,它类似于
数据库技术中的触发器(trigger),当contentobserver所观察的uri发生变化时,便会触发它。触发器分为表触发器、行触发器,
相应地contentobserver也分为“表“contentobserver、“行”contentobserver,当然这是与它所监听的uri mime type有关的。

熟悉content provider(内容提供者)的应该知道,我们可以通过urimatcher类注册不同类型的uri,我们可以通过这些不同的
uri来查询不同的结果。根据uri返回的结果,uri type可以分为:返回多条数据的uri、返回单条数据的uri。

注册/取消注册contentobserver方法,抽象类contentresolver类中的方法原型如下:

public final void registercontentobserver(uri uri, boolean notifyfordescendents, contentobserver observer)
功能:为指定的uri注册一个contentobserver派生类实例,当给定的uri发生改变时,回调该实例对象去处理。
参数:uri,需要观察的uri(需要在urimatcher里注册,否则该uri也没有意义了)
notifyfordescendents  为false 表示精确匹配,即只匹配该uri
为true 表示可以同时匹配其派生的uri,举例如下:
假设urimatcher 里注册的uri共有一下类型:
1 、content://com.qin.cb/student (学生)
2 、content://com.qin.cb/student/#
3、content://com.qin.cb/student/schoolchild(小学生,派生的uri)

假设我们当前需要观察的uri为content://com.qin.cb/student,如果发生数据变化的 uri 为  
content://com.qin.cb/student/schoolchild ,当notifyfordescendents为 false,那么该contentobserver会监听不到, 
但是当notifyfordescendents 为ture,能捕捉该uri的数据库变化。

observer       contentobserver的派生类实例

public final void unregistercontentobserver(contentobserver observer)

功能:取消对给定uri的观察
参数: observer contentobserver的派生类实例

contentobserver类介绍

构造方法 public void contentobserver(handler handler) 
说明:所有   contentobserver的派生类都需要调用该构造方法
参数: handler  handler对象。可以是主线程handler(这时候可以更新ui 了),也可以是任何handler对象。
常用方法

void onchange(boolean selfchange)

功能:当观察到的uri发生变化时,回调该方法去处理。所有contentobserver的派生类都需要重载该方法去处理逻辑。
参数:selfchange 回调后,其值一般为false,该参数意义不大(我也不懂,理解方法最重要)。

另外两个方法,用处不大,我也不懂,大家参照sdk自行理解,冒昧了。
boolean  deliverselfnotifications()
说明:returns true if this observer is interested in notifications for changes made through the cursor the observer is registered with.

final void dispatchchange(boolean selfchange)


观察特定uri的步骤如下:

1、创建我们特定的contentobserver派生类,必须重载父类构造方法,必须重载onchange()方法去处理回调后的功能实现
2、利用context.getcontentresolover()获得contentresolove对象,接着调用registercontentobserver()方法去注册内容观察者
3、由于contentobserver的生命周期不同步于activity和service等,因此,在不需要时,需要手动的调用
unregistercontentobserver()去取消注册。   

好了,基本讲解就介绍到这儿了。下面给出小demo的简单说明:
demo中共有两个不同的contentobserver派生类,如下:
1、用来观察系统是否改变了飞行模式状态,
ps: 大家可以去sdk中查看该类:android.provider.settings.system。该类封装了对设置模块下所有值的存取,比如:
飞行模式状态、蓝牙状态、屏幕亮度值等,并且提供了相应的uri。
2、观察系统的短信息数据发生了变化。当监听到短信数据发生变化时,查询所有已发送的短信并且显示出来。

短信的uri共有一下几种:

  • content://sms/inbox     收件箱        
  • content://sms/sent        已发送
  • content://sms/draft        草稿          
  • content://sms/outbox    发件箱           (正在发送的信息)
  • content://sms/failed      发送失败    
  • content://sms/queued  待发送列表  (比如开启飞行模式后,该短信就在待发送列表里)

使用举例:

package com.example.android_contentobserver;
 
import android.app.activity;
import android.database.contentobserver;
import android.database.cursor;
import android.net.uri;
import android.os.bundle;
import android.os.handler;
 
public class mainactivity extends activity {
 
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
     
    //注册观察者observser
    this.getcontentresolver().registercontentobserver(uri.parse("content://sms"),true,new smsobserver(new handler()));
 
  }
 
  private final class smsobserver extends contentobserver {
 
    public smsobserver(handler handler) {
      super(handler);
 
    }
 
   
    @override
    public void onchange(boolean selfchange) {
 
      cursor cursor = mainactivity.this.getcontentresolver().query(
          uri.parse("content://sms/inbox"), null, null, null, null);
 
      while (cursor.movetonext()) {
        stringbuilder sb = new stringbuilder();
 
        sb.append("address=").append(
            cursor.getstring(cursor.getcolumnindex("address")));
 
        sb.append(";subject=").append(
            cursor.getstring(cursor.getcolumnindex("subject")));
 
        sb.append(";body=").append(
            cursor.getstring(cursor.getcolumnindex("body")));
 
        sb.append(";time=").append(
            cursor.getlong(cursor.getcolumnindex("date")));
 
        system.out.println("--------has receivered sms::" + sb.tostring());
 
         
      }
 
    }
 
  }
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网