在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. "
2017-12-13 18:45
525 查看
在项目中,有一些公共的数据是存放在存放在 系统数据库SettingsProvider的System表中 .
当需要获取数据时调用:
将key-value存入系统公共的数据库SettingsProvider的System的表中,在简单的跨进程数据的存储和共享的场景下十分简单高效。
但是当项目运行在Android M版本以后当继续使用该数据库时抛出了如下异常。
从字面上理解,不能够使用settings。
既然在L版本中可用,在M版本中不可用,那么肯定是因为在M版本中引入了权限检查,并且抛出异常。
在梳理源码以后发现,在M版本中,在Settings.System表中执行更新或者删除操作时,都要会调用函数
warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk。该函数是M新增,而问题正在于该函数:
说明当app尝试更新Settings.System的时候,会进行版本校验,如果targetSDK 小于等于Build.VERSION_CODES.LOLLIPOP_MR1,即低版本的apk时,给出warning,保证代码的兼容性。
而当tagetSDK大于Build.VERSION_CODES.LOLLIPOP_MR1,即M版本及更高的版本的时候,则会抛出异常,禁止apk写或者删除SettingsProvider数据库中的System表。
Build.VERSION_CODES.LOLLIPOP_MR1以下,利用Android程序向前兼容性,规避问题,但是这样的方法并不是最优方案,有可能在后续版本中,Android甚至可能放弃兼容,直接抛出异常。
放弃写Settings.System,改用Settings.Global保存共享数据。
在Android L中的使用方法是:
当需要写数据时调用:Settings.System.putStringForUser(ContentResolver cr, String name, int value, int userHandle)
当需要获取数据时调用:
Settings.System.getStringForUser(ContentResolver cr, String name, final int userHandle)
将key-value存入系统公共的数据库SettingsProvider的System的表中,在简单的跨进程数据的存储和共享的场景下十分简单高效。
但是当项目运行在Android M版本以后当继续使用该数据库时抛出了如下异常。
IllegalArgumentException: You cannot keep your settings in the secure settings.
从字面上理解,不能够使用settings。
既然在L版本中可用,在M版本中不可用,那么肯定是因为在M版本中引入了权限检查,并且抛出异常。
从framework源码入手:
调用Settings.System.putStringForUser最终都是对数据库SettingsProvider进行操作。frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
在梳理源码以后发现,在M版本中,在Settings.System表中执行更新或者删除操作时,都要会调用函数
warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk。该函数是M新增,而问题正在于该函数:
private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(int ta 9909 rgetSdkVersion, String name) { // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash. if (targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) { if (Settings.System.PRIVATE_SETTINGS.contains(name)) { Slog.w(LOG_TAG, "You shouldn't not change private system settings." + " This will soon become an error."); } else { Slog.w(LOG_TAG, "You shouldn't keep your settings in the secure settings." + " This will soon become an error."); } } else { if (Settings.System.PRIVATE_SETTINGS.contains(name)) { throw new IllegalArgumentException("You cannot change private secure settings."); } else { throw new IllegalArgumentException("You cannot keep your settings in" + " the secure settings."); } } }
说明当app尝试更新Settings.System的时候,会进行版本校验,如果targetSDK 小于等于Build.VERSION_CODES.LOLLIPOP_MR1,即低版本的apk时,给出warning,保证代码的兼容性。
而当tagetSDK大于Build.VERSION_CODES.LOLLIPOP_MR1,即M版本及更高的版本的时候,则会抛出异常,禁止apk写或者删除SettingsProvider数据库中的System表。
分析到这里,针对这样的问题,由如下两个解决方案。
如果对targetSDK没有要求,则将targetSDK降为Build.VERSION_CODES.LOLLIPOP_MR1以下,利用Android程序向前兼容性,规避问题,但是这样的方法并不是最优方案,有可能在后续版本中,Android甚至可能放弃兼容,直接抛出异常。
放弃写Settings.System,改用Settings.Global保存共享数据。
相关文章推荐
- 在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. "
- 在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. "
- 在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. "
- 在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. "
- 在Android M及更高版本中使用 Settings.System 抛出异常"You cannot keep your settings in the secure settings. "
- BaiduMap:You cannot keep your settings in the secure settings.
- "Your computer could not be joined to the domain. You have exceeded the maximum number of computer accounts you are allowed to create in this domain. Contact your system administrator to have this limit reset or increased."
- You cannot access the client's file system using the FileSystemObject in your ASP code
- 在使用Navicat for MySQL 出现 异常"You have an error in your SQL syntax......"
- Hibernate操作MySQL使用reserved word引发错误: “You have an error in your SQL syntax; check the manual that co
- Hibernate操作MySQL使用reserved word引发错误: “You have an error in your SQL syntax; check the manual that co
- 安装服务时出现"The system cannot execute the specified program"
- You should be the top dog in your department and always keep an eye on the outside world.
- Genymotion使用,和 "virtualbox cannot start the virtual device"解决方法
- 在Ubuntu 上编译qt4.8.6,提示“You don't seem to have 'make' or 'gmake' in your PATH. cannot proceed".”
- ADODB使用excel的"Cannot modify the design of table 'xxxx'. It is in a read-only database"的问题
- php首次使用date函数 遇到警告:Warning:date():It is not safe to rely on the system's timezone settings.You...
- 使用Jstl异常:HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in
- "The object cannot be deleted because it was not found in the ObjectStateManager."
- django1.8 提示(1_8.W001) The standalone TEMPLATE_* settings were deprecated in Django 1.8 and the TEMPLATES dictionary takes precedence. You must put the values of the following settings into your defau