SettingsProvdier相关说明

    科技2022-07-13  133

    1. 概述

    在Android启动之后,我们通常需要根据自己的一些需要来设置一些符合我们使用习惯的属性。例如:来电铃声、锁屏时间、日期格式等等。而这些属性的设置通常是有Settings为入口,通过SettingsProvider来进行的。

    2. 数据储存形式及位置

    在Android5.0之前,SettingsProvider中系统设置是存储在settings.db数据库中;在Android6.0之后,SettingsProvider中系统设置改为由xml存储。改变存储方式主要是为了提高性能(400ms降低到10ms),还能为每一个用户独立储存偏好设置,同时限制了第三方app对偏好设置的写入,增加了安全性。

    Android5.0之前 /data/data/com.android.providers.settings/databases/settings.db

    Android6.0以后 /data/system/users//settings_system.xml /data/system/users//settings_global.xml /data/system/users//settings_secure.xml Android M以前:

    3. 数据分类

    SettingsProvider对数据进行了分类,分别是Global、System和Secure三种类型:

    Global: 用户全局偏好设置System:用户系统偏好设置Secure:用户安全偏好设置

    Settings.java类中分别声明了Global、Secure、System三个静态内部类,分别对应SettingsProvider中的Global、Secure、System三种数据类型。Global、System和Global类的VALIDATORS属性,可以查看各偏好设置的定义以及属性赋值过程。

    4. 系统设置初始化

    frameworks/base/packages/SettingsProvider/src/com/Android/providers/settings/DatabaseHelper.Java frameworks/base/packages/SettingsProvider/res/values/defaults.xml

    在DatabaseHelper中通过三个函数来分别加载Global、System和Secure设置

    loadSystemSettings()loadSecureSettings()loadGlobalSettings()

    通过读取defaults.xml对应的参数进行配置,其中支持的数据格式是

    <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi,nfc,wimax</string> <bool name="def_auto_time">true</bool> <integer name="def_screen_brightness">102</integer> <fraction name="def_window_animation_scale">100%</fraction>

    根据参数类型调用不同加载函数,最终通过loadSetting()最终将设置项转换为String类型存储起来

    private void loadStringSetting(SQLiteStatement stmt, String key, int resid) { loadSetting(stmt, key, mContext.getResources().getString(resid)); } private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) { loadSetting(stmt, key, mContext.getResources().getBoolean(resid) ? "1" : "0"); } private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) { loadSetting(stmt, key, Integer.toString(mContext.getResources().getInteger(resid))); } private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) { loadSetting(stmt, key, Float.toString(mContext.getResources().getFraction(resid, base, base))); } private void loadSetting(SQLiteStatement stmt, String key, Object value) { stmt.bindString(1, key); stmt.bindString(2, value.toString()); stmt.execute(); }

    5. 修改默认设置

    以默认输入法为例:

    在defaults.xml中添加对应配置

    frameworks/base/packages/SettingsProvider/res/values/defaults.xml

    + <string name="enabled_input_methods" translatable="false">com.android.inputmethod.latin/.LatinIME:com.iflytek.inputmethod.google/com.iflytek.inputmethod.FlyIME:com.google.android.inputmethod.pinyin/.PinyinIME</string> + <string name="def_input_method" translatable="false">com.iflytek.inputmethod.google/com.iflytek.inputmethod.FlyIME</string> 在中导入配置 private void loadSecureSettings(SQLiteDatabase db) { SQLiteStatement stmt = null; try { stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)" + " VALUES(?,?);"); + loadStringSetting(stmt, Settings.Secure.ENABLED_INPUT_METHODS, + R.string.enabled_input_methods); + loadStringSetting(stmt, Settings.Secure.DEFAULT_INPUT_METHOD, + R.string.def_input_method);

    6. 使用adb 查看修改SettingProvider的值

    adb shell settings

    分别查看 System、Global和Secure的所有属性

    adb shell settings list system adb shell settings list global adb shell settings list secure

    对于一些设置参数不明确的设置项,可以先在机器上进行手动设置,然后用adb查看设置项后,再在源码中进行修改,以默认输入法为例子:

    设置默认输入法: 首先在机器上安装相应的输入法并设置成默认,然后连接adb输入以下命令

    $ adb shell settings get secure enabled_input_methods com.android.inputmethod.latin/.LatinIME:com.iflytek.inputmethod.google/com.iflytek.inputmethod.FlyIME:com.google.android.inputmethod.pinyin/.PinyinIME $ adb shell settings get secure default_input_method com.iflytek.inputmethod.google/com.iflytek.inputmethod.FlyIME
    Processed: 0.018, SQL: 8