Framework 层Settings.System, Settings.Secure和Settings.Global存储及应用

场景-需求

实际应用场景太多了,举个例子Framework层释放动态控制底部导航栏显示和隐藏,如果客户端app设置了打开或者关闭,就需要保存一个状态。重启机器后根据保存的状态值去控制当前导航栏显示还是隐藏。
即:重启后保持关机前的状态。

分析

既然是状态的保存和获取、动态控制等方式。那么这个动作 保存和获取状态值,动态控制等操作实现需求的解决方案,可以放到Framework层去处理,也可以客户端应用App 自己去处理。

实际问题:

  • 如上分析,要么Framework层处理,要么应用端处理。实际开发过程中,特别客户对接过程中,app 端开发并不擅长也不愿意做这个工作、Framework层也不愿意做这个工作。

  • 其实存储相关,无论App应用层还是framework层,因为是基于Linux系统开发的,存在进程、用户空间访问的读写权限、安全隔离等。所以存储方式不同,都是基于不同方式和为了解决某些问题而存在的。

下面仅从需求的角度集合Framework层,来介绍存储和读取的相关知识。

参考资料

先通过部分资料,了解下 Settings.System, Settings.Secure和Settings.Global存储 的应用环境
Android系统APP之SettingsProvider数据库的使用介绍
Android Settings中System/Global/Secure
Android中的Settings.System, Settings.Secure和Settings.Global:区别与用途
Settings属性读写:
Android 官网 Settings.Global:
Android 官网 Settings.Secure
Android 官网 Settings.System

理解-使用 Global-Secure-System

先从概念上来理解这方面内容,

Settings.Global

 Global system settings, containing preferences that always apply identically to all defined users. Applications can read these but are not allowed to write; like the "Secure" settings, these are for preferences that the user must explicitly modify through the system UI or specialized APIs for those values.

意思是对所有用户都是公开的,第三方应用没有写入权限,那么系统用它存储那些内容呢? 我们可以看官网链接、也可以看源码
再次贴一下官网位置 Settings.Global: https://developer.android.com/reference/android/provider/Settings.Global
同时也可以从源码中查看,Global 到底能存储哪些内容, 源码位置 :
看看相关存储的内容:

 static {
   
   
            MOVED_TO_GLOBAL = new HashSet<>();
            MOVED_TO_SECURE_THEN_GLOBAL = new HashSet<>();

            // these were originally in system but migrated to secure in the past,
            // so are duplicated in the Secure.* namespace
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.ADB_ENABLED);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.BLUETOOTH_ON);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.DATA_ROAMING);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.DEVICE_PROVISIONED);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.HTTP_PROXY);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.NETWORK_PREFERENCE);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.USB_MASS_STORAGE_ENABLED);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS);
            MOVED_TO_SECURE_THEN_GLOBAL.add(Global.WIFI_MAX_DHCP_RETRY_COUNT);

            // these are moving directly from system to global
            MOVED_TO_GLOBAL.add(Settings.Global.AIRPLANE_MODE_ON);
            MOVED_TO_GLOBAL.add(Settings.Global.AIRPLANE_MODE_RADIOS);
            MOVED_TO_GLOBAL.add(Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
            MOVED_TO_GLOBAL.add(Settings.Global.AUTO_TIME);
            MOVED_TO_GLOBAL.add(Settings.Global.AUTO_TIME_ZONE);
            MOVED_TO_GLOBAL.add(Settings.Global.CAR_DOCK_SOUND);
            MOVED_TO_GLOBAL.add(Settings.Global.CAR_UNDOCK_SOUND);
            MOVED_TO_GLOBAL.add(Settings.Global.DESK_DOCK_SOUND);
            MOVED_TO_GLOBAL.add(Settings.Global.DESK_UNDOCK_SOUND);
            MOVED_TO_GLOBAL.add(Settings.Global.DOCK_SOUNDS_ENABLED);
            MOVED_TO_GLOBAL.add(Settings.Global.LOCK_SOUND);
            MOVED_TO_GLOBAL.add(Settings.Global.UNLOCK_SOUND);
            MOVED_TO_GLOBAL.add(Settings.Global.LOW_BATTERY_SOUND);
            MOVED_TO_GLOBAL.add(Settings.Global.POWER_SOUNDS_ENABLED);
            MOVED_TO_GLOBAL.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
            MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SLEEP_POLICY);
            MOVED_TO_GLOBAL.add(Settings.Global.MODE_RINGER);
            MOVED_TO_GLOBAL.add(Settings.Global.WINDOW_ANIMATION_SCALE);
            MOVED_TO_GLOBAL.add(Settings.Global.TRANSITION_ANIMATION_SCALE);
            MOVED_TO_GLOBAL.add(Settings.Global.ANIMATOR_DURATION_SCALE);
            MOVED_TO_GLOBAL.add(Settings.Global.FANCY_IME_ANIMATIONS);
            MOVED_TO_GLOBAL.add(Settings.Global.COMPATIBILITY_MODE);
            MOVED_TO_GLOBAL.add(Settings.Global.EMERGENCY_TONE);
            MOVED_TO_GLOBAL.add(Settings.Global.CALL_AUTO_RETRY);
            MOVED_TO_GLOBAL.add(Settings.Global.DEBUG_APP);
            MOVED_TO_GLOBAL.add(Settings.Global.WAIT_FOR_DEBUGGER);
            MOVED_TO_GLOBAL.add(Settings.Global.ALWAYS_FINISH_ACTIVITIES);
            MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_CONTENT_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_METADATA_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_CONTENT_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_METADATA_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_CONTENT_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_CONTENT_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_METADATA_URL);
            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_NFC);
            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_CELL);
            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_WIFI);
            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_BLUETOOTH);
            MOVED_TO_GLOBAL.add(Settings.Global.RADIO_WIMAX);
            MOVED_TO_GLOBAL.add(Settings.Global.SHOW_PROCESSES);
        } 

代码层面读写:

 //读Global 根据类型来, getLong  getString 
Settings.Global.getLong(context.getContentResolver(), key, defaltValue);
//写Global  根据类型来, putLong  putString等 
Settings.Global.putLong(mContext.getContentResolver(), key, value); 
很多时候,我们为了更好的调试程序,直接通过adb 来看数据的状态

adb 对应操作

// adb读
adb shell settings get global key
     
// adb写
adb shell settings put global key value

// 列出所有属性值
adb shell settings list global

// 如果需要过滤,那么就过滤获取下
settings list global | grep adb_enabled

实际代码使用

上面概念上面已经介绍了如何读取及有哪些相关的属性值,我们看看实际中的使用。

设置飞行模式:
   fun setAirplaneMode(context: Context, isEnabled: Boolean) {
   
   
        Settings.Global.putInt(
            context.contentResolver,
            Settings.Global.AIRPLANE_MODE_ON,
            if (isEnabled) 1 else 0
        )
   }
获取当前飞行模式状态
 @SuppressLint("NewApi")
    private fun checkAirPlan() {
   
   
        val data = DeviceStateLiveData.value!!
        // //飞行模式判断  0:非  飞行模式  1:飞行模式
        val isAirplaneMode=  Settings.Global.getInt(ContextProvider.get().context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
        Log.d(TAG,"  checkAirPlan isAirplaneMode:${isAirplaneMode}")
         data.isAirPlan=isAirplaneMode
     }
关闭蓝牙服务:
 fun disableA2dpSource() {
   
   
        val contentResolver = ContextProvider.get().applicationContext.contentResolver;
        val value = (1 shl 2).toLong()//1<<BluetoothProfile.A2DP
        Log.i(TAG
<think>我们正在查找Android源码中settings_secure.xml文件的位置。根据Android系统开发经验,这个文件通常位于frameworks/base/core/res/res/values目录下。但为了确保准确性,我们可以通过以下步骤进行验证: 1. **Android源码结构**:在AOSP(Android Open Source Project)中,系统级的资源文件通常放在`frameworks/base/core/res/res`目录下,其中`values`子目录存放各种XML资源文件。 2. **文件作用**:`settings_secure.xml`定义了系统安全相关的设置项,这些设置项会存储在`Secure`命名空间下(通过`Settings.Secure`类访问)。 3. **具体路径**:完整的路径应该是: ``` frameworks/base/core/res/res/values/settings_secure.xml ``` 4. **验证方法**:我们可以查看AOSP的官方源码仓库,例如在Google的AOSP镜像中查看该文件: [AOSP frameworks/base/core/res/res/values/settings_secure.xml](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/res/res/values/settings_secure.xml) 5. **文件内容示例**:该文件通常包含类似以下内容: ```xml <?xml version="1.0" encoding="utf-8"?> <resources> <!-- 定义安全设置项 --> <string name="secure_setting_name">setting_default_value</string> ... </resources> ``` 6. **注意**:不同版本的Android源码路径可能略有不同,但基本结构一致。如果是在特定分支(如android-13.0.0_r7)下,路径相同。 因此,我们可以确定该文件位于: `frameworks/base/core/res/res/values/settings_secure.xml` ### 相关问题 1. 如何修改`settings_secure.xml`中的默认设置值? 2.应用如何读取`settings_secure.xml`中定义的设置项? 3. `settings_secure.xml``settings_global.xml`、`settings_system.xml`有什么区别? 4. 如何为自定义设备添加新的安全设置项? 5. 修改`settings_secure.xml`后如何重新编译系统镜像? [^1]: 参考AOSP源码中`LocationMode`的初始化逻辑,该逻辑会读取`settings_secure.xml`中定义的默认值。</think>### Android源码中`settings_secure.xml`的位置 在Android源码中,`settings_secure.xml`文件位于以下路径: ```bash frameworks/base/core/res/res/values/settings_secure.xml ``` #### 关键说明: 1. **文件作用** 该文件定义了系统安全设置(`Settings.Secure`)的默认值数据,包含位置服务、备份配置等敏感权限设置。如您提供的引用[1]所示,`Secure.LOCATION_MODE`等关键配置的默认值就是在此定义的[^1]。 2. **文件结构示例**: ```xml <!-- frameworks/base/core/res/res/values/settings_secure.xml --> <resources> <string name="def_location_mode" translatable="false">1</string> <string name="location_providers_allowed" translatable="false">gps,network</string> <!-- 其他安全相关配置 --> </resources> ``` 3. **相关源码调用** 系统通过`SettingsState`类读取这些配置(如您提供的代码片段): ```java // 在com.android.server.SettingsState.java中 final SettingsState secureSettings = getSecureSettingsLocked(userId); Setting locationMode = secureSettings.getSettingLocked(Secure.LOCATION_MODE); if (locationMode.isNull()) { // 使用settings_secure.xml中的默认值 int defLocationMode = getContext().getResources().getInteger(R.integer.def_location_mode); } ``` 4. **编译后位置** 编译后,该文件会被打包到: ```bash out/target/product/<device>/system/framework/framework-res.apk ``` 可通过反编译APK查看最终生成的资源文件。 --- ### 📌 相关问题 1. 如何修改`settings_secure.xml`中的默认值并重新编译系统? 2. `Settings.Secure`与`Settings.System``Settings.Global`有何区别? 3. 应用如何安全地读取`Secure`设置(如`Settings.Secure.LOCATION_MODE`)? 4. 修改`Secure`设置需要哪些特殊权限? 5. 如何为自定义设备添加新的`Secure`设置项? [^1]: 如您提供的源码片段所示,当`Secure.LOCATION_MODE`未设置时,系统会从资源文件读取默认值`R.integer.def_location_mode`,该值定义在`settings_secure.xml`中。 [^2]: 文件系统权限错误可能影响`Secure`设置的持久化存储,如您日志中的`vold`错误所示。 [^3]: 类似于Django的静态资源配置,Android资源文件也通过路径映射机制被系统识别。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值