攔截簡訊,比如當發簡訊的時候,就把簡訊讀取出來,當系統的簡訊發生變化的時候,大叫一聲,把數據發送到公共的消息郵箱裡面,我們的應用通過內容觀察者觀察公共的消息郵箱 獲取ContentResolver對象,調用函數getContentResolver(), 調用ContentResolver對象的reg ...
攔截簡訊,比如當發簡訊的時候,就把簡訊讀取出來,當系統的簡訊發生變化的時候,大叫一聲,把數據發送到公共的消息郵箱裡面,我們的應用通過內容觀察者觀察公共的消息郵箱
獲取ContentResolver對象,調用函數getContentResolver(),
調用ContentResolver對象的registerContentObserver(uri,notifyForDescendents,observer)方法,參數:Uri對象,是否精確uri(true不精確,false精確),observer對象 ContentObserver對象
因為ContentObserver是抽象類,因此我們寫一個內部類來繼承這個抽象類,必須實現構造函數,構造函數的Handler對象消息處理器稍後會講,定義一個內部類MyObserver,實現父類的onChange()回調方法,觀察到消息郵箱發生變化的時候會回調這個方法。
在這個回調函數裡面,使用獲取到簡訊內容,取最後一條,調用Cursor對象的moveToFirst()指針指向最後一條
系統應用是如何發出這個叫聲的呢,獲取ContentResolver對象,通過getContentResolver()方法,調用ContentResolver對象的notifyChange(uri,observer)方法,參數:uri隨便定義,observer指定誰處理預設null
系統的很多應用進行通知通信都是通過這個公共消息郵箱機制來實現的
接下來實戰一下,接著《Android 內容提供者的實現》中使用的項目作為基礎,新建一個項目,並添加代碼如下:
package com.wuyudong.observer; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Uri uri = Uri.parse("content://com.wuyudong.db.personprovider/"); getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler())); } private class MyObserver extends ContentObserver { public MyObserver(Handler handler) { // handler 是一個消息處理器 super(handler); } @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub System.out.println("haha,資料庫的內容變化了!!!"); super.onChange(selfChange); } } }
並修改PersonDBProvider.java中的代碼:
public Uri insert(Uri uri, ContentValues values) { if (matcher.match(uri) == INSERT) { // 返回查詢的結果集 SQLiteDatabase db = helper.getWritableDatabase(); db.insert("person", null, values); getContext().getContentResolver().notifyChange(uri, null); } else { throw new IllegalArgumentException("路徑不匹配,不能執行插入操作"); } return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if (matcher.match(uri) == DELETE) { // 返回查詢的結果集 SQLiteDatabase db = helper.getWritableDatabase(); int result = db.delete("person", selection, selectionArgs); db.close(); if (result > 0) { getContext().getContentResolver().notifyChange(uri, null); } } else { throw new IllegalArgumentException("路徑不匹配,不能執行刪除操作"); } return 0; }
這樣在每次點擊按鈕的時候,都會列印相關資料庫數據被修改的提示