Cuando tengo una API de destino de 23 en Android M Preview 3, parece que no puedo adquirir el permiso Manifest.permission.WRITE_SETTTINGS.
requestPermissions(new String[]{Manifest.permission.WRITE_SETTINGS},
101);
Solicitar permiso no muestra el cuadro de diálogo que esperaba, pero si hago la siguiente llamada sin este permiso,
RingtoneManager.setActualDefaultRingtoneUri(activity, RingtoneManager.TYPE_RINGTONE, ringUri);
La llamada se hará excepto porque no tengo el permiso.
No estoy seguro de adónde ir desde aquí. ¿Existe una nueva API de tono de llamada para 23? ¿O este cambio de permiso simplemente hizo imposible que cualquier aplicación ajena al sistema cambiara el tono de llamada?
fuente
dangerous
enfoque habitual de permisos de tiempo de ejecución que usaron con otras cosas en Android 6.0. Me sorprendería que esto cambiara pronto.intent.setData(Uri.parse("package:" + Context.getPackageName()));
Además de la respuesta de CommonsWare y el comentario de Ogix, aquí hay un código ficticio:
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; }
El Fragment PopupwritePermission luego da una ventana donde se explica la situación. Un clic en el botón Aceptar abrirá el menú del sistema Android donde se puede otorgar el permiso:
private void openAndroidPermissionsMenu() { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getActivity().getPackageName())); startActivity(intent); }
fuente
Las respuestas anteriores son geniales, solo tengo una pequeña adición para obtener también el resultado de la solicitud de permiso.
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); } } }
Y luego en el
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 } }
fuente
MainActivity.CODE_WRITE_SETTINGS_PERMISSION
?MainActivity.CODE_WRITE_SETTINGS_PERMISSION
?Este es un ejemplo completo:
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); } }
fuente
A partir de Android Marshmellow, debe usar permisos de tiempo de ejecución que apuntan a una mayor seguridad, o usar permisos cuando sea necesario aquí es documentación
y para la documentación de configuración de escritura está aquí
En manifiesto agregar
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
En tu clase
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); } }
Y úsalo así
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(); }
fuente
El permiso
android.permission.WRITE_SETTINGS
ahora está en el gruposignature|appop|pre23|preinstalled
comoandroid.permission.CHANGE_NETWORK_STATE
yandroid.permission.SYSTEM_ALERT_WINDOW
Esto significa que lo obtienes en SDK 22 e inferior. En la versión más reciente, debe ser un operador de la aplicación.
fuente
He usado abajo como ..
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(); } }
Permiso manifiesto
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
fuente
Mencione a continuación el permiso en AndroidManifest.xml
En Actividad, use a continuación si no es así para cambiar la configuración.
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); }
fuente
•
Kotlin Version in Simple Steps
Sigue estos pasos:
1. Agregue el elemento de uso del permiso
manifest.xml
normalmente:<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
2. Donde desee cambiar la configuración, verifique el acceso de escritura:
if (context.canWriteSettings) { // change the settings here ... } else { startManageWriteSettingsPermission() }
3. También agregue estas líneas de código en caso de solicitar el permiso:
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 }
fuente