Не удается получить разрешение WRITE_SETTINGS

Когда у меня есть целевой API 23 на Android M Preview 3, я не могу получить разрешение Manifest.permission.WRITE_SETTTINGS.

requestPermissions(new String[]{Manifest.permission.WRITE_SETTINGS}, 101); 

Разрешение запроса не вызывает диалог, который я ожидал бы, но если я сделаю следующий вызов без этого разрешения,

  RingtoneManager.setActualDefaultRingtoneUri(activity, RingtoneManager.TYPE_RINGTONE, ringUri); 

Вызов будет за исключением того, что у меня нет разрешения.

Я не знаю, куда идти отсюда. Есть ли новый рингтон API для 23? Или изменилось это разрешение, чтобы сделать невозможным изменение каких-либо несистемных приложений рингтоном?

Чтобы использовать WRITE_SETTINGS , на основе документов:

  1. Примените элемент <uses-permission> в манифесте как обычно.

  2. Вызовите Settings.System.canWrite() чтобы узнать, имеете ли вы право на запись настроек.

  3. Если canWrite() возвращает false , запустите действие ACTION_MANAGE_WRITE_SETTINGS чтобы пользователь мог договориться с ним, чтобы ваше приложение действительно могло писать настройки.

IOW, запись в настройки теперь является двойной опцией (соглашайтесь устанавливать, соглашаться отдельно в настройках), сродни API-интерфейсам устройств, службам доступности и т. Д.

Также обратите внимание, что я еще не пробовал использовать их – это основано на исследованиях, которые я сделал вчера в Android 6.0 .

В дополнение к ответу от CommonsWare и комментариям Ogix, здесь есть какой-то фиктивный код

 private boolean checkSystemWritePermission() { boolean retVal = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { retVal = Settings.System.canWrite(this); Log.d(TAG, "Can Write Settings: " + retVal); if(retVal){ Toast.makeText(this, "Write allowed :-)", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(this, "Write not allowed :-(", Toast.LENGTH_LONG).show(); FragmentManager fm = getFragmentManager(); PopupWritePermission dialogFragment = new PopupWritePermission(); dialogFragment.show(fm, getString(R.string.popup_writesettings_title)); } } return retVal; } 

Фрагмент PopupwritePermission затем дает окно, где объясняется ситуация. Щелчок по кнопке OK откроет системное меню Android, где разрешение может быть предоставлено:

 private void openAndroidPermissionsMenu() { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getActivity().getPackageName())); startActivity(intent); } 

Предыдущие ответы велики, у меня есть только небольшое дополнение для получения результата для разрешения.

  public static void youDesirePermissionCode(Activity context){ boolean permission; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { permission = Settings.System.canWrite(context); } else { permission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED; } if (permission) { //do your code } else { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); context.startActivityForResult(intent, MainActivity.CODE_WRITE_SETTINGS_PERMISSION); } else { ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_SETTINGS}, MainActivity.CODE_WRITE_SETTINGS_PERMISSION); } } } 

А затем в Управлении:

 @SuppressLint("NewApi") @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == CODE_WRITE_SETTINGS_PERMISSION && Settings.System.canWrite(this)){ Log.d("TAG", "CODE_WRITE_SETTINGS_PERMISSION success"); //do your code } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == CODE_WRITE_SETTINGS_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //do your code } } 

Разрешение android.permission.WRITE_SETTINGS теперь находится в группе signature|appop|pre23|preinstalled как android.permission.CHANGE_NETWORK_STATE и android.permission.SYSTEM_ALERT_WINDOW

Это означает, что вы получаете его на sdk 22 и ниже. В новой версии вы должны быть оператором приложения.

Это полный пример:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Settings.System.canWrite(context) { // Do stuff here } else { Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse(“package:” + getActivity().getPackageName())); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } } 
Intereting Posts
Диалог со списком и сообщением MediaPlayer с эффектом объемного звучания? Как получить имя категории «Все Android-приложения»? Android: Какой код ответа делает в VC-приложение для выставления счетов при истечении времени ожидания? Android – Проблемы с управлением конечными точками сервера в приложении клиент Как добавить настраиваемые элементы управления в MapFragment в Google Maps Android API v2? Как повысить точность датчиков акселерометра и компаса? Viewpager переполняет экран внутри макета координатора Android – использование Google Analytics v4 Campaign Measurement Загрузите изображение с Android на Amazon S3? Можно ли отменить предыдущий Toast, когда я хочу показать другой Toast? Определить, включена ли моя служба доступности Используя SimpleXML, как игнорировать элементы xml, которых у меня нет в классе объектов при десериализации Выпускать ресурсы в onPause вместо onDestroy Как изменить значок меню переполнения Android