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

    xiaoxiao2021-12-14  18

    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()去取消注册。    

    转载请注明原文地址: https://ju.6miu.com/read-965025.html

    最新回复(0)