监听ContentProvider数据的改变

前面介绍的是当ContentProvider将数据共享出来之后,ContentResolver会根据业务需要去主动查询ContentProvider所共享的数据;但有时候程序需要实时监听ContentProvider所共享的数据,并提供相应的响应,这就需要利用ContentObserver了。

其实在ContentProvider中,不管实现的哪个方法,只要该方法导致数据发生了变化。程序就调用了如下代码:

getContext().getContentResolver().notifyChange(uri, null);

用于通知所有注册在该Uri上的监听者:该ContentProvider所共享的数据发生了改变。

监听ContentProvider数据改变的监听器需要继承ContentObserver类,并重写onChange方法,当ContentProvider数据发生改变时,该方法会被触发。

为了监听指定ContentProvider的数据变化,需要通过ContentResolver向指定的Uri注册监听器。ContentResolver提供了如下方法来组成监听器:

该方法中三个参数说明如下:

下面用监听用户发送短信的实例来演示,通过Activity启动一个Service服务,去监听ContentProvider数据的变化。代码如下:

Activity:

package com.lovo.testcontentobserver;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {
	private Button startBtn, stopBtn;
	private Intent intent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		startBtn = (Button) findViewById(R.id.main_btn_start);
		stopBtn = (Button) findViewById(R.id.main_btn_stop);
		startBtn.setOnClickListener(this);
		stopBtn.setOnClickListener(this);
		intent = new Intent();
		// 为intent设置Action属性
		intent.setAction("com.lovo.myservice");
	}

	@Override
	public void onClick(View v) {
		if (v == startBtn) {
			// 启动指定Service
			startService(intent);
		}
		if (v == stopBtn) {
			// 停止指定Service
			stopService(intent);
		}
	}
}

布局XML只有2个按钮就省略不写了。

Service:

package com.lovo.service;

import android.app.Service;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		// 为content://sms的数据改变注册监听器
		getContentResolver().registerContentObserver(
				Uri.parse("content://sms"), true,
				new SmsObserver(new Handler()));
	}

	// 提供自定义的ContentProvider监听器类
	private final class SmsObserver extends ContentObserver {

		public SmsObserver(Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange) {
			// 查询发送箱中的短信(处于正在发送状态的短信放在发送箱中)
			Cursor cursor = getContentResolver().query(
					Uri.parse("content://sms/outbox"), null, null, null, null);
			while (cursor.moveToNext()) {
				StringBuffer sb = new StringBuffer();
				// 获取短信的发送地址
				sb.append("address=").append(
						cursor.getString(cursor.getColumnIndex("address")));
				// 获取短信的标题
				sb.append(";subject=").append(
						cursor.getString(cursor.getColumnIndex("subject")));
				// 获取短信的内容
				sb.append(";body=").append(
						cursor.getString(cursor.getColumnIndex("body")));
				// 获取短信的发生时间
				sb.append(";time=").append(
						cursor.getLong(cursor.getColumnIndex("date")));
				Log.i("发送的短信:", sb.toString());
			}
		}
	}
}

加上权限:

<uses-permission android:name="android.permission.WRITE_SMS"/>
 <uses-permission android:name="android.permission.READ_SMS"/> 





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值