NotificationCompat.Builder obsolète dans Android O

161

Après la mise à niveau de mon projet vers Android O

buildToolsVersion "26.0.1"

Lint dans Android Studio affiche un avertissement obsolète pour la méthode de générateur de notification suivante:

new NotificationCompat.Builder(context)

Le problème est le suivant: les développeurs Android mettent à jour leur documentation décrivant NotificationChannel pour prendre en charge les notifications dans Android O et nous fournissent un extrait de code, mais avec le même avertissement obsolète:

Notification notification = new Notification.Builder(MainActivity.this)
        .setContentTitle("New Message")
        .setContentText("You've received new messages.")
        .setSmallIcon(R.drawable.ic_notify_status)
        .setChannelId(CHANNEL_ID)
        .build();  

Aperçu des notifications

Ma question: existe-t-il une autre solution pour créer des notifications et prendre en charge Android O?

Une solution que j'ai trouvée est de transmettre l'ID de canal en tant que paramètre dans le constructeur Notification.Builder. Mais cette solution n'est pas exactement réutilisable.

new Notification.Builder(MainActivity.this, "channel_id")
GuilhermeFGL
la source
4
Mais cette solution n'est pas exactement réutilisable. comment?
Tim
5
NotificationCompat.Builder est obsolète et non Notification.Builder. Remarquez que la partie Compat a disparu. La notification est leur nouvelle classe où ils rationalisent tout
Kapil G
1
@kapsym, c'est l'inverse en fait. Notification.Builder est plus âgé
Tim
De plus, je ne le vois pas obsolète ici developer.android.com/reference/android/support/v4/app/… . Peut-être un bug dans Lint
Kapil G
L'identifiant du canal est passé au constructeur ou peut être placé à l'aide de notificationBuild.setChannelId("channel_id"). Dans mon cas, cette dernière solution est plus réutilisable car my NotificationCompat.Builderest réutilisée dans quelques méthodes, enregistrant des paramètres pour les icônes, les sons et les vibrations.
GuilhermeFGL

Réponses:

167

Il est mentionné dans la documentation que la méthode du générateur NotificationCompat.Builder(Context context)est obsolète. Et nous devons utiliser le constructeur qui a le channelIdparamètre:

NotificationCompat.Builder(Context context, String channelId)

Documentation NotificationCompat.Builder:

Ce constructeur était obsolète au niveau d'API 26.0.0-beta1. utilisez plutôt NotificationCompat.Builder (Context, String). Toutes les notifications publiées doivent spécifier un identifiant NotificationChannel.

Documentation Notification.Builder:

Ce constructeur était obsolète au niveau de l'API 26. Utilisez plutôt Notification.Builder (Context, String). Toutes les notifications publiées doivent spécifier un identifiant NotificationChannel.

Si vous souhaitez réutiliser les setters de générateur, vous pouvez créer le générateur avec channelId, et transmettre ce générateur à une méthode d'assistance et définir vos paramètres préférés dans cette méthode.

Bob
la source
3
Il semble qu'ils se contredisent lorsqu'ils publient la Notification.Builder(context)solution dans la session NotificationChannel. Mais bon, au moins vous avez trouvé un message notifiant cette obsolescence =)
GuilhermeFGL
23
Quel est le channelId pouvez-vous s'il vous plaît expliquer?
Santanu Sur
15
qu'est-ce que channelId?
RoundTwo
3
Vous pouvez également toujours utiliser NotificationCompat.Builder(Context context), puis attribuer le canal comme builder.setChannelId(String channelId)
suit
36
Un identifiant de canal peut être n'importe quelle chaîne, il est trop gros pour être discuté dans les commentaires, mais il est utilisé pour séparer vos notifications en catégories afin que l'utilisateur puisse désactiver ce qu'il pense n'est pas important pour lui plutôt que de bloquer toutes les notifications de votre application.
yehyatt
110

entrez la description de l'image ici

Voici le code de travail pour toutes les versions d'Android à partir de l' API LEVEL 26+ avec compatibilité descendante.

 NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getContext(), "M_CH_ID");

        notificationBuilder.setAutoCancel(true)
                .setDefaults(Notification.DEFAULT_ALL)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.ic_launcher)
                .setTicker("Hearty365")
                .setPriority(Notification.PRIORITY_MAX) // this is deprecated in API 26 but you can still use for below 26. check below update for 26 API
                .setContentTitle("Default notification")
                .setContentText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
                .setContentInfo("Info");

NotificationManager notificationManager = (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());

MISE À JOUR pour l'API 26 pour définir la priorité maximale

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";

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

        // 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 notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);

    notificationBuilder.setAutoCancel(true)
            .setDefaults(Notification.DEFAULT_ALL)
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.drawable.ic_launcher)
            .setTicker("Hearty365")
       //     .setPriority(Notification.PRIORITY_MAX)
            .setContentTitle("Default notification")
            .setContentText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
            .setContentInfo("Info");

    notificationManager.notify(/*notification id*/1, notificationBuilder.build());
Aks4125
la source
Comment pouvez-vous faire en sorte que la notification s'affiche réellement à l'écran dans l'application ou dans une autre application?
BlueBoy
@BlueBoy je ne comprends pas votre question. pourriez-vous s'il vous plaît expliquer ce dont vous avez besoin exactement?
Aks4125
@ Aks4125 La notification ne glisse pas vers le bas et ne s'affiche pas en haut de l'écran. Vous entendez une tonalité et une petite icône de notification apparaît dans la barre d'état - mais rien ne glisse vers le bas et ne s'affiche que si vous aviez un message txt.
BlueBoy
@BlueBoy vous devez définir la priorité sur HIGH pour ce comportement. faites-moi savoir si vous avez besoin de moi pour mettre à jour ce code. si vous vous faufilez pour une notification hautement prioritaire, vous obtiendrez votre réponse.
Aks4125
2
@BlueBoy vérifie la réponse mise à jour. si vous ne ciblez pas 26 API, utilisez simplement le même code avec .setPriority(Notification.PRIORITY_MAX)sinon utilisez le code mis à jour pour 26 API. `
Aks4125
31

Appelez le constructeur 2-arg: pour la compatibilité avec Android O, appelez support-v4 NotificationCompat.Builder(Context context, String channelId). Lors de l'exécution sur Android N ou version antérieure, le channelIdsera ignoré. Lorsque vous utilisez Android O, créez également un NotificationChannelavec le même channelId.

Exemple de code obsolète: exemple de code sur plusieurs pages JavaDoc telles que l' appel Notification.Buildernew Notification.Builder(mContext) est obsolète.

Constructeurs obsolètes :Notification.Builder(Context context) et v4 NotificationCompat.Builder(Context context) sont obsolètes au profit de Notification[Compat].Builder(Context context, String channelId). (Voir Notification.Builder (android.content.Context) et v4 NotificationCompat.Builder (contexte de contexte) .)

Classe obsolète : toute la classe v7 NotificationCompat.Builder est obsolète. (Voir v7 NotificationCompat.Builder .) Auparavant, la v7 NotificationCompat.Builderétait nécessaire pour prendre en charge NotificationCompat.MediaStyle. Dans Android O, il y a une v4 NotificationCompat.MediaStyledans la bibliothèque multimédia-compat de android.support.v4.mediapackage. Utilisez celui-ci si vous en avez besoin MediaStyle.

API 14+: dans Support Library à partir de 26.0.0 et versions ultérieures, les packages support-v4 et support-v7 prennent tous deux en charge un niveau d'API minimum de 14. Les noms v # sont historiques.

Voir Révisions récentes de la bibliothèque de support .

Jerry101
la source
22

Au lieu de vérifier Build.VERSION.SDK_INT >= Build.VERSION_CODES.O autant de réponses le suggèrent, il existe un moyen un peu plus simple -

Ajoutez la ligne suivante à la applicationsection du fichier AndroidManifest.xml comme expliqué dans le document Configurer une application client Firebase Cloud Messaging sur Android :

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id" 
        android:value="@string/default_notification_channel_id" />

Ajoutez ensuite une ligne avec un nom de canal au fichier values ​​/ strings.xml :

<string name="default_notification_channel_id">default</string>

Après cela, vous pourrez utiliser la nouvelle version du constructeur NotificationCompat.Builder avec 2 paramètres (puisque l'ancien constructeur avec 1 paramètre est obsolète dans Android Oreo):

private void sendNotification(String title, String body) {
    Intent i = new Intent(this, MainActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pi = PendingIntent.getActivity(this,
            0 /* Request code */,
            i,
            PendingIntent.FLAG_ONE_SHOT);

    Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, 
        getString(R.string.default_notification_channel_id))
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(true)
            .setSound(sound)
            .setContentIntent(pi);

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

    manager.notify(0, builder.build());
}
Alexander Farber
la source
1
comment est-ce plus simple? : S
Nactus
17

Voici l'exemple de code, qui fonctionne sous Android Oreo et moins que Oreo.

  NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationCompat.Builder builder = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                int importance = NotificationManager.IMPORTANCE_DEFAULT;
                NotificationChannel notificationChannel = new NotificationChannel("ID", "Name", importance);
                notificationManager.createNotificationChannel(notificationChannel);
                builder = new NotificationCompat.Builder(getApplicationContext(), notificationChannel.getId());
            } else {
                builder = new NotificationCompat.Builder(getApplicationContext());
            }

            builder = builder
                    .setSmallIcon(R.drawable.ic_notification_icon)
                    .setColor(ContextCompat.getColor(context, R.color.color))
                    .setContentTitle(context.getString(R.string.getTitel))
                    .setTicker(context.getString(R.string.text))
                    .setContentText(message)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setAutoCancel(true);
            notificationManager.notify(requestCode, builder.build());
Arpit
la source
8

Échantillon simple

    public void showNotification (String from, String notification, Intent intent) {
        PendingIntent pendingIntent = PendingIntent.getActivity(
                context,
                Notification_ID,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );


        String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.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(context, NOTIFICATION_CHANNEL_ID);
        Notification mNotification = builder
                .setContentTitle(from)
                .setContentText(notification)

//                .setTicker("Hearty365")
//                .setContentInfo("Info")
                //     .setPriority(Notification.PRIORITY_MAX)

                .setContentIntent(pendingIntent)

                .setAutoCancel(true)
//                .setDefaults(Notification.DEFAULT_ALL)
//                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
                .build();

        notificationManager.notify(/*notification id*/Notification_ID, mNotification);

    }
Mehul
la source
4
Notification notification = new Notification.Builder(MainActivity.this)
        .setContentTitle("New Message")
        .setContentText("You've received new messages.")
        .setSmallIcon(R.drawable.ic_notify_status)
        .setChannelId(CHANNEL_ID)
        .build();  

Le bon code sera:

Notification.Builder notification=new Notification.Builder(this)

avec la dépendance 26.0.1 et de nouvelles dépendances mises à jour telles que 28.0.0.

Certains utilisateurs utilisent ce code sous la forme de ceci:

Notification notification=new NotificationCompat.Builder(this)//this is also wrong code.

Donc, la logique est la méthode que vous déclarerez ou initierez, puis la même méthode du côté droit sera utilisée pour l'allocation. si dans le côté gauche de = vous utiliserez une méthode, la même méthode sera utilisée à droite de = pour l'allocation avec new.

Essayez ce code ... Cela fonctionnera à coup sûr

Pradeep Sheoran
la source
1

Ce constructeur était obsolète au niveau d'API 26.1.0. utilisez plutôt NotificationCompat.Builder (Context, String). Toutes les notifications publiées doivent spécifier un identifiant NotificationChannel.

Sandeep Singh
la source
Peut-être plutôt ajouter un commentaire avec un lien vers la documentation au lieu de copier le chat et de poster comme réponse.
JacksOnF1re
0
  1. Besoin de déclarer un canal de notification avec Notification_Channel_ID
  2. Créez une notification avec cet ID de canal. Par exemple,

...
 public static final String NOTIFICATION_CHANNEL_ID = MyLocationService.class.getSimpleName();
...
...
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL_ID+"_name",
                NotificationManager.IMPORTANCE_HIGH);

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

notifManager.createNotificationChannel(channel);


NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(getString(R.string.notification_text))
                .setOngoing(true)
                .setContentIntent(broadcastIntent)
                .setSmallIcon(R.drawable.ic_tracker)
                .setPriority(PRIORITY_HIGH)
                .setCategory(Notification.CATEGORY_SERVICE);

        startForeground(1, builder.build());
...
Zaman
la source