Когда у меня есть целевой 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? Или это изменение разрешения просто сделало невозможным изменение мелодии звонка для каких-либо несистемных приложений?
источник
dangerous
подхода к разрешению времени выполнения, который они использовали с другими вещами в Android 6.0. Я буду удивлен, если это изменится в ближайшее время.intent.setData(Uri.parse("package:" + Context.getPackageName()));
В дополнение к ответу 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; }
Затем Fragment 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); } } }
А потом в
Activity
:@SuppressLint("NewApi") @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == MainActivity.CODE_WRITE_SETTINGS_PERMISSION && Settings.System.canWrite(this)){ Log.d("TAG", "MainActivity.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 == MainActivity.CODE_WRITE_SETTINGS_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //do your code } }
источник
MainActivity.CODE_WRITE_SETTINGS_PERMISSION
?MainActivity.CODE_WRITE_SETTINGS_PERMISSION
?Это полный пример:
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); } }
источник
Что касается Android Marshmellow, вам необходимо использовать разрешения времени выполнения, которые нацелены на большую безопасность, или использовать разрешение, когда это необходимо здесь документация
а для записи настроек документация здесь
В манифесте добавить
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
В вашем классе
private boolean checkSystemWritePermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if(Settings.System.canWrite(context)) return true; else openAndroidPermissionsMenu(); } return false; } private void openAndroidPermissionsMenu() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); context.startActivity(intent); } }
И используйте это так
try { if (checkSystemWritePermission()) { RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, newUri); Toast.makeText(context, "Set as ringtoon successfully ", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(context, "Allow modify system settings ==> ON ", Toast.LENGTH_LONG).show(); } } catch (Exception e) { Log.i("ringtoon",e.toString()); Toast.makeText(context, "unable to set as Ringtoon ", Toast.LENGTH_SHORT).show(); }
источник
Разрешение
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) { boolean retVal = true; retVal = Settings.System.canWrite(this); if (retVal == false) { if (!Settings.System.canWrite(getApplicationContext())) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName())); Toast.makeText(getApplicationContext(), "Please, allow system settings for automatic logout ", Toast.LENGTH_LONG).show(); startActivityForResult(intent, 200); } }else { Toast.makeText(getApplicationContext(), "You are not allowed to wright ", Toast.LENGTH_LONG).show(); } }
Разрешение манифеста
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
источник
Упомяните ниже разрешение в AndroidManifest.xml
В действии используйте ниже, если еще для изменения настройки.
if(Settings.System.canWrite(this)){ // change setting here } else{ //Migrate to Setting write permission screen. Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + mContext.getPackageName())); startActivity(intent); }
источник
•
Kotlin Version in Simple Steps
Следуй этим шагам:
1. Добавьте элемент использования разрешения в
manifest.xml
обычно:<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
2. Там, где вы хотите изменить настройки, проверьте доступ на запись:
if (context.canWriteSettings) { // change the settings here ... } else { startManageWriteSettingsPermission() }
3. Также добавьте эти строки кода в случае запроса разрешения:
private fun startManageWriteSettingsPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Intent( Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:${context.packageName}") ).let { startActivityForResult(it, REQUEST_CODE_WRITE_SETTINGS_PERMISSION) } } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQUEST_CODE_WRITE_SETTINGS_PERMISSION -> { if (context.canWriteSettings) { // change the settings here ... } else { Toast.makeText(context, "Write settings permission is not granted!", Toast.LENGTH_SHORT).show() } } } } val Context.canWriteSettings: Boolean get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.System.canWrite(this) companion object { private const val REQUEST_CODE_WRITE_SETTINGS_PERMISSION = 5 }
источник