16

Due to recent changes in Android 6 Marshmallow regarding permissions, the following code no longer works and throws an exception.

Settings.System.putInt(getContentResolver(), "vibrate_when_ringing", 0);

This happens even after granting WRITE_SETTINGS permission to the app:

Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, WRITE_SETTINGS_PERMISSION_REQUEST_CODE);
//at this point Settings activity is opened and user is prompted for permission

...

if (Settings.System.canWrite(this)) { //now returns true, because permissions were granted
    Settings.System.putInt(getContentResolver(), "vibrate_when_ringing", 0); //still crashes
} else {
    Log.w(LOG_TAG, "No permission to write settings.");
}

How can I change the ringtone vibration settings (and similar secure settings) in Android 6?

Full stack trace:

10-12 02:26:37.728 1927-2765/? E/DatabaseUtils: Writing exception to parcel
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils: java.lang.IllegalArgumentException: You cannot change private secure settings.
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at com.android.providers.settings.SettingsProvider.warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk(SettingsProvider.java:1173)
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at com.android.providers.settings.SettingsProvider.enforceRestrictedSystemSettingsMutationForCallingPackage(SettingsProvider.java:1030)
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at com.android.providers.settings.SettingsProvider.mutateSystemSetting(SettingsProvider.java:906)
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at com.android.providers.settings.SettingsProvider.insertSystemSetting(SettingsProvider.java:874)
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:257)
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at android.content.ContentProvider$Transport.call(ContentProvider.java:398)
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:283)
10-12 02:26:37.728 1927-2765/? E/DatabaseUtils:     at android.os.Binder.execTransact(Binder.java:453)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime: FATAL EXCEPTION: IntentService[DetectedActivityIntentService]
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime: Process: <package_name>, PID: 10084
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime: java.lang.IllegalArgumentException: You cannot change private secure settings.
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:165)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.content.ContentProviderProxy.call(ContentProviderNative.java:646)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.provider.Settings$NameValueCache.putStringForUser(Settings.java:1322)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.provider.Settings$System.putStringForUser(Settings.java:1671)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.provider.Settings$System.putIntForUser(Settings.java:1776)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.provider.Settings$System.putInt(Settings.java:1770)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at <package_name>.DetectedActivityIntentService.activate(DetectedActivityIntentService.java:116)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at <package_name>.DetectedActivityIntentService.onHandleIntent(DetectedActivityIntentService.java:94)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:148)
10-12 02:26:37.729 10084-11411/<package_name> E/AndroidRuntime:     at android.os.HandlerThread.run(HandlerThread.java:61)
EyesClear
  • 28,077
  • 7
  • 32
  • 43
  • This isn't a full answer, but hopefully it will help - it appears that a lot of vibration settings were moved/changed in M. Taking a look at http://developer.android.com/reference/android/provider/Settings.Secure.html I'm seeing that at least 3 entries have the description: "Accessing this setting from an app that is targeting M or later throws a SecurityException". – WoogieNoogie Oct 12 '15 at 02:23
  • I'm stuck at the same problem. There is no note about a security exception and this being a secure setting in the documentation. – joe1806772 Oct 14 '15 at 12:06
  • According to the docs, you need to show system settings interface launching an activity with ACTION_MANAGE_WRITE_SETTINGS action. http://developer.android.com/reference/android/Manifest.permission.html#WRITE_SETTINGS – mehmet6parmak Dec 09 '15 at 12:52
  • Stuck at the same point. Settings activity launched, permission granted. I am changing the mode from the widget, where it crashes with `java.lang.IllegalArgumentException: You cannot change private secure settings` – CAPS LOCK Dec 25 '15 at 18:57

2 Answers2

5

Because the security

as we know,in Android 6.0(Marshmallow),Android add lots of strategies to control the SECURITY, promote efficiency such as :

  • Runtime permission
  • Doze mode(Power Manager)
  • re-write SettingsProviders see details
    • move system settings from db to xml
    • /data/data/com.android.providers.settings/../settings.db --> /data/system/users/userid/settings_[system|global|secure].xml

So Now(after API 22)

  • you can NOT write some private/dangerous settings
  • you MUST deal with some EXCEPTION during porting to API level 22 or later. see details

PS

need deal with some EXCEPTION

can not change

Community
  • 1
  • 1
caopeng
  • 914
  • 13
  • 23
  • Thanks, but this answer is incorrect (or rather off-topic). I know that VIBRATE_WHEN_RINGING is a private secure setting, but my question remains open. – EyesClear May 23 '16 at 07:30
  • I was looking for where did settings.db had gone. This info was real hard to find. Thanks! – Gene Pavlovsky Nov 09 '16 at 23:25
0

Based on this ticket the problem seems to be resolved on Dec. 9th. Issue will be fixed in the future build.

Issue was openned by Stack Overflow member and discussed here.

Community
  • 1
  • 1
CAPS LOCK
  • 1,960
  • 3
  • 26
  • 41