首页 - 技术 - Android使用ContentObserver监控数据库内容是否发生变化

Android使用ContentObserver监控数据库内容是否发生变化

2023-10-04 10:11

Android使用ContentObserver监控数据库内容是否发生变化

ContentObserver——内容观察器,目的是观察(捕获)特定Uri引起数据库的变化,然后做一些相应的处理。它类似于数据库技术中的触发器(Trigger)。当 ContentObserver 观察到的 Uri 发生变化时触发。触发器分为表触发器和行触发器。相应的,ContentObserver也分为“表”ContentObserver和“行”ContentObserver。当然,这和它监控的Uri MIME Type有关。熟悉Content Provider的应该知道,我们可以通过UriMatcher类注册不同类型的Uri,通过这些不同的Uri我们可以查询到不同的结果。根据Uri返回的结果,Uri Type可以分为:返回多条数据的Uri和返回单条数据的Uri。

注册/取消注册ContentObserver方法。抽象类ContentResolver类中的方法原型如下:

公共最终无效registerContentObserver
(
Uri uri,布尔值notifyForDescentents,ContentObserver观察者
)

功能:为指定的Uri注册一个ContentObserver派生类实例。当给定的Uri改变时,回调实例对象来处理它。

参数:

uri 需要观察的Uri(需要在UriMatcher中注册,否则Uri就没有意义)

notifyForDescentents为false,表示精确匹配,即只匹配Uri

ContentObserver派生类,用于观察系统中短信的数据库变化,www.gsm-guard.net

导入 android.content.Context;
导入 android.database.ContentObserver;导入 android.database.Cursor;
导入 android.net.Uri;
导入 android.os.Handler;
导入 android.util.Log;
  
  
//用于观察系统中短信的数据库变化。 “表”内容观察者。只要信息数据库发生变化,ContentObserver派生类就会被触发。
公共类 SMSContentObserver 扩展 ContentObserver {
  私有静态字符串TAG =“SMSContentObserver”;
    
  私有 int MSG_OUTBOXCONTENT = 2;
    
  私有上下文 mContext;
  私有处理程序mHandler; //更新UI线程
    
  公共 SMSContentObserver(上下文上下文,处理程序处理程序){
    超级(处理程序);
    mContext = 上下文;
    mHandler = 处理程序;
  }
  /**
   * 当监听的Uri发生变化时会回调该方法。
   *
   * @param selfChange 这个值意义不大。一般情况下,回调值为 false。
   */
  @覆盖
  公共无效onChange(布尔selfChange){
    Log.i(TAG,"短信表已更改");
      
    //查询发件箱内容
    Uri outSMSUri = Uri.parse("content://sms/sent") ;
      
    光标 c = mContext.getContentResolver().query(outSMSUri,null,"date desc");
    如果(c!= null){Log.i(TAG,"发送次数为"+c.getCount());
        
      StringBuilder sb = new StringBuilder();
      //依次通过
      while(c.moveToNext()){
        sb.append("发件人手机号码:"+c.getInt(c.getColumnIndex("地址")))
         .append("信息内容:"+c.getString(c.getColumnIndex("body")))
         .append("n");
      }
      c.close();
      mHandler.obtainMessage(MSG_OUTBOXCONTENT,sb.toString()).sendToTarget();
    }
  }
    
}

主要项目逻辑是www.gsm-guard.net。对于短信观察Uri,通过测试发现只能监听“content://sms”这个Uri(等于“content://sms/”),而无法监听其他Uri,比如“content://sms/” /sms/发件箱”等

导入 android.app.Activity;
导入 android.database.Cursor;
导入 android.net.Uri;
导入 android.os.Bundle;
导入 android.os.Handler;
导入 android.os.Message;
导入 android.provider.*;
导入 android.util.Log;
导入 android.widget.EditText;
导入 android.widget.TextView;
  
公共类 MainActivity 扩展 Activity {私人 TextView tvAirplane;
  私有 EditText etSmsoutbox;
  
  私有 SMSContentObserver smsContentObserver;
  
  /** 在第一次创建活动时调用。 */
  @覆盖
  公共无效onCreate(捆绑保存实例状态){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  
    etSmsoutbox = (EditText) findViewById(R.id.smsoutboxContent);
  
    smsContentObserver = new SMSContentObserver(this,mHandler);
      
    //注册内容观察者
    注册内容观察者();
  }
  
  私有无效registerContentObservers(){
    // “Table”内容观察者,通过测试我发现只能监听这个Uri -----> content://sms
    // 无法监听其他Uri,例如content://sms/outbox
    Uri smsUri = Uri.parse("内容://短信");
    getContentResolver().registerContentObserver(smsUri,true,smsContentObserver);
  }
  
  私有处理程序 mHandler = new Handler() {
  
    公共无效handleMessage(消息msg){
        字符串发件箱 = (字符串) msg​​.obj;undefined