Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"You cannot change private secure settings" - how to toggle ringtone vibration in Android 6?

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)
like image 703
EyesClear Avatar asked Oct 12 '15 00:10

EyesClear


1 Answers

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

like image 51
caopeng Avatar answered Oct 21 '22 10:10

caopeng