Este codelab es parte del curso Aspectos avanzados de Android en Kotlin. Aprovecharás al máximo este curso si trabajas con los codelabs de forma secuencial, aunque no es obligatorio. Todos los codelabs del curso se indican en la página de destino de los codelabs de Aspectos avanzados de Android en Kotlin.
Introducción
Las notificaciones son mensajes que se muestran al usuario fuera de la IU de tu app. Las notificaciones se muestran en la parte superior de la pantalla si el dispositivo está desbloqueado o, según la configuración de seguridad, en la pantalla de bloqueo cuando el dispositivo está bloqueado.
Una notificación típica consta de un título, una descripción y un ícono. Las notificaciones también pueden tener acciones en las que se puede hacer clic, respuestas rápidas, contenido extensible e imágenes.
Las notificaciones pueden entregar material oportuno y tener botones para permitir que el usuario realice acciones rápidas, como enviar una respuesta o posponer una alarma. Cuando el usuario hace clic en una notificación, se lo dirige a una vista de tu app relacionada con el contenido de la notificación.
Las notificaciones son una forma útil de recordarles a los usuarios una tarea importante, informarles que ocurrió algo o comunicarles información importante que necesitan de inmediato mientras tu app se ejecuta en segundo plano. Usa las notificaciones con moderación. Esto no solo respeta a los usuarios, sino que también aumenta las probabilidades de que la notificación de tu app reciba la atención que merece.
En este codelab, aprenderás a crear y usar notificaciones en una app para Android.
Conocimientos que ya deberías tener
Debes estar familiarizado con lo siguiente:
- Cómo crear apps para Android en Kotlin En particular, trabajar con el SDK de Android
- Cómo diseñar apps con los componentes de arquitectura y la vinculación de datos
- Conocimientos básicos sobre BroadcastReceivers
- Conocimientos básicos sobre AlarmManager
Qué aprenderás
- Cómo crear, diseñar y enviar una notificación
- Cómo cancelar las notificaciones
- Cómo crear canales de notificaciones
- Cómo agregar acciones rápidas a las notificaciones
- Cómo mostrar distintivos de notificaciones en el ícono de la app
Actividades
- Agrega una notificación a la app de inicio.
- Cancela la notificación que enviaste anteriormente.
- Crea canales para diferentes tipos de notificaciones.
- Personaliza las notificaciones en la app de inicio.
- Agrega acciones rápidas para que tu notificación sea interactiva.
- Desactiva los distintivos de notificaciones.
Cocinar huevos es sencillo, pero puede ser una tarea difícil si no controlas el tiempo. En este codelab, trabajarás en una app de temporizador de huevos y la perfeccionarás, al igual que tus futuros huevos. Comenzarás con una app de temporizador de huevos que funciona y que permite al usuario establecer diferentes parámetros de configuración de tiempo de cocción para diferentes estilos de huevos. El temporizador realiza una cuenta regresiva desde el intervalo de tiempo seleccionado y muestra un mensaje emergente cuando los huevos están listos.
Esto puede parecer funcional, pero está lejos de ser perfecto y no es muy fácil de usar. Para empezar, el mensaje emergente solo se muestra durante un breve período, por lo que es fácil pasarlo por alto. Además, si la app no está en primer plano o el dispositivo está bloqueado, no hay ningún indicador visual del estado del temporizador una vez que desaparece el mensaje emergente.
Lo ideal es que el temporizador de huevos use notificaciones para avisar a los usuarios cuando se acabe el tiempo. El usuario realmente necesita saber que los huevos están listos de inmediato, de lo contrario, se cocinarán demasiado. Las notificaciones son visuales, pueden incluir sonidos y hacer que el dispositivo vibre. Todas estas son formas de captar la atención del usuario. De esta manera, puedes lograr huevos perfectos y usuarios felices y bien alimentados.
Para obtener la app de ejemplo, puedes hacer lo siguiente:
Clona el repositorio desde GitHub y cambia a la rama starter.
$ git clone https://github.com/googlecodelabs/android-kotlin-notifications
También puedes descargar el repositorio como un archivo ZIP, descomprimirlo y abrirlo en Android Studio.
- Abre y ejecuta la app en Android Studio.
Verás una imagen de un huevo y un menú desplegable con una lista de intervalos de tiempo predefinidos para cocinar un huevo. Haz clic en el triángulo del menú desplegable Huevo pasado por agua. La primera opción de la lista se proporciona con fines de prueba y configura la alarma en solo 10 segundos. Junto a la lista, hay un interruptor que inicia el temporizador de huevos. Puedes usar este interruptor para iniciar y detener el temporizador de huevos cuando quieras. El código de partida es completamente funcional, lo que significa que puedes configurar el temporizador de huevos y ver cómo hace la cuenta regresiva hasta 0. Una vez que finaliza el temporizador, se muestra un mensaje emergente, como se muestra a continuación.
- Inspecciona el código fuente. La app de inicio consta de una sola actividad llamada
MainActivity
. Hay tres paquetes secundarios llamadosreceiver
,ui
yutil
.
- /receiver: El paquete
receiver
contiene dos receptores de transmisiones llamadosAlarmReceiver
ySnoozeReceiver
.AlarmReceiver
se activa conAlarmManager
para enviar la notificación cuando finaliza el temporizador definido por el usuario.SnoozeReceiver
controla el clic del usuario para posponer la notificación. - /ui: Contiene el
EggTimerFragment
, que forma parte de la porción de la IU de la app.EggTimerViewModel
es responsable de iniciar y cancelar el temporizador, y de otras tareas de la app relacionadas con el ciclo de vida. - /util: En este paquete, hay dos archivos.
BindingUtils.kt
tiene adaptadores de vinculación para habilitar la vinculación de datos entre la IU de la app y el elementoViewModel
.NotificationUtils.kt
tiene métodos de extensión enNotificationManager
.
Usar notificaciones es una excelente manera de llamar la atención de los usuarios hacia tu app. Ya sea que tu app no se esté ejecutando o se esté ejecutando en primer plano, una notificación mostrará una ventana emergente en la parte superior de la pantalla y puede incluir sonido o vibración. Para crear una notificación, debes usar un compilador de notificaciones y proporcionar un texto de título, un texto de contenido y un ícono. Una vez que el compilador tiene todos los campos necesarios, NotificationManager
, que es un servicio del sistema, te ayuda a mostrar este contenido como una notificación. NotificationManager
es responsable de enviar una notificación, actualizar su contenido y cancelar la notificación. En los siguientes pasos, agregarás métodos de extensión a NotificationManager
. De esta manera, cada vez que necesites usar NotificationManager
, podrás usar estas funciones de extensión para lograr la funcionalidad que necesitas.
Paso 1: Crea una notificación básica
En esta tarea, crearás una notificación nueva, establecerás un mensaje para el usuario y enviarás la notificación.
- Abre la clase
NotificationUtils.kt
y buscaTODO: Step 1.1
. Encontrarás coincidencias en este codelab y en el código de la app. - Examina la función
sendNotification()
proporcionada. Extenderás esta función de extensión aNotificationManager
para enviar notificaciones.
//NotificationUtils.kt
// TODO: Step 1.1 extension function to send messages (GIVEN)
/**
* Builds and delivers a notification.
*
* @param messageBody, notification text.
* @param context, activity context.
*/
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
- Obtén una instancia del compilador de notificaciones, pasa el contexto de la app y un ID de canal. El ID del canal es un valor de cadena para el canal.
Los canales de notificaciones son una forma de agrupar las notificaciones. Al agrupar tipos de notificaciones similares, los desarrolladores y los usuarios pueden controlar todas las notificaciones del canal. Una vez que se crea un canal, se puede usar para enviar cualquier cantidad de notificaciones.
//NotificationUtils.kt
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
val builder = NotificationCompat.Builder(
applicationContext,
applicationContext.getString(R.string.egg_notification_channel_id)
)
- Establece el ícono de notificación para representar tu app, un título y el texto de contenido del mensaje que deseas mostrarle al usuario. En el codelab, verás más opciones para personalizar aún más tu notificación, pero esta es la cantidad mínima de datos que debes configurar para enviar una notificación.
//NotificationUtils.kt
// TODO: Step 1.3 set title, text and icon to builder
.setSmallIcon(R.drawable.cooked_egg)
.setContentTitle(applicationContext.getString(R.string.notification_title))
.setContentText(messageBody)
- A continuación, debes llamar a
notify()
con un ID único para tu notificación y con el objetoNotification
de tu compilador.
Este ID representa la instancia de notificación actual y es necesario para actualizar o cancelar esta notificación. Dado que tu app solo tendrá una notificación activa en un momento determinado, puedes usar el mismo ID para todas tus notificaciones. Ya se te proporcionó una constante para este propósito llamada NOTIFICATION_ID
en NotificationUtils.kt
. Ten en cuenta que puedes llamar a notify()
directamente, ya que realizas la llamada desde una función de extensión en la misma clase.
//NotificationUtils.kt
// TODO: Step 1.4 call notify to send the notification
// Deliver the notification
notify(NOTIFICATION_ID, builder.build())
- Abre
ui/EggTimerViewModel.kt
y busca la funciónstartTimer()
. Esta función crea una alarma con el intervalo de tiempo seleccionado cuando el usuario habilita el temporizador de huevos. - En esta función, activarás una notificación cuando el usuario inicie el temporizador. Para llamar a la función
sendNotification()
que implementaste anteriormente, necesitas una instancia deNotificationManager
.NotificationManager
es un servicio del sistema que proporciona todas las funciones expuestas para la API de Notifications, incluida la función de extensión que agregaste. Cada vez que quieras enviar, cancelar o actualizar una notificación, debes solicitar una instancia deNotificationManager
al sistema. Llama a la funciónsendNotification()|
con el mensaje de notificación y con el contexto.
// EggTimerViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager
// and call sendNotification
val notificationManager = ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.sendNotification(app.getString(R.string.timer_running), app)
Ya casi terminas. Sin embargo, si ejecutas la app ahora y configuras el temporizador, no recibirás una notificación.
- Abre
logcat
y busca"No Channel found"
. Deberías ver un mensaje de error que indica queegg_channel
no existe. En los siguientes pasos, obtendrás más información sobre los canales de notificaciones y solucionarás este problema.
Paso 2: Canales de notificación
A partir del nivel de API 26, todas las notificaciones deben asignarse a un canal. Si mantienes presionado el ícono del selector de apps, seleccionas la información de la app y presionas Notificaciones, verás una lista de los canales de notificaciones asociados a la app. Por el momento, la lista está vacía porque tu app no creó ningún canal.
Los canales representan un "tipo" de notificación. Por ejemplo, el temporizador de huevos puede enviar una notificación cuando el huevo esté cocido y también usar otro canal para enviar notificaciones diarias que te recuerden que comas huevos en el desayuno. Todas las notificaciones de un canal se agrupan, y los usuarios pueden configurar los parámetros de configuración de las notificaciones para todo el canal. Esto permite que los usuarios personalicen la configuración de notificaciones según el tipo de notificación que les interese. Por ejemplo, los usuarios pueden inhabilitar las notificaciones del desayuno, pero seguir viendo las notificaciones del temporizador.
Los desarrolladores establecen la configuración inicial, la importancia y el comportamiento que se aplicarán a todas las notificaciones de un canal. Después de establecer la configuración inicial, los usuarios pueden anularla.
En el paso 1.1, usaste egg_notification_channel_id
como tu canal de notificaciones, por lo que ahora debes crear y personalizar la configuración y el comportamiento de las notificaciones de este canal.
- Abre
EggTimerFragment.kt
y busca la funcióncreateChannel()
. - Pasa el ID de canal único al constructor de
NotificationChannel
. - Pasa el nombre del canal de notificación, que los usuarios también verán en la pantalla de Configuración.
- Como último parámetro, pasa el nivel de importancia del canal de notificación. Los niveles de importancia se tratarán más adelante en este codelab, por lo que, por ahora, puedes usar
NotificationManag
er.IMPORTANCE_LOW
. - En el objeto
notificationChannel
, estableceenableLights
como verdadero. Este parámetro de configuración habilitará las luces cuando se muestre una notificación. - En el objeto
notificationChannel
, establecelightColor
en rojo para mostrar una luz roja cuando se muestre una notificación. - En el objeto
notificationChannel
, estableceenableVibration
como verdadero para habilitar la vibración. - En el objeto
notificationChannel
, establece la descripción del canal en‘Time for breakf
ast". - Para obtener una instancia de
NotificationManager
, llama agetSystemService()
. - Llama a
createNotificationChannel()
enNotificationManager
y pasa el objetonotificationChannel
que creaste en el paso anterior.
//EggTimerFragment.kt
private fun createChannel(channelId: String, channelName: String) {
// TODO: Step 1.6 START create a channel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(
channelId,
channelName,
// TODO: Step 2.4 change importance
NotificationManager.IMPORTANCE_LOW
)
// TODO: Step 2.6 disable badges for this channel
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.RED
notificationChannel.enableVibration(true)
notificationChannel.description = "Time for breakfast"
val notificationManager = requireActivity().getSystemService(
NotificationManager::class.java
)
notificationManager.createNotificationChannel(notificationChannel)
}
// TODO: Step 1.6 END create channel
}
- A continuación, para crear un canal, debes llamar a la función
createChannel()
que acabas de escribir (paso 1.7). Esta función toma dos parámetros: el ID del canal y el nombre del canal. Debes buscar el ID y el nombre de tu canal en los recursos de cadena que ya se proporcionan en tu proyecto.
// EggTimerFragment.kt
// TODO: Step 1.7 call createChannel
createChannel(
getString(R.string.egg_notification_channel_id),
getString(R.string.egg_notification_channel_name)
)
- Debes pasar el ID del canal al compilador de notificaciones. Ya lo hiciste en el paso 1.2. Si se establece un valor incorrecto como ID del canal, la notificación fallará. Abre
NotificationUtils.kt
para verificar que el ID del canal que configuraste anteriormente sea correcto.
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
applicationContext,
// TODO: Step 1.8 verify the notification channel name
applicationContext.getString(R.string.egg_notification_channel_id)
)
- Ejecuta la app y verás que envía una notificación cada vez que inicias el temporizador.
- Desliza la barra de estado y observa que el título, el contenido y el ícono de la notificación son los que configuraste en los pasos anteriores.
- Para verificar el canal recién creado, cierra la app y busca el ícono de la app. Mantén presionado el ícono de la app y selecciona Información de la app.
- Selecciona Notificaciones en la lista de parámetros de configuración. Deberías ver un nuevo canal llamado Huevo justo debajo del parámetro de configuración Mostrar notificaciones.
Cuando ejecutes la app, ahora se mostrará la notificación. Tanto tú, como desarrollador de la app, como tus usuarios pueden personalizar la configuración y el comportamiento de todas las notificaciones que se envían en este canal. ¡Felicitaciones! Creaste una notificación.
Paso 3: Agrega notificaciones a tu app
Hasta ahora, se muestra el uso básico de la API de Notifications, pero enviar una notificación justo después de iniciar el temporizador no tiene mucho sentido. Es probable que los usuarios prefieran recibir una notificación cuando el huevo esté listo. En la siguiente parte del codelab, corregirás este problema y cambiarás el mensaje Toast por una notificación.
Ya enviaste la notificación y observaste cómo se muestra a los usuarios, pero este fue solo el primer paso para crear notificaciones excelentes. En este paso, cambiarás la notificación para que se envíe en un momento más adecuado.
Tu app usa AlarmManager
para configurar una alarma. El código relacionado con AlarmManager
ya se proporciona en el código de partida y se usa para mostrar el mensaje de notificación. AlarmManager
realiza un seguimiento de la selección de tiempo deseada y activará la función onReceive()
de AlarmReceiver.kt
cuando se acabe el tiempo. Si abres AlarmReceiver.kt
y navegas a onReceive()
, deberías ver el mensaje emergente que se muestra cada vez que configuras un temporizador de huevos.
- Abre
AlarmReceiver.kt
, una instancia deNotificationManager
, y llama a la funciónsendNotification()
con el texto del mensaje y los parámetros de contexto.
// AlarmReceiver.kt
// TODO: Step 1.9 add call to sendNotification
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.sendNotification(
context.getText(R.string.eggs_ready).toString(),
context
)
- De manera opcional, quita el mensaje emergente, ya que tu app enviará una notificación cuando se acabe el tiempo.
// AlarmReceiver.kt
// TODO: Step 1.10 [Optional] remove toast
// Toast.makeText(
// context,
// context.getText(R.string.eggs_ready),
// Toast.LENGTH_SHORT
// ).show()
- Ejecuta tu app . Deberías ver una notificación cada vez que inicies el temporizador y cada vez que se acabe el tiempo.
Esto no es ideal. No envíes demasiadas notificaciones a los usuarios. Puedes quitar la primera notificación que se envía cuando el usuario inicia el temporizador.
- Abre
EggTimerFragment.kt
y quita el código de notificación del paso 1.5.
// EggTimeViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager
// and call sendNotification
// val notificationManager = ContextCompat.getSystemService(
// app,
// NotificationManager::class.java
// ) as NotificationManager
// notificationManager.sendNotification(app.getString(R.string.eggs_ready), app)
- Vuelve a ejecutar tu app.
- Configura un temporizador, ponlo en segundo plano y espera a que termine el tiempo. Verás una notificación. Esta es una notificación mucho más útil.
Paso 4: Agrega una intención de contenido
- Vuelve a ejecutar la app si aún no se está ejecutando.
- Haz clic en la notificación. No pasa nada.
Mostrar la notificación e informar al usuario es excelente, pero cuando un usuario hace clic en una notificación, espera volver a la app correspondiente. En esta parte del codelab, agregarás un intent a tu notificación para que el usuario vuelva a la pantalla del temporizador.
Un Intent
es un objeto de mensajería que puedes usar para solicitar una acción de otro componente de la app. Los intents se pueden usar para iniciar una actividad, un servicio o entregar una emisión. En este caso, usas este intent para indicarle al sistema que abra MainActivity
cuando el usuario presione la notificación. Como tu app consta de una sola vista, no tienes muchas opciones aquí. Sin embargo, en una app más grande, la notificación debería crear una experiencia fluida llevando al usuario a una pantalla que tenga sentido cuando interactúe con la notificación.
- Abre
NotificationUtils.kt
y busca la función de extensiónsendNotification()
. - Crea un
Intent
con tuapplicationContext
y la actividad que se lanzará,MainActivity::class.java
.
// NotificationUtils.kt
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
// Create the content intent for the notification, which launches
// this activity
// TODO: Step 1.11 create intent
val contentIntent = Intent(applicationContext, MainActivity::class.java)
Creaste el intent, pero la notificación se muestra fuera de tu app. Para que un intent funcione fuera de tu app, debes crear un nuevo PendingIntent
.
PendingIntent
otorga derechos a otra aplicación o al sistema para realizar una operación en nombre de tu aplicación. Un PendingIntent
en sí es simplemente una referencia a un token que mantiene el sistema y que describe los datos originales que se usaron para recuperarlo. Esto significa que, incluso si se anula el proceso de la aplicación propietaria, el PendingIntent
en sí seguirá siendo utilizable desde otros procesos a los que se haya proporcionado. En este caso, el sistema usará el intent pendiente para abrir la app en tu nombre, independientemente de si la app de temporizador se está ejecutando o no.
- Crea un
PendingIntent
conapplicationContext
,NOTIFICATION_ID
, elcontentIntent
que creaste en el paso anterior y la marcaPendingIntent
. La marcaPendingIntent
especifica la opción para crear unPendingIntent
nuevo o usar uno existente. Debes establecerPendingIntent.FLAG_UPDATE_CURRENT
como la marca, ya que no quieres crear una notificación nueva si ya existe una. De esta manera, modificarás elPendingIntent
actual que está asociado con el intent que proporcionas.
// NotificationUtils.kt
// TODO: Step 1.12 create PendingIntent
val contentPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_ID,
contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
- Pasa el
PendingIntent
a tu notificación. Para ello, llama asetContentIntent()
enNotificationBuilder
. Ahora, cuando hagas clic en la notificación, se activaráPendingIntent
y se abrirá tuMainActivity
. - También establece
setAutoCancel()
entrue
para que, cuando el usuario presione la notificación, esta se descarte automáticamente mientras lo lleva a la app.
// NotificationUtils.kt
// TODO: Step 1.13 set content intent
.setContentIntent(contentPendingIntent)
.setAutoCancel(true)
- Vuelve a ejecutar la app.
- Establece un temporizador, pon la app en segundo plano y espera a que aparezca la notificación.
- Una vez que veas la notificación, haz clic en ella tirando hacia abajo de la barra de estado y observa cómo la app se abre en primer plano.
Paso 5: Cancela la notificación
Tienes un temporizador de huevos funcional con notificaciones, pero hay un pequeño problema. Si configuras el temporizador, recibes una notificación y vuelves a configurarlo, la notificación anterior permanecerá en la barra de estado mientras se ejecuta el nuevo temporizador. Esto puede confundir al usuario si la app está en segundo plano y puede provocar que los huevos queden poco cocidos.
Para solucionar este problema, debes borrar la notificación anterior cuando inicies un nuevo temporizador. Comienza por crear otra función de extensión en tu NotificationUtils.kt
. NotificationManager
tiene una API para cancelar todas las notificaciones activas llamada cancelAll
()
.
- Abre
NotificationsUtil.kt
. - Agrega una función de extensión en
NotificationManager
que llame acancelAll()
.
// NotificationUtils.kt
// TODO: Step 1.14 Cancel all notifications
/**
* Cancels all notifications.
*
*/
fun NotificationManager.cancelNotifications() {
cancelAll()
}
- Abre
EggTimerViewModel.kt
y navega a la funciónstartTimer()
. - Dentro de
startTimer()
, obtén una instancia deNotificationManager
del sistema y llama acancelNotifications()
.
// EggTimerViewModel.kt
//TODO Step 1.15 call cancel notification
val notificationManager =
ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelNotifications()
- Ejecuta la app y comienza el temporizador.
- Después de ver la notificación, vuelve a iniciar el temporizador y observa cómo nuestra app borra automáticamente la notificación anterior de la barra de estado.
El framework de notificaciones ofrece una variedad de opciones de personalización para que los desarrolladores establezcan acciones personalizadas y diseñen sus notificaciones según sea necesario. En esta tarea, aprenderás a personalizar las notificaciones del temporizador de huevos.
Paso 1: Aplica estilo a tu notificación
Si le aplicas un diseño a la notificación según tus necesidades y el contenido de la notificación, esta se destacará y se verá más como una extensión de tu aplicación. El framework de notificaciones incluye varios estilos integrados para ayudarte, y siempre puedes crear los tuyos.
NotificationCompat
ofrece estilos integrados para lo siguiente:
BigTextStyle
, que puede mostrar un bloque de texto grande, como el contenido de un correo electrónico cuando se expande.BigPictureStyle
, que muestra notificaciones de formato grande que incluyen un archivo adjunto de imagen grande.InboxStyle
, que muestra contenido de texto con estilo de conversación.MediaStyle
, que muestra los controles de reproducción de contenido multimediaMessagingStyle
, que muestra notificaciones de formato grande que incluyen varios mensajes entre cualquier cantidad de personas.
Puedes encontrar más información sobre otros estilos en la documentación de Cómo crear una notificación expandible. En este paso, usarás NotificationCompat.BigPictureStyle
para crear una notificación expandible que muestre una imagen grande de un huevo cuando se expanda.
- Abre
NotificationUtils.kt
y busca la funciónsendNotification()
. - Comienza por cargar una imagen desde
resources
conBitmapFactory
.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
- Crea un objeto
BigPictureStyle
nuevo y configura tu imagen. - Establece
bigLargeIcon()
ennull
para que el ícono grande desaparezca cuando se expanda la notificación.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
.bigPicture(eggImage)
.bigLargeIcon(null)
- Establece el estilo con
setStyle()
enbigPicStyle
. - Establece el ícono grande con
setLargeIcon()
eneggImage
, de modo que la imagen se muestre como un ícono más pequeño cuando se contraiga la notificación.
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
- Ejecuta la app y configura un temporizador. Cuando se muestra la notificación por primera vez, se encuentra en estado contraído en el panel de notificaciones. Si expandes la notificación, se mostrará una imagen grande en el área de notificación extendida.
Paso 2: Acciones de la notificación
Las acciones de notificación son otra personalización que puedes agregar a tus notificaciones. Actualmente, tus notificaciones redireccionan a tu app cuando los usuarios hacen clic en ellas. Además de esta acción de notificación predeterminada, puedes agregar botones de acción que ejecuten una tarea relacionada con la app desde la notificació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. 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 PendingIntent
a la función addAction()
en el compilador. Esto es similar a configurar la acción de toque predeterminada de la notificación llamando a setContentIntent()
, excepto que, en lugar de iniciar una actividad, puedes llevar a cabo una variedad de otras funciones, por ejemplo, iniciar un BroadcastReceiver
que realice un trabajo en segundo plano, de modo que la acción no interrumpa a la app que ya está abierta.
En este codelab, ya se te proporciona un BoadcastReceiver
llamado SnoozeReceiver
. Usarás SnoozeReceiver
para recibir el clic del usuario en la acción de notificación. En los siguientes pasos, agregarás código para posponer la notificación del temporizador de huevos durante 60 segundos cuando el usuario haga clic en el botón de acción para posponer. Cuando se hace clic en la acción de posponer, el SnoozeReceiver
recibirá una intención y creará una alarma nueva para enviar una notificación nueva después de 60 segundos.
- Abre
SnoozeReceiver.kt
. Esta clase es similar aAlarmReceiver
, que usaste antes. En los siguientes pasos, agregarás código que activará la funciónonReceive()
delSnoozeReceiver
. En resumen, el código enSnoozeReceiver
creará una alarma nueva para enviar una notificación nueva un minuto después. Desplázate hacia abajo hasta el final de la función onReceive, obtén una instancia de notificationManager del sistema y llama a cancelAll.
// SnoozeReceiver.kt
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelAll()
- Para usar
SnoozeReceiver
, abreNotificationUtils.kt
. - Crea un nuevo
Intent
snoozeIntent
para elSnoozeReceiver
justo después del diseño en la funciónsendNotification()
. - Crea un intent pendiente llamando al método
getBroadcast()
enPendingIntent
, que espera los parámetros en los siguientes pasos. El sistema usará estePendingIntent
para configurar una alarma nueva que publique una notificación nueva después de 60 s cuando el usuario presione el botón de posponer. - El primer parámetro es el contexto de la aplicación en el que este
PendingIntent
debería iniciar la actividad. - El segundo parámetro es el código de solicitud, que es el código de solicitud de este intent pendiente. Si necesitas actualizar o cancelar esta intención pendiente, debes usar este código para acceder a ella.
- A continuación, agrega el objeto
snoozeIntent
, que es el intent de la actividad que se iniciará. - Por último, agrega el valor de la marca
#FLAG_ONE_SHOT
, ya que la intención se usará solo una vez. La acción rápida y la notificación desaparecerán después del primer toque, por lo que la intención solo se puede usar una vez.
// NotificationUtils.kt
// TODO: Step 2.2 add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
applicationContext,
REQUEST_CODE,
snoozeIntent,
FLAGS
)
- A continuación, llama a la función
addAction()
en elnotificationBuilder
. Esta función espera un ícono y un texto para describir tu acción al usuario. También debes agregarsnoozeIntent
. Este intent se usará para activar elboadcastReceiver
correcto cuando se haga clic en tu acción.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
R.drawable.egg_icon,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
- Ejecuta la app de temporizador de huevos para probar la acción de posponer.
- Ejecuta el temporizador y pon la app en segundo plano. Una vez que se acabe el tiempo, expande la notificación y verás que ahora tiene un botón de acción para posponer el temporizador de huevos por un minuto más.
Paso 3: Importancia de la notificación
La importancia determina el nivel de interrupción visual y auditiva de la notificación para el usuario. Las notificaciones con mayor importancia interrumpirán más a los usuarios.
Debes especificar el nivel de importancia en el constructor NotificationChannel
. Originalmente, estableciste una importancia baja para la app de temporizador. Puedes usar uno de los cinco niveles de importancia, que van desde IMPORTANCE_NONE(0)
hasta IMPORTANCE_HIGH(4)
. El nivel de importancia que asignas a un canal se aplica a todos los mensajes de notificaciones que publicas en este.
Niveles de importancia del canal
Nivel de importancia visible para el usuario | Importancia (Android 8.0 y versiones posteriores) | Prioridad (Android 7.1 y versiones anteriores) |
Emite un sonido y aparece como una notificación emergente (aparece en la parte superior de la pantalla) | ||
Emite un sonido | ||
Sin sonido | ||
No emite sonido ni aparece en la barra de estado |
Para obtener información sobre cómo elegir un nivel de prioridad adecuado, consulta la sección "Niveles de prioridad" en la Guía de diseño de notificaciones. Debes tener cuidado al seleccionar un nivel de importancia para las notificaciones de tu app. La importancia del canal se debe elegir teniendo en cuenta el tiempo y la atención del usuario. Cuando una notificación poco importante se disfraza de urgente, puede generar una alarma innecesaria y distraer. Los usuarios tienen control total sobre el nivel de importancia de sus notificaciones, por lo que, si creas una notificación molesta, pueden desactivar por completo tu canal de notificaciones.
Cuando creaste la notificación por primera vez en el paso 1.6, el temporizador de huevos se configuró para enviar notificaciones con prioridad baja, ya que se diseñó para no molestar al usuario con notificaciones. Sin embargo, puede ser una buena idea llamar la atención del usuario antes de que el huevo se cocine demasiado. Para cambiar el nivel de importancia de la notificación, comienza con la configuración del canal. La importancia del canal afecta el nivel de interrupción de todas las notificaciones publicadas en el canal y debe especificarse en el constructor NotificationChannel
.
- Para cambiar el nivel de importancia del canal de notificación de tu app, abre
EggTimerFragment.kt
y navega acreateChannel()
. Cambia el nivel de importancia deIMPORTANCE_LOW
aIMPORTANCE_HIGH
.
// EggTimerFragment.kt
val notificationChannel = NotificationChannel(
channelId,
channelName,
// TODO: Step 2.4 change importance
NotificationManager.IMPORTANCE_HIGH
)
Para admitir dispositivos con Android 7.1 (nivel de API 25) o inferior, también debes llamar a setPriority()
para cada notificación, utilizando una constante de prioridad de la clase NotificationCompat
.
- Abre
NotificationUtils.kt
y agrega lo siguiente al objeto compilador de notificaciones.
// NotificationUtils.kt
.addAction(
R.drawable.common_google_signin_btn_icon_dark,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
// TODO: Step 2.5 set priority
.setPriority(NotificationCompat.PRIORITY_HIGH)
- Antes de ejecutar la app, mantén presionado el ícono de la app en tu dispositivo o emulador y selecciona desinstalar para borrar la configuración anterior del canal. Si no desinstalas la app, no se cambiará la configuración de prioridad del canal y no se producirá ningún cambio de comportamiento cuando se publique la notificación.
- Ahora, vuelve a ejecutar la app y, luego, inicia el temporizador. Esta vez, cuando se entregue la notificación, deberías ver una ventana emergente en la parte superior de la pantalla, independientemente de si tu app se ejecuta en primer plano o en segundo plano.
Paso 4: Insignias de notificación
Las insignias de notificación son pequeños puntos que aparecen en el ícono del selector de la app asociada cuando esta tiene una notificación activa. Los usuarios pueden mantener presionado el ícono de la app para mostrar las notificaciones.
Estos puntos, llamados insignias, aparecen de forma predeterminada, y tu app no necesita realizar ninguna acción. Sin embargo, es posible que en algunas situaciones no tenga sentido incluir insignias en las notificaciones, por lo que puedes inhabilitarlas en cada canal. Para ello, llama a setShowBadge(false)
en tu objeto NotificationChannel
. Dado que el temporizador de huevos solo tiene una notificación activa en un momento determinado, la insignia en el ícono de la app no ofrece muchos beneficios para los usuarios. En los siguientes pasos, inhabilitarás la insignia y solo mostrarás una notificación para el temporizador de huevos.
- Agrega
setShowBadge(false)
al código de creación del canal del temporizador de huevos para inhabilitar las insignias.
// EggTimerFragment.kt
).apply {
// TODO: Step 2.6 disable badges for this channel
setShowBadge(false)
}
- Vuelve a ejecutar la app, inicia el temporizador y observa el ícono de la app. No deberías ver insignias en el ícono de la app.
El código de la solución se encuentra en la rama principal del código que descargaste.
- Usa la clase NotificationManager para crear, enviar, actualizar y cancelar una notificación.
- Usa un objeto NotificationChannel con el método createNotificationChannel para establecer un canal para la notificación.
- Usa addAction() para agregar acciones rápidas a una notificación.
- Usa setShowBadge() para habilitar o inhabilitar insignias.
- Asigna un estilo a tus notificaciones con estilos que se extiendan desde Notification.Style.
- Establece el nivel de importancia con NotificationChannel.setImportance()
Curso de Udacity:
Documentación para desarrolladores de Android:
Para obtener vínculos a otros codelabs de este curso, consulta la página de destino de los codelabs de Aspectos avanzados de Android en Kotlin.