web-dev-qa-db-fra.com

Android - API du canal de notification> = 26 ne fonctionne pas correctement

J'ai eu du mal avec le nouveau NotificationChannels qui est introduit dans l'API 26 et plus.

Je suis en train de développer une application avec une option pour choisir d'être notifié dans quatre cas:

  1. Son et vibration.
  2. Son uniquement.
  3. Vibrez seulement.
  4. Pas de son ni de vibration, juste un pop-up.

Dans tous les cas, mon application notifie par son et vibre ce que je choisis.

Mon code est:

NotificationCompat.Builder builder;
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        builder = new NotificationCompat.Builder(context, CHANNEL_ID);
        int importance;
        NotificationChannel channel;

        //Boolean for choosing Sound
        if(sound) {
            importance = NotificationManager.IMPORTANCE_DEFAULT;
        } else {
            importance = NotificationManager.IMPORTANCE_LOW;
        }

        channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance);
        channel.setDescription(CHANNEL_DESC);

        //Boolean for choosing Vibrate
        if(vibrate) {
            channel.enableVibration(true);
        } else {
            channel.enableVibration(false);
        }

        notificationManager.createNotificationChannel(channel);
    } else {
        builder = new NotificationCompat.Builder(context);
    }

    if(sound && vibrate) {
        //Sound and Vibrate
        builder.setDefaults(Notification.DEFAULT_ALL);
    } else if(sound && !vibrate) {
        //Sound
        builder.setDefaults(Notification.DEFAULT_SOUND);
    } else if(!sound && vibrate) {
        //Vibrate
        builder.setDefaults(Notification.DEFAULT_VIBRATE);
    } else if(!sound && !vibrate) {
        //None
        //Do nothing! just notification with no sound or vibration
    }

    builder.setSmallIcon(R.drawable.ic_logo)
            .setContentTitle(title)
            .setContentText(text)
            .setAutoCancel(true)
            .setOnlyAlertOnce(false)
            .setPriority(Notification.PRIORITY_MAX);

De plus, je change CHANNEL_ID à chaque fois que je lance l'application, elle obtient donc un nouvel identifiant de chaîne à chaque fois juste pour les tests jusqu'à ce que je trouve une solution.

Bien sûr, cela fonctionne bien avec une API inférieure à 26.

Merci les gars!

7
Ahmed

j'ai trouvé cela dans la documentation. Peut-être que cela vous aidera:

Sur Android 8.0 (API niveau 26) et plus, l'importance d'une notification est déterminée par l'importance du canal sur lequel la notification a été publiée. Les utilisateurs peuvent modifier l'importance d'un canal de notification dans le système (figure 12). Sur Android 7.1 (API niveau 25) et au-dessous, l'importance de chaque notification est déterminée par la priorité de la notification.

Et aussi :

Android O introduit des canaux de notification pour fournir un système unifié pour aider les utilisateurs à gérer les notifications. Lorsque vous ciblez Android O, vous devez implémenter un ou plusieurs canaux de notification pour afficher les notifications à vos utilisateurs. Si vous ne ciblez pas Android O, vos applications se comportent de la même manière que sur Android 7.0 lors de l'exécution sur Android O appareils.

Et enfin :

  • Les notifications individuelles doivent maintenant être placées dans un canal spécifique.
  • Les utilisateurs peuvent désormais désactiver les notifications par canal, au lieu de désactiver toutes les notifications d'une application.
  • Les applications avec des notifications actives affichent un "badge" de notification en haut de l'icône de leur application sur l'écran d'accueil/du lanceur.
  • Les utilisateurs peuvent désormais répéter une notification dans le tiroir. Vous pouvez définir un délai d'expiration automatique pour une notification.
  • Certaines API concernant les comportements de notification ont été déplacées de Notification vers NotificationChannel. Par exemple, utilisez NotificationChannel.setImportance () au lieu de NotificationCompat.Builder.setPriority () pour Android 8.0 et supérieur).
6
Arnauld Alex

Merci à tous,

J'ai réussi à le résoudre en créant simplement un NotificationCompat.Builder et NotificationChannel pour chaque cas, et notifiez chaque Builder lorsque sa condition est remplie.

Je ne sais pas si c'est la meilleure pratique, mais j'essaierai d'optimiser le code plus tard, si quelqu'un a une opinion à ce sujet, n'hésitez pas. Mais ça fonctionnait si bien maintenant.

Voici mon code:

NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationCompat.Builder builder_all, builder_sound, builder_vibrate, builder_none;
        NotificationChannel channel_all = new NotificationChannel(CHANNEL_ID_ALL, CHANNEL_NAME_ALL, NotificationManager.IMPORTANCE_HIGH);
        channel_all.enableVibration(true);
        notificationManager.createNotificationChannel(channel_all);

        NotificationChannel channel_sound = new NotificationChannel(CHANNEL_ID_SOUND, CHANNEL_NAME_SOUND, NotificationManager.IMPORTANCE_HIGH);
        channel_sound.enableVibration(false);
        notificationManager.createNotificationChannel(channel_sound);

        NotificationChannel channel_vibrate = new NotificationChannel(CHANNEL_ID_VIBRATE, CHANNEL_NAME_VIBRATE, NotificationManager.IMPORTANCE_HIGH);
        channel_vibrate.setSound(null, null);
        channel_vibrate.enableVibration(true);
        notificationManager.createNotificationChannel(channel_vibrate);

        NotificationChannel channel_none = new NotificationChannel(CHANNEL_ID_NONE, CHANNEL_NAME_NONE, NotificationManager.IMPORTANCE_HIGH);
        channel_none.setSound(null, null);
        channel_none.enableVibration(false);
        notificationManager.createNotificationChannel(channel_none);

        //Boolean for Sound or Vibrate are chosen
        if(sound && vibrate) {
            builder_all = new NotificationCompat.Builder(context, CHANNEL_ID_ALL);
            builder_all.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_all.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_all.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_all.build());
        } else if(sound && !vibrate) {
            builder_sound = new NotificationCompat.Builder(context, CHANNEL_ID_SOUND);
            builder_sound.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_sound.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_sound.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_sound.build());
        } else if(!sound && vibrate) {
            builder_vibrate = new NotificationCompat.Builder(context, CHANNEL_ID_VIBRATE);
            builder_vibrate.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_vibrate.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_vibrate.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_vibrate.build());
        } else if(!sound && !vibrate) {
            builder_none = new NotificationCompat.Builder(context, CHANNEL_ID_NONE);
            builder_none.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_none.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_none.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_none.build());
        }
    } else {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context);

        if(sound && vibrate) {
            //Sound and Vibrate
            builder.setDefaults(Notification.DEFAULT_ALL);
        } else if(sound && !vibrate) {
            //Sound
            builder.setDefaults(Notification.DEFAULT_SOUND);
        } else if(!sound && vibrate) {
            //Vibrate
            builder.setDefaults(Notification.DEFAULT_VIBRATE);
        } else if(!sound && !vibrate) {
            //None
            //Do nothing! just notification with no sound or vibration
        }

        builder.setSmallIcon(R.drawable.ic_logo)
                .setContentTitle(title)
                .setContentText(text)
                .setAutoCancel(true)
                .setOnlyAlertOnce(false)
                .setPriority(Notification.PRIORITY_MAX);

        switch (transition) {
            case Geofence.GEOFENCE_TRANSITION_ENTER:
                builder.setSmallIcon(R.drawable.ic_entered_white);
                break;
            case Geofence.GEOFENCE_TRANSITION_EXIT:
                builder.setSmallIcon(R.drawable.ic_left_white);
                break;
        }

        notificationManager.notify(notificationID, builder.build());
    }
7
Ahmed

Si votre son et vos vibrations viennent des paramètres de votre application, notez que l'intention est de supprimer ceux de votre application et d'envoyer l'utilisateur aux paramètres de la chaîne à la place:

"Après avoir créé un canal de notification, vous ne pouvez pas modifier les comportements visuels et auditifs du canal de notification par programme. Seul l'utilisateur peut modifier les comportements du canal à partir des paramètres système. Pour permettre à vos utilisateurs d'accéder facilement à ces paramètres de notification, vous devez ajouter un élément dans l'interface utilisateur des paramètres de votre application qui ouvre ces paramètres système. "

https://developer.Android.com/training/notify-user/channels#UpdateChannel

0
Sam Mortimer