监听ContentProvider

监听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组件了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值