Settings.System的使用

本文介绍了Android中用于存储系统设置的SettingsProvider组件及其数据库路径。详细解释了如何使用Settings类及ContentResolver接口读取和更新飞行模式等系统设置值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

那通过数据库来保存就会有Provider了,所以就会有SettingsProvider了。数据库的路径就是:/data/data/com.android.providers.settings/databases/settings.db

但我们平常获取这里面的数据不是直接通过ContentResolve而是android已经封装了一层,通过Settings这个类来获取,就像MediaStore一样。 
比如我们获取飞行模式:

Java代码  
  1. Settings.System.getInt(mContext.getContentResolver(),  
  2.                 Settings.System.AIRPLANE_MODE_ON, 0)  

 

通过name,查询数据库,获取你想要的值,如果没有取到,就默认为def.否则就是其返回的值

public static int getInt (ContentResolver cr, String name, int def)
Since:  API Level 3

Convenience function for retrieving a single secure settings value as an integer. Note that internally setting values are always stored as strings; this function converts the string to an integer for you. The default value will be returned if the setting is not defined or not an integer.

Parameters
cr The ContentResolver to access.
name The name of the setting to retrieve.
def Value to return if the setting is not defined.
Returns
  • The setting's current value, or 'def' if it is not defined or not a valid integer.


//更改name对应的value值
public static boolean putInt (ContentResolver cr, String name, int value)
Since:  API Level 3

Convenience function for updating a single settings value as an integer. This will either create a new entry in the table if the given name does not exist, or modify the value of the existing row with that name. Note that internally setting values are always stored as strings, so this function converts the given value to a string before storing it.

Parameters
cr The ContentResolver to access.
name The name of the setting to modify.
value The new value for the setting.
Returns
  • true if the value was set, false on database errors

更多contentprovider的资料,看:http://www.eoeandroid.com/thread-29089-1-1.html
<think>我们讨论的是Android开发中的Settings.System,用于存储系统级别的设置。用户使用自定义key-value存储int值,但读取不到。可能的原因包括:1.权限问题:写入和读取Settings.System需要特定权限。2.作用域问题:自定义key需要声明为系统属性,否则可能无法访问。3.未正确写入:写入操作可能失败,但未检查返回值。4.同步问题:写入后可能没有立即同步到系统。5.自定义key未在系统设置中声明(对于非系统应用,通常不能自定义系统设置)。详细解释:1.权限:写入需要`android.permission.WRITE_SETTINGS`,读取需要`android.permission.READ_SETTINGS`。在Android6.0(API23)及以上,WRITE_SETTINGS权限属于危险权限,但不在运行时请求之列,而是需要在清单中声明,并且用户必须在系统设置中手动授予(对于WRITE_SETTINGS,应用需要引导用户到设置页面授权)。注意:READ_SETTINGSAPI23及以上被移除,因此只需要声明WRITE_SETTINGS(但读取不需要权限?实际上,读取Settings.System在较低版本需要READ_SETTINGS,但高版本中,普通应用可能无法读取系统设置,除非是系统应用)。2.自定义key:如果使用自定义key,必须确保该key在系统设置中已声明,否则可能无法使用。通常,只有系统应用(预装在系统分区)或拥有系统签名的应用才能定义新的系统设置项。普通应用只能使用系统已经存在的设置项。3.写入操作:使用`Settings.System.putInt()`方法,需要检查其返回值(boolean型),如果返回false,表示写入失败。4.同步:写入后,系统可能会异步保存,但通常立即生效。不过,读取时可能需要重新查询。5.其他:在Android O(8.0)及以上,系统对设置进行了更严格的限制,普通应用几乎无法使用Settings.System来存储自定义设置。因此,解决方案:1.确认应用拥有正确的权限:在AndroidManifest.xml中声明:```xml<uses-permission android:name="android.permission.WRITE_SETTINGS"tools:ignore="ProtectedPermissions"/> <!--忽略警告,因为普通应用可能无法使用-->```注意:普通应用(非系统应用)可能无法获得WRITE_SETTINGS权限,即使声明了,用户手动授权后,也只能修改系统提供的设置项,不能新增自定义设置项。2.如果是系统应用,需要在/frameworks/base/core/java/android/provider/Settings.java中定义自己的key(不推荐,因为需要修改系统源码)。或者,系统应用可以使用自定义的Systemproperty,但Settings.System并不直接对应系统属性(system properties)。3.替代方案:对于普通应用,建议使用其他方式存储配置,如SharedPreferences、数据库使用Settings.Global(如果应用是系统应用且拥有相应权限)。示例代码(仅当应用是系统应用时有效):写入:```javatry{//检查是否有写入权限if(Settings.System.canWrite(context)){//写入boolean success= Settings.System.putInt(context.getContentResolver(), "custom_key",123);if(!success) {Log.e("TAG", "Failedto writetosystemsettings");}}else {//引导用户去设置页面开启权限Intentintent =new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);intent.setData(Uri.parse("package:"+ context.getPackageName()));context.startActivity(intent);} }catch (Exceptione){e.printStackTrace(); }```读取:```javatry{int value= Settings.System.getInt(context.getContentResolver(), "custom_key");//使用value}catch (Settings.SettingNotFoundExceptione){e.printStackTrace();//设置项不存在} ```但是,如果custom_key没有在系统设置中预先定义,那么即使有权限,写入也可能失败(返回false),或者读取时抛出SettingNotFoundException。因此,对于普通应用,强烈建议不要使用Settings.System存储自定义设置,而应使用SharedPreferences等。如果应用是系统应用(拥有系统签名或预装在系统分区),那么可以按照以下步骤定义自定义设置项:1.在frameworks/base/core/java/android/provider/Settings.java文件中添加自定义key(需要修改系统源码并重新编译系统):在Settings.javaSystem中添加:publicstatic finalString CUSTOM_KEY= "custom_key";2.在frameworks/base/core/res/res/values/config.xml中添加默认值(可选)。3.重新编译系统后,系统应用就可以使用该key了。由于普通应用无法做到这一点,因此这里只讨论系统应用的情况。结论:普通应用读取不到自定义key的原因主要是权限不足以及自定义key未被系统认可。建议普通应用使用其他存储方式。相关问题:</think>### 可能导致 Settings.System 读取不到自定义 int 值的原因及解决方案 在 Android 开发中,使用 `Settings.System` 存储自定义 key-value 时读取失败,通常由以下原因导致: --- #### 1. **缺少 WRITE_SETTINGS 权限** - **原因**:Android 6.0+ 需要动态申请 `WRITE_SETTINGS` 权限,且该权限无法通过常规 `requestPermissions()` 获取。 - **解决方案**: - 在 `AndroidManifest.xml` 声明权限: ```xml <uses-permission android:name="android.permission.WRITE_SETTINGS" /> ``` - 引导用户手动开启权限(跳转到系统设置页): ```java if (!Settings.System.canWrite(context)) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); context.startActivity(intent); } ``` --- #### 2. **自定义 Key 未声明为系统属性** - **原因**:Android 禁止普通应用写入未预定义的 Key。自定义 Key 必须通过系统级配置声明(仅系统/特权应用可用)。 - **解决方案**: - **系统应用**:在 `frameworks/base/core/res/res/values/config.xml` 添加: ```xml <!-- 声明自定义 Key --> <string name="custom_key" translatable="false">my_custom_int_key</string> ``` - **非系统应用**:改用 `SharedPreferences` 或 `ContentProvider`。 --- #### 3. **未正确同步数据** - **原因**:`Settings.System` 的写入是异步的,读取时可能未完成同步。 - **解决方案**:写入后主动通知 ContentResolver: ```java Settings.System.putInt(contentResolver, "my_key", 100); // 强制同步 ContentResolver.notifyChange(Settings.System.getUriFor("my_key"), null); ``` --- #### 4. **Key 名称冲突或无效** - **原因**:Key 包含非法字符(如空格、大写字母)或与系统 Key 冲突。 - **解决方案**: - 使用全小写 + 下划线命名(如 `my_custom_key`)。 - 添加应用专属前缀(如 `com.example.my_key`)。 --- #### 5. **作用域限制 (Android 9+)** - **原因**:Android 9 开始限制普通应用访问系统设置。 - **解决方案**: - 非系统应用避免使用 `Settings.System`,改用: ```java // 使用 SharedPreferences SharedPreferences prefs = context.getSharedPreferences("config", Context.MODE_PRIVATE); prefs.edit().putInt("my_key", 100).apply(); ``` --- ### 完整代码示例 #### 写入自定义 int 值 ```java // 检查权限 if (Settings.System.canWrite(context)) { ContentResolver resolver = context.getContentResolver(); // 写入值 boolean success = Settings.System.putInt(resolver, "my_custom_key", 42); // 强制同步 ContentResolver.notifyChange(Settings.System.getUriFor("my_custom_key"), null); } else { // 引导用户开启权限 Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); context.startActivity(intent); } ``` #### 读取自定义 int 值 ```java try { int value = Settings.System.getInt( context.getContentResolver(), "my_custom_key" ); Log.d("TAG", "Read value: " + value); } catch (Settings.SettingNotFoundException e) { Log.e("TAG", "Key not found: " + e.getMessage()); } ``` --- ### 关键注意事项 1. **系统应用限制**:自定义 Key 需预声明,否则仅系统/特权应用可写入。 2. **权限特殊性**:`WRITE_SETTINGS` 需用户手动授权(系统设置页)。 3. **替代方案**:优先使用 `SharedPreferences` 或 `ContentProvider` 存储应用私有数据。 4. **作用域**:`Settings.System` 用于全局系统配置,而非应用私有数据。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值