44 votes

Les notifications ne s'affichent pas dans Android Oreo (API 26)

Je reçois ce message lorsque j'essaie d'afficher une notification sur Android O.

L'utilisation des types de flux est dépréciée pour les opérations autres que le volume. contrôle

La notification provient directement de la documentation de l'exemple et s'affiche correctement sur Android 25.

1 votes

Cette erreur n'a rien à voir avec la raison pour laquelle votre notification ne s'affiche pas. Veuillez inclure votre adresse complète NotificationCompat que vous utilisez et votre targetSdkVersion .

0 votes

J'avais initialement prévu de répondre à ma propre question, l'erreur citée étant ce que les autres rechercheraient. Maintenant je réalise que l'erreur n'a rien à voir avec le fait qu'elle ne s'est pas affichée. C'est parce que je n'avais pas de NotificationChannel. Android devrait enregistrer les cas où il ne peut pas afficher une notification, ou lancer une exception ou autre chose.

0 votes

63voto

ianhanniballake Points 18370

Selon les commentaires sur ce post Google+ :

Ces [avertissements] sont actuellement attendus lors de l'utilisation de l'option NotificationCompat sur les appareils Android O ( NotificationCompat appelle toujours setSound() même si vous ne passez jamais de son personnalisé).

jusqu'à ce que la bibliothèque d'assistance modifie son code pour utiliser l'option AudioAttributes version de setSound vous aurez toujours cet avertissement.

Il n'y a donc rien que vous puissiez faire à propos de cet avertissement. Conformément à la guide des canaux de notification En effet, Android O ne permet plus de définir un son sur une notification individuelle, mais sur un canal de notification utilisé par toutes les notifications d'un type particulier.

0 votes

Merci @ianhanniballake. Je suis curieux de savoir pourquoi les NotificationChannels ne peuvent pas être modifiés après leur création. Je comprends qu'un utilisateur puisse passer outre la configuration pour, par exemple, diminuer l'importance du canal, mais s'il ne l'a pas fait, pourquoi empêcher l'application de modifier le canal ?

0 votes

Que se passe-t-il si les utilisateurs se rendent dans les paramètres, confirment qu'ils sont appropriés, puis que vous les modifiez par la suite ? Une garantie utile consiste à faire en sorte que l'utilisateur s'attende à ce que les paramètres ne soient jamais modifiés, sauf s'il les modifie lui-même.

0 votes

Pourquoi ne pas conserver une copie des paramètres configurés, et des paramètres spécifiés par l'utilisateur, s'il les a modifiés. Pour chaque paramètre qui a changé, l'appliquer par-dessus la configuration du NotificationChannel. Sinon, laissez-les changer. Le comportement actuel rend difficile de tester les choses, et il est fou de penser que le moment où vous enregistrez un canal, il est gravé dans la pierre pour la vie de l'application. Comme si vous ne pouviez jamais changer ce canal. Il suffit de passer à autre chose et d'en créer un nouveau - ce que feront exactement les développeurs d'applications, ce qui revient à dire que les utilisateurs n'ont plus aucun contrôle.

48voto

Sky Kelsey Points 3405

À partir d'Android O, vous êtes tenu de configurer une NotificationChannel et faites référence à ce canal lorsque vous tentez d'afficher une notification.

private static final int NOTIFICATION_ID = 1;
private static final String NOTIFICATION_CHANNEL_ID = "my_notification_channel";

...

NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_DEFAULT);

  // Configure the notification channel.
  notificationChannel.setDescription("Channel description");
  notificationChannel.enableLights(true);
  notificationChannel.setLightColor(Color.RED);
  notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
  notificationChannel.enableVibration(true);
  notificationManager.createNotificationChannel(notificationChannel);
}

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
  .setVibrate(new long[]{0, 100, 100, 100, 100, 100})
  .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
  .setSmallIcon(R.mipmap.ic_launcher)
  .setContentTitle("Content Title")
  .setContentText("Content Text");

  notificationManager.notify(NOTIFICATION_ID, builder.build());

Quelques remarques importantes :

  1. Les paramètres tels que le modèle de vibration spécifié dans le NotificationChannel remplacent celles qui sont spécifiées dans le Notification . Je sais, c'est contre-intuitif. Vous devriez soit déplacer les paramètres qui vont changer dans la notification, soit utiliser un NotificationChannel différent pour chaque configuration.
  2. Vous ne pouvez pas modifier la plupart des NotificationChannel après l'avoir transmis à createNotificationChannel() . Vous ne pouvez même pas appeler deleteNotificationChannel() et essayez ensuite de le réinsérer. En utilisant l'ID d'un fichier supprimé NotificationChannel le ressuscitera, et il sera tout aussi immuable que lors de sa création. Il continuera à utiliser les anciens paramètres jusqu'à ce que l'application soit désinstallée. Vous devez donc être sûr des paramètres de votre canal et réinstaller l'application si vous jouez avec ces paramètres pour qu'ils prennent effet.

0 votes

"Vous devriez soit déplacer les paramètres qui vont changer dans la Notification, soit..." -- Est-ce que cela fonctionne ? Ou est-ce que le NotificationChannel a des paramètres par défaut (écrasants) pour le modèle de vibration etc. même si vous ne les avez pas définis ?

0 votes

Je pense qu'au moins pour certains des paramètres qui sont optionnels, les laisser non définis dans la configuration du canal permet aux paramètres de la Notification de prendre le dessus.

1 votes

Eh bien, cette hypothèse ne s'est pas vérifiée. Le fait de laisser un paramètre de canal non défini a pour effet de sélectionner le son de notification par défaut, la visibilité publique de l'écran de verrouillage, la vibration désactivée ou la lumière de notification désactivée. Et une fois que l'application a créé un canal, l'utilisateur peut voir et modifier ses paramètres avant même que l'application ne crée des notifications.

8voto

Kirill Vashilo Points 702

Tout ce que @sky-kelsey a décrit est bon, Juste des ajouts mineurs :

Vous ne devez pas enregistrer le même canal à chaque fois s'il a déjà été enregistré, donc J'ai la méthode de la classe Utils qui crée un canal pour moi :

public static final String NOTIFICATION_CHANNEL_ID_LOCATION = "notification_channel_location";

public static void registerLocationNotifChnnl(Context context) {
    if (Build.VERSION.SDK_INT >= 26) {
        NotificationManager mngr = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
        if (mngr.getNotificationChannel(NOTIFICATION_CHANNEL_ID_LOCATION) != null) {
            return;
        }
        //
        NotificationChannel channel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID_LOCATION,
                context.getString(R.string.notification_chnnl_location),
                NotificationManager.IMPORTANCE_LOW);
        // Configure the notification channel.
        channel.setDescription(context.getString(R.string.notification_chnnl_location_descr));
        channel.enableLights(false);
        channel.enableVibration(false);
        mngr.createNotificationChannel(channel);
    }
}

strings.xml :

<string name="notification_chnnl_location">Location polling</string>
<string name="notification_chnnl_location_descr">You will see notifications on this channel ONLY during location polling</string>

Et j'appelle la méthode chaque fois que je vais afficher une notification de ce type :

    ...
    NotificationUtil.registerLocationNotifChnnl(this);
    return new NotificationCompat.Builder(this, NotificationUtil.NOTIFICATION_CHANNEL_ID_LOCATION)
            .addAction(R.mipmap.ic_launcher, getString(R.string.open_app),
                    activityPendingIntent)
            .addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.remove_location_updates),
                    servicePendingIntent)
            .setContentText(text)
            ...

Un autre problème typique - le son par défaut du canal - décrit ici : https://stackoverflow.com/a/45920861/2133585

2voto

Md Imran Choudhury Points 2536

Dans Android O, il est indispensable d'utiliser une NotificationChannel y NotificationCompat.Builder est déprécié ( référence ).

Vous trouverez ci-dessous un exemple de code :

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(mContext.getApplicationContext(), "notify_001");
Intent ii = new Intent(mContext.getApplicationContext(), RootActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, ii, 0);

NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
bigText.bigText(verseurl);
bigText.setBigContentTitle("Today's Bible Verse");
bigText.setSummaryText("Text in detail");

mBuilder.setContentIntent(pendingIntent);
mBuilder.setSmallIcon(R.mipmap.ic_launcher_round);
mBuilder.setContentTitle("Your Title");
mBuilder.setContentText("Your text");
mBuilder.setPriority(Notification.PRIORITY_MAX);
mBuilder.setStyle(bigText);

NotificationManager mNotificationManager =
        (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel channel = new NotificationChannel("notify_001",
            "Channel human readable title",
            NotificationManager.IMPORTANCE_DEFAULT);
    mNotificationManager.createNotificationChannel(channel);
}

mNotificationManager.notify(0, mBuilder.build());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X