SettingsProvider監聽值變化(ContentObserver)

1. registerContentObserver註冊要監聽的變量

public class MainActivity extends Activity {
    public static final String TAG = "Tobserver";

    private Button btnEnable,btnDisable,btnRegister,btnUnregister;
    public ContentResolver mresolver;
    //public SettingsValueChangeContentObserver mObserver;
    int brightness = 100;
    public static final String TEST_URL = "test_main";
    public int ENABLE_TEST_URL = 1;
    public int DISENABLE_TEST_URL = 2;

    private final SettingObserver mObserver = new SettingObserver();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        registerOB();
        btnEnable.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG ,"onClick  1");
                registerOB();
            }
        });

        btnDisable.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG ,"onClick  2");
                //Settings.System.putInt(mresolver, Settings.System.SCREEN_BRIGHTNESS, brightness);
                putIntValue(brightness);
                brightness ++ ;
            }
        });

        btnUnregister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG ,"onClick  4");
                unRegisterOB();
            }
        });


    }

    public  void registerOB() {
        getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES), false,
                mObserver);
        getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS), false,
                mObserver);
        getIntValue();
    }

    public int getIntValue() {
        int newValue = Settings.Secure.getInt(getContentResolver(),
                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,10);
        Log.d(TAG, " getString = " + newValue);
        return newValue;
    }

    public void putIntValue(int value) {
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, value);
        Log.d(TAG, " putIntValue " + value);
    }

    public  void unRegisterOB() {
        getContentResolver().unregisterContentObserver(mObserver);
    }

    private final class SettingObserver extends ContentObserver {
        public SettingObserver() {
            super(new Handler(Looper.getMainLooper()));
        }
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            //reloadList();
            Log.d(TAG, "onChange newValue = " + getIntValue());
        }
    }
}

2. 自定義變量監聽

把1代碼中的,在Settings.Secure定義的變量,直接定義在本地DMS_BUTTON,就可以直接put get值了

public static final String DMS_BUTTON = "dms_button";
public int ENABLE_DMS_BUTTON = 1;
public int DISENABLE_DMS_BUTTON = 2;


public  void registerOB() {
    getContentResolver().registerContentObserver(
            Settings.Secure.getUriFor(DMS_BUTTON), false,
            mObserver);
    getContentResolver().registerContentObserver(
            Settings.Secure.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS), false,
            mObserver);
    getIntValue();

}


public int getIntValue() {
    int newValue = Settings.Secure.getInt(getContentResolver(),
            DMS_BUTTON,10);
    Log.d(TAG, " getString = " + newValue);
    return newValue;
}

public void putIntValue(int value) {

    Settings.Secure.putInt(getContentResolver(), DMS_BUTTON, value);
    Log.d(TAG, " putIntValue " + value);
}
//put和get自己定義的值
* adb shell settings get secure avm_gesture_switch
* adb shell settings put secure avm_gesture_switch 1

3. 原理

ContentProvider、ContentResolver、ContentObserver之間的關係

ContentProvider:
* 四大組件的內容提供者,主要用於對外提供數據
* 實現各個應用程序之間的(跨應用)數據共享,比如聯繫人應用中就使用了ContentProvider,你在自己的應用中可以讀取和修改聯繫人的數據,不過需要獲得相應的權限。其實它也只是一箇中間人,真正的數據源是文件或者SQLite等
* 一個應用實現ContentProvider來提供內容給別的應用來操作,通過ContentResolver來操作別的應用數據,當然在自己的應用中也可以

ContentResolver:
* 內容解析者,用於獲取內容提供者提供的數據
* ContentResolver.notifyChange(uri)發出消息

ContentObserver:
* 內容監聽器,可以監聽數據的改變狀態
* 目的是觀察(捕捉)特定Uri引起的數據庫的變化,繼而做一些相應的處理,它類似於數據庫技術中的觸發器(Trigger),當ContentObserver所觀察的Uri發生變化時,便會觸發它。觸發器分爲表觸發器、行觸發器,
相應地ContentObsever也分爲表ContentObserver、行ContentObserver,當然這是與它所監聽的Uri MIME Type有關的
* ContentResolver.registerContentObserver()監聽消息

聯繫:
簡單一句話來描述就是:使用ContentResolver來獲取ContentProvider提供的數據,同時註冊ContentObserver監聽Uri數據的變化

4. Settings.java添加新變量方法


1. Settings或者其他class添加變量

2.Settingsprovider初始化或者不初始化
loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
    "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);

5. SettingsProvider知識點

  • 2.權限問題
    查閱SettingsProvider的設置項不需要聲明任何權限。

修改SettingsProvider需要權限:

android.permission.WRITE_SETTINGS,Protection level: signature
Secure數據:android.permission.WRITE_SECURE_SETTINGS,Not for use by third-party applications.
對已Global和Secure模塊,還需要關心上文中的isGlobalOrSecureSettingRestrictedForUser()方法設置到的限制
  • 3.數據分類
    SettingsProvider對數據進行了分類,分別是Global、System、Secure三種類型,它們的區別如下:
Global:所有的偏好設置對系統的所有用戶公開,第三方APP有讀沒有寫的權限;
System:包含各種各樣的用戶偏好系統設置;
Secure:安全性的用戶偏好系統設置,第三方APP有讀沒有寫的權限。
  • 4.命令查詢和設置用法
    (主要用於調試和便於bug分析)
#獲取亮度是否爲自動獲取
adb shell settings get system screen_brightness_mode
#設置亮度值
adb shell settings put system screen_brightness 150
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章