Android は ContentObserver を使用して、SettingsProvider 値の変更を監視します

開発中に、Settings を通じていくつかの値を設定して保存し、最終的にそれらを SettingsProvider のデータベースに保存します。

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

システムアプリケーションにして権限を追加する必要があります。

<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />-
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

adb は読み書きもできます。たとえば、

settings put global ContentObserverTest 1

settings get global ContentObserverTest

これらの値の変化を監視する必要がある場合は、
registerContentObserver(Uri uri, boolean notifyForDescendants,ContentObserver observer) {} 、 を使用します。

3つのパラメータ

  • uri: 監視データの Uri は、Settings.Global.getUriFor("key") を通じて取得できます。
  • NoticeForDescendants: false は完全一致を示します。 true は、uri から派生した URI も照合できることを意味します。
  • オブザーバー: データ変更時にメッセージを受信する 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);
        }
    }

コンストラクターでハンドラーを渡す必要がある場合は、ハンドラーを作成します。

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

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

モニター

この例では、Bluetooth スイッチが監視されており、URI は content://settings/global/bluetooth_on です。

  • uri.getScheme() :内容
  • uri.getAuthority() :設定
  • uri.getHost() :設定
  • 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));

モニタリングを中止する

使用後(アクティビティ、サービス終了)、監視をキャンセルする必要があります。

getContentResolver().unregisterContentObserver(mObserver);

この例はBluetoothスイッチを監視する通常のアプリケーションとして使用されており、監視は可能ですが、権限がないため設定ができません。

エミュレータは実行可能であり、通知バーの Bluetooth スイッチをオンまたはオフにすることで確認できます。完全なコード

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;
        }
    }
}

おすすめ

転載: blog.csdn.net/weixin_44021334/article/details/133383736