NotificationCompat.Builder en desuso en Android O

161

Después de actualizar mi proyecto a Android O

buildToolsVersion "26.0.1"

Lint en Android Studio muestra una advertencia obsoleta para el siguiente método de creación de notificaciones:

new NotificationCompat.Builder(context)

El problema es: los desarrolladores de Android actualizan su documentación que describe NotificationChannel para admitir notificaciones en Android O, y nos proporcionan un fragmento, pero con la misma advertencia obsoleta:

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

Resumen de notificaciones

Mi pregunta: ¿hay alguna otra solución para generar notificaciones y todavía es compatible con Android O?

Una solución que encontré es pasar el ID del canal como un parámetro en el constructor Notification.Builder. Pero esta solución no es exactamente reutilizable.

new Notification.Builder(MainActivity.this, "channel_id")
GuilhermeFGL
fuente
44
Pero esta solución no es exactamente reutilizable. ¿Cómo es eso?
Tim
55
NotificationCompat.Builder está en desuso, no Notification.Builder. Observe que la parte de Compat desapareció. La notificación es su nueva clase donde están racionalizando todo
Kapil G el
1
@kapsym es al revés en realidad. Notification.Builder es mayor
Tim
Además, no lo veo en desuso aquí developer.android.com/reference/android/support/v4/app/… . Tal vez un error en Lint
Kapil G
El id del canal se pasa al constructor, o se puede colocar usando notificationBuild.setChannelId("channel_id"). En mi caso, esta última solución es más reutilizable ya que mi NotificationCompat.Builderse reutiliza en un par de métodos, guardando parámetros para iconos, sonidos y vibraciones.
GuilhermeFGL

Respuestas:

167

Se menciona en la documentación que el método del constructor NotificationCompat.Builder(Context context)ha quedado en desuso. Y tenemos que usar el constructor que tiene el channelIdparámetro:

NotificationCompat.Builder(Context context, String channelId)

NotificationCompat.Builder Documentation:

Este constructor quedó en desuso en el nivel de API 26.0.0-beta1. use NotificationCompat.Builder (Context, String) en su lugar. Todas las notificaciones publicadas deben especificar un Id. De canal de notificación.

Notificación Documentación del constructor:

Este constructor quedó en desuso en el nivel 26 de la API. Use Notification.Builder (Context, String) en su lugar. Todas las notificaciones publicadas deben especificar un Id. De canal de notificación.

Si desea reutilizar los channelIdconfiguradores del generador, puede crear el generador con , y pasar ese generador a un método auxiliar y establecer su configuración preferida en ese método.

Beto
fuente
3
Parece que se contradicen cuando publican la Notification.Builder(context)solución en la sesión NotificationChannel. Pero bueno, al menos encontraste una publicación en la que se notificaba que este desaprobación =)
GuilhermeFGL
23
¿Cuál es el ID de canal? ¿Puedes explicarlo?
Santanu Sur
15
¿Qué es channelId?
Alrededor de dos
3
También puede seguir utilizando NotificationCompat.Builder(Context context), y luego asignar el canal de la siguiente manera:builder.setChannelId(String channelId)
deyanm
36
Un ID de canal puede ser cualquier cadena, es demasiado grande para discutirlo en los comentarios, pero se usa para separar sus notificaciones en categorías para que el usuario pueda desactivar lo que cree que no es importante para él en lugar de bloquear todas las notificaciones de su aplicación.
yehyatt
110

ingrese la descripción de la imagen aquí

Aquí hay un código de trabajo para todas las versiones de Android a partir de API LEVEL 26+ con compatibilidad con versiones anteriores.

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

ACTUALIZACIÓN para API 26 para establecer la prioridad máxima

    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
fuente
¿Cómo puede hacer que la notificación se muestre en la pantalla en la aplicación o en otra aplicación?
BlueBoy
@BlueBoy no recibo tu pregunta. ¿podría explicar qué es exactamente lo que necesita?
Aks4125
@ Aks4125 La notificación no se desliza hacia abajo y se muestra en la parte superior de la pantalla. Escucha un tono y aparece un pequeño ícono de notificación en la barra de estado, pero nada se desliza hacia abajo y se muestra como si recibiera un mensaje de texto.
BlueBoy
@BlueBoy necesita establecer prioridad en ALTO para ese comportamiento. avíseme si necesita que actualice este código. Si se escabulle para recibir notificaciones de alta prioridad, recibirá su respuesta.
Aks4125
2
@BlueBoy verifica la respuesta actualizada. si no está apuntando a 26 API, simplemente use el mismo código con .setPriority(Notification.PRIORITY_MAX)otro código actualizado para 26 API. `
Aks4125
31

Llame al constructor de 2 argumentos: para compatibilidad con Android O, llame a support-v4 NotificationCompat.Builder(Context context, String channelId). Cuando se ejecuta en Android N o anterior, channelIdse ignorará. Cuando se ejecuta en Android O, también crea un NotificationChannelcon el mismo channelId.

Fuera de código de ejemplo la fecha: El código de ejemplo en varias páginas JavaDoc como Notification.Builder llamado new Notification.Builder(mContext)está fuera de fecha.

Constructores en desuso :Notification.Builder(Context context) y v4 NotificationCompat.Builder(Context context) están en desuso a favor de Notification[Compat].Builder(Context context, String channelId). (Consulte Notification.Builder (android.content.Context) y v4 NotificationCompat.Builder (Contexto contextual) .)

Clase en desuso : toda la clase v7 NotificationCompat.Builder está en desuso. (Consulte v7 NotificationCompat.Builder .) Anteriormente, la v7 NotificationCompat.Builderera necesaria para admitir NotificationCompat.MediaStyle. En Android O, hay una v4 NotificationCompat.MediaStyleen la biblioteca de medios-compat 's android.support.v4.mediapaquete. Usa ese si lo necesitas MediaStyle.

API 14+: en la Biblioteca de soporte de 26.0.0 y superior, los paquetes support-v4 y support-v7 admiten un nivel mínimo de API de 14. Los nombres v # son históricos.

Ver revisiones recientes de la biblioteca de soporte .

Jerry101
fuente
22

En lugar de buscar Build.VERSION.SDK_INT >= Build.VERSION_CODES.Otodas las respuestas que sugieren, hay una forma un poco más simple:

Agrega la siguiente línea a la applicationsección del archivo AndroidManifest.xml como se explica en la Configuración de una aplicación de cliente Firebase Cloud Messaging en el documento de Android :

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

Luego agregue una línea con un nombre de canal al archivo values ​​/ strings.xml :

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

Después de eso, podrá utilizar la nueva versión del constructor NotificationCompat.Builder con 2 parámetros (ya que el antiguo constructor con 1 parámetro ha quedado en desuso en 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
fuente
1
¿Cómo es esto más simple? : S
Nactus
17

Aquí está el código de muestra, que funciona en Android Oreo y menos 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
fuente
8

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

El código correcto será:

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

con dependencia 26.0.1 y nuevas dependencias actualizadas como 28.0.0.

Algunos usuarios usan este código en la forma de esto:

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

Entonces, la lógica es el método que declarará o iniciará, luego se utilizará el mismo método en el lado derecho para la asignación. si en Leftside of = utilizará algún método, se utilizará el mismo método en el lado derecho de = para Asignación con nuevo.

Pruebe este código ... seguramente funcionará

Pradeep Sheoran
fuente
1

Este constructor quedó en desuso en el nivel de API 26.1.0. use NotificationCompat.Builder (Context, String) en su lugar. Todas las notificaciones publicadas deben especificar un Id. De canal de notificación.

Sandeep Singh
fuente
Quizás prefiera agregar un comentario con un enlace a la documentación en lugar de copiar cat y publicar como respuesta.
JacksOnF1re
0
  1. Necesita declarar un canal de notificación con Notification_Channel_ID
  2. Crear notificación con esa ID de canal. Por ejemplo,

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