Android 中自定义ContentProvider与ContentObserver的使用简单实例
示例说明:
该示例中一共包含两个工程。其中一个工程完成了自定义ContentProvider,另外一个工程用于测试该自定义ContentProvider且在该工程中使用了ContentObserver监听自定义ContentProvider的数据变化
以下代码为工程TestContentProvider
ContentProviderTest如下:
package cn.testcontentprovider;
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 ContentProviderTest extends ContentProvider {
private SQLiteDatabaseOpenHelper mSQLiteDatabaseOpenHelper;
private final static String AUTHORITY="cn.bs.testcontentprovider";
private static UriMatcher mUriMatcher;
private static final int PERSON_DIR = 0;
private static final int PERSON = 1;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// 该URI表示返回所有的person,其中PERSONS为该特定Uri的标识码
mUriMatcher.addURI(AUTHORITY, "person", PERSON_DIR);
// 该URI表示返回某一个person,其中PERSON为该特定Uri的标识码
mUriMatcher.addURI(AUTHORITY, "person/#", PERSON);
}
@Override
public String getType(Uri uri) {
switch (mUriMatcher.match(uri)) {
case PERSON_DIR:
return "vnd.android.cursor.dir/"+AUTHORITY+".persons";
case PERSON:
return "vnd.android.cursor.item/"+AUTHORITY+".person";
default:
throw new IllegalArgumentException("unknown uri"+uri.toString());
}
}
@Override
public boolean onCreate() {
mSQLiteDatabaseOpenHelper=new SQLiteDatabaseOpenHelper(getContext());
return true;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = mSQLiteDatabaseOpenHelper.getWritableDatabase();
switch (mUriMatcher.match(uri)) {
case PERSON_DIR:
long newId = db.insert("person", "name,phone,salary", values);
//向外界通知该ContentProvider里的数据发生了变化 ,以便ContentObserver作出相应
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, newId);
default:
throw new IllegalArgumentException("unknown uri" + uri.toString());
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
SQLiteDatabase db = mSQLiteDatabaseOpenHelper.getWritableDatabase();
int updatedNum = 0;
switch (mUriMatcher.match(uri)) {
// 更新表
case PERSON_DIR:
updatedNum = db.update("person", values, selection, selectionArgs);
break;
// 按照id更新某条数据
case PERSON:
long id = ContentUris.parseId(uri);
String where = "personid=" + id;
if (selection != null && !"".equals(selection.trim())) {
where = selection + " and " + where;
}
updatedNum = db.update("person", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("unknown uri" + uri.toString());
}
//向外界通知该ContentProvider里的数据发生了变化 ,以便ContentObserver作出相应
getContext().getContentResolver().notifyChange(uri, null);
return updatedNum;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = mSQLiteDatabaseOpenHelper.getWritableDatabase();
int deletedNum = 0;
switch (mUriMatcher.match(uri)) {
// 删除表
case PERSON_DIR:
deletedNum = db.delete("person", selection, selectionArgs);
break;
// 按照id删除某条数据
case PERSON:
long id = ContentUris.parseId(uri);
String where = "personid=" + id;
if (selection != null && !"".equals(selection.trim())) {
where = selection + " and " + where;
}
deletedNum = db.delete("person", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("unknown uri" + uri.toString());
}
//向外界通知该ContentProvider里的数据发生了变化 ,以便ContentObserver作出相应
getContext().getContentResolver().notifyChange(uri, null);
return deletedNum;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = mSQLiteDatabaseOpenHelper.getWritableDatabase();
Cursor cursor =null;
switch (mUriMatcher.match(uri)) {
// 查询表
case PERSON_DIR:
cursor = db.query("person", projection, selection, selectionArgs,null, null, sortOrder);
break;
// 按照id查询某条数据
case PERSON:
// 第一步:
long id = ContentUris.parseId(uri);
String where = "personid=" + id;
// 第二步:
if (selection != null && !"".equals(selection.trim())) {
where = selection + " and " + where;
}
cursor = db.query("person", projection, where, selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("unknown uri" + uri.toString());
}
return cursor;
}
}
SQLiteDatabaseOpenHelper如下:
package cn.testcontentprovider;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class SQLiteDatabaseOpenHelper extends SQLiteOpenHelper {
public SQLiteDatabaseOpenHelper(Context context) {
super(context, "contentprovidertest.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table person(personid integer primary key autoincrement,name varchar(20),phone varchar(12),salary Integer(12))");
}
//当数据库版本号发生变化时调用该方法
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
//db.execSQL("ALTER TABLE person ADD phone varchar(12) NULL");
//db.execSQL("ALTER TABLE person ADD salary Integer NULL");
}
}
MainActivity如下:
[java] view plain copy
package cn.testcontentprovider;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
AndroidManifest.xml如下:
main.xml如下:
以下代码为工程TestBaidu
MainActivity如下:
package cn.testbaidu;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
public class MainActivity extends Activity {
private Button mAddButton;
private Button mDeleteButton;
private Button mUpdateButton;
private Button mQueryButton;
private Button mTypeButton;
private long lastTime=0;
private ContentResolver mContentResolver;
private ContentObserverSubClass mContentObserverSubClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
initContentObserver();
}
private void init() {
mContentResolver=this.getContentResolver();
mAddButton=(Button) findViewById(R.id.addButton);
mAddButton.setonClickListener(new ClickListenerImpl());
mDeleteButton=(Button) findViewById(R.id.deleteButton);
mDeleteButton.setonClickListener(new ClickListenerImpl());
mUpdateButton=(Button) findViewById(R.id.updateButton);
mUpdateButton.setonClickListener(new ClickListenerImpl());
mQueryButton=(Button) findViewById(R.id.queryButton);
mQueryButton.setonClickListener(new ClickListenerImpl());
mTypeButton=(Button) findViewById(R.id.typeButton);
mTypeButton.setonClickListener(new ClickListenerImpl());
}
// 注册一个针对ContentProvider的ContentObserver用来观察内容提供者的数据变化
private void initContentObserver() {
Uri uri = Uri.parse("content://cn.bs.testcontentprovider/person");
mContentObserverSubClass=new ContentObserverSubClass(new Handler());
this.getContentResolver().registerContentObserver(uri, true,mContentObserverSubClass);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mContentObserverSubClass!=null) {
this.getContentResolver().unregisterContentObserver(mContentObserverSubClass);
}
}
// 自定义一个内容观察者ContentObserver
private class ContentObserverSubClass extends ContentObserver {
public ContentObserverSubClass(Handler handler) {
super(handler);
}
//采用时间戳避免多次调用onChange( )
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
System.out.println("ContentObserver onChange() selfChange="+ selfChange);
if (System.currentTimeMillis()-lastTime>2000) {
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://cn.bs.testcontentprovider/person");
// 获取最新的一条数据
Cursor cursor = resolver.query(uri, null, null, null,"personid desc limit 1");
while (cursor.moveTonext()) {
int personid = cursor.getInt(cursor.getColumnIndex("personid"));
System.out.println("内容提供者中的数据发生变化,现数据中第一条数据的personid="+ personid);
}
cursor.close();
lastTime=System.currentTimeMillis();
}else{
System.out.println("时间间隔过短,忽略此次更新");
}
}
@Override
public boolean deliverSelfNotifications() {
return true;
}
}
private class ClickListenerImpl implements onClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.addButton:
Person person = null;
for (int i = 0; i < 5; i++) {
person = new Person("xiaoming" + i, "9527" + i, (8888 + i));
testInsert(person);
}
break;
case R.id.deleteButton:
testDelete(1);
break;
case R.id.updateButton:
testUpdate(3);
break;
case R.id.queryButton:
// 查询表
// queryFromContentProvider(-1);
// 查询personid=2的数据
testQuery(2);
break;
case R.id.typeButton:
testType();
break;
default:
break;
}
}
}
private void testInsert(Person person) {
ContentValues contentValues=new ContentValues();
contentValues.put("name", person.getName());
contentValues.put("phone", person.getPhone());
contentValues.put("salary",person.getSalary());
Uri insertUri=Uri.parse("content://cn.bs.testcontentprovider/person");
Uri returnUri=mContentResolver.insert(insertUri, contentValues);
System.out.println("新增数据:returnUri="+returnUri);
}
private void testDelete(int index){
Uri uri=Uri.parse("content://cn.bs.testcontentprovider/person/"+String.valueOf(index));
mContentResolver.delete(uri, null, null);
}
private void testUpdate(int index){
Uri uri=Uri.parse("content://cn.bs.testcontentprovider/person/"+String.valueOf(index));
ContentValues values=new ContentValues();
values.put("name", "hanmeimei");
values.put("phone", "1234");
values.put("salary", 333);
mContentResolver.update(uri, values, null, null);
}
private void testQuery(int index) {
Uri uri=null;
if (index<=0) {
//查询表
uri=Uri.parse("content://cn.bs.testcontentprovider/person");
} else {
//按照id查询某条数据
uri=Uri.parse("content://cn.bs.testcontentprovider/person/"+String.valueOf(index));
}
//对应上面的:查询表
//Cursor cursor= mContentResolver.query(uri, null, null, null, null);
//对应上面的:查询personid=2的数据
//注意:因为name是varchar字段的,所以应该写作"name='xiaoming1'"
// 若写成"name=xiaoming1"查询时会报错
Cursor cursor= mContentResolver.query(uri, null, "name='xiaoming1'", null, null);
while(cursor.moveTonext()){
int personid=cursor.getInt(cursor.getColumnIndex("personid"));
String name=cursor.getString(cursor.getColumnIndex("name"));
String phone=cursor.getString(cursor.getColumnIndex("phone"));
int salary=cursor.getInt(cursor.getColumnIndex("salary"));
System.out.println("查询得到:personid=" + personid+",name="+name+",phone="+phone+",salary="+salary);
}
cursor.close();
}
private void testType(){
Uri dirUri=Uri.parse("content://cn.bs.testcontentprovider/person");
String dirType=mContentResolver.getType(dirUri);
System.out.println("dirType:"+dirType);
Uri itemUri=Uri.parse("content://cn.bs.testcontentprovider/person/3");
String itemType=mContentResolver.getType(itemUri);
System.out.println("itemType:"+itemType);
}
}
Person如下:
package cn.testbaidu;
public class Person {
private Integer id;
private String name;
private String phone;
private Integer salary;
public Person(String name, String phone,Integer salary) {
this.name = name;
this.phone = phone;
this.salary=salary;
}
public Person(Integer id, String name, String phone,Integer salary) {
this.id = id;
this.name = name;
this.phone = phone;
this.salary=salary;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", phone=" + phone+ ", salary=" + salary + "]";
}
}
main.xml如下:
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!



