Knowledge center Programación Entornos de programación

Programación de widgets en Android

Autor: Jose Mª Rodriguez-Maimón San Martín

Los Widgets son los pequeños programas que instalamos en el fondo del escritorio. Todos los conocemos de sobra; quién no tiene un reloj, calendario o el tiempo! En esta sección vamos a crear un widget para que podamos instalarlo en nuestro dispositivo.

Widget estático

Crear Widget

1

Vamos paso a paso, así que la primera parte será crear uno que nos muestre un icono en nuestro escritorio, posteriormente le daremos interactividad. En nuestro entorno definiremos una nueva aplicación. Añadiremos una clase que llamaremos "MiWidget":

 

2

Le ponemos el nombre y la creamos. Añadimos también un fichero de layout para poner el contenido del Widget:

 

3

En el layout de este Widget ponemos un gráfico con un texto:

 

4

Tenemos novedades: una clase "MiWidget.java", un fichero de recursos "miwidget_initial_layout.xml" y ahora añadiremos un fichero más. Creamos una carpeta para recursos y que llamaremos "xml":

 

5

Y luego:

 

6

Quedando:

 

7

En esta carpeta vamos a crear un fichero XML que llamaremos "widget_info.xml":

 

8

En este fichero xml "widget_info.xml" escribiremos la información de cómo será el widget:

 

9

Veamos de qué partes se compone:

  • minWidth y minHeight. Anchura y altura mínima del "widget". Se expresa en "dp" o en densidad de puntos.
  • updatePreriodMillis. Definiremos la frecuencia en milisegundos de actualización del widget.
  • label. Si aparece, es el nombre que aparecerá en el menú de selección de Android.
  • initialLayout. "layout" asociada. Como vemos se trata de "widget_initial_layout" que es la que acabamos de ver.

Edición de la funcionalidad del "widget"

1

El siguiente paso es la edición de la funcionalidad del "widget" con "AppWidgetProvider", que es el segundo fichero Java que tenemos en el proyecto y que está vacío. Vamos a "extender" de la clase que se encarga de los "widgets" llamada "AppWidgetProvider" y le indicaremos desde el menú que "Overryde" el método:

 

2

Este método es el encargado de actualizar el Widget.

 

3

Además, aunque no los utilicemos ahora tenemos:

  • onEnabled(). Se ejecuta al añadirse al escritorio por primera vez.
  • opUpdate(). Al actualizarse el "widget".
  • onDeleted(). Cuando se elimina del escritorio una instancia (podemos tener varios a la vez en la pantalla del dispositivo).
  • onDisabled(). Cuando se elimina la última instancia.

4

Vamos a escribir el siguiente código para que nos muestre el widget en pantalla:

Es el código estándar para recoger el layout del widget y mostrarlo con el método "updateAppWindget". "views" asocia la vista con el layout. Por tanto en "view" es donde tendremos que mostrar nuestro gráfico.

Como el origen con él pueden ser muchos, veremos que cada uno de ellos es un elemento de la matriz de entrada "int[] appWindgetIds". Como solo tenemos uno, por eso añadimos el elemento 0: "updateAppWidget (appWidgetIds[0],views)". El resto del código nos crea un "pendingintet" para lanzar un actividad bajo algún evento. Esto lo veremos en el siguiente ejemplo.

5

Por último veamos en el manifest debemos añadir el siguiente código para que lo reconozca como Widget y avisemos de la presencia del fichero de recursos:

 

6

Es un elemento  de configuración estándar que permitirá a las aplicaciones de nuestro dispositivo distinguir cuales de ellas tienen "widgets". Ejecutamos la aplicación y nos vamos a la configuración del dispositivo y luego a la sección de Widgets. A partir de Android 6 basta con pulsar en el escritorio unos segundos para acceder a la configuración de los "widgets":

 

7

 

8

Ahí veremos el nuestro. Pulsamos unos segundos para colocarlo en el escritorio que queramos:

 

Ya tenemos el marco completo de la aplicación. Si nuestro widget solo mostrara información cada cierto tiempo, por ejemplo un dato de los sensores, nos valdría con este ejemplo. Pero vamos a subirlo de nivel añadiendo interactividad.

 

Crear un widget automáticamente

1

Podemos crear un widget de una forma muy sencilla gracias al editor y su asistente. Por ejemplo, en una aplicación nueva añadimos:

 

2

Indicamos ahora la ubicación, si se va a poder cambiar de tamaño y su tamaño predefinido:

 

3

Nos creará una clase parecida a la anterior con su propio fichero de recursos:

 

4

Son los mismos ficheros que hemos creado antes. Veamos el ejemplo creado:

 

5

Vemos que el código es idéntico al que vimos antes:

 

6

Y lo mismo para el layout del componente:

 

7

Y su inclusión, en este caso automática, del código en el archivo "manifest":

 

8

Si ejecutamos la aplicación y añadimos el widget: 

 

9

 

Añadir interactividad

1

El siguiente paso será añadir interactividad. Para esto partimos del ejemplo que nos ha creado "Android Studio" con el widget para añadir dos sencillos gráficos a nuestro proyecto y  simular que activamos una opción.

 

2

Estos son los gráficos por si los quieres descargar:

 

Tenemos dos iconos en la zona de recursos: una cara normal y otra con gafas. La idea es que detectemos el "clic" del usuario, ejecutemos una acción y actualicemos el gráfico. Para esto crearemos dos layouts, uno con un gráfico y otro con el segundo gráfico.

3

Cambiamos los nombres a los ficheros de recursos:

 

4

Y así tenemos dos pantallas, una con cada icono. Ahora vamos con el código. Vamos a estructurar un poco más el código para crear un método que nos haga los cambios:

 

La actualización la haremos en el método "actualizarWidget", para poderlo llamar desde varias partes de nuestro programa y no tener que repetir código. Un "widget" es un tipo de "broadcast receiver", es decir va a ser una aplicación que va a estar escuchando mensajes del sistema operativo. Si hacemos clic en la pantalla en nuestro icono, el sistema operativo generará el mensaje adecuado, y nuestro programa podrá interceptarlo para ejecutar las instrucciones necesarias, en este caso, cambiar de "layout".

5

Veamos el código de este método:

 

6

Los elementos que tenemos en los "widgets" no son controles capturables como en el resto de las aplicaciones. Se trata de "RemoteView" donde, como hemos dicho, no podemos asociar eventos como un "listener" de un botón. A cambio de esto asociaremos a un evento (el clic sobre un botón) un determinado mensaje (Pending Intent) de tipo broadcast que se lanzará en cada evento.

Por tanto veamos nuestro código. Para empezar tenemos en la variable de entrada "value" el "string" que indica si el "widget" está activado o no. Sea lo que sea lo tendremos que actualizar, así que con "vista" y "este_widget" obtenemos referencias de la pantalla o vista actual y de nuestro propio "widget".

Ahora lanzaremos un "intent broadcast" cada vez que se pulse el botón del widget. Para ello, en el método actualizarWidget() construiremos un nuevo Intent asociándole una acción personalizada, que en nuestro caso llamaremos por ejemplo ?ACTION_cambiar_icono?.

Luego crearemos un "PendingIntent" mediante el método getBroadcast() y lo asociaremos al evento onClick del control llamando a setOnClickPendingIntent() pasándole el identificador del control, en nuestro caso el "widget" completo.

Finalmente llamamos al método updateAppWidget() del widget manager para que se actualicen los controles del "widget".

Ahora implementaremos los dos métodos de esta clase:

  • onReceive. El método recibe los mensajes enviados por otros componentes y por el mismo. Por tanto, será nuestro controlador de eventos.
  • onUpdate. Actualiza la interfaz. Se ejecuta periódicamente cada vez que se debe actualizar un widget. (por ejemplo en el número de milisegundos definido).

7

En el caso de "onReceive":

 

Hemos recibido un mensaje de "broadcast", comprobamos primero que es el nuestro, el que generamos antes en el "escuchador" de "pendingintent", con el primer "if". Si es correcto ejecutamos nuestro código. Como estamos pasando valores (el layout con el icono) entre cada ejecución ponemos el valor actual en una preferencia de usuario, que es la primera parte del código con "preferencias". Luego en el "if/else" evaluamos el valor de la preferencia de usuario y actualizamos su valor. Finalmente cogemos la referencia del "widget" con "getInstance" y llamamos al método anterior para actualizar el "widget".

8

Para el caso del "onUpdate":

 

Hay que actualizar el estado, leemos el valor del estado de las preferencias en la variable "mensaje". SI es la primera vez forzamos y actualizamos con "desactivado", en caso contrario con el valor que tuviera y finamente actualizamos el Widget.

9

Ejecutamos la aplicación y podemos ver que se detectan el clic sobre el "widget":

 

Pulsa aquí para descargar los ejemplos de este tema.

 

Esta píldora formativa está extraída del Curso online de Programación en Android con Android Studio.

¿Te gusta el contenido de esta píldora de conocimiento?

No pierdas tu oportunidad y ¡continúa aprendiendo!

Política de privacidad

ADR Formación utiliza cookies propias y de terceros para fines analíticos anónimos, guardar las preferencias que selecciones y para el funcionamiento general de la página.

Puedes aceptar todas las cookies pulsando el botón "Aceptar" o configurarlas o rechazar su uso pulsando el botón "Configurar".

Puedes obtener más información y volver a configurar tus preferencias en cualquier momento en la Política de cookies