Android 使用ContentObserver监听SettingsProvider值的变化

开发中,我们会通过 Settings 设置、保存一些值,最终是存储到 SettingsProvider 的数据库里的,如

Settings.Global.putInt(getContentResolver(), "ContentObserverTest", 0);
Settings.System.putInt(getContentResolver(), "ContentObserverTest", 0);
Settings.Secure.putInt(getContentResolver(), "ContentObserverTest", 0);

需要是系统应用且添加权限 ,

-

adb 也可以读取、写入,如

settings put global ContentObserverTest 1

settings get global ContentObserverTest

在需要监听这些值的变动时,
就用 registerContentObserver(Uri uri, boolean notifyForDescendants,ContentObserver observer) {}

3个参数

  • uri :被监听数据的 uri ,可以通过 Settings.Global.getUriFor(“key”) 得到。
  • notifyForDescendants :false 表示精确匹配。true 表示还可以匹配 uri 派生的 uri 。
  • observer :数据变化时接收消息的 ContentObserver

创建自定义ContentObserver

重写 onChange 方法,回调时会跑这里。selfChange 意思不大,一般都是 false 。

private static class MyContentObserver extends ContentObserver{

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

        @Override
        public void onChange(boolean selfChange, @Nullable Uri uri) {
            super.onChange(selfChange, uri);
        }
    }

构造函数中需要传一个 Handler ,那就创建 Handler 。

	private static Handler mHandler = new Handler(Looper.getMainLooper()){

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

监听

本例监听蓝牙开关,uri 是 content://settings/global/bluetooth_on ,

  • uri.getScheme() :content
  • uri.getAuthority() :settings
  • uri.getHost() :settings
  • uri.getPath() :/global/bluetooth_on
  • uri.getLastPathSegment() :bluetooth_on
Uri uri = Settings.Global.getUriFor(Settings.Global.BLUETOOTH_ON);// content://settings/global/bluetooth_on
getContentResolver().registerContentObserver(uri, true, new MyContentObserver(mHandler));

取消监听

使用后(Activity 、Service 退出)需要取消监听,

getContentResolver().unregisterContentObserver(mObserver);

本例是作为普通应用监听蓝牙开关,监听是可以的,设置不行,因为没权限。

模拟器可运行,通过通知栏开关蓝牙开关可验证。完整代码

public class ContentObserverActivity extends AppCompatActivity {

    private static class MyContentObserver extends ContentObserver{

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

        @Override
        public void onChange(boolean selfChange, @Nullable Uri uri) {
            super.onChange(selfChange, uri);
        }
    }

    private static Handler mHandler = new Handler(Looper.getMainLooper()){

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

    private MyContentObserver mObserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_content_observer);
        Objects.requireNonNull(getSupportActionBar()).setTitle("ContentObserverActivity");

        mObserver = new MyContentObserver(mHandler);

        Uri uri = Settings.Global.getUriFor(Settings.Global.BLUETOOTH_ON);// content://settings/global/bluetooth_on
        getContentResolver().registerContentObserver(uri, true, mObserver);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (null != mObserver) {
            getContentResolver().unregisterContentObserver(mObserver);
            mObserver = null;
        }
    }
}

你可能感兴趣的:(Android,android,java)