Notificaciones Android – Básicos y acción

Anteriormente en otros artículos hemos visto como notificar al usuario los procesos que está llevando o ha llevado a cabo nuestra aplicación. Esto podemos hacerlo mediante avisos Toast, o su hermano mayor el SnackBar. Se utilizan para mostrar mensajes cortos y concisos a modo informativo cuando realizamos según que acciones dentro de una app. Digo a modo informativo ya que este tipo de avisos aparecen durante unos segundos y luego desaparecen sin necesidad que el usuario pulse en ellos. Hoy veremos cómo crear notificaciones Android de una forma rápida y sencilla.

Notificación Android SnackBar

Snackbar

Notificación Android Toast

Toast

Buscando la atención del usuario

En bastantes casos se puede necesitar notificar al usuario esperando una  acción por su parte e interactuar con la aplicación que la ha lanzado. Para ello Android cuenta con la barra de estado, en la que se muestran una serie de notificaciones cuando se produce algún evento en la app y por ende, nosotros tenemos que reaccionamos a él. Es el caso de la notificación que salta cuando recibimos un nuevo mail, una llamada perdida, un mensaje de whatsapp o telegram, cuando descargamos un archivo… Hay miles de casos! La gran mayoría de aplicaciones crean notificaciones en la barra de estado para llamar nuestra atención.

Ejemplo notificacion Android

Notificaciones Android: Big View Style

Una notificación nos informa sobre la hora en la que se ha producido, nos muestra un pequeño icono de la aplicación que la lanza, un título y un texto descriptivo. En los siguientes artículos veremos que no siempre es así, este tipo de notificaciones son básicas y algo antiguas, conforme Android fue madurando se le fueron añadiendo mejoras a las notificaciones, por ejemplo una de ellas es el llamado Big View Style que se implementó en Android 4.1, este permite mostrar una notificación con posibilidad de expandirla para que muestre una descripción mas larga o una imagen, además permite incluir botones de acción en la propia notificación que nos darán la posibilidad de realizar cierta acción sin necesidad de abrir la app, ahorrándole al usuario final cierto tiempo.

Notificacion Android Big View Extendida

Notificacion Big View Extendida

Notificacion Android Big View Simple

Notificacion Big View Simple

Las imágenes de arriba corresponden a Android 7.0 Nougat

Notificaciones Android: Head’s Up

Otra de las novedades fueron las notificaciones tipo Head’s-Up. Esta funcionalidad que se implementó en Android 5.0 permite mostrar las notificaciones completas en la parte superior de la pantalla independientemente de la app que tengamos abierta. Están pensadas para poder ver las notificaciones cuando nos encontramos en una app con formato pantalla completa (donde normalmente no vemos la barra de estado) o cuando se define una notificación con prioridad alta (más adelante lo entenderéis). Las imágenes superiores de ‘Notificación Big View’ son un ejemplo de las notificaciones Head’s Up.

Dedos al teclado!

En esta primera parte sobre notificaciones Android veremos una app a modo de ejemplo que nos permita entender como lanzar una notificación simple, una extendida y una con el modo Head’s Up.

El escenario que vamos a reproducir es el siguiente:

Imaginamos que una aplicación se acaba de actualizar a la nueva versión disponible y esta nos avisa que tenemos que volver a iniciar sesión. Para ello, aparte de nuestra actividad principal, crearemos otra actividad tipo (Login Activity) en la que no realizaremos ningún cambio en su código, simplemente la dejaremos tal cual para que se muestre en nuestro ejemplo. Esta pantilla de LoginActivity ya viene con un layout predefinido con 2 entradas de texto para usuario y contraseña (aunque poco hablaremos de ella en este ejemplo). Para crear la Actividad basta con ir al menú «File > New > Activity > Login Activity» de Android Studio.

Nuestra interfaz de usuario la basaremos en 2 simples botones que nos permitan lanzar los diferentes tipos de notificaciones. En los siguientes artículos iremos extendiendo esta interfaz añadiendo más botones que nos muestren más estilos de notificaciones que iremos viendo.

Layout de ejemplo para notificaciones Android

Nuestro contenido del archivo XML activity_main.xml corresponde al siguiente :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="es.mscdroidlabs.mscnotificaciones.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:text="Crear notificacion"
        android:id="@+id/textView" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Estándar"
        android:id="@+id/btn_estandar"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Estilo Big View"
        android:id="@+id/btn_big_view"
        android:layout_below="@+id/btn_estandar"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />


</RelativeLayout>

-«¡Ya tenemos nuestra interfaz de usuario definida!»

Ahora pasamos al archivo MainActivity.java en el que declararemos los botones y asignaremos las correspondientes funciones. Seguidamente comentaremos linea por linea el código de los métodos que se encargaran de preparar la notificación y mostrarla. (CrearNotificacion(); y CrearNotificacionBigView(); en lineas 44 y 90 respectivamente),

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //Constantes para la identificacion de las notificaciones
    private final int idNotificacion_basica = 001;
    private final int idNotificacion_big_view = 002;

    //UI
    private Button btn_estandar;
    private Button btn_big_view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Definimos botones y asociamos el evento on clic que implementa nuestra activity
        btn_estandar = (Button)findViewById(R.id.btn_estandar);
        btn_estandar.setOnClickListener(this);

        btn_big_view = (Button)findViewById(R.id.btn_big_view);
        btn_big_view.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        //Dependiendo del boton pulsado realizaremos una acción u otra.
        switch (v.getId()){
            case R.id.btn_estandar:
                CrearNotificacion();

                break;

            case R.id.btn_big_view:
                CrearNotificacionBigView();

                break;

        }
    }



    private void CrearNotificacion() {

        try{
            NotificationCompat.Builder NotiBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.logo_hecta)
                            .setContentTitle("Aplicación actualizada")
                            .setContentText("Vuelve a iniciar sesión")
                            .setPriority(Notification.PRIORITY_HIGH)
                            .setDefaults(Notification.DEFAULT_ALL)//Requiere permisos de Vibración.
                            .setAutoCancel(true);


            //Creamos un nuevo Intent que contiene la clase/Actividad a abrir
            Intent intentFinal = new Intent(this, LoginActivity.class);

            //Definimos la nueva actividad como nueva tarea
            intentFinal.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_CLEAR_TASK);

            //Encapsulamos el intenFinal anteriormente creado dentro de un nuevo PendingIntent.
            PendingIntent resultPendingIntent = PendingIntent.getActivity(
                                        this,
                                        0,
                                        intentFinal,
                                        PendingIntent.FLAG_UPDATE_CURRENT
                    );


            //Añadimos el contenido del Intent al NotificactionCompat.Builder
            NotiBuilder.setContentIntent(resultPendingIntent);

            //Obtenemos una instancia del servicio de NotificactionManager
            NotificationManager mNotifyMgr =
                    (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

            //Creamos y mostramos la notificación
            mNotifyMgr.notify(idNotificacion_basica, NotiBuilder.build());


        }catch (Exception e){
            Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
        }
    }


    private void CrearNotificacionBigView() {


        //Creamos los Intents y correspondientes PendingIntents que responderan a los botones que aparecen en la notificación.
        Intent _intentAbrir = new Intent(this, MainActivity.class);
        PendingIntent _pendingAbrir = PendingIntent.getActivity(this, 0, _intentAbrir, 0);

        Intent _intentIniciar = new Intent(this, LoginActivity.class);
        PendingIntent _pendingIniciar = PendingIntent.getActivity(this, 0, _intentIniciar, 0);

       
        NotificationCompat.Action accion_abrir = new NotificationCompat.Action.Builder(android.R.drawable.ic_menu_delete, "Abrir App", _pendingAbrir).build();
        NotificationCompat.Action accion_iniciar = new NotificationCompat.Action.Builder(android.R.drawable.ic_menu_edit, "Iniciar Sesión", _pendingIniciar).build();


        /*
            En este caso, omitiremos el intent principal que se lanza al pulsar sobre la notificacion,
                    dejando así solo las acciones añadidas

            //Definimos el intent para la acción principal
            Intent intentFinal = new Intent(this, LoginActivity.class);

            //Definimos la nueva actividad como nueva tarea
            intentFinal.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_CLEAR_TASK);


            //Encapsulamos el intenFinal anteriormente creado dentro de un nuevo PendingIntent.
            PendingIntent resultPendingIntent = PendingIntent.getActivity(
                    this,
                    0,
                    intentFinal,
                    PendingIntent.FLAG_UPDATE_CURRENT
            );
        */
        try{
            Notification NotiBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.logo_hecta)
                            .setContentTitle("Aplicación actualizada")
                            .setContentText("Vuelve a iniciar sesión")
                            .setPriority(Notification.PRIORITY_HIGH)
                            .setDefaults(Notification.DEFAULT_ALL)//Requiere permisos de Vibración.
//                            .setContentIntent(resultPendingIntent)



                            //Métodos exclusivos para definir una notificacion como Big View.
                            .setStyle(new NotificationCompat.BigTextStyle()
                                    .bigText("La aplicación se ha actualizado a una nueva versión, es necesario que vuelvas a iniciar sesión."))
                            .addAction (accion_abrir)
                            .addAction (accion_iniciar).build();


            //Obtenemos una instancia del servicio de NotificactionManager
            NotificationManager mNotifyMgr =
                    (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

            //Creamos y mostramos la notificación
            mNotifyMgr.notify(idNotificacion_big_view, NotiBuilder);


        }catch (Exception e){
            Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
        }
    }
}

Como podéis ver, entre las lineas 17 y 21 declaramos los botones y escuhamos el evento onClick en el listener que implementa la actividad (linea 25 a 40, luego comprobamos con un switch() (linea 28) qué botón se pulsa, en función del que pulsemos derivamos a un método u otro.

La funcion CrearNotificacion() se encargará de mostrar una notificación simple, sin botones.

Ejemplo notificaciones android

Empezamos por la linea 47, NotificationCompat.Builder, es el objeto que contiene la notificación en sí misma, a este le pasamos el contexto como parámetro, seguidamente editamos las opciones básicas:

1.setSmalIcon(id): Es el icono que aparecera junto a la notificación. En este caso referencia a un recurso situado en la carpeta drawable.

2.setContenTitle(String): Es el texto que corresponde al título de la notificación. «Aplicación actualizada»

3.setContentText(String): Es el texto que corresponde al contenido de la notificación «Vuelve a iniciar sesión»

4.setPriority(int): Establecemos una prioridad a la notificación, tenemos posibles valores a escoger:

4.1.Notification.PRIORITY_HIGH

4.2.Notification.PRIORITY_LOW

4.3.Notification.PRIORITY_DEFAULT 

4.5.Notification.PRIORITY_MIN

4.6.Notification.PRIORITY_MAX

Os preguntaréis por qué he utilizado PRIORITY_HIGH, os acordáis que más arriba hemos comentado las notificaciones Head’s up? Bien, sí ejecutáis el código en Android 5 o superior toda notificación con prioridad ‘High‘ aparecerá en primer plano, da igual si estamos en el escritorio o dentro de alguna aplicación. Si no queréis que aparezca la notificación en modo Head’s Up, basta con que quitéis esta línea.

5.setDefaults(int): Esta opción nos permitirá escoger si queremos que nuestra notificación vaya acompañada de una vibración, un sonido, o luz indicadora del dispositivo. Las posibles opciones son:

DEFAULT_SOUND     Solo se reproducirá un sonido, por defecto el que este seleccionado en el sistema.

DEFAULT_VIBRATE  Solo hará vibrar el dispositivo.

DEFAULT_LIGHTS   Solo se iluminará el led indicador del dispositivo.

DEFAULT_ALL         Se aplicarán todas las anteriores. Hay que aclarar que tanto si utilizamos DEFAULT_ALL como DEFAULT_VIBRATE, tendremos que declarar los permisos en el archivo manifest.

<uses-permission android:name="android.permission.VIBRATE" />

6.setAutoCancel(boolean): Con valor «true» sirve para cancelar la notificación automáticamente una vez la pulsamos. Si este valor no está definido o está con valor «false» la aplicación quedará en la barra hasta que la descartemos manualmente deslizandola hacia algún lado o hasta que alguna de nuestras clases la elimine. Más adelante veremos como cancelar y modificar una notificación mostrada.

En la línea 58 creamos un nuevo Intent() con el activity que queramos que se abra cuando pulsemos la notificación, en este caso LoginActivity.class, seguidamente definiremos el Intent con .setFlags(), pasándole los valores FLAG_ACTIVITY_NEW_TASK   para que la actividad creada se ejecute al principio de una nueva tarea y FLAG_ACTIVITY_CLEAR_TASK  para que la tarea se limpie antes de ejecutar la nueva actividad.

Línea 65:

PendingIntent resultPendingIntent = PendingIntent.getActivity(
                                        this,
                                        0,
                                        intentFinal,
                                        PendingIntent.FLAG_UPDATE_CURRENT
                    );

Creamos un nuevo PendingIntent que más adelante incluiremos en la notificación a partir de .getActivity, pasándole como parámetros :

1.Context: Contexto de la actividad.

2.RequestCode | int: Un numero entero para identificar y controlar el inicio de la actividad. No utilizado en este caso.

3.Intent: El intent que hemos creado anteriormente.

4. PendingIntent.FLAG_UPDATE_CURRENT | int: Se define esta opción para las notificaciones ya que nos permite cambiar solo el contenido del PendingIntent si necesidad de que este vuelva a crearse si ya existe.

Línea 74:

NotiBuilder.setContentIntent(resultPendingIntent);

Añadimos el PendingIntent creado anteriormente al NotificationCompat.Builder con .setContentIntent(PendingIntent);

Línea 77:

NotificationManager mNotifyMgr =
                    (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

Declaramos e instaciamos un objeto NotificationManager con el que obtenemos el servicio de Notificaciones del sistema, necesario si queremos mostrar alguna notificación.

Línea 81:

mNotifyMgr.notify(idNotificacion_basica, NotiBuilder.build());

Lanzamos nuestra notificación con .notify( int , NotificationCompat.Builder.build() ). El valor int «idNotificacion_basica» corresponde a ‘001‘, es una variable definida al principio de la clase. Se le asigna un int a la notificación para identificarla en otras partes del código, por si queremos actualizarla o eliminarla. El siguiente objeto «NotiBuilder» lo hemos creado en la línea 47.

Si todo ha ido bien, vuestra aplicación ya será capaz de mostrar una notificación simple, si no es así revisad el código. De todas maneras si tenéis algún error y no se puede ejecutar el bloque try, saltará un toast situado en el bloque catch con el error.

Big View Style

notificacion android

Vamos a por el segundo tipo de notificación, el BigView Style. Para este caso hacen falta unas líneas más de código al principio comparando con la notificación anterior. Os recuerdo que es necesario ejecutar sobre Android 4.1 o superior para mostrarlas, en este tipo de notificación podemos incluir botones de acción aparte del Intent que se abre normalmente al pulsar en la notificación (en rojo en la imagen superior). En este ejemplo incluiremos 2 botones, uno de ellos abrirá el Activity principal de la aplicación «MainActivity.java» (marcado en verde en la imagen superior) y el otro nos llevará directamente al «LoginActivity.java» (marcado en amarillo en la imagen superior). Para ello, lo primero a declarar será un intent con el Activity correspondiente que abrirá cada botón de acción para luego encapsularlo dentro de un PendingIntent. Seguimos en la línea 94:

Intent _intentAbrir = new Intent(this, MainActivity.class);
        PendingIntent _pendingAbrir = PendingIntent.getActivity(this, 0, _intentAbrir, 0);

Repetimos el paso para el segundo botón que nos llevara al Log-in, en la linea 97:

Intent _intentIniciar = new Intent(this, LoginActivity.class);
        PendingIntent _pendingIniciar = PendingIntent.getActivity(this, 0, _intentIniciar, 0);

En las líneas 101 y 102 creamos los NotificationCompat.Action, estos son en si mismo las propias acciones de la notificación, más adelante las añadiremos al NotificationCompat.Builder.

NotificationCompat.Action accion_abrir = new NotificationCompat.Action.Builder(android.R.drawable.ic_menu_delete, "Abrir App", _pendingAbrir).build();
NotificationCompat.Action accion_iniciar = new NotificationCompat.Action.Builder(android.R.drawable.ic_menu_edit, "Iniciar Sesión", _pendingIniciar).build();

En el objeto Action pasamos los siguiente parámetros:

1.int | icono: «android.R.drawable.ic_menu_delete» Imágen de icono que se mostrará junto al botón. Este desaparece en Android 7.0 Nougat, aun así hay que declararlo para que se muestre en antiguas versiones.

2.String | Texto: «Abrir App» El texto que se verá en el botón de acción.

3. PendingIntent: «_pendingAbrir» Aquí pasamos los PendingIntent creados en las lineas 95 y 98 correspondientes a cada acción.

Luego añadimos .build() para crear la acción.

Desde las líneas 105 a 124 el código está comentado para evitar abrir el intent al pulsar la notificación (la zona marcada en rojo en la imagen de arriba). Con esto conseguiremos que solo los botones nos lleven a otra pantalla, en un vídeo que os dejaré al final del artículo veréis que por mucho que pulsemos la notificación, esta no hará nada. Son las mismas líneas que podemos encontrar en el bloque CrearNotificacion() y que sí están activadas.

A partir de la línea 125 volvemos a crear nuestro Builder, el cuerpo de la notificación. Su principio es idéntico al de la notificación simple, pero a partir de la línea 138 añadimos 3 valores más:

//Métodos exclusivos para definir una notificacion como Big View.
                            .setStyle(new NotificationCompat.BigTextStyle()
                                    .bigText("La aplicación se ha actualizado a una nueva versión, es necesario que vuelvas a iniciar sesión."))
                            .addAction (accion_abrir)
                            .addAction (accion_iniciar).build();

1.setStyle(NotificationCompat.Style): Aquí declaramos el tipo de estilo que queremos para nuestra notificación, utilizamos el tipo BigTextStyle().bigText(String) para incluir una descripción más detallada que la que se muestra en el método .setContentText() en la línea 130.

2.addAction(NotificationCompat.Action): Declararemos este método por tantos botones/acciones queramos mostrar, en este caso son 2. Basta con pasarle cada acción creada (líneas 101 y 102). Seguidamente utilizamos .build() para crear el Builder.

En las líneas 145 y 149 volvemos a obtener la referencia al servicio de notificaciones del sistema, aunque esto nos lo podríamos haber ahorrado si la hubiéramos declarado 1 sola vez en el método onCreate(). Luego con mNotifyMgr.notify() mostramos la notificación dándole su id único por sí tenemos que trabajar con ella mas adelante.

-«Nivel completado! Si habéis llegado hasta aquí deberíais tener ya vuestras notificaciones funcionando. Si os ha surgido algún error revisad vuestro código. Si no, podéis dejar un comentario más abajo e intentaré ayudaros a resolverlo. Aquí os dejo un vídeo para que veáis las notificaciones Android a pleno rendimiento.

Estos son los contenido de los archivos Manifest.xml y build.gradle

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="es.mscdroidlabs.mscnotificaciones">

    <!-- To auto-complete the email text field in the login form with the user's emails -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".LoginActivity"
            android:label="@string/title_activity_login"
            android:excludeFromRecents="true"
            android:parentActivityName=".MainActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="es.mscdroidlabs.mscnotificaciones.MainActivity" />
        </activity>
    </application>

</manifest>
apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"

    defaultConfig {
        applicationId "es.mscdroidlabs.mscnotificaciones"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.android.support:design:24.2.0'
}

También te podría gustar...

Ads Blocker Image Powered by Code Help Pro

Bloqueador de anuncios detectado

Por favor, desactiva tu bloqueador de anuncios para este sitio web. Sabemos que la publicidad puede resultarte molesta, pero esta es la única manera de mantener la web de forma gratuita y accesible para todo el mundo.