DesarrolloLibre

Desarrollo Web, Android, juegos 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());

Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

Templates para Android y iOS

Templates para Android y iOS

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

Algunos artículos que te pueden interesar

Cómo crear un lector de códigos QR en Android con Android Studio

Cómo crear un lector de códigos QR en Android con Android Studio

Andrés Cruz 29-08-2016

Las primeras apps: Dolphin Note y List 1.0

Las primeras apps: Dolphin Note y List 1.0

Hoy les vengo a hablar de un par de aplicaciones que he venido desarrollando hace unos cuantos meses para Android y que he puesto finalmente en la Google Play.

Andrés Cruz 10-08-2015

Desarrollando aplicaciones de Realidad Aumentada con Wikitude (parte 3.2)

Desarrollando aplicaciones de Realidad Aumentada con Wikitude (parte 3.2)

En este artículo realizaremos una aplicación para Android con las mismas características de la aplicación del artículo pasado pero esta vez usando el atributo HTML en vez del atributo URI.

Andrés Cruz 12-03-2014