NotificationCompat.Builder obsoleto in Android O


161

Dopo aver aggiornato il mio progetto su Android O

buildToolsVersion "26.0.1"

Lint in Android Studio mostra un avviso obsoleto per il seguente metodo del generatore di notifiche:

new NotificationCompat.Builder(context)

Il problema è: gli sviluppatori Android aggiornano la loro documentazione che descrive NotificationChannel per supportare le notifiche in Android O e ci forniscono uno snippet, ma con lo stesso avviso deprecato:

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

Panoramica delle notifiche

La mia domanda: esiste un'altra soluzione per creare notifiche e supportare ancora Android O?

Una soluzione che ho trovato è passare l'ID canale come parametro nel costruttore Notification.Builder. Ma questa soluzione non è esattamente riutilizzabile.

new Notification.Builder(MainActivity.this, "channel_id")

4
Ma questa soluzione non è esattamente riutilizzabile. come mai?
Tim

5
NotificationCompat.Builder è obsoleto, non Notification.Builder. Notare che la parte Compat è sparita. Le notifiche sono la loro nuova classe in cui stanno razionalizzando tutto
Kapil G,

1
@kapsym è il contrario in realtà. Notification.Builder è più vecchio
Tim

Inoltre non lo vedo deprecato qui developer.android.com/reference/android/support/v4/app/… . Forse un bug in Lint
Kapil G

L'ID canale viene passato al costruttore o può essere posizionato utilizzando notificationBuild.setChannelId("channel_id"). Nel mio caso quest'ultima soluzione è più riutilizzabile in quanto la mia NotificationCompat.Builderviene riutilizzata in un paio di metodi, salvando i parametri per icone, suoni e vibrazioni.
GuilhermeFGL,

Risposte:


167

Nella documentazione viene menzionato che il metodo builder NotificationCompat.Builder(Context context)è stato deprecato. E dobbiamo usare il costruttore che ha il channelIdparametro:

NotificationCompat.Builder(Context context, String channelId)

Documentazione di NotificationCompat.Builder:

Questo costruttore è stato deprecato nel livello API 26.0.0-beta1. utilizzare invece NotificationCompat.Builder (Context, String). Tutte le notifiche pubblicate devono specificare un ID NotificationChannel.

Notification.Builder Documentation:

Questo costruttore è stato deprecato a livello di API 26. utilizzare invece Notification.Builder (Context, String). Tutte le notifiche pubblicate devono specificare un ID NotificationChannel.

Se si desidera riutilizzare i setter del builder, è possibile creare il builder con channelIde passare quel builder a un metodo helper e impostare le impostazioni preferite in quel metodo.


3
Sembra che si stiano contraddicendo quando pubblicano la Notification.Builder(context)soluzione nella sessione NotificationChannel. Ma bene, almeno hai trovato un post che notifica questo deprecante =)
GuilhermeFGL

23
Qual è il channelId puoi spiegarmi, per favore?
Santanu Sur,

15
che cos'è channelId?
RoundDue

3
Puoi anche usare NotificationCompat.Builder(Context context)e quindi assegnare il canale in questo modo:builder.setChannelId(String channelId)
deyanm

36
Un ID canale può essere qualsiasi stringa, è troppo grande per essere discusso nei commenti, ma viene utilizzato per separare le notifiche in categorie in modo che l'utente possa disabilitare ciò che ritiene non sia importante per lui piuttosto che bloccare tutte le notifiche dalla tua app.
yehyatt,

110

inserisci qui la descrizione dell'immagine

Ecco il codice funzionante per tutte le versioni di Android a partire da API LEVEL 26+ con compatibilità con le versioni precedenti.

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

AGGIORNAMENTO per API 26 per impostare la priorità massima

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

Come si può effettivamente mostrare la notifica sullo schermo nell'app o se in un'altra app?
BlueBoy

@BlueBoy non ricevo la tua domanda. potresti spiegare di cosa hai bisogno esattamente?
Aks4125,

@ Aks4125 La notifica non scorre verso il basso e non viene visualizzata nella parte superiore dello schermo. Si sente un tono e nella barra di stato viene visualizzata una piccola icona di notifica, ma nulla scorre verso il basso e viene visualizzato come se si ricevesse un messaggio txt.
BlueBoy,

@BlueBoy devi impostare la priorità su HIGH per quel comportamento. fammi sapere se hai bisogno di me per aggiornare questo codice. se cerchi una notifica ad alta priorità otterrai la tua risposta.
Aks4125 il

2
@BlueBoy controlla la risposta aggiornata. se non stai scegliendo come target 26 API, usa semplicemente lo stesso codice, .setPriority(Notification.PRIORITY_MAX)altrimenti usa il codice aggiornato per 26 API. `
Aks4125 il

31

Chiama il costruttore 2-arg: per la compatibilità con Android O, chiama support-v4 NotificationCompat.Builder(Context context, String channelId). Quando si esegue su Android N o versioni precedenti, channelIdverrà ignorato. Quando si esegue su Android O, crea anche uno NotificationChannelcon lo stesso channelId.

Non aggiornato codice di esempio: Il codice di esempio su più pagine JavaDoc quali Notification.Builder chiamata new Notification.Builder(mContext)non è aggiornato.

Costruttori obsoleti: Notification.Builder(Context context) e v4 NotificationCompat.Builder(Context context) sono deprecati a favore di Notification[Compat].Builder(Context context, String channelId). (Vedi Notification.Builder (android.content.Context) e v4 NotificationCompat.Builder (contesto di contesto) .)

Classe obsoleta : l'intera classe v7 NotificationCompat.Builder è obsoleta. (Vedi v7 NotificationCompat.Builder .) In precedenza, v7 NotificationCompat.Builderera necessaria per supportare NotificationCompat.MediaStyle. In Android O, c'è un v4 NotificationCompat.MediaStylenella libreria multimediale-compat 's android.support.v4.mediapacchetto. Usalo se ne hai bisogno MediaStyle.

API 14+: in Support Library dalla 26.0.0 e successive, i pacchetti support-v4 e support-v7 supportano entrambi un livello API minimo di 14. I nomi v # sono storici.

Consulta le revisioni recenti della libreria di supporto .


22

Invece di verificare Build.VERSION.SDK_INT >= Build.VERSION_CODES.Oil numero di risposte suggerite, esiste un modo leggermente più semplice:

Aggiungi la seguente riga alla applicationsezione del file AndroidManifest.xml come spiegato nel documento Configurare un'app client Firebase Cloud Messaging sul documento Android :

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

Quindi aggiungere una riga con un nome di canale al file valori / strings.xml :

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

Dopodiché sarai in grado di utilizzare la nuova versione del costruttore NotificationCompat.Builder con 2 parametri (poiché il vecchio costruttore con 1 parametro è stato deprecato in 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());
}

1
come è più semplice? : S
Nactus,

17

Ecco il codice di esempio, che funziona in Android Oreo e meno di 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());

8

Campione semplice

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

    }

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

Il codice corretto sarà:

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

con dipendenza 26.0.1 e nuove dipendenze aggiornate come 28.0.0.

Alcuni utenti utilizzano questo codice nella forma di questo:

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

Quindi la logica è quel metodo che dichiarerai o inizializzerai, quindi lo stesso metodo sul lato destro sarà usato per l'allocazione. se in Leftside di = userete qualche metodo, lo stesso metodo verrà usato nella parte destra di = per Allocation con new.

Prova questo codice ... Funzionerà sicuramente


1

Questo costruttore è stato deprecato nel livello API 26.1.0. utilizzare invece NotificationCompat.Builder (Context, String). Tutte le notifiche pubblicate devono specificare un ID NotificationChannel.


Forse piuttosto aggiungere un commento con link alla documentazione invece di copiare cat e pubblicare come risposta.
JacksOnF1re

0
  1. È necessario dichiarare un canale di notifica con Notification_Channel_ID
  2. Crea notifica con quell'ID canale. Per esempio,

...
 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());
...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.