NotificationCompat.Builder in Android O veraltet

161

Nach dem Upgrade meines Projekts auf Android O.

buildToolsVersion "26.0.1"

Lint in Android Studio zeigt eine veraltete Warnung für die folgende Benachrichtigungs-Builder-Methode an:

new NotificationCompat.Builder(context)

Das Problem ist: Android-Entwickler aktualisieren ihre Dokumentation, in der NotificationChannel beschrieben wird , um Benachrichtigungen in Android O zu unterstützen, und stellen uns ein Snippet mit derselben veralteten Warnung zur Verfügung:

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();  

Benachrichtigungsübersicht

Meine Frage: Gibt es eine andere Lösung für die Erstellung von Benachrichtigungen und die Unterstützung von Android O?

Eine Lösung, die ich gefunden habe, besteht darin, die Kanal-ID als Parameter im Notification.Builder-Konstruktor zu übergeben. Diese Lösung ist jedoch nicht gerade wiederverwendbar.

new Notification.Builder(MainActivity.this, "channel_id")
GuilhermeFGL
quelle
4
Diese Lösung ist jedoch nicht gerade wiederverwendbar. Wie das?
Tim
5
NotificationCompat.Builder ist veraltet, nicht Notification.Builder. Beachten Sie, dass der Compat-Teil weg ist. Benachrichtigung ist ihre neue Klasse, in der sie alles rationalisieren
Kapil G
1
@kapsym es ist eigentlich umgekehrt. Notification.Builder ist älter
Tim
Außerdem sehe ich es hier nicht veraltet. Developer.android.com/reference/android/support/v4/app/… . Vielleicht ein Fehler in Lint
Kapil G
Die Kanal-ID wird am Konstruktor übergeben oder kann mit platziert werden notificationBuild.setChannelId("channel_id"). In meinem Fall ist diese letzte Lösung wiederverwendbarer, da meine NotificationCompat.Builderin einigen Methoden wiederverwendet wird, wodurch Parameter für Symbole, Sounds und Vibrationen gespeichert werden.
GuilhermeFGL

Antworten:

167

In der Dokumentation wird erwähnt, dass die Builder-Methode NotificationCompat.Builder(Context context)veraltet ist. Und wir müssen den Konstruktor verwenden, der den channelIdParameter hat:

NotificationCompat.Builder(Context context, String channelId)

NotificationCompat.Builder-Dokumentation:

Dieser Konstruktor war in API Level 26.0.0-beta1 veraltet. Verwenden Sie stattdessen NotificationCompat.Builder (Context, String). Alle veröffentlichten Benachrichtigungen müssen eine NotificationChannel-ID angeben.

Notification.Builder-Dokumentation:

Dieser Konstruktor war in API-Ebene 26 veraltet. Verwenden Sie stattdessen Notification.Builder (Context, String). Alle veröffentlichten Benachrichtigungen müssen eine NotificationChannel-ID angeben.

Wenn Sie die Builder-Setter wiederverwenden möchten, können Sie den Builder mit erstellen channelIdund diesen Builder an eine Hilfsmethode übergeben und Ihre bevorzugten Einstellungen in dieser Methode festlegen.

Bob
quelle
3
Es scheint, dass sie sich widersprechen, wenn sie die Notification.Builder(context)Lösung in der NotificationChannel-Sitzung veröffentlichen. Aber gut, zumindest haben Sie einen Beitrag gefunden, der diese Abwertung meldet =)
GuilhermeFGL
22
Was ist die Kanal-ID, die Sie bitte erklären können?
Santanu Sur
15
Was ist ChannelId?
RoundTwo
3
Sie können NotificationCompat.Builder(Context context)den Kanal auch weiterhin verwenden und dann wie builder.setChannelId(String channelId)
folgt
36
Eine Kanal-ID kann eine beliebige Zeichenfolge sein. Sie ist zu groß, um sie in Kommentaren zu diskutieren. Sie wird jedoch verwendet, um Ihre Benachrichtigungen in Kategorien zu unterteilen, sodass der Benutzer deaktivieren kann, was seiner Meinung nach für ihn nicht wichtig ist, anstatt alle Benachrichtigungen aus Ihrer App zu blockieren.
Yehyatt
110

Geben Sie hier die Bildbeschreibung ein

Hier ist Arbeitscode für alle Android-Versionen ab API LEVEL 26+ mit Abwärtskompatibilität.

 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());

UPDATE für API 26 zum Festlegen der maximalen Priorität

    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
quelle
Wie können Sie dafür sorgen, dass die Benachrichtigung tatsächlich in der App oder in einer anderen App auf dem Bildschirm angezeigt wird?
BlueBoy
@ BlueBoy Ich bekomme deine Frage nicht. Könnten Sie bitte erklären, was genau Sie brauchen?
Aks4125
@ Aks4125 Die Benachrichtigung wird nicht nach unten verschoben und oben auf dem Bildschirm angezeigt. Sie hören einen Ton und ein winziges Benachrichtigungssymbol wird in der Statusleiste angezeigt. Es wird jedoch nichts nach unten verschoben und angezeigt, als ob Sie eine txt-Nachricht erhalten hätten.
BlueBoy
@BlueBoy Sie müssen für dieses Verhalten die Priorität auf HIGH setzen. Lassen Sie mich wissen, wenn ich diesen Code aktualisieren muss. Wenn Sie sich für eine Benachrichtigung mit hoher Priorität herumschleichen, erhalten Sie Ihre Antwort.
Aks4125
2
@ BlueBoy aktualisierte Antwort überprüfen. Wenn Sie nicht auf 26 API abzielen, verwenden Sie einfach denselben Code, .setPriority(Notification.PRIORITY_MAX)andernfalls verwenden Sie aktualisierten Code für 26 API. `
Aks4125
31

Rufen Sie den 2-Argumente-Konstruktor auf: Rufen Sie zur Kompatibilität mit Android O support-v4 auf NotificationCompat.Builder(Context context, String channelId). Wenn Sie mit Android N oder früher arbeiten, channelIdwird dies ignoriert. Wenn Sie mit Android O arbeiten, erstellen Sie auch ein NotificationChannelmit demselben channelId.

Beispielcode für veraltete Zeit: Der Beispielcode auf mehreren JavaDoc-Seiten, z. B. Notification.Builder , new Notification.Builder(mContext)ist veraltet.

Veraltete Konstruktoren: Notification.Builder(Context context) und v4 NotificationCompat.Builder(Context context) sind zugunsten von veraltet Notification[Compat].Builder(Context context, String channelId). (Siehe Notification.Builder (android.content.Context) und v4 NotificationCompat.Builder (Kontextkontext ) .)

Veraltete Klasse: Die gesamte Klasse v7 NotificationCompat.Builder ist veraltet. (Siehe v7 NotificationCompat.Builder .) Bisher wurde v7 NotificationCompat.Builderzur Unterstützung benötigt NotificationCompat.MediaStyle. In Android O gibt es eine v4 NotificationCompat.MediaStylein der Medien-compat Bibliothek ‚s - android.support.v4.mediaPaket. Verwenden Sie diese, wenn Sie brauchen MediaStyle.

API 14+: In der Support Library ab 26.0.0 unterstützen die Pakete support-v4 und support-v7 beide eine Mindest-API-Stufe von 14. Die v # -Namen sind historisch.

Siehe Aktuelle Revisionen der Support-Bibliothek .

Jerry101
quelle
22

Anstatt nach zu suchen Build.VERSION.SDK_INT >= Build.VERSION_CODES.O so vielen Antworten zu suchen, gibt es einen etwas einfacheren Weg -

Fügen Sie dem applicationAbschnitt der Datei AndroidManifest.xml die folgende Zeile hinzu, wie im Dokument Einrichten einer Firebase Cloud Messaging-Client-App unter Android erläutert :

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

Fügen Sie dann der Datei values ​​/ strings.xml eine Zeile mit einem Kanalnamen hinzu :

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

Danach können Sie die neue Version des NotificationCompat.Builder- Konstruktors mit 2 Parametern verwenden (da der alte Konstruktor mit 1 Parameter in Android Oreo veraltet ist):

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
quelle
1
Wie ist das einfacher? : S
Nactus
17

Hier ist der Beispielcode, der in Android Oreo und weniger als Oreo funktioniert.

  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
quelle
8

Einfache Probe

    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
quelle
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();  

Der richtige Code lautet:

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

mit Abhängigkeit 26.0.1 und neuen aktualisierten Abhängigkeiten wie 28.0.0.

Einige Benutzer verwenden diesen Code in folgender Form:

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

Logik ist also die Methode, die Sie deklarieren oder initiieren, dann wird dieselbe Methode auf der rechten Seite für die Zuordnung verwendet. Wenn Sie auf der linken Seite von = eine Methode verwenden, wird dieselbe Methode auf der rechten Seite von = für die Zuordnung mit neu verwendet.

Versuchen Sie diesen Code ... Es wird sicher funktionieren

Pradeep Sheoran
quelle
1

Dieser Konstruktor war in API-Level 26.1.0 veraltet. Verwenden Sie stattdessen NotificationCompat.Builder (Context, String). Alle veröffentlichten Benachrichtigungen müssen eine NotificationChannel-ID angeben.

Sandeep Singh
quelle
Fügen Sie vielleicht lieber einen Kommentar mit Link zur Dokumentation hinzu, anstatt cat zu kopieren und als Antwort zu posten.
JacksOnF1re
0
  1. Sie müssen einen Benachrichtigungskanal mit Notification_Channel_ID deklarieren
  2. Erstellen Sie eine Benachrichtigung mit dieser Kanal-ID. Beispielsweise,

...
 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
quelle