#獲取cursor記錄數#
要獲取cursor中實際有多少個記錄,不能使用cursor.getColumnCount()來獲取,必須使用以下方法來獲取,因爲記錄小於10時,cursor.getColumnCount()返回10.
/** * 獲取Cursor中的記錄數 * @param cursor * @return */ public int getCursorCount(Cursor cursor) { int count = 0; if(cursor.moveToFirst()) { do { count++; } while(cursor.moveToNext()); } return count; }
#handler.post(Runnable)#
在ContentObserver.onChange方法中,如果要求去更新UI,需要使用Handler來發出消息,一種方法是handler.sendEmptyMessage(what)來發消息,這種方法要求handler中重寫handleMessage方法。另外一種比較簡潔的方法是handler.post(new Runnable(){ })然後重新run()方法。
handler.post(new Runnable() { @Override public void run() { load(); } });
#註冊和註銷ContentObserver#
在onCreateView方法中註冊ContentObserver,然後在onDestroyView中註銷ContentObserver.
// 註冊 resolver.registerContentObserver(DataProvider.getUri(), true, observer); // 註銷 resolver.unregisterContentObserver(observer);
#從數據庫中獲取數據#
如果在ContentObserver的onChange方法中發現有數據變化,那麼在load方法中使用現成的cursor,如果是第一次加載數據,那麼在load方法中重新從數據庫中獲取數據。
private void load(Cursor cursor) { if (cursor == null) { cursor = context.getContentResolver().query(DataProvider.getUri(), null, SimpleDataColumns.MODULE + "= ? and " + SimpleDataColumns.DATA3 + " = ?", new String[] { Constants.PROGRAM, TvRemind.UNREMIND }, SimpleDataColumns.DATA1 + " asc"); } if (DEBUG) Logger.v(TAG, "@load. Cursor count >> " + getCursorCount(cursor)); listRemind.clear(); if (cursor.moveToFirst()) { do { int id = cursor.getInt(cursor.getColumnIndex(SimpleDataColumns._ID)); String programId = cursor.getString(cursor.getColumnIndex(SimpleDataColumns.KEY)); String time = cursor.getString(cursor.getColumnIndex(SimpleDataColumns.DATA1)); String name = cursor.getString(cursor.getColumnIndex(SimpleDataColumns.DATA2)); String status = cursor.getString(cursor.getColumnIndex(SimpleDataColumns.DATA3)); listRemind.add(new TvRemind(id, time, name, programId, status)); } while (cursor.moveToNext()); } cursor.close(); adapterRemind.notifyDataSetChanged(listRemind); if (DEBUG) Logger.v(TAG, "@load. listRemind.size() >> " + listRemind.size() + ", listRemind >> " + listRemind); }
#監聽提醒數據發生變化#
在ContentObserver中,如果相應數據發生變化,從數據庫中取出cursor,再比較cursor中的記錄數和listRemind的條目數,如果不等,表示數據發生變化,就要調用load方法更新UI。
private ContentObserver observer = new ContentObserver(null) { @Override public void onChange(boolean selfChange, android.net.Uri uri) { final Cursor cursor = context.getContentResolver().query(DataProvider.getUri(), null, SimpleDataColumns.MODULE + "= ? and " + SimpleDataColumns.DATA3 + " = ?", new String[] { Constants.PROGRAM, TvRemind.UNREMIND }, SimpleDataColumns.DATA1 + " asc"); int cursorCount = getCursorCount(cursor); if (DEBUG) Logger.v(TAG, "@onChange. Cursor count >> " + cursorCount + ", Current remind count >> " + listRemind.size()); if (cursorCount != listRemind.size()) { handler.post(new Runnable() { @Override public void run() { load(cursor); } }); } else { cursor.close(); } } };
#取消提醒#
點擊取消提醒,將改提醒記錄從數據庫中刪除,然後通知數據庫發生變化。
View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (DEBUG) Logger.v(TAG, "@onClick. Delete the remind item and notify change >> " + DataProvider.getUri()); TvRemind remind = (TvRemind)v.getTag(); SimpleData.deleteByKey(session, Constants.PROGRAM, remind.getProgramId()); context.getContentResolver().notifyChange(DataProvider.getUri(), null); } };