94
魔獸
Android開發14——監聽內容提供者ContentProvider的數據變化
一、提出需求
有A,B,C三個應用,B中的數據需要被共享,所以B中定義了內容提供者ContentProvider;A應用修改了B應用的數據,插入了一條數據。有這樣一個需求,此時C應用需要得到數據被修改的通知並處理相應操作。
二、示例代碼
A應用 /** * 對內容提供者進行操作 * * @author XY * */ 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; /** * @author XY * */ 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); } } ...... } 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的基本使用》
最後更新:2017-04-04 07:32:13