Lorsque j'ai une API cible de 23 sur Android M Preview 3, il me semble impossible d'acquérir l'autorisation Manifest.permission.WRITE_SETTTINGS.
requestPermissions(new String[]{Manifest.permission.WRITE_SETTINGS},
101);
Demander la permission ne fait pas apparaître le dialogue auquel je m'attendrais, mais si je passe l'appel suivant sans cette permission,
RingtoneManager.setActualDefaultRingtoneUri(activity, RingtoneManager.TYPE_RINGTONE, ringUri);
L'appel sera sauf parce que je n'ai pas la permission.
Je ne suis pas sûr où aller d'ici. Existe-t-il une nouvelle API de sonnerie pour 23? Ou bien ce changement d'autorisation a-t-il simplement rendu impossible la modification de la sonnerie pour une application non-système?
Pour utiliser WRITE_SETTINGS
, en fonction de la documentation:
Avoir l’élément <uses-permission>
dans le manifeste comme d’habitude.
Appelez Settings.System.canWrite()
pour voir si vous avez le droit d'écrire les paramètres.
Si canWrite()
retourne false
, démarrez l'activité ACTION_MANAGE_WRITE_SETTINGS
] afin que l'utilisateur puisse accepter de permettre à votre application d'écrire dans les paramètres.
En d'autres termes, l'écriture dans les paramètres est désormais un double opt-in (accepter d'installer, d'accord séparément dans Paramètres pour autoriser), semblable aux API d'administration de périphérique, aux services d'accessibilité, etc.
Notez également que je n’ai pas encore essayé de les utiliser - c’est basé sur recherche que j’ai faite hier sur Android 6.0 modifications .
Outre la réponse de CommonsWare et le commentaire d’Ogix, voici un code factice:
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;
}
Le fragment PopupwritePermission donne alors une fenêtre où la situation est expliquée. Un clic sur le bouton OK ouvre le Android System Menu où l'autorisation peut être accordée:
private void openAndroidPermissionsMenu() {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
startActivity(intent);
}
Les réponses précédentes sont excellentes, j’ai juste un petit ajout pour obtenir également le résultat obtenu avec la permission demandée.
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);
}
}
}
Et puis dans la 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
}
}
Ceci est un exemple complet:
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);
}
}
À partir de Android Marshmellow, vous devez utiliser des autorisations d’exécution qui visent une sécurité accrue, ou les utiliser lorsque le besoin s’en fait documenatation
et pour les paramètres d'écriture, la documentation est ici
Dans manifeste ajouter
<uses-permission Android:name="Android.permission.WRITE_SETTINGS" />
Dans votre classe
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);
}
}
Et l'utiliser comme ça
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();
}
La permission Android.permission.WRITE_SETTINGS
est maintenant dans le groupe signature|appop|pre23|preinstalled
comme Android.permission.CHANGE_NETWORK_STATE
et Android.permission.SYSTEM_ALERT_WINDOW
Cela signifie que vous l'obtenez sur sdk 22 et inférieur. Sur la nouvelle version, vous devez être un opérateur d'application.
Mention ci-dessous permission dans AndroidManifest.xml
Dans Activité, utilisez ci-dessous si vous souhaitez modifier les paramètres.
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);
}