使用内容观察者(ContentObserver)来观察 蓝牙 打开和关闭的状态

ContentObserver -- 内容观察者, 目的是观察(捕捉)特定Uri 引起的数据库的变化,继而做一些相应的处理。

它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。


一、使用ContentObserver来观察蓝牙打开和关闭状态的步骤

1. 创建一个子类,继承ContentObserver;

2. 在此子类中重写 onChange() 方法;

3. 根据Uri 来注册内容观察者。


具体步骤如下所示:

1. 创建一个子类,继承ContentObserver。

/**
 * 用于观察 sysem 中的 手电筒是否打开或者关闭
 * Created by czj on 2016/12/2.
 */
public class BluetoothObserver extends ContentObserver {

    private Context mContext;
    private Handler mHandler;

    private static final int MSG_BLUETOOTH_ON = 3;


    /**
     * Creates a content observer.
     *
     * @param handler The handler to run {@link #onChange} on, or null if none.
     */
    public BluetoothObserver(Context context, Handler handler) {
        super(handler);

        mContext = context;
        mHandler = handler;

        Log.e("TAG", "FlashlightObserver: " );
    }

    @Override
    public void onChange(boolean selfChange) {

        Log.e("TAG", "FlashlightObserver onChange" );

        try {
            int bluetoothOn = Settings.System.getInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON);

            mHandler.obtainMessage(MSG_BLUETOOTH_ON,bluetoothOn).sendToTarget();
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
    }
}

3. 根据Uri 来注册内容观察者。

public class MainActivity extends AppCompatActivity {


    private static final String TAG = "MainActivity";

    private TextView tvAirplane;

    //Message 类型值
    private static final int MSG_FLASHLIGHT_ON = 3;

    private BluetoothObserver bluetoothObserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvAirplane = (TextView) findViewById(R.id.tvAirplane);

        bluetoothObserver = new BluetoothObserver(this, mHandler);

        //注册内容观察者
        registerContentObservers();
    }

    private void registerContentObservers() {
        Uri flashlightUri = Settings.System.getUriFor(Settings.System.BLUETOOTH_ON);
        getContentResolver().registerContentObserver(flashlightUri, false, bluetoothObserver);
    }


    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            Log.e("TAG", "handleMessage" + msg.what);

            switch (msg.what){
                case MSG_FLASHLIGHT_ON:
                    int isFlashlightOpen = (int) msg.obj;
                    if (isFlashlightOpen == 0){
                        tvAirplane.setText("蓝牙关闭");
                    }else{
                        tvAirplane.setText("蓝牙打开");
                    }

                    break;
            }
        }
    };
}

xml 文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.zhengjunchen.observerdemo.MainActivity"
    tools:showIn="@layout/activity_main">

    <TextView
        android:id="@+id/tvAirplane"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>

    <EditText
        android:id="@+id/smsoutboxContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


</LinearLayout>


 注册/取消注册ContentObserver方法,抽象类ContentResolver类中的方法原型如下:

 

    public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)

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

             参数:uri          需要观察的Uri(需要在UriMatcher里注册,否则该Uri也没有意义了)

                        notifyForDescendents  为false 表示精确匹配,即只匹配该Uri

                                                                     为true 表示可以同时匹配其派生的Uri,举例如下:

                          假设UriMatcher 里注册的Uri共有一下类型:

                                1 、content://com.qin.cb/student (学生)

                                2 、content://com.qin.cb/student/# 

                                3、 content://com.qin.cb/student/schoolchild(小学生,派生的Uri)

 

                    假设我们当前需要观察的Uri为content://com.qin.cb/student,如果发生数据变化的 Uri 为   

           content://com.qin.cb/student/schoolchild ,当notifyForDescendents为 false,那么该ContentObserver会监听不到,  

           但是当notifyForDescendents 为ture,能捕捉该Uri的数据库变化。

 

                     observer       ContentObserver的派生类实例

 

 

    public final void  unregisterContentObserver(ContentObserver observer)

          功能:取消对给定Uri的观察

          参数: observer ContentObserver的派生类实例

 

        

ContentObserver类介绍

 

  构造方法 public void ContentObserver(Handler handler)  

                       说明:所有   ContentObserver的派生类都需要调用该构造方法

        参数: handler  Handler对象。可以是主线程Handler(这时候可以更新UI 了),也可以是任何Handler对象。

 常用方法

   void onChange(boolean selfChange)

       功能:当观察到的Uri发生变化时,回调该方法去处理。所有ContentObserver的派生类都需要重载该方法去处理逻辑。

       参数:selfChange 回调后,其值一般为false,该参数意义不大(我也不懂,理解方法最重要)。

 

  另外两个方法,用处不大,我也不懂,大家参照SDK自行理解,冒昧了。

  boolean  deliverSelfNotifications()

     说明:Returns true if this observer is interested in notifications for changes made through the cursor the observer is registered with.

  

  final void dispatchChange(boolean selfChange)

 

 

  观察特定Uri的步骤如下

 

     1、    创建我们特定的ContentObserver派生类,必须重载父类构造方法,必须重载onChange()方法去处理回调后的功能实现

     2、    利用context.getContentResolover()获得ContentResolove对象,接着调用registerContentObserver()方法去注册内容观察者

     3、    由于ContentObserver的生命周期不同步于Activity和Service等,因此,在不需要时,需要手动的调用

             unregisterContentObserver()去取消注册。    





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值