Configurar Notificaciones En Android

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:

  1. Crear un objeto de la clase NotificationChannel con un identificador y el nombre que verá el usuario en la pantalla de ajustes
  2. Asignar valores a los atributos adicionales que desees modificar como: descripción, patrón de vibración, activación de luces, etc.
  3. 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():

  1. Recibe como parámetros el contexto, la importancia, el nombre y la descripción del canal
  2. Crea un objeto del tipo NotificationChannel con las propiedades previas y setea aquellas que no hagan parte del constructor con la función apply().
    1. enableLights(): Determina si el dispositivo debe mostrar luces asociadas a las notificaciones de este canal. Claro está, si el dispositivo soporta esta característica
    2. enableVibration(): Habilita la vibración del dispositivo al producir una notificación en el canal
    3. lightColor: El color de la luz de notificación
    4. vibrationPattern: 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.
  3. 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:

ImportanciaConstanteEfecto
UrgenteIMPORTANCE_HIGHLa notificación produce un sonido y se muestra como un aviso en la parte superior de la pantalla
AltaIMPORTANCE_DEFAULTLa notificación produce un sonido
MediaIMPORTANCE_LOWLa notificación no produce sonido
BajaIMPORTANCE_MINLa 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:

Importancia de notificaciones en Android

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:

ImportanciaPrioridad
IMPORTANCE_HIGHPRIORITY_HIGH o PRIORITY_MAX
IMPORTANCE_DEFAULTPRIORITY_DEFAULT
IMPORTANCE_LOWPRIORITY_LOW
IMPORTANCE_MINPRIORITY_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:

Notificaciones en la lock screen

El segundo es VISIBILITY_PRIVATE, que solo expone el icono pequeño de la cabecera y el título del área de contenido:

Visibilidad VISIBILITY_PRIVATE de notificación

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:

Método setPublicVersion() en Notificación

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:

Notificaciones en la pantalla de bloqueo de Android

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:

Pantalla de bloqueo con PIN

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

Modo no interrumpir en Android

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íaDescripción
CATEGORY_ALARMAlarma o temporizador
CATEGORY_CALLLlamada entrante
CATEGORY_EMAILMensaje asincrónico como un email
CATEGORY_ERRORError en una operación de segundo plano o en una autenticación
CATEGORY_EVENTEvento de calendario
CATEGORY_MESSAGEMensaje entrante (SMS, chats, etc.)
CATEGORY_PROGRESSProgreso de una operación larga de segundo plano
CATEGORY_PROMOPromoción o anuncio
CATEGORY_RECOMMENDATIONRecomendación especifica y oportuna del contenido en la App como la publicación de un nuevo artículo
CATEGORY_REMINDERRecordatorio programado por el usuario
CATEGORY_SERVICEIndicación de que está corriendo un servicio en segundo plano
CATEGORY_SOCIALActualización de redes sociales o compartición de datos
CATEGORY_STATUSInformació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.


Más Contenidos Android

Únete Al Discord De Develou

Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!