监控ContentProvider的数据改变
实现监听要熟悉一下的问题:
1.如何监听ContentProvider?
通过ContentResolver向指定Uri注册ContentObserver监听器来监听指定的ContentProvider的数据变化。
用如下方法来注册监听器
registerContentObserver(Uri uri,boolean notifyForDescendents,ContentObserver observer)
其 中notifyForDescendents :如果该参数设为true,假如Uri为content://abc,那么Uri为content://abc/xyz, content://abc/xyz/foo的数据改变时也会触发该监听器,如果参数为false,那么只有content://abc的数据改变时会触 发该监听器
2. 监听器如何设置?监听到ContentProvider数据变化时需要做什么?
监听ContentProvider数据改变的监听器需要继承ContentObserver类,并重写该基类所定义的onChange(boolean selfChange)方法,当它所监听的ContentProvider所共享的数据发生改变时,该onChange将会触发。
3. ContentProvider的数据发生改变时,如何通知监听器?
ContentProvider中实现增、删、改、查都会调用 getContext().getContentResolver().notifyChange(uri,null)方法,这个方法是通知所有注册在该 Uri上的监听者,该ContentProvider所共享的数据发生了改变。
一、监听ContentProvider主要步骤
1.在ContentProvider类的insert\update\delete方法加入this.getContext().getContentResolver().notifyChange(URI,null);
其中URI表示监听的URI
null表示发送消息给任何人;
2.在访问者的类中调用如下方法:
context.getContentResolver().registerContentObserver(uri,true,new ContentObserver(new Handler()));
3.创建内部类继承ContentObserver并重写下面两个方法:
(1)带有Handler的构造函数;
(2)public void onChange(boolean selfChange); 此函数在内容提供者发出改变信号时就会被调用
参数selfChange为如果是自己改变的原因,则为true;如果不是自己改变的,则为false;
我们在Test1和Test2应用都对ContentProvider的数据改变进行注册,如果ContentProvider发出通知,则Test1和Test2都会收到通知;
注意:此处有一个很重要的问题,如果Test1和Test2应用的MainActivity为同一个包,则如果先运行Test2,再运行Test1,则Test2会停止运行,因为Test1应用会覆盖Test2的应用,即接收不到通知;
因此我们要把Test1应用和Test2应用的包名设为不同,此处为org.xiazdong和org.xzdong;
StudentProvider .java
package com.example.sqlite;
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;
public class StudentProvider extends ContentProvider {
private DBOpenHelper helper;
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH); //Creates the root node of the URI tree.
private static final int STUDENT = 1;
private static final int STUDENT2 =2;
static{
MATCHER.addURI("cn.olay.providers.studentprovider", "student", STUDENT);
MATCHER.addURI("cn.olay.providers.studentprovider", "student/#", STUDENT2);
}
@Override
public boolean onCreate() {
helper = new DBOpenHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
}
@Override
public String getType(Uri uri) {
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
if(MATCHER.match(uri)==1){
long id=db.insert("student", "name", values);
//Uri insertUri =Uri.parse("content://cn.olay.providers.studentprovider/student"+id);
Uri insertUri =ContentUris.withAppendedId(uri, id);
this.getContext().getContentResolver().notifyChange(uri, null); ////如果改变数据,则通知所有人
return insertUri;
}else{
throw new IllegalArgumentException("this id unknow uri:"+uri);
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
}
}
在Test1中插入数据
package com.example.sqlitetesta;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void insert(View view){
Uri uri = Uri.parse("content://cn.olay.providers.studentprovider/student");
ContentResolver resolver = this.getContentResolver();
ContentValues values = new ContentValues();
values.put("name", "A");
values.put("phone", "15989776346");
values.put("account", 22.0);
resolver.insert(uri, values);
}
}
在Test2中监听数据变化
package com.example.sqlitetest;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.database.ContentObserver;
import android.database.Cursor;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Uri uri = Uri.parse("content://cn.olay.providers.studentprovider/student");
this.getContentResolver().registerContentObserver(uri, true, new StudentContentObserver(new Handler()));//注册监听
}
public class StudentContentObserver extends ContentObserver {
public StudentContentObserver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
}
@Override
//当ContentProvier数据发生改变,则触发该函数
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
super.onChange(selfChange);
Uri uri = Uri.parse("content://cn.olay.providers.studentprovider/student");
Cursor cursor=getContentResolver().query(uri, null, null, null, null);
if(cursor.moveToFirst()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone = cursor.getString(cursor.getColumnIndex("phone"));
Double account = cursor.getDouble(cursor.getColumnIndex("account"));
Log.i("olay", "name:"+name+" phone:"+phone+" account:"+account);
}
}
}
}