Las notificaciones proporcionan información breve y oportuna sobre eventos de tu app cuando no está en uso. En este documento, se muestra cómo crear una notificación con varias funciones. Para ver una introducción sobre cómo aparecen las notificaciones en Android, consulta la Descripción general de notificaciones. Para ver un código de muestra que usa notificaciones, consulta el ejemplo de Socialite en GitHub.
El código de esta página usa las APIs de NotificationCompat
de la biblioteca de AndroidX. Estas APIs te permiten agregar funciones disponibles solo en versiones más recientes de Android, al tiempo que proporcionan compatibilidad con Android 9 (nivel de API 28). Sin embargo, algunas funciones, como la acción de respuesta en línea, generan una no-op en versiones anteriores.
Agrega la biblioteca principal de AndroidX
Si bien la mayoría de los proyectos creados con Android Studio incluyen las dependencias necesarias para usar NotificationCompat
, verifica que tu archivo build.gradle
a nivel de módulo incluya la siguiente dependencia:
Groovy
dependencies { implementation "androidx.core:core:2.2.0" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:2.2.0") }
Cómo crear una notificación básica
En su forma más básica y compacta (también conocida como forma contraída), una notificación muestra un ícono, un título y una pequeña cantidad de texto contextual. En esta sección, se muestra cómo crear una notificación en la que el usuario pueda presionar para iniciar una actividad en tu app.
Para obtener más detalles sobre cada parte de las notificaciones, lee la documentación sobre la anatomía de las notificaciones.
Declara el permiso de tiempo de ejecución
Android 13 (nivel de API 33) y versiones posteriores admiten un permiso de tiempo de ejecución para publicar notificaciones no exentas (incluidos los servicios en primer plano [FGS]) desde una app.
El permiso que debes declarar en el archivo de manifiesto de tu app aparece en el siguiente fragmento de código:
<manifest ...> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <application ...> ... </application> </manifest>
Para obtener más detalles sobre los permisos durante el tiempo de ejecución, consulta Permiso de tiempo de ejecución de notificaciones.
Cómo definir el contenido de la notificación
Para comenzar, configura el contenido y el canal de la notificación con un objeto NotificationCompat.Builder
. En el siguiente ejemplo, se muestra cómo crear una notificación con lo siguiente:
Un ícono pequeño, establecido por
setSmallIcon()
. que es el único contenido necesario visible para el usuarioUn título, establecido por
setContentTitle()
.El texto del cuerpo, establecido por
setContentText()
La prioridad de la notificación, establecida por
setPriority()
. La prioridad determina cuán intrusiva es la notificación en Android 7.1 y versiones anteriores. Para Android 8.0 y versiones posteriores, establece la importancia del canal como se muestra en la siguiente sección.
Kotlin
var builder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle(textTitle) .setContentText(textContent) .setPriority(NotificationCompat.PRIORITY_DEFAULT)
Java
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle(textTitle) .setContentText(textContent) .setPriority(NotificationCompat.PRIORITY_DEFAULT);
El constructor NotificationCompat.Builder
requiere que proporciones un ID de canal. Esto es obligatorio para la compatibilidad con Android 8.0 (nivel de API 26) y versiones posteriores, pero se ignora en versiones anteriores.
De forma predeterminada, el contenido de texto de la notificación se trunca para que quepa en una línea. Puedes mostrar información adicional creando una notificación expandible.
Si deseas que la notificación sea más larga, puedes habilitar una notificación expandible agregando una plantilla de estilo con setStyle()
.
Por ejemplo, el siguiente código crea un área de texto más grande:
Kotlin
var builder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Much longer text that cannot fit one line...") .setStyle(NotificationCompat.BigTextStyle() .bigText("Much longer text that cannot fit one line...")) .setPriority(NotificationCompat.PRIORITY_DEFAULT)
Java
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Much longer text that cannot fit one line...") .setStyle(new NotificationCompat.BigTextStyle() .bigText("Much longer text that cannot fit one line...")) .setPriority(NotificationCompat.PRIORITY_DEFAULT);
Para obtener más información sobre otros estilos de notificaciones más grandes, incluso sobre cómo agregar una imagen y controles de reproducción multimedia, consulta Cómo crear una notificación expandible.
Cómo crear un canal y definir la importancia
Antes de poder publicar la notificación en Android 8.0 y versiones posteriores, registra el canal de notificaciones de la app en el sistema transfiriendo una instancia de NotificationChannel
a createNotificationChannel()
.
El siguiente código está bloqueado por una condición en la versión SDK_INT
:
Kotlin
private fun createNotificationChannel() { // Create the NotificationChannel, but only on API 26+ because // the NotificationChannel class is not in the Support Library. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val name = getString(R.string.channel_name) val descriptionText = getString(R.string.channel_description) val importance = NotificationManager.IMPORTANCE_DEFAULT val channel = NotificationChannel(CHANNEL_ID, name, importance).apply { description = descriptionText } // Register the channel with the system. val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } }
Java
private void createNotificationChannel() { // Create the NotificationChannel, but only on API 26+ because // the NotificationChannel class is not in the Support Library. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = getString(R.string.channel_name); String description = getString(R.string.channel_description); int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); // Register the channel with the system; you can't change the importance // or other notification behaviors after this. NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } }
Debido a que debes crear el canal de notificación antes de publicar notificaciones en Android 8.0 y versiones posteriores, ejecuta este código tan pronto como se inicie la app. Se considera que realizar llamadas repetidas es seguro porque, cuando se crea un canal de notificación, no se lleva a cabo ninguna operación.
El constructor NotificationChannel
requiere un importance
, con una de las constantes de la clase NotificationManager
. Este parámetro determina cómo interrumpir al usuario con cualquier notificación que pertenezca a este canal. Establece la prioridad con setPriority()
para admitir Android 7.1 y versiones anteriores, como se muestra en el ejemplo anterior.
Si bien debes definir la importancia o prioridad de la notificación como se muestra en el siguiente ejemplo, el sistema no garantiza el comportamiento de alerta que obtengas. En algunos casos, el sistema puede cambiar el nivel de importancia en función de otros factores, y el usuario siempre puede redefinir el nivel de importancia para un canal determinado.
Para obtener más información sobre el significado de los diferentes niveles, lee información sobre los niveles de importancia de las notificaciones.
Cómo establecer la acción de toque de la notificación
Cada notificación debe responder a un toque, por lo general para abrir una actividad en la app que se corresponda con la notificación. Para ello, especifica un intent de contenido definido con un objeto PendingIntent
y pásalo a setContentIntent()
.
En el siguiente fragmento, se muestra cómo crear un intent básico para abrir una actividad cuando el usuario presiona la notificación:
Kotlin
// Create an explicit intent for an Activity in your app. val intent = Intent(this, AlertDetails::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE) val builder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Set the intent that fires when the user taps the notification. .setContentIntent(pendingIntent) .setAutoCancel(true)
Java
// Create an explicit intent for an Activity in your app. Intent intent = new Intent(this, AlertDetails.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Set the intent that fires when the user taps the notification. .setContentIntent(pendingIntent) .setAutoCancel(true);
Este código llama a setAutoCancel()
, que quita automáticamente la notificación cuando el usuario la presiona.
El método setFlags()
que se muestra en el ejemplo anterior conserva la experiencia de navegación esperada del usuario después de que este abre la app con la notificación. Te recomendamos que la uses según el tipo de actividad que inicies, que puede ser una de las siguientes:
Una actividad que existe exclusivamente para respuestas a la notificación. No hay motivo para que el usuario navegue a esta actividad durante el uso normal de la app, por lo que la actividad inicia una nueva tarea, en lugar de agregarse a la pila de actividades existente de la app. Este es el tipo de intent que se creó en el ejemplo anterior.
Una actividad que existe en el flujo regular de la app. En este caso, cuando se inicia la actividad, se crea una pila de actividades, de modo que se conserven las expectativas del usuario relacionadas con los botones Atrás y Arriba.
Para obtener más información sobre las diferentes maneras de configurar el intent de tu notificación, consulta Cómo iniciar una actividad desde una notificación.
Cómo mostrar la notificación
Para que aparezca la notificación, llama a NotificationManagerCompat.notify()
y pásale un ID único para la notificación y el resultado de NotificationCompat.Builder.build()
.
Esto se muestra en el siguiente ejemplo:
Kotlin
with(NotificationManagerCompat.from(this)) { if (ActivityCompat.checkSelfPermission( this@MainActivity, Manifest.permission.POST_NOTIFICATIONS ) != PackageManager.PERMISSION_GRANTED ) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, // grantResults: IntArray) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return@with } // notificationId is a unique int for each notification that you must define. notify(NOTIFICATION_ID, builder.build()) }
Java
with(NotificationManagerCompat.from(this)) { if (ActivityCompat.checkSelfPermission( this@MainActivity, Manifest.permission.POST_NOTIFICATIONS ) != PackageManager.PERMISSION_GRANTED ) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return } // notificationId is a unique int for each notification that you must define. notify(NOTIFICATION_ID, builder.build()) }
Guarda el ID de la notificación que le pasas a NotificationManagerCompat.notify()
, ya que lo necesitarás cuando quieras actualizar o quitar la notificación.
Además, para probar las notificaciones básicas en dispositivos que ejecutan Android 13 y versiones posteriores, activa las notificaciones de forma manual o crea un diálogo para solicitarlas.
Cómo agregar botones de acción
Una notificación puede ofrecer hasta tres botones de acción que le permitan al usuario responder de manera rápida, como posponer un recordatorio o responder un mensaje de texto. Pero estos botones de acción no deben duplicar la acción realizada cuando el usuario presiona la notificación.
Para agregar un botón de acción, pasa un elemento PendingIntent
al método addAction()
. Esto es similar a configurar la acción de toque predeterminada de la notificación, excepto que, en lugar de iniciar una actividad, puedes realizar otras acciones, como iniciar un BroadcastReceiver
que realice una tarea en segundo plano, de modo que la acción no interrumpa la app que ya está abierta.
Por ejemplo, en el siguiente código, se muestra cómo enviar una transmisión a un receptor específico:
Kotlin
val ACTION_SNOOZE = "snooze" val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply { action = ACTION_SNOOZE putExtra(EXTRA_NOTIFICATION_ID, 0) } val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0) val builder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .addAction(R.drawable.ic_snooze, getString(R.string.snooze), snoozePendingIntent)
Java
String ACTION_SNOOZE = "snooze" Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class); snoozeIntent.setAction(ACTION_SNOOZE); snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0); PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .addAction(R.drawable.ic_snooze, getString(R.string.snooze), snoozePendingIntent);
Para obtener más información sobre cómo compilar un elemento BroadcastReceiver
para ejecutar el trabajo en segundo plano, consulta la descripción general de las transmisiones.
En cambio, si estás intentando compilar una notificación con botones de reproducción multimedia, como pausar y omitir pistas, consulta cómo crear una notificación con controles de contenido multimedia.
Cómo agregar una acción de respuesta directa
La acción de respuesta directa, introducida en Android 7.0 (nivel de API 24), permite a los usuarios ingresar texto directamente en la notificación. Luego, el texto se entrega a tu app sin abrir una actividad. Por ejemplo, puedes usar una acción de respuesta directa para permitir que los usuarios respondan mensajes de texto o actualicen listas de tareas desde dentro de la notificación.
La acción de respuesta directa aparece como un botón adicional en la notificación, que abre una entrada de texto. Cuando el usuario termina de escribir, el sistema adjunta la respuesta de texto al intent que especificaste para la acción de la notificación y lo envía a tu app.
Cómo agregar el botón de respuesta
Para crear una acción de notificación que admita respuesta directa, sigue estos pasos:
- Crea una instancia de
RemoteInput.Builder
que puedas agregar a tu acción de notificación. El constructor de esta clase acepta una cadena que el sistema usa como clave para la inserción de texto. Luego, tu app usa esa clave para recuperar el texto de la entrada.Kotlin
// Key for the string that's delivered in the action's intent. private val KEY_TEXT_REPLY = "key_text_reply" var replyLabel: String = resources.getString(R.string.reply_label) var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run { setLabel(replyLabel) build() }
Java
// Key for the string that's delivered in the action's intent. private static final String KEY_TEXT_REPLY = "key_text_reply"; String replyLabel = getResources().getString(R.string.reply_label); RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY) .setLabel(replyLabel) .build();
- Crea un
PendingIntent
para la acción de respuesta.Kotlin
// Build a PendingIntent for the reply action to trigger. var replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(applicationContext, conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT)
Java
// Build a PendingIntent for the reply action to trigger. PendingIntent replyPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT);
- Adjunta el objeto
RemoteInput
a una acción conaddRemoteInput()
.Kotlin
// Create the reply action and add the remote input. var action: NotificationCompat.Action = NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .build()
Java
// Create the reply action and add the remote input. NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .build();
- Aplica la acción a una notificación y emite la notificación.
Kotlin
// Build the notification and add the action. val newMessageNotification = Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentTitle(getString(R.string.title)) .setContentText(getString(R.string.content)) .addAction(action) .build() // Issue the notification. with(NotificationManagerCompat.from(this)) { notificationManager.notify(notificationId, newMessageNotification) }
Java
// Build the notification and add the action. Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentTitle(getString(R.string.title)) .setContentText(getString(R.string.content)) .addAction(action) .build(); // Issue the notification. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, newMessageNotification);
Cuando se active la acción de notificación, el sistema le solicitará al usuario que ingrese una respuesta, como se muestra en la figura 4.
Cómo recuperar entradas del usuario a partir de la respuesta
Para recibir entradas del usuario de la IU de respuesta de la notificación, llama a RemoteInput.getResultsFromIntent()
y pásale el elemento Intent
que recibió tu BroadcastReceiver
:
Kotlin
private fun getMessageText(intent: Intent): CharSequence? { return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY) }
Java
private CharSequence getMessageText(Intent intent) { Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); if (remoteInput != null) { return remoteInput.getCharSequence(KEY_TEXT_REPLY); } return null; }
Después de procesar el texto, llama a NotificationManagerCompat.notify()
con el mismo ID y la misma etiqueta (si corresponde) para actualizar la notificación. Esto es necesario para ocultar la IU de respuesta directa y confirmar al usuario que se recibió y procesó correctamente su respuesta.
Kotlin
// Build a new notification, which informs the user that the system // handled their interaction with the previous notification. val repliedNotification = Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentText(getString(R.string.replied)) .build() // Issue the new notification. NotificationManagerCompat.from(this).apply { notificationManager.notify(notificationId, repliedNotification) }
Java
// Build a new notification, which informs the user that the system // handled their interaction with the previous notification. Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentText(getString(R.string.replied)) .build(); // Issue the new notification. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, repliedNotification);
Cuando trabajes con esta nueva notificación, usa el contexto que se pasa al método onReceive()
del receptor.
Llama a setRemoteInputHistory()
para adjuntar la respuesta en la parte inferior de la notificación.
Sin embargo, si vas a compilar una app de mensajería, crea una notificación de estilo de mensajería y adjunta el nuevo mensaje a la conversación.
Si quieres obtener más consejos sobre las notificaciones de apps de mensajería, consulta la sección sobre prácticas recomendadas para apps de mensajería.
Cómo agregar una barra de progreso
Las notificaciones pueden incluir un indicador de progreso animado que muestre a los usuarios el estado de una operación constante.
Si puedes estimar qué parte de la operación estará completa en cualquier momento, usa el formulario "definido" del indicador (como se muestra en la figura 5) llamando a setProgress(max, progress,
false)
.
El primer parámetro es el valor "completo", como 100. El segundo es cuánta información está completa. El último indica que se trata de una barra de progreso determinada.
A medida que la operación avance, llama a setProgress(max, progress,
false)
de manera continua con un valor actualizado de progress
y vuelve a emitir la notificación, como se muestra en el siguiente ejemplo.
Kotlin
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentTitle("Picture Download") setContentText("Download in progress") setSmallIcon(R.drawable.ic_notification) setPriority(NotificationCompat.PRIORITY_LOW) } val PROGRESS_MAX = 100 val PROGRESS_CURRENT = 0 NotificationManagerCompat.from(this).apply { // Issue the initial notification with zero progress. builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false) notify(notificationId, builder.build()) // Do the job that tracks the progress here. // Usually, this is in a worker thread. // To show progress, update PROGRESS_CURRENT and update the notification with: // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false); // notificationManager.notify(notificationId, builder.build()); // When done, update the notification once more to remove the progress bar. builder.setContentText("Download complete") .setProgress(0, 0, false) notify(notificationId, builder.build()) }
Java
... NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setContentTitle("Picture Download") .setContentText("Download in progress") .setSmallIcon(R.drawable.ic_notification) .setPriority(NotificationCompat.PRIORITY_LOW); // Issue the initial notification with zero progress. int PROGRESS_MAX = 100; int PROGRESS_CURRENT = 0; builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false); notificationManager.notify(notificationId, builder.build()); // Do the job that tracks the progress here. // Usually, this is in a worker thread. // To show progress, update PROGRESS_CURRENT and update the notification with: // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false); // notificationManager.notify(notificationId, builder.build()); // When done, update the notification once more to remove the progress bar. builder.setContentText("Download complete") .setProgress(0,0,false); notificationManager.notify(notificationId, builder.build());
Al final de la operación, progress
debe ser igual a max
. Puedes dejar que la barra de progreso se siga viendo cuando la operación finalizó o puedes quitarla. En cualquier caso, actualiza el texto de la notificación para mostrar que la operación se completó. Para quitar la barra de progreso, llama a setProgress(0, 0, false)
.
Para mostrar una barra de progreso indefinido (una barra que no indica el porcentaje completado de la operación), llama a setProgress(0, 0, true)
. El resultado es un indicador que tiene el mismo estilo que la barra de progreso anterior, excepto que es una animación continua que no indica qué porcentaje de la operación se completó. La animación de progreso se ejecuta hasta que llamas a setProgress(0, 0, false)
. Luego, tienes que actualizar la notificación para quitar el indicador de actividad.
Recuerda cambiar el texto de la notificación para mostrar que la operación se completó.
Cómo establecer una categoría para todo el sistema
Android usa categorías predefinidas para todo el sistema para determinar si es necesario molestar al usuario con una notificación determinada cuando este habilita el modo No interrumpir.
Si tu notificación está dentro de una de las categorías de notificación definidas en NotificationCompat
, como CATEGORY_ALARM
, CATEGORY_REMINDER
, CATEGORY_EVENT
o CATEGORY_CALL
, declárala como tal pasando la categoría apropiada a setCategory()
:
Kotlin
var builder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setCategory(NotificationCompat.CATEGORY_MESSAGE)
Java
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setCategory(NotificationCompat.CATEGORY_MESSAGE);
El sistema utiliza esta información sobre la categoría de tu notificación para tomar decisiones acerca de mostrar la notificación cuando el dispositivo está en modo No interrumpir. Sin embargo, no es necesario que establezcas una categoría para todo el sistema. Solo debes hacerlo si tus notificaciones coinciden con una de las categorías definidas en NotificationCompat
.
Cómo mostrar un mensaje urgente
Es posible que tu app necesite mostrar un mensaje urgente e importante, como una llamada telefónica entrante o una alarma. En estas situaciones, puedes asociar un intent de pantalla completa a tu notificación.
Cuando se invoca la notificación, los usuarios ven una de las siguientes opciones, según el estado de bloqueo del dispositivo:
- Si el dispositivo del usuario está bloqueado, aparece una actividad en pantalla completa, que cubre la pantalla de bloqueo.
- Si el dispositivo del usuario está desbloqueado, la notificación aparece en forma expandida e incluye opciones para controlar o descartar la notificación.
En el siguiente fragmento de código, se demuestra cómo asociar la notificación con un intent de pantalla completa:
Kotlin
val fullScreenIntent = Intent(this, ImportantActivity::class.java) val fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT) var builder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setFullScreenIntent(fullScreenPendingIntent, true)
Java
Intent fullScreenIntent = new Intent(this, ImportantActivity.class); PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setFullScreenIntent(fullScreenPendingIntent, true);
Cómo establecer la visibilidad de la pantalla de bloqueo
Para controlar el nivel de los detalles visibles en la notificación desde la pantalla de bloqueo, llama a setVisibility()
y especifica uno de los siguientes valores:
VISIBILITY_PUBLIC
: Se muestra el contenido completo de la notificación en la pantalla de bloqueo.VISIBILITY_SECRET
: No se muestra ninguna parte de la notificación en la pantalla de bloqueo.VISIBILITY_PRIVATE
: Solo se muestra información básica en la pantalla de bloqueo, como el ícono de la notificación y el título del contenido. No se muestra todo el contenido de la notificación.
Cuando configuras VISIBILITY_PRIVATE
, también puedes proporcionar una versión alternativa del contenido de la notificación que oculta algunos detalles. Por ejemplo, una app de SMS podría mostrar una notificación que indique "Tienes 3 mensajes de texto nuevos", pero oculta el contenido del mensaje y los remitentes. Para proporcionar esta notificación alternativa, primero crea la notificación alternativa con NotificationCompat.Builder
como de costumbre. Luego, adjunta la notificación alternativa a la normal con setPublicVersion()
.
Ten en cuenta que el usuario siempre tiene el control final sobre si sus notificaciones son visibles en la pantalla de bloqueo y puede controlarlas en función de los canales de notificación de tu app.
Cómo actualizar una notificación
Para actualizar una notificación después de emitirla, vuelve a llamar a NotificationManagerCompat.notify()
y pásale el mismo ID que usaste antes. Si se descarta la notificación anterior, se crea una nueva.
De manera opcional, puedes llamar a setOnlyAlertOnce()
para que tu notificación interrumpa al usuario (con sonido, vibración o pistas visuales) solo la primera vez que aparece, y no en las actualizaciones posteriores.
Cómo quitar una notificación
Las notificaciones permanecen visibles hasta que alguna de estas acciones tiene lugar:
- El usuario descarta la notificación.
- El usuario presiona la notificación si llamas a
setAutoCancel()
cuando creas la notificación. - Llamas a
cancel()
para un ID de notificación específico. Este método también borra las notificaciones constantes. - Llamas a
cancelAll()
, que quita todas las notificaciones que emitiste previamente. - Si estableces un tiempo de espera cuando creas la notificación, con
setTimeoutAfter()
, transcurre la duración especificada. Si es necesario, puedes cancelar una notificación antes de que transcurra el tiempo de espera especificado.
Prácticas recomendadas para apps de mensajería
Ten en cuenta las prácticas recomendadas que se enumeran aquí cuando crees notificaciones para tus apps de mensajería y chat.
Usa MessagingStyle
A partir de Android 7.0 (nivel de API 24), Android proporciona una plantilla de estilo de notificación específica para contenidos de mensajería. Con la clase NotificationCompat.MessagingStyle
, puedes cambiar varias de las etiquetas que aparecen en la notificación, incluidos el título de la conversación, mensajes adicionales y la vista de contenido para la notificación.
En el siguiente fragmento de código, se muestra cómo personalizar el estilo de una notificación con la clase MessagingStyle
.
Kotlin
val user = Person.Builder() .setIcon(userIcon) .setName(userName) .build() val notification = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("2 new messages with $sender") .setContentText(subject) .setSmallIcon(R.drawable.new_message) .setStyle(NotificationCompat.MessagingStyle(user) .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson()) .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson()) ) .build()
Java
Person user = new Person.Builder() .setIcon(userIcon) .setName(userName) .build(); Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("2 new messages with " + sender) .setContentText(subject) .setSmallIcon(R.drawable.new_message) .setStyle(new NotificationCompat.MessagingStyle(user) .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson()) .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson()) ) .build();
A partir de Android 9.0 (nivel de API 28), también se debe usar la clase Person
para obtener una renderización óptima de la notificación y sus avatares.
Cuando uses NotificationCompat.MessagingStyle
, haz lo siguiente:
- Llama a
MessagingStyle.setConversationTitle()
para definir un título para los chats en grupos de más de dos personas. El nombre del chat en grupo puede ser un buen título para la conversación. Si no tiene un nombre, puedes usar una lista de los participantes de la conversación. Sin esto, es posible que se considere erróneamente que el mensaje pertenece a una conversación entre dos personas con el remitente del mensaje más reciente. - Usa el método
MessagingStyle.setData()
para incluir mensajes multimedia, como imágenes. Se admiten los tipos de MIME del patrón image/*.
Usa Respuesta directa
La respuesta directa permite al usuario responder en línea a un mensaje.
- Después de que un usuario responda con la acción de respuesta intercalada, usa
MessagingStyle.addMessage()
para actualizar la notificaciónMessagingStyle
y no retractarte ni cancelarla. Si no cancelas la notificación, el usuario puede enviar respuestas múltiples desde la notificación. - Para que la acción de respuesta intercalada sea compatible con Wear OS, llama a
Action.WearableExtender.setHintDisplayInlineAction(true)
. - Usa el método
addHistoricMessage()
para proporcionar contexto a una conversación de respuesta directa. Para ello, agrega mensajes históricos a la notificación.
Cómo habilitar la Respuesta inteligente
- Para habilitar la Respuesta inteligente, llama a
setAllowGeneratedResponses(true)
en la acción de respuesta. Esto hace que las respuestas de Respuesta inteligente estén disponibles para los usuarios cuando se conecta la notificación con un dispositivo Wear OS. Los mensajes que sugiere Respuesta inteligente son generados por un modelo de aprendizaje automático totalmente incorporado en el reloj a partir del contexto que brinda la notificación deNotificationCompat.MessagingStyle
y no se suben datos a Internet para generar las respuestas.
Agrega metadatos de notificación
- Asigna metadatos de notificación para indicarle al sistema cómo debe controlar las notificaciones de tu app cuando el dispositivo está en
Do Not Disturb mode
. Por ejemplo, usa el métodoaddPerson()
osetCategory(Notification.CATEGORY_MESSAGE)
para anular el modo No interrumpir.