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());

Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

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

Paleta de colores para el Material Design

Paleta de colores para el Material Design

Algunos artículos que te pueden interesar

Los ViewPager para desplazarse  entre pantallas (fragments) en Android

Los ViewPager para desplazarse entre pantallas (fragments) en Android

Los viewPager son unos tipos de vistas que cada vez son más comunes y permite desplazarnos entre distintas pantallas a través; son perfectas para emplearlas en conjunto con los fragments.

Andrés Cruz 08-11-2016

El elemento symbol para los SVG en HTML

El elemento symbol para los SVG en HTML

En esta entrada veremos un elemento muy útil para trabajar con los SVG que es el elemento symbol; este elemento ahorra mucho trabajo y permite agrupar una serie de figuras básicas y pintarlos empleando el elemento use.

Andrés Cruz 01-06-2015

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