Como ya venimos acostumbrándonos, cada domingo podremos encontrarnos un nuevo capítulo de Aprende Android en 20 conceptos. Hoy es el turno de los conceptos número 7 y 8.
Hoy toca analizar qué es un Intent y para qué se utiliza, pues es una de las clases más importantes de Android. Y un buen ejemplo de uso de los Intents lo veremos en otro de los pilares de Android: los receptores de mensajes Broadcast.
7. La clase Intent
Un Intent es un mensaje que podemos utilizar para solicitar una acción determinada a otra componente de una aplicación. Se trata de una clase que nos facilita la comunicación entre componentes, principalmente en uno de estos casos básicos (mecanismos diferentes según el tipo de componente que queramos lanzar):
- Empezar una actividad: Con un Intent podemos empezar una nueva instancia de una Actividad, gracias al método startActivity. En el Intent introduciremos la información de la actividad a empezar, así como cualquier otro dato que la actividad necesite.
- Empezar un servicio: Totalmente similar al anterior, pero utilizando el método startService. Pero también hay que destacar, que si el servicio está diseñado con una interfaz cliente-servidor, podremos utilizar el método bindService.
- Enviar un broadcast: Con un Intent y uno de los métodos sendBroadcast, sendOrderedBroadcast o sendStickyBroadcast, podremos enviar mensajes broadcast al sistema operativo de nuestro dispositivo.
¿Qué información contiene un Intent? Básicamente, portará información que el sistema operativo utilizará para determinar qué componente lanzar, así como cualquier información adicional que la componente pueda necesitar para poder llevar a cabo su acción.
La información principal que podemos encontrar en un Intent es la siguiente:
- Component Name (Nombre de componente): En este campo podremos indicar el nombre del componente que queremos lanzar. Es opcional, pues no siempre conoceremos el componente a lanzar (imagina que queremos lanzar la cámara, pero no sabemos qué actividad utilizar…). Sólo será obligatorio en el caso de un servicio.
- Action (Acción): Se trata de una cadena de texto que nos permite especificar una acción a ejecutar (ya sea una disponible en Android o la nuestra propia). En el caso de los mensajes broadcast, este campo será esencial, pues será en base al que lanzaremos los diferentes mensajes.
- Data (Datos): Será una URI que haga referencia a los datos que queremos utilizar, así como el tipo de datos que son (MYME type).
- Category (Categoría): Es una cadena de texto que ofrece información adicional sobre el tipo de componente que debería ser lanzado.
- Extras (Extras): Aquí podremos meter tantos pares llave-valor como queramos como información adicional que queremos enviar al componente a lanzar.
- Flags (Banderas): Son metadatos que ayudan a indicar al sistema cómo lanzar, por ejemplo, nuestra actividad.
Tal como hemos comentado, habrá situaciones en las que sabemos qué componente queremos lanzar. Pero habrá otras donde conoceremos qué queremos hacer, pero no qué componente exacto lo hace (por ejemplo, lanzar la cámara). Es por ello que se definen dos tipos de Intents:
- Intent Explícito: Este tipo de Intent es aquel en el que conocemos exactamente qué componente lanzar, el cual especificaremos a través del nombre de componente. Lo utilizaremos cuando querramos lanzar un servicio o actividad, típicamente de nuestra propia aplicación.
- Intent Implícito: En este caso, no conocemos el nombre de componente (estará vacío), pero sabemos la acción que queremos ejectuar. De esta forma, le pediremos al sistema operativo que busque por nosotros qué aplicación podría realizar dicha acción y, en el caso de que haya varias, nos dará a elegir cuál utilizar.
La pregunta que nos podríamos hacer llegado este punto es: ¿cómo sabe Android qué acciones realiza cada componente de aplicación? Y aquí es donde juega un papel crucial el fichero Manifest. En él, ya hemos comentado que debemos dejar registrados todos los componentes que forman parte de la aplicación. Pero no sólo eso. También deberemos añadir dentro de cada componente en el Manifest el concepto de Intent Filter. Este filtro nos permite indicar cuál es la capacidad de dicha componente. Concretamente, un Intent Filter puede contener los siguientes campos completos:
- Acción
- Datos
- Categoría
Entonces, cuando nosotros lancemos un Intent implícito, Android buscará en todos los Manifest de todas las aplicaciones instaladas aquellos componentes que cumplan los requisitos de nuestro Intent: todos y cada uno de ellos. Es decir, tendremos que cumplir los requisitos de acción, categoría y datos:
En el siguiente link, tenéis una serie de lecciones donde podéis descubrir más información sobre la interacción con otras aplicaciones a través de Intents.
8. Receptores de mensajes broadcast (Broadcast Receiver)
Un broadcast es un mensaje que cualquier aplicación puede recibir. El propio sistema operativo ya de por sí envía varios mensajes o anuncios broadcast según los eventos que tengan lugar (por ejemplo, en un reinicio del dispositivo, al conectarlo a un cargador o al saltar el estado de batería baja, entre otras muchas opciones). Nosotros, como programadores, podemos decidir cuáles deberían ser capturados en nuestra aplicación y cómo los gestionamos.
Para registrar un evento en un receptor de broadcast concreto en nuestra aplicación, deberemos hacer uso del método registerReceiver o publicarlo estáticamente a través de la etiqueta <receiver> en nuestro fichero Manifest. Sin embargo, si sólo deseamos enviar estos mensajes a nivel interno de nuestra aplicación, podríamos usar la clase LocalBroadcastManager en su lugar.
Hemos visto cómo registrar el receptor de broadcast y los eventos asociados, pero también debemos eliminarlo del registro. Para ello utilizaremos el método unregisterReceiver.
Por último, mencionar que hay dos tipos de broadcasts:
- Broadcasts normales: Son completamente asíncronos, de forma que todos los receptores corren en un orden desconocido, incluso al mismo tiempo. Es más eficiente, pero perdemos control en el orden de las acciones a realizar.
- Broadcasts ordenados: En este caso, el mensaje se envía a un sólo receptor a la vez. Cada receptor tendrá un turno en el cual recibirá el mensaje, y propagará el resultado al siguiente receptor o incluso cancelar el mensaje. Podremos controlar el orden con prioridades, pero perderemos eficiencia.
Con esto damos por terminados los conceptos de hoy, donde ya hemos visto cómo comunicarnos entre aplicaciones, así como solicitar al sistema operativo alguna acción en concreto.
La semana que viene llegaremos al ecuador de la sección. Pero mientras tanto, ¿has empezado ya a desarrollar tu primera app?
Ver la sección Aprende Android en 20 conceptos