监听ContentProvider

来源:互联网 发布:写作软件排行 编辑:程序博客网 时间:2024/06/09 21:35

监听ContentProvider的数据改变

使用ContentProvider时,不管实现insert、delete、update方法中的哪一个,只要该方法导致ContentProvider数据的改变,程序就会调用如下代码:
getContext().getContentResolver().notifyChange(uri, null);
这行代码可用于通知所有注册在该Uri上的监听者:该ContentProvider所共享的数据发生了改变。

为了在该应用程序中监听ContentProvider数据的改变,需要利用Android提供的ContentObserver基类。监听ContentProvider数据改变的监听器需要继承ContentObserver类,并重写该基类所定义的onChange(boolean selfChange)方法——当它所监听的ContentProvider数据发生改变时,该onChange()方法将会被触发。

为了监听指定ContentProvider的数据变化,需要通过ContentResolver向指定Uri注册ContentObserver监听器。ContentResolver提供了如下方法来注册监听器。
registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
该方法中的三个参数说明如下。
uri:该监听器所监听的ContentProvider的uri。
notifyForDescendents:如果该参数设为true,假如注册监听的Uri为content://abc,那么Uri为content://abc/xyz、content://abc/foo的数据改变时也会触发 该监听器;如果该参数设为false,假如注册监听的Uri为content://abc,那么只有content://abc的数据发生改变时才会触发该监听器。
observer:监听器实例。

例如,如下代码片段可用于为指定Uri注册监听器:
getContentResolver().registerContentObserver(Uri.parse(“content://sms”)), true, new SmsObserver(new Handler()));
上面的代码中SmsObserver就是ContentObserver的子类。

实例:监听用户发出的短信
本实例通过监听Uri为content://sms的数据改变即可监听到用户短信的数据改变,并在监听器的onChange(boolean selfChange)方法里查询Uri为content://sms/outbox的数据,这样即可获取用户正在发送的短信(用户正在发送的短信保存在发件箱内)。

该程序的代码如下。

public class MainActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //为content://sms的数据改变注册监听器,可以监听到用户短信数据的改变        getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler()));    }    //提供自定义的ContentObserver监听器类    private final class SmsObserver extends ContentObserver {        public SmsObserver(Handler handler) {            super(handler);        }        @Override        public void onChange(boolean selfChange) {            //查询发件箱中的短信(处于正在发送状态的短信放在发件箱中),用于查询content://sms/outbox的全部数据,也就是查询发件箱(正在发送的短信保存在发件箱内)内的全部短信,这样就可以获取用户正在发送的短信详情            Cursor cursor = getContentResolver().query(Uri.parse("content://sms/outbox"), null, null, null, null);            //遍历查询得到的结果集,即可获取用户正在发送的短信            while (cursor.moveToNext()) {                StringBuilder stringBuilder = new StringBuilder();                //获取短信的发送地址                stringBuilder.append("address=").append(cursor.getString(cursor.getColumnIndex("address")));                //获取短信的标题                stringBuilder.append(";subject=").append(cursor.getString(cursor.getColumnIndex("subject")));                //获取短信的内容                stringBuilder.append(";body=").append(cursor.getString(cursor.getColumnIndex("body")));                //获取短信的发送时间                stringBuilder.append(";time=").append(cursor.getLong(cursor.getColumnIndex("date")));                System.out.println("发送短信:" + stringBuilder.toString());            }        }    }}

运行该程序,在不关闭该程序的情况下打开Android系统内置的”Messaging”程序发送短信——直接向本机号码发送即可。当用户发送短信时,可以在LogCat面板看到如下:
发送短信:address=555-4;subject=null;body=this is test message;time=14217364484

本程序需要读取系统短信的内容,因此还需要为该应用添加读取短信的权限

后记:
这个监听用户发送短信的程序采用Activity来实现并不合适——因为用户必须先主动打开该Activity,并保持该Activity不关闭的情况下,用户所发送的短信才会被监听到。这明显不太符合实际需求场景,在实际情况下,可能更希望该程序以后台进程的方式“不知不觉”的运行,这就需要利用Android的service组件了。