web-dev-qa-db-fra.com

Sous Android 7 (API niveau 24), mon application n'est pas autorisée à mettre le téléphone en sourdine (régler le mode de sonnerie sur Silencieux)

J'ai une application qui coupe le téléphone en utilisant AudioManager et en mettant le mode de sonnerie sur Silence avec ce code:

AudioManager audioManager = 
    (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
try {
    audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT)
} catch (Exception e) {
    e.printStackTrace();
}

Cela fonctionne avec Android 6, mais maintenant avec Android 7, j'obtiens l'erreur suivante:

System.err: Java.lang.SecurityException: Not allowed to change Do Not Disturb state
System.err: at Android.os.Parcel.readException(Parcel.Java:1683)
System.err: at Android.os.Parcel.readException(Parcel.Java:1636)
System.err: at Android.media.IAudioService$Stub$Proxy.setRingerModeExternal(IAudioService.Java:962)
System.err: at Android.media.AudioManager.setRingerMode(AudioManager.Java:1022)
System.err: at controllers.SearchResultController.mutePhone(SearchResultController.Java:185)

Dois-je demander de nouvelles autorisations pour que cela fonctionne?

J'ai parcouru la liste des autorisations Android, mais je n'ai pas trouvé celles qui semblaient pertinentes.

33
Bjarte Aune Olsen

Merci pour vos réponses, voici un peu plus de détails.

Pour pouvoir désactiver le mode de sonnerie en mode silencieux, vous devez demander l'autorisation d'accéder à la stratégie de notification (comme @ucsunil).

<uses-permission Android:name="Android.permission.ACCESS_NOTIFICATION_POLICY" />

Ensuite, vérifiez si vous avez cette permission. Si vous ne le faites pas, ouvrez les paramètres pour "Ne pas déranger l'accès" pour votre application:

NotificationManager notificationManager = 
    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
    && !notificationManager.isNotificationPolicyAccessGranted()) {

    Intent intent = new Intent(
                        Android.provider.Settings
                        .ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);

    startActivity(intent);
}

Lorsque vous exécutez startActivity (), Android ouvre les paramètres d'accès Ne pas déranger pour votre application.

Ce qui m'a dérouté, c'est que la manière de demander cette autorisation est complètement différente des autres autorisations.

Juste pour référence, voici la façon de demander la permission READ_CONTACTS:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
    && ActivityCompat.checkSelfPermission(activity,
        Manifest.permission.READ_CONTACTS)
        == PackageManager.PERMISSION_DENIED) {

    ActivityCompat.requestPermissions(activity,
        new String[]{ Manifest.permission.READ_CONTACTS },
            REQUEST_CODE_READ_CONTACTS);
}
46
Bjarte Aune Olsen

L'accès que vous recherchez est:

<uses-permission Android:name="Android.permission.ACCESS_NOTIFICATION_POLICY" />

Vous devez demander à l'utilisateur de vous fournir cette autorisation spécifique.

9
ucsunil

ACCESS_NOTIFICATION_POLICY est considéré comme une autorisation "normale", ce qui signifie que vous n'avez PAS à demander cette autorisation au moment de l'exécution. Il vous suffit d'ajouter l'autorisation à AndroidManifest.xml

    <uses-permission Android:name="Android.permission.ACCESS_NOTIFICATION_POLICY" />

Ensuite, pour désactiver toutes les notifications, définissez le filtre Interruption sur INTERRUPTION_FILTER_NONE.

NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            previous_notification_interrupt_setting = notificationManager.getCurrentInterruptionFilter();
            notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
        }

INTERRUPTION_FILTER_ALARMS - Alarmes uniquement
INTERRUPTION_FILTER_ALL - Filtre normal
INTERRUPTION_FILTER_NONE - Aucune interruption (MUTE)
INTERRUPTION_FILTER_PRIORITY - Interruptions de priorité

J'utilise

 int previous_notification_interrupt_setting = notificationManager.getCurrentInterruptionFilter();

pour réinitialiser le filtre plus tard quand onPause () ou onStop ()

3
Winston Brown

Sur la base de la documentation Android, vous devez autoriser l'accès à Ne pas déranger.

À partir de N, les ajustements en mode sonnerie qui activeraient l'option Ne pas déranger ne sont pas autorisés, sauf si l'application a reçu l'autorisation Ne pas déranger l'accès. Voir isNotificationPolicyAccessGranted ().

S'il vous plaît vérifier le lien

J'espère que ça aide!

1
Lucas Santos

J'ai résolu ce problème en ouvrant le menu Réglages et en demandant à l'utilisateur de lui accorder l'autorisation si api> 23.

Appelez simplement requestMutePermissions () de n’importe où et cela fonctionnera!

private void requestMutePermissions() {
    try {
        if (Build.VERSION.SDK_INT < 23) {
            AudioManager audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
            audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
        } else if( Build.VERSION.SDK_INT >= 23 ) {
            this.requestForDoNotDisturbPermissionOrSetDoNotDisturbForApi23AndUp();
        }
    } catch ( SecurityException e ) {

    }
}

private void requestForDoNotDisturbPermissionOrSetDoNotDisturbForApi23AndUp() {

    NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
    // if user granted access else ask for permission
    if ( notificationManager.isNotificationPolicyAccessGranted()) {
        AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
    } else{
        // Open Setting screen to ask for permisssion
        Intent intent = new Intent(Android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
        startActivityForResult( intent, ON_DO_NOT_DISTURB_CALLBACK_CODE );
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == ON_DO_NOT_DISTURB_CALLBACK_CODE ) {
        this.requestForDoNotDisturbPermissionOrSetDoNotDisturbForApi23AndUp();
    }
}
0
Waqar UlHaq