监听内容提供者ContentProvider的数据变化

http://blog.sina.com.cn/s/blog_67aaf444010162bj.html

一、提出需求

有A,B,C三个应用,B中的数据需要被共享,所以B中定义了内容提供者ContentProvider;A应用修改了B应用的数据,插入了一条数据。有这样一个需求,此时C应用需要得到数据被修改的通知并处理相应操作。

 

二、示例代码

A应用

public class MainActivity extends Activity
{

 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
 }

 public void insert(View v)
 {
  Uri uri = Uri.parse("content://cn.xyCompany.providers.personProvider/person");
  ContentResolver resolver = this.getContentResolver();
  ContentValues values = new ContentValues();
  values.put("name", "xy_new_new");
  values.put("phone", "xy_new_111");
  resolver.insert(uri, values);
 }
}


B应用
package cn.xy.cotentProvider.app.providers;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
import cn.xy.cotentProvider.service.DBOpeningHelper;


public class PersonProvider extends ContentProvider
{
 private DBOpeningHelper dbHelper;

 // 若不匹配采用UriMatcher.NO_MATCH(-1)返回
 private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

 // 匹配码
 private static final int CODE_NOPARAM = 1;
 private static final int CODE_PARAM = 2;

 static
 {
  // 对等待匹配的URI进行匹配操作,必须符合cn.xyCompany.providers.personProvider/person格式
  // 匹配返回CODE_NOPARAM,不匹配返回-1
  MATCHER.addURI("cn.xyCompany.providers.personProvider", "person", CODE_NOPARAM);

  // #表示数字 cn.xyCompany.providers.personProvider/person/10
  // 匹配返回CODE_PARAM,不匹配返回-1
  MATCHER.addURI("cn.xyCompany.providers.personProvider", "person/#", CODE_PARAM);
 }

 @Override
 public boolean onCreate()
 {
  dbHelper = new DBOpeningHelper(this.getContext());
  return true;
 }

 
 @Override
 public Uri insert(Uri uri, ContentValues values)
 {
  SQLiteDatabase db = dbHelper.getWritableDatabase();
  switch (MATCHER.match(uri))
  {
   case CODE_NOPARAM:
    // 若主键值是自增长的id值则返回值为主键值,否则为行号,但行号并不是RecNo列
    long id = db.insert("person", "name", values);
    Uri insertUri = ContentUris.withAppendedId(uri, id);
    // 发出变化通知(非必须)设监听者为null。
    // 若设置某个监听者则不管有多少个监听者,该监听者一定可以获得该通知
    getContext().getContentResolver().notifyChange(uri, null);
    return insertUri;
   default:
    throw new IllegalArgumentException("this is unkown uri:" + uri);
  }
 }
 ......
}

【注解:(我)为了查询Content Provider中的数据,开发人员需要使用ContentResolver.query()或Activity.managerQuery()方法。这两个方法使用相同的参数,并且都返回Cursor对象。然而managedQuery()方法导致Activity管理Cursor的生命周期。托管的Cursor处理所有的细节,例如当Activity暂停时卸载自身,当Activity重启时加载自身。调用Activity.startManagingCursor()方法可以让Activity管理未托管的Cursor对象。query()和managerQuery()方法的第一个参数是provider的URL。注意和SQLite应用详解里面论述对比】
C应用
package cn.xt.contentProvider.lisenter;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

public class MainActivity extends Activity
{
 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  Uri uri = Uri.parse("content://cn.xyCompany.providers.personProvider/person");
  ContentResolver resolver = this.getContentResolver();
  resolver.registerContentObserver(uri, true, new PersonContentObserver(new Handler()));
 }

 private class PersonContentObserver extends ContentObserver
 {
  public PersonContentObserver(Handler handler)
  {
   super(handler);
  }

  // 得到数据的变化通知,该方法只能粗略知道数据的改变,并不能判断是哪个业务操作进行的改变
  @Override
  public void onChange(boolean selfChange)
  {
   // select * from person order by id desc limit 1 // 取得最近插入的值(序号大——>小并取第一个)
   Uri uri = Uri.parse("content://cn.xyCompany.providers.personProvider/person");
   ContentResolver resolver = MainActivity.this.getContentResolver();
   Cursor cursor = resolver.query(uri, null, null, null, "id desc limit 1");
   if(cursor.moveToFirst())
   {
    String name = cursor.getString(cursor.getColumnIndex("name"));
    Log.i("lisenter", name);
   }
  }
 }
}

关于contentProvider的基本使用,请参看本博客博文《Android开发13——内容提供者ContentProvider的基本使用》

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值