En este tutorial verás cómo configurar notificaciones en Android para modificar el nivel de intrusión y sonoridad, que el sistema operativo les da a la hora de comunicar los eventos de tu App.
Concretamente verás ejemplos para:
- Personalizar canales de notificaciones
- Establecer categorías de notificaciones
- Modificar la prioridad de una notificación
- Cambiar la visibilidad de una notificación
Nota: Este tutorial hace parte de la guía de notificaciones en Android, por lo que asumiré que leíste las partes anteriores. Si no es así, entonces puedes leer Crear Notificaciones y Manejar Interacciones.
Ejemplo De Configurar Notificaciones En Android
El código final de este ejemplo lo encontrarás en un nuevo módulo llamado P3_Configuracion, creado al interior de nuestro proyecto Android Studio actual. Puedes descargar el código desde el siguiente enlace:
Nuestro objetivo será ver el efecto que tiene el cambiar varias propiedades de nuestra notificación actual y ver qué efecto tiene en el sistema.
Comencemos por la configuración de los canales.
Canales De Notificaciones
Los canales son un mecanismo introducido en Android 8.0, para permitir al usuario controlar qué tan invasivas son las notificaciones de sus Apps.
Al crear un canal, puedes ver su existencia en la pantalla de configuración para canales de tu App.
Como notas, aparece un Switch para activar/desactivar la llegada de notificaciones que pertenezcan a nuestro canal Notificación Básica.
Crear Un Canal De Notificaciones
Como vimos en el tutorial de creación de notificaciones, es obligatorio tener un canal para publicar las notificaciones desde el nivel de API 26.
El proceso de creación se compone de:
- Crear un objeto de la clase
NotificationChannel
con un identificador y el nombre que verá el usuario en la pantalla de ajustes - Asignar valores a los atributos adicionales que desees modificar como: descripción, patrón de vibración, activación de luces, etc.
- Registrar el canal de notificaciones a través del método
NotificationManagerCompat.createNotificationChannel()
Con esto en mente traslademos el código createNotificationChannel()
de MainActivity
hacia un objeto compañero de utilidad en un nuevo archivo NotificationUtils.kt
:
object NotificationUtil {
lateinit var CHANNEL_ID: String
fun createChannel(
context: Context,
importance: Int,
name: String,
description: String
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CHANNEL_ID = context.resources.getString(R.string.basic_channel_id)
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
enableLights(true)
enableVibration(true)
this.description = description
lightColor = Color.BLUE
vibrationPattern = longArrayOf(0, 500, 500, 500, 500)
}
val nm: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
nm.createNotificationChannel(channel)
}
}
}
Este método createChannel()
:
- Recibe como parámetros el contexto, la importancia, el nombre y la descripción del canal
- Crea un objeto del tipo
NotificationChannel
con las propiedades previas y setea aquellas que no hagan parte del constructor con la funciónapply()
.enableLights()
: Determina si el dispositivo debe mostrar luces asociadas a las notificaciones de este canal. Claro está, si el dispositivo soporta esta característicaenableVibration()
: Habilita la vibración del dispositivo al producir una notificación en el canallightColor
: El color de la luz de notificaciónvibrationPattern
: El patrón de vibración establecido por un arreglo de duraciones en milisegundos. El primer valor representa un retraso de vibración, el segundo la vibración y así consecutivamente.
- Crea en el sistema el canal a través del
NotificationManager
Cambiar Nivel De Importancia
La importancia de un canal de notificaciones determina el nivel de interrupción con el que se alertará al usuario. Para determinarla, usaremos los siguientes valores constantes que personalicen el efecto en el sistema cuando se despliega una notificación:
Importancia | Constante | Efecto |
---|---|---|
Urgente | IMPORTANCE_HIGH | La notificación produce un sonido y se muestra como un aviso en la parte superior de la pantalla |
Alta | IMPORTANCE_DEFAULT | La notificación produce un sonido |
Media | IMPORTANCE_LOW | La notificación no produce sonido |
Baja | IMPORTANCE_MIN | La notificación no produce sonido y tampoco aparece en la barra de estado |
Para el caso de IMPORTANCE_HIGH
, se produce un estilo de notificación llamada heads-up notification con la siguiente apariencia:
Y para IMPORTANCE_MIN
verás que al desplegar el cajón de notificaciones aparecerá minimizada al final:
Ahora bien, el usuario puede modificar la importancia si hace click en el canal Notificación Básica:
Las preferencias que aparecen en el detalle del canal equivalen a las cuatro constantes mencionadas:
Predeterminada -> IMPORTANCE_DEFAULT
Silencio -> IMPORTANCE_LOW
Minimizar -> IMPORTANCE_MIN
Mostrar en la pantalla -> IMPORTANCE_HIGH
Persistencia De Canales
Una vez creado el canal con una de las anteriores constantes, no es posible cambiarle la importancia en tiempo de ejecución. Solo el usuario será capaz de modificar la importancia desde la pantalla de configuración.
Por lo que si actualizas la importancia desde Kotlin y luego corres el proyecto en Android Studio, no se producirá el cambio, ya que el canal fue creado en las preferencias de notificaciones.
Prioridad De Una Notificación
Al construir una notificación con la clase NotificationCompat.Builder
puedes establecer su prioridad con el método setPriority()
.
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
//..
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
//..
.build()
La prioridad es el equivalente a la importancia de un canal de notificaciones, pero la usaremos para sostener la compatibilidad con versiones del SDK igual o menores a 25 (Android 7.1).
Como ves, existen constantes con el estilo PRIORITY_*
para establecer los niveles de intrusión. Es más, podemos realizar una correspondencia con la importancia como vemos en la siguiente tabla:
Importancia | Prioridad |
---|---|
IMPORTANCE_HIGH | PRIORITY_HIGH o PRIORITY_MAX |
IMPORTANCE_DEFAULT |
|
IMPORTANCE_LOW | PRIORITY_LOW |
IMPORTANCE_MIN | PRIORITY_MIN |
Visibilidad De Una Notificación
Recuerda que las notificaciones pueden verse desde la pantalla de bloqueo del usuario, con el fin de permitirle estar al tanto de los avisos de aquellas Apps cuyos eventos le interesen.
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
//..
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
//..
.build()
Puesto que la notificación puede revelar contenido sensible, el framework te permite controlar la rigurosidad con la que revelas información a partir del método setVisibility()
.
Este método recibe como argumento tres posibles valores representados por constantes con el nombre VISIBILITY_*
. El primero de ellos es VISIBILITY_PUBLIC
, el cual muestra todo el contenido de la notificación:
El segundo es VISIBILITY_PRIVATE
, que solo expone el icono pequeño de la cabecera y el título del área de contenido:
Y la tercera es VISIBILITY_SECRET
que evitará mostrar cualquier elemento de la notificación en la pantalla de bloqueo.
Personalizar Versión Pública
En el caso que desees usar una visibilidad privada, pero requieras evitar la exposición cuando el usuario cambie la visibilidad a pública en un contexto inseguro, es posible proveer una versión pública alterna para la notificación con setPublicVersion()
:
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
//..
.setPublicVersion(NotificationUtil.createPublicNotification(this))
.build()
En nuestro caso agregaremos otro método de utilidad para producir la versión pública así:
object NotificationUtil {
//..
fun createPublicNotification(context: Context): Notification {
return NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_circle_notifications)
.setContentTitle("Nuevo tutorial publicado")
.setSubText("Develou.com")
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
.build()
}
}
El ejemplo anterior construye una nueva notificación que usa un título genérico para avisar al usuario que existe un nuevo tutorial, pero no expone ningún otro detalle:
Visibilidad En Pantalla De Ajustes
El usuario puede modificar la visibilidad general de notificaciones en la lock screen desde los ajustes. Este debe ir a Ajustes > Apps y notificaciones > Notificaciones > Notificaciones de ajustes de las notificaciones de tu App y seleccionar el perfil:
Además si activas la opción Notificaciones confidenciales se intercambiará al modo público. Esto significa que al final, el usuario será el encargado de establecer las condiciones de visibilidad.
Esta característica se activa si tenemos un modo de protección en la pantalla de bloqueo como lo es el PIN. Inclusive, cuando añades este mecanismo, se te permite elegir de inmediato la restricción del contenido sensible:
Aunque también es posible realizar la modificación de visibilidad desde el detalle del canal de la notificación con la opción Pantalla de bloqueo:
Categorías Para Notificaciones
Las categorías de notificaciones le permiten a Android decidir que acciones específicas tomar al filtrar y clasificar notificaciones. Además de establecer si una notificación debe ser despachada aunque el usuario tenga activo el modo No interrumpir (No molestar).
Asigna un valor de categoría con el método setCategory()
en la construcción de la notificación:
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
//..
.setCategory(NotificationCompat.CATEGORY_RECOMMENDATION)
.build()
La siguiente es una tabla con varias posibles constantes para categorías y la descripción del tipo de notificación:
Categoría | Descripción |
---|---|
CATEGORY_ALARM | Alarma o temporizador |
CATEGORY_CALL | Llamada entrante |
CATEGORY_EMAIL | Mensaje asincrónico como un email |
CATEGORY_ERROR | Error en una operación de segundo plano o en una autenticación |
CATEGORY_EVENT | Evento de calendario |
CATEGORY_MESSAGE | Mensaje entrante (SMS, chats, etc.) |
CATEGORY_PROGRESS | Progreso de una operación larga de segundo plano |
CATEGORY_PROMO | Promoción o anuncio |
CATEGORY_RECOMMENDATION | Recomendación especifica y oportuna del contenido en la App como la publicación de un nuevo artículo |
CATEGORY_REMINDER | Recordatorio programado por el usuario |
CATEGORY_SERVICE | Indicación de que está corriendo un servicio en segundo plano |
CATEGORY_SOCIAL | Actualización de redes sociales o compartición de datos |
CATEGORY_STATUS | Información sobre el estado del dispositivo |
Como ves, para nuestra notificación sobre la publicación de un nuevo tutorial usaremos CATEGORY_RECOMMENDATION
con el objetivo de que Android tome las acciones necesarias para este tipo de contenido.
Modo No Interrumpir
Desde Android 5.0 se introdujo el modo No interrumpir en los dispositivos, con el objetivo de permitir al usuario desactivar el sonido y vibración de todas las notificaciones. Puedes encontrarlo en Ajustes > Notificaciones > No interrumpir o desplegando el cajón de notificaciones.
Y es aquí donde entran las categorías de notificaciones que vimos anteriormente, ya que la interfaz de la pantalla de configuración de este modo te permite personalizar qué clase de notificaciones son permitidas en el modo No interrumpir.
Puedes encontrar las categorías divididas en tres opciones en la sección PUEDEN SUSPENDER LA FUNCIÓN NO INTERRUMPIR:
- Personas: Permite personalizar qué conversaciones, llamadas y mensajes son la excepción al modo
- Apps: Aquí puedes agregar las Apps que serán excepción
- Alarmas y otras interrupciones: Configura las alarmas, sonidos multimedia, sonidos de teclas y botones, recordatorios y eventos de calendario
Si deseamos que nuestra App de ejemplo no sea omitida en el modo de No molestar, entonces podemos incluirla desde la opción Apps de esta forma:
Incluso es posible añadir los canales individuales de la App que serán excluidos del modo.
Otra forma de hacerlo es ir directamente del detalle del canal de la notificación y seleccionar Opciones Avanzadas > Anular No interrumpir:
Plantillas De Notificaciones
En este tutorial aprendiste a configurar el canal, prioridad, visibilidad y categoría de una notificación con el fin de personalizar su comportamiento en el sistema.
Avanzando en el tema, continuaremos con el uso de clases de estilo de notificaciones (todo) que nos proporcionan plantillas prediseñadas, para presentar patrones de información como progresos, reproductores de música, mensajes de chat, etc.