(1) MyContentObserver.java:實作繼承ContentObserver,並完成
public MyContentObserver(Handler handler) {
super(handler);
}
public void onChange(boolean selfChange) {
//當增加一筆資料時,想要做任何事,就寫在這裡
Log.d("MyContentObserver", "Data insert!");
}
(2) MyContentProvider.java中: 在query() 裡增加c.setNotificationUri();另外在insert() 裡增加getContext().getContentResolver().notifyChange(); 如此一旦資料新增時,就會去利用callback function呼叫到MyContentObserver裡面的onChange()
(3)Main.java: 利用registerContentObservers() 和 unregisterContentObservers()進行監聽資料和取消監聽資料的動作
程式碼如下:
MyContentObserver.java (和Main是放在同一支apk)
public class MyContentObserver extends ContentObserver {
public MyContentObserver(Handler handler) {
super(handler);
}
public void onChange(boolean selfChange) {
Log.d("MyContentObserver", "Data is changed!");
}
}
public class MyContentProvider extends ContentProvider {
private MyOpenHelper myOpenHelper;
private SQLiteDatabase myDB;
public static final String AUTHORITY = "com.gill.test.authorities";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/MyTable");
private static final String[] MYCOLUMN = new String[] { "mycolumn" };
@Override
public boolean onCreate() {
myOpenHelper = new MyOpenHelper(getContext());
myDB = myOpenHelper.getWritableDatabase();
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase myDatabase = myOpenHelper.getWritableDatabase();
Cursor c = myDatabase.query(uri.getLastPathSegment(), MYCOLUMN, null,
null, null, null, null);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowId = -1;
//第二個參數隨便是該table內的任一個欄位,反正insert就是一整筆下去新增,系統會自動配對欄位和values
rowId = myDB.insert(uri.getLastPathSegment(), "mycolumn", values);
Uri newUri = Uri.withAppendedPath(CONTENT_URI, "" + rowId);
getContext().getContentResolver().notifyChange(uri, null);
return newUri;
}
}
Main.java
public class Main extends Activity {
private ContentResolver mResolver;
private Cursor myCursor;
private TextView txt;
private EditText edit;
private MyContentObserver myObserver;
private Handler handler = new Handler();
// AUTHORITY要看該Provider的AndroidManifest.xml中的定義
public static final String AUTHORITY = "com.gill.test.authorities";
// URI = AUTHORITY再加table name
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/MyTable");
private static final String[] MYCOLUMN = new String[] { "mycolumn" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mResolver = getContentResolver();
// 透過getContentResolver由系統依據uri,決定要執行那一個ContentProvider
// 所以這裡不用直接呼叫MyDataBaseProvider也可以取得資料
myCursor = mResolver.query(CONTENT_URI, MYCOLUMN, null, null, null);
myCursor.moveToFirst(); // 一定要寫,不然會出錯
txt = (TextView) findViewById(R.id.txt);
txt.setText(myCursor.getString(0));
edit = (EditText) findViewById(R.id.edit);
Button insert_btn = (Button) findViewById(R.id.insert);
// 新增
OnClickListener insert_lis = new OnClickListener() {
public void onClick(View v) {
ContentValues values = new ContentValues();
// 如果table有很多欄位,就在這裡把所有的欄位利用values.put補齊
values.put("mycolumn", edit.getText().toString());
mResolver.insert(CONTENT_URI, values);
txt.setText(myCursor.getString(0));
}
};
insert_btn.setOnClickListener(insert_lis);
registerContentObservers();
}
@Override
protected void onStop() {
super.onStop();
unregisterContentObservers();
}
//註冊監聽
private void registerContentObservers() {
myObserver = new MyContentObserver(handler);
getContentResolver().registerContentObserver(CONTENT_URI, true, myObserver);
}
//取消監聽
private void unregisterContentObservers() {
if (myObserver != null) {
getContentResolver().unregisterContentObserver(myObserver);
myObserver = null;
}
}
}
注 意registerContentObserver()第二個參數是true,表示對這個CONTENT_URI底下所有的uri都進行監聽。舉例如果該 值是true,則content://com.gill.test.authorities/MyTable/1的變化,也會監聽。這裡的1是指 table裡面的_id(也有可能是2、3、…等)。如果是false的話,就只對 content://com.gill.test.authorities/MyTable監聽,那就達不到我們要的效果了。content: //com.gill.test.authorities/MyTable就叫Base Uri,而content://com.gill.test.authorities/MyTable/1這種的就是Base Uri的descendanted uri。請參考原文:http://developer.android.com/reference/android/content/ContentResolver.html#registerContentObserver%28android.net.Uri,%20boolean,%20android.database.ContentObserver%29
沒有留言:
張貼留言