Android系统之registerContentObserver(一)

Android系统之registerContentObserver(一),第1张

(1)API

ContentObserver——内容观察者,目的是观察特定Uri引起的数据库的数据变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri数据发生变化时,便会触发它。

(A)ContentResolver类:注册/取消注册ContentObserver方法

/*
为指定的Uri注册一个ContentObserver派生类实例,当给定的Uri发生改变时,回调该实例对象去处理。

uri——  需要观察的Uri(需要在UriMatcher里注册)
notifyForDescendents——  为false 表示精确匹配,即只匹配该Uri
														为true 表示可以同时匹配其派生的Uri,
*/
registerContentObserver(Uri uri, boolean notifyForDescendants, ContentObserver observer)

unregisterContentObserver(ContentObserver observer)

(B)ContentObserver类:回调函数

//构造函数——所有ContentObserver的派生类都需要调用该构造方法
public void ContentObserver(Handler handler)  

//当观察到的Uri发生变化时,回调该方法去处理。所有ContentObserver的派生类都需要重载该方法去处理逻辑。
void onChange(boolean selfChange)

(C)观察特定Uri的步骤如下

创建我们特定的ContentObserver派生类,必须重载父类构造方法,必须重载onChange()方法去处理回调后的功能实现;利用context.getContentResolover()获得ContentResolove对象,接着调用registerContentObserver()方法去注册内容观察者;由于ContentObserver的生命周期不同步于Activity和Service等,因此,在不需要时,需要手动的调用unregisterContentObserver()去取消注册;

(2)部分常用的Uri

//管理联系人的Uri:
ContactsContract.Contacts.CONTENT_URI

MediaStore.Files.FileColumns.xxx
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
MediaStore.Images.Images.EXTERNAL_CONTENT_URI
MediaStore.Video.Images.EXTERNAL_CONTENT_URI

content://sms/inbox    // 收件箱         
content://sms/sent        //已发送
content://sms/draft        //草稿           
content://sms/outbox    //发件箱(正在发送的信息)
content://sms/failed      //发送失败     
content://sms/queued  //待发送列表  (比如开启飞行模式后,该短信就在待发送列表里)

(3)相关Demo

(A)
观察系统是否改变了飞行模式状态

//(1) 观察飞行模式状态的ContentObserver派生类

public class AirplaneContentObserver extends ContentObserver {
 
	private static String TAG = "AirplaneContentObserver" ;
	private static int MSG_AIRPLANE = 1 ;
	private Context mContext;    
    private Handler mHandler ;  //此Handler用来更新UI线程
    
	public AirplaneContentObserver(Context context, Handler handler) {
		super(handler);
		mContext = context;
		mHandler = handler ;
	}
 
	/**
	 * 当所监听的Uri发生改变时,就会回调此方法
	 * 
	 * @param selfChange 此值意义不大 一般情况下该回调值false
	 */
	@Override
	public void onChange(boolean selfChange) {
        Log.i(TAG, "-------------the airplane mode has changed-------------");
        
		// 系统是否处于飞行模式下
		try {
			int isAirplaneOpen = Settings.System.getInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON);
		    Log.i(TAG, " isAirplaneOpen -----> " +isAirplaneOpen) ;
		    mHandler.obtainMessage(MSG_AIRPLANE,isAirplaneOpen).sendToTarget() ;
		}
		catch (SettingNotFoundException e) {
			e.printStackTrace();
		}
	}
}

观察系统的短信息数据是否发生了变化

//(2)观察系统里短消息的数据库变化的ContentObserver派生类

public class SMSContentObserver extends ContentObserver {
    private static String TAG = "SMSContentObserver";
	
    private int MSG_OUTBOXCONTENT = 2 ;
    
	private Context mContext  ;
	private Handler mHandler ;   //更新UI线程
	
	public SMSContentObserver(Context context,Handler handler) {
		super(handler);
		mContext = context ;
		mHandler = handler ;
	}
	/**
	 * 当所监听的Uri发生改变时,就会回调此方法
	 * 
	 * @param selfChange  此值意义不大 一般情况下该回调值false
	 */
    @Override
	public void onChange(boolean selfChange){
    	Log.i(TAG, "the sms table has changed");
    	
		//查询发件箱里的内容    	
    	Uri outSMSUri = Uri.parse("content://sms/sent") ;
    	Cursor c = mContext.getContentResolver().query(outSMSUri, null, null, null,"date desc");
    	if(c != null){
        	Log.i(TAG, "the number of send is"+c.getCount()) ;
        	StringBuilder sb = new StringBuilder() ;
        	//循环遍历
        	while(c.moveToNext()){
        		sb.append("发件人手机号码: "+c.getInt(c.getColumnIndex("address")))
      		      .append("信息内容: "+c.getString(c.getColumnIndex("body")))
      		      .append("\n");
        	}
        	c.close();       	
        	mHandler.obtainMessage(MSG_OUTBOXCONTENT, sb.toString()).sendToTarget();       	
    	}
	}
}
public class MainActivity extends Activity {
 
	private TextView tvAirplane;
	private EditText etSmsoutbox;

	private static final int MSG_AIRPLANE = 1;
	private static final int MSG_OUTBOXCONTENT = 2;
 
	private AirplaneContentObserver airplaneCO;
	private SMSContentObserver smsContentObserver;
 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
 
		tvAirplane = (TextView) findViewById(R.id.tvAirplane);
		etSmsoutbox = (EditText) findViewById(R.id.smsoutboxContent);

		airplaneCO = new AirplaneContentObserver(this, mHandler);
		smsContentObserver = new SMSContentObserver(this, mHandler);

		registerContentObservers() ;
	}
 
	private void registerContentObservers() {
		Uri airplaneUri = Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON);
		getContentResolver().registerContentObserver(airplaneUri, false, airplaneCO);

		Uri smsUri = Uri.parse("content://sms");
		getContentResolver().registerContentObserver(smsUri, true,smsContentObserver);
	}
 
	private Handler mHandler = new Handler() {
 
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_AIRPLANE:
				int isAirplaneOpen = (Integer) msg.obj;
				if (isAirplaneOpen != 0)
					tvAirplane.setText("飞行模式已打开");
				else if (isAirplaneOpen == 0)
					tvAirplane.setText("飞行模式已关闭");
				break;
			case MSG_OUTBOXCONTENT:
				String outbox = (String) msg.obj;
				etSmsoutbox.setText(outbox);
				break;
			default:
				break;
			}
		}
	};
}

(B)监听图片变化

mPhotoObserver = new PhotoObserver(new Handler());
getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, mPhotoObserver);
  
class PhotoObserver extends ContentObserver {
        public PhotoObserver(Handler handler) {
            super(handler);
        }
 
        @Override
        public void onChange(boolean selfChange) {
 
        }
 
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            Log.d("image onChange", selfChange + ", " + uri);
 
            //查询出第一条记录
            Cursor c = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, "_id DESC LIMIT 1");
//                Cursor c = getContentResolver().query(uri, null, null, null, "_id DESC LIMIT 1");
            if (c.moveToNext()) {
                int imageId = c.getInt((c.getColumnIndex(MediaStore.Images.Media._ID)));
                String title = c.getString(c.getColumnIndex(MediaStore.Files.FileColumns.DATA));
                Bitmap bm = MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(),
                        imageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
            }
            c.close();
        }
    }

(C)监听视频变化

mVideoObserver = new VideoObserver(new Handler());
getContentResolver().registerContentObserver(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, mVideoObserver);

class VideoObserver extends ContentObserver {
    public VideoObserver(Handler handler) {
        super(handler);
    }
 
    @Override
    public void onChange(boolean selfChange) {
    }
 
    @Override
    public void onChange(boolean selfChange, Uri uri) {
        Log.d("video onChange", selfChange + ", " + uri);
        //查询出第一条记录
        Cursor c = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null, "_id DESC LIMIT 1");
        if (c.moveToNext()) {
            int imageId = c.getInt((c.getColumnIndex(MediaStore.Video.Media._ID)));
            Bitmap bm = MediaStore.Video.Thumbnails.getThumbnail(getContentResolver(),
                    imageId, MediaStore.Video.Thumbnails.MINI_KIND, null);
        }
        c.close();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/992087.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存