DesarrolloLibre

Desarrollo Web, Android y mucho más

12-12-2016

En esta entrada veremos cómo crear una notificación personalizada desde Android.

¿A qué nos referimos con notificación personalizada?

A que emplearemos una vista desarrollada desde cero para tal fin; incluso emplearemos unos botones los cuales pueden ejercer sus acciones sobre la actividad, servicios o BroadCast; el código de la vista está un poco más adelante, pero por ahora indicaremos los primeros pasos para crear una notificación en Android.

        Intent intent = new Intent(getApplicationContext(), MusicService.class);
        noBundle.putInt("accion", 1);//This is the value I want to pass
        intent.putExtras(noBundle);
        PendingIntent pendingIntent = PendingIntent.getService(ListActivity.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.ibAccion, pendingIntent);

Expliquemos para que es cada componente del código presentado anteriormente:

  • El Bundle Es empleado generalmente para pasar datos entre componentes como actividades y fragments.
  • El Intent Los intents son el componente empleado para iniciar la comunicación entre los componentes como inicar una actividad o servicio (más información en la documentación oficial).
  • El PendingIntent es un objeto que contiene a un intent; este objeto PendingIntent permite al NotificationManager mandar al sistema la acción a ejecutar (como abrir una actividad).

Muy importante la bandera PendingIntent.FLAG_UPDATE_CURRENT que en conjunto con:

        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:launchMode="singleTop"
            android:screenOrientation="portrait">
...
</activity>

Indicamos que la actividad existe actualmente (por defecto el MainActivity es la primera actividad que inició) y el android:launchMode="singleTop" y es una forma de indicar que la instancia de la actividad sea única, aunque existen otras formas como puedes consultar en el siguiente enlace (en otras palabras significa actualizar la instancia de la actividad que está en ejecución actualmente).

Cómo son tres botones, necesitamos tres Intents diferentes y todo lo que esto conlleva, por lo tanto ahora multiplicamos esto por tres:

        Intent intent = new Intent(getApplicationContext(), MusicService.class);
        noBundle.putInt("accion", 1);//This is the value I want to pass
        intent.putExtras(noBundle);
        PendingIntent pendingIntent = PendingIntent.getService(ListActivity.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.ibAccion, pendingIntent);


        Bundle noBundle2 = new Bundle();
        noBundle2.putInt("accion", 2);//This is the value I want to pass
        Intent intent2 = new Intent(getApplicationContext(), ListActivity.class);
        intent2.putExtras(noBundle2);
        PendingIntent pendingIntent2 = PendingIntent.getActivity(ListActivity.this, 2, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.ibQuitar, pendingIntent2);


        Bundle noBundle3 = new Bundle();
        noBundle3.putInt("accion", 3);//This is the value I want to pass
        Intent intent3 = new Intent(getApplicationContext(), ListActivity.class);
        intent3.putExtras(noBundle3);
        PendingIntent pendingIntent3 = PendingIntent.getActivity(ListActivity.this, 3, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.ibSiguiente, pendingIntent3);

Esta otra notificación se emplea al momento que el usuario da clic en la notificación (en cualquier parte y no en sus botones).

        Intent intentNoti = new Intent(this, ListActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendIntentNoti = PendingIntent.getActivity(this, 0,
                intentNoti, PendingIntent.FLAG_UPDATE_CURRENT);

Cómo puedes darte cuenta, nos interesa actualizar el estatus de un servicio, que para efectos de esta entrada no importa su implementación.

Ahora podemos crear nuestra notificación; primero El administrador de la notificación (NotificationManager) que como su nombre indica mediante una instancia de esta clase podemos lanzar la notificación con el NotificationCompat.Builde podemos establecer las propiedades de la notificación; por ejemplo indicamos el título, subtítulo el icono y el PendingIntent cuya acción será ejercida al momento de que el usuario realice un clic sobre la notificación:

        NotificationManager nManager;
        NotificationCompat.Builder nBuilder;
        RemoteViews remoteView;


        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, ListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);


        nBuilder = new NotificationCompat.Builder(this)
                .setContentTitle(getString(R.string.app_name))
                .setTicker(getString(R.string.app_name))
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(contentIntent)
                .setOngoing(false)
                .setAutoCancel(false);

Ahora falta especificar cual es la vista en cuestión, esto lo hacemos mediante un RemoteViews:

        remoteView = new RemoteViews(getPackageName(), R.layout.notification_layout);
        remoteView.setImageViewResource(R.id.image, R.mipmap.ic_launcher);
        remoteView.setTextViewText(R.id.title, "Título");
        remoteView.setTextViewText(R.id.text,"Nombre");

Como podemos ver en el código anterior, accedemos a cada una de sus componentes y establecemos un valor que para efectos de este tutorial son fijos.

En nuestro caso la vista tiene el siguiente contenido:

<?xml version="1.0" encoding="UTF-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#333333"
    android:orientation="vertical"
    android:weightSum="1">


    <LinearLayout
        android:id="@+id/right"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">


        <ImageView
            android:id="@+id/imagenotileft"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:background="@mipmap/ic_launcher" />


        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:orientation="vertical">


            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:layout_marginTop="9dp"
                android:textColor="#FFFFFF"
                android:textSize="16sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/title"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:textColor="#EEEEEE"
                android:textSize="14sp" />
        </LinearLayout>


        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="horizontal">


            <ImageButton
                android:id="@+id/ibAtras"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_margin="0dp"
                android:background="@null"
                android:gravity="center_horizontal|center_vertical"
                android:padding="0dp"
                android:src="@drawable/ic_action_av_skip_previous" />


            <ImageButton
                android:id="@+id/ibAccion"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_margin="0dp"
                android:background="@null"
                android:gravity="center_horizontal|center_vertical"
                android:padding="0dp"
                android:src="@drawable/ic_action_ic_play_pause" />


            <ImageButton
                android:id="@+id/ibSiguiente"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_margin="0dp"
                android:background="@null"
                android:gravity="center_horizontal|center_vertical"
                android:padding="0dp"
                android:src="@drawable/ic_action_av_skip_next" />


            <Button
                android:id="@+id/ibQuitar"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_margin="0dp"
                android:background="@null"
                android:gravity="center_horizontal|center_vertical"
                android:padding="0dp"
                android:text="X"
                android:textColor="#444444"
                android:textSize="16sp" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

Finalmente establecemos la vista anterior y lanzamos la notificación:

        setListeners(remoteView);
        nBuilder.setContent(remoteView);


        nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nManager.notify(2, nBuilder.build());
Ayúdanos a seguir creciendo

Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

Paleta de colores para el Material Design

Paleta de colores para el Material Design

Librería oficial de PayPal para Android

Librería oficial de PayPal  para Android

Creando increibles Drawer en Android con MaterialDrawer

Creando increibles Drawer en Android con MaterialDrawer

Algunos artículos que te pueden interesar

Creando un FloatingActionButton en Android (Lib de Soporte)

Creando un FloatingActionButton en Android (Lib de Soporte)

Esta entrada ofrece una introducción para Android Studio; veremos como instalarlo, sus herramientas, crear proyectos, los archivos Gradle, combinación de teclas, etc.

Andrés Cruz 24-08-2015

Desarrollando aplicaciones de Realidad Aumentada con Wikitude (parte 2)

Desarrollando aplicaciones de Realidad Aumentada con Wikitude (parte 2)

En esta segunda entrega haremos una aplicación funcional utilizando la realidad aumentada y el reconocimiento de imágenes utilizando el API de Wikitude.

Andrés Cruz 23-10-2013

Construyendo nuestro propio logo Android con SVG en HTML

Construyendo nuestro propio logo Android con SVG en HTML

En esta entrada abordaremos un tema un poco más práctico y veremos cómo construir nuestro propio logo de Android empleando lo hablado hasta el momento.

Andrés Cruz 21-05-2015