ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。
public class ContactsContentProvider extends ContentProvider{
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
return false;
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri arg0, ContentValues arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
String arg4) {
// TODO Auto-generated method stub
return null;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
return 0;
}
}public class ProviderMetaData {
public static final String AUTHORITY = "com.johnny.contactsprovider";
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
public static final class ContactsData implements BaseColumns{
public static final String TABLE_NAME = "contacts";
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, TABLE_NAME);
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact";
public static final String CONTACT_NAME = "name";
public static final String CONTACT_TELEPHONE = "telephone";
public static final String CONTACT_CREATE_DATE = "create_date";
public static final String CONTACT_CONTENT = "content";
public static final String CONTACT_GROUP = "group_name";
public static final String DEFAULT_ORDERBY = "create_date DESC";
public static final String SQL_CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " ("
+ _ID + " INTEGER PRIMARY KEY,"
+ CONTACT_NAME + " VARCHAR(50),"
+ CONTACT_TELEPHONE + " VARCHAR(11),"
+ CONTACT_CONTENT +" TEXT,"
+ CONTACT_CREATE_DATE + " INTEGER"
+ ");" ;
}
}static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static final HashMap<String, String> CONTACTS_PROJECTION_MAP = new HashMap<String, String>();
private static final int CONTACTS = 1;
private static final int CONTACTS_ID = 2;
static{
final UriMatcher matcher = URI_MATCHER;
matcher.addURI(ProviderMetaData.AUTHORITY, "contacts", CONTACTS);
matcher.addURI(ProviderMetaData.AUTHORITY, "contacts/#", CONTACTS_ID);
HashMap<String, String> map = CONTACTS_PROJECTION_MAP;
map.put(ContactsData._ID, ContactsData._ID);
map.put(ContactsData.CONTACT_NAME, ContactsData.CONTACT_NAME);
map.put(ContactsData.CONTACT_TELEPHONE, ContactsData.CONTACT_TELEPHONE);
map.put(ContactsData.CONTACT_CONTENT, ContactsData.CONTACT_CONTENT);
map.put(ContactsData.CONTACT_CREATE_DATE, ContactsData.CONTACT_CREATE_DATE);
}private class DatabaseHelper extends SQLiteOpenHelper{
static final String DATABASE_NAME = "test.db";
static final int DATABASE_VERSION = 1;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(ContactsData.SQL_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
onCreate(db);
}
} @Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// TODO Auto-generated method stub
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
switch(URI_MATCHER.match(uri)){
case CONTACTS_ID:
queryBuilder.setTables(ContactsData.TABLE_NAME);
queryBuilder.setProjectionMap(CONTACTS_PROJECTION_MAP);
queryBuilder.appendWhere(ContactsData.TABLE_NAME + "._id="+Long.toString(ContentUris.parseId(uri)));
break;
case CONTACTS:
queryBuilder.setTables(ContactsData.TABLE_NAME);
queryBuilder.setProjectionMap(CONTACTS_PROJECTION_MAP);
break;
}
String orderBy;
if(TextUtils.isEmpty(sortOrder))
{
orderBy = ContactsData.DEFAULT_ORDERBY;
} else {
orderBy = sortOrder;
}
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, orderBy);
return cursor;
} @Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
SQLiteDatabase db = mDbHelper.getWritableDatabase();
long id = db.insertOrThrow(ContactsData.TABLE_NAME, null, values);
// 更新数据时,通知其他ContentObserver
getContext().getContentResolver().notifyChange(ContactsData.CONTENT_URI, null);
if(id > 0){
return ContentUris.withAppendedId(uri, id);
}
return null;
} @Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int modified = 0;
switch(URI_MATCHER.match(uri)){
case CONTACTS_ID:
selection = DatabaseUtils.concatenateWhere(selection,ContactsData.TABLE_NAME + "._id=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
new String[]{Long.toString(ContentUris.parseId(uri))});
Log.d("Test", "selectionArgs 0"+selectionArgs);
modified = db.update(ContactsData.TABLE_NAME, values, selection, selectionArgs);
break;
case CONTACTS:
modified = db.update(ContactsData.TABLE_NAME, values, selection, selectionArgs);
Log.d("Test", "selectionArgs 1"+selectionArgs);
break;
}
// 更新数据时,通知其他ContentObserver
getContext().getContentResolver().notifyChange(ContactsData.CONTENT_URI, null);
return modified;
} @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase db = mDbHelper.getWritableDatabase();
int deleted = 0;
switch(URI_MATCHER.match(uri)){
case CONTACTS_ID:
selection = DatabaseUtils.concatenateWhere(selection,ContactsData.TABLE_NAME + "._id=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
new String[]{Long.toString(ContentUris.parseId(uri))});
Log.d("Test", "selectionArgs 0"+selectionArgs);
deleted = db.delete(ContactsData.TABLE_NAME, selection, selectionArgs);
break;
case CONTACTS:
deleted = db.delete(ContactsData.TABLE_NAME, selection, selectionArgs);
Log.d("Test", "selectionArgs 1"+selectionArgs);
break;
}
// 更新数据时,通知其他ContentObserver
getContext().getContentResolver().notifyChange(ContactsData.CONTENT_URI, null);
return deleted;
} @Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
switch(URI_MATCHER.match(uri)){
case CONTACTS:
return ContactsData.CONTENT_TYPE;
case CONTACTS_ID:
return ContactsData.CONTENT_ITEM_TYPE;
// default:
// throw new IllegalArgumentException("Unknow URI: " + uri);
}
return null;
} <provider
android:name="com.johnny.testcontentprovider.ContactsContentProvider"
android:authorities="com.johnny.contactsprovider">
</provider> private void insertContact1(){
ContentValues values = new ContentValues();
values.put(ContactsData.CONTACT_NAME, "James");
values.put(ContactsData.CONTACT_TELEPHONE, "18888888888");
values.put(ContactsData.CONTACT_CONTENT, "NBA Star");
values.put(ContactsData.CONTACT_CREATE_DATE, System.currentTimeMillis());
Uri uri = getContentResolver().insert(ContactsData.CONTENT_URI, values);
Log.d("Test", "uri = "+uri);
}
private void deleteContact1(){
int count = getContentResolver().delete(ContactsData.CONTENT_URI, ContactsData.CONTACT_NAME+"='James'", null);
Log.d("Test", "count = "+count);
}
private void updateContact1(){
ContentValues values = new ContentValues();
values.put(ContactsData.CONTACT_TELEPHONE, "16666666666");
int count = getContentResolver().update(ContactsData.CONTENT_URI,values, ContactsData.CONTACT_NAME+"='James'", null);
Log.d("Test", "count = "+count);
}
private void queryContact1(){
Cursor cursor = this.getContentResolver().query(ContactsData.CONTENT_URI, null, ContactsData.CONTACT_NAME+"='James'", null, null);
Log.e("test ", "count=" + cursor.getCount());
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsData.CONTACT_NAME));
String telephone = cursor.getString(cursor.getColumnIndex(ContactsData.CONTACT_TELEPHONE));
long createDate = cursor.getLong(cursor.getColumnIndex(ContactsData.CONTACT_CREATE_DATE));
Log.e("Test", "name: " + name);
Log.e("Test", "telephone: " + telephone);
Log.e("Test", "date: " + createDate);
cursor.moveToNext();
}
cursor.close();
} private ContentObserver mContentObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
Log.d("Test", "mContentObserver onChange");
super.onChange(selfChange);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
getContentResolver().registerContentObserver(ContactsData.CONTENT_URI, true, mContentObserver);
} private class DatabaseHelper extends SQLiteOpenHelper{
static final String DATABASE_NAME = "test.db";
static final int DATABASE_VERSION = 2;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(ContactsData.SQL_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.d("Test", "onUpgrade oldVersion = "+oldVersion+", newVersion = "+newVersion);
//onCreate(db);
for(int i = oldVersion+1;i <= newVersion;i++){
switch(i){
case 2:
db.execSQL("ALTER TABLE " + ContactsData.TABLE_NAME + " ADD COLUMN " + ContactsData.CONTACT_GROUP + " TEXT");
break;
}
}
}
}下面是升级前后数据库的结果:
用下面代码为DATABASE_VERSION = 2的数据库中的James设在组别和加入Howard联系人:
private void modifyContact1(){
ContentValues values = new ContentValues();
values.put(ContactsData.CONTACT_GROUP, "Miami");
int count = getContentResolver().update(ContactsData.CONTENT_URI,values, ContactsData.CONTACT_NAME+"='James'", null);
Log.d("Test", "count = "+count);
}
private void insertContact2(){
ContentValues values = new ContentValues();
values.put(ContactsData.CONTACT_NAME, "Howard");
values.put(ContactsData.CONTACT_TELEPHONE, "13333333333");
values.put(ContactsData.CONTACT_CONTENT, "NBA Star");
values.put(ContactsData.CONTACT_GROUP, "Rockets");
values.put(ContactsData.CONTACT_CREATE_DATE, System.currentTimeMillis());
Uri uri = getContentResolver().insert(ContactsData.CONTENT_URI, values);
Log.d("Test", "uri = "+uri);
}
参考:http://codingnow.cn/android/1078.html
Android ContentProvider、ContentResolver和ContentObserver的使用,布布扣,bubuko.com
Android ContentProvider、ContentResolver和ContentObserver的使用
原文:http://blog.csdn.net/heqiangflytosky/article/details/31777363