Android desde Cero: Entendiendo la Transmisión de Android
Spanish (Español) translation by Rodney Martinez (you can also view the original English article)
La mayoría de nosotros estamos demasiado familiarizados con los anuncios en los lugares públicos. Son claros mensajes de que están destinados a informa a grupos grandes de personas acerca de algo importante. Las aplicaciones Android, también tienen que tratar con anuncios algunas veces: los anuncios generados ya sea por otras aplicaciones o por el mismo sistema operativo Android. Tales anuncios son llamados broadcasts y son vistos como una forma importante del proceso interno de comunicación en la plataforma Android.
En este tutorial le mostraré como crear, enviar y recibir ambos; las locales como las broadcasts del sistema. También le mostraré cómo usar bibliotecas de otros desarrolladores llamada EventBus que puede servir como una alternativa para los broadcasts locales.
1. Creando un Broadcast
Los broadcasts de Android son enviados en la forma de objetos Intent. Por lo tanto, antes de crear un broadcast, primero debe crear un objeto Intent. Esta serie tiene un tutorial detallado sobre los objetos Intents. Si aún no lo ha leído, ahora sería un buen momento para hacerlo.
Cada objeto Intent que envía como un broadcast debe tener un nombre de acción. Aunque el nombre de acción puede ser cualquier String, le recomiendo que siempre use prefijos en él con el nombre del paquete de su aplicación para evitar conflictos con broadcasts de otras aplicaciones.
El siguiente fragmento de código muestra como crear un nuevo Intent cuyo nombre de acción es com.tutsplus.my.first.broadcast:
1 |
Intent myIntent = new Intent("com.tutsplus.my.first.broadcast"); |
Para enviar el objeto Intent como un broadcast, todo lo que necesita hacer es llamar al método sendBroadcast() y pasar el objeto Intent como un argumento.
1 |
sendBroadcast(myIntent); |
Observe que el método sendBroadcast() crea un broadcast global que puede ser recibido, no solamente por su aplicación, sino también cualquier otra aplicación instalada en el dispositivo del usuario.
2. Recibiendo Broadcasts
Para poder recibir un broadcast, su aplicación debe tener un recibidor broadcast adecuadamente configurado. Usted puede crear un recibidor broadcast al extender la clase abstracta BroadcastReceiver y cancelar su método onReceive(). Por ejemplo, así es cómo usted crea un recibidor broadcast que imprime un mensaje cada vez que recibe un broadcast.
1 |
public class MyBroadcastReceiver extends BroadcastReceiver { |
2 |
public void onReceive(Context context, Intent intent) { |
3 |
Log.d("MYAPP", "I received a broadcast"); |
4 |
}
|
5 |
}
|
Un recibidor broadcast funciona solamente si está registrado. La forma más fácil de hacer eso es por medio de declararlo en la archivo manifiesto del proyecto usando la etiqueta receiver.
De manera adicional, dentro de la declaración de un broadcast recibidor, debe incluir las etiquetas intent-filter que especifican los nombres de acción del recibidor broadcast en el que está interesado.
El siguiente fragmento de código registra MyBroadcastReceiver y lo configura para responder a una acción llamada com.tutsplus.my.first.broadcast:
1 |
<receiver android:name=".MyBroadcastReceiver"> |
2 |
<intent-filter>
|
3 |
<action android:name="com.tutsplus.my.first.broadcast" /> |
4 |
</intent-filter>
|
5 |
</receiver>
|
3. Recibiendo un Sistema Broadcasts
El sistema operativo Android emite varios broadcast globales. La mayoría de ellos contienen información valiosa sobre los cambios en el dispositivo Android. Por ejemplo, cada vez que un usuario coloca una nueva llamada saliente, entonces el broadcast android.intent.action.NEW_OUTGOINGT_CALL es emitido. De manera similar, cada vez que un usuario enciende o apaga el modo avión, el broadcast android.intent.action.AIRPLANE_MODE es emitido.
Recibir los sistemas broadcast es como recibir broadcast broadcasts normales. La mayoría de los intents broadcast, sin embargo, contienen información adicional en la forma de extras. Usted puede buscar todos esos extras como un objeto Bundle, al llamar al método getExtras(). Por ejemplo, el intent broadcast android.intent.action.AIRPLANE_MODE, siempre contiene un extra llamado state, que es un valor boolean especificando si el modo avión ha sido encendido o apagado.
El siguiente fragmento de código muestra cómo registrar el valor del extra state:
1 |
// Check if you have the right broadcast intent
|
2 |
if (intent.getAction().equals("android.intent.action.AIRPLANE_MODE")) { |
3 |
// Get all extras
|
4 |
Bundle extras = intent.getExtras(); |
5 |
|
6 |
// Fetch the boolean extra using getBoolean()
|
7 |
boolean state = extras.getBoolean("state"); |
8 |
|
9 |
// Log the value of the extra
|
10 |
Log.d("MYAPP", "AIRPLANE MODE: " + state); |
11 |
}
|
Note que el código anterior funcionará solamente si el recibidor broadcast ha sido registrado con el siguiente filtro intent:
1 |
<intent-filter>
|
2 |
<action android:name="android.intent.action.AIRPLANE_MODE" /> |
3 |
</intent-filter>
|
4. Trabajando con Broadcasts locales
Por razones obvias, los broadcasts globales nunca deben contener información confidencial. Sin embargo, usted puede anunciar tal información de forma local usando la clase LocalBroadcastManager, que es parte de la Biblioteca de Soporte de Android.
Si está usando la última versión de Android Studio, entonces no tendrá que agregar manualmente una dependencia para la Biblioteca de Soporte de Android. No obstante, si quiere implementar broadcasts locales en un antiguo proyecto, entonces asegúrese que la siguiente línea está presente en el archivo build.gradle del módulo.
1 |
compile 'com.android.support:support-v4:23.4.0' |
Para crear una instancia nueva de la clase LocalBroadcastManager, debe llamar al método getInstance() y pasar su activity o servicio como su contexto. Por ejemplo, así es cómo crearía la instancia dentro de un activity llamado: MyActivitiy:
1 |
LocalBroadcastManager localBroadcastManager |
2 |
= LocalBroadcastManager.getInstance(MyActivity.this); |
Ahora puede enviar broadcasts locales usando el método sendBroadcast() de la clase LocalBroadcastManager. El siguiente fragmento de código crea un nuevo intent, cuyo nombre de acción es my-local-broadcast, y lo envía como un broadcast local:
1 |
// Create intent with action
|
2 |
Intent myIntent = new Intent("my-local-broadcast"); |
3 |
|
4 |
// Send local broadcast
|
5 |
localBroadcastManager.sendBroadcast(myIntent); |
Recibir una broadcast local es un poco más implicado. Un recibidos broadcast local no debe estar registrado en el archivo manifiesto del proyecto. En lugar de eso, éste debe estar registrado de forma dinámica usando el método registerReceiver() de la clase LocalBroadcastManager. Además, para la instancia de un recibidor broadcast, el método registerReceiver() requiere un objeto IntentFilter que especifica el nombre de acción al que el recibidor broadcast debería responder.
Así es como crearía y registraría un recibidor broadcast que pued responder a la acción my-local-broadcast.
1 |
// Create a broadcast receiver as usual
|
2 |
BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() { |
3 |
@Override
|
4 |
public void onReceive(Context context, Intent intent) { |
5 |
Log.d("MYAPP", "Received a local broadcast"); |
6 |
}
|
7 |
};
|
8 |
|
9 |
// Create intent filter for it
|
10 |
IntentFilter myFilter = new IntentFilter("my-local-broadcast"); |
11 |
|
12 |
// Register it
|
13 |
localBroadcastManager.registerReceiver( |
14 |
myBroadcastReceiver, myFilter); |
Los recibidores registrados de forma dinámica no pueden ser registrados cuando ya no son necesarios. Para hacer esto debe usar el método unregisterReceiver() de la clase LocalBroadcastManager.
1 |
localBroadcastManager.unregisterReceiver( |
2 |
myBroadcastReceiver); |
5. Usando la biblioteca EventBus
Si cree que los broadcasts locales y los intent no le dan toda la flexibilidad que usted necesita, entonces debería de considerar usar EventBus, una biblioteca de otros desarrolladores que le permite asíncronamente enviar datos desde un componente de su aplicación a otro. En mi opinión, la API EventBus es muy intuitiva y concisa.
Para incluir EventBus en su proyecto agregue la siguiente dependencia compile a su archivo build.gradle del módulo de su aplicación.
1 |
compile 'org.greenrobot:eventbus:3.0.0' |
En vez de sólo objetos Intent, EventBus permite enviar y recibir objetos de cualquier clase Java. Por ejemplo, las instancias de las siguientes clases pueden ser fácilmente usadas con EventBus:
1 |
public class MyMessage { |
2 |
String title; |
3 |
String text; |
4 |
|
5 |
public MyMessage(String title, String text) { |
6 |
this.title = title; |
7 |
this.text = text; |
8 |
}
|
9 |
}
|
EventBus implementa el modelo publicador-subscriptor y crea un bus central que es accesible para todos los componentes de su aplicación. Por lo tanto, un componente que necesita enviar objetos debe simplemente, publicar los objetos en el bus. Un componente que está interesado en recibir esos objetos debe registrarse como un subscriptor del bus.
La manera más fácil de buscar una instancia del bus central es usando el método getDefault() de la clase EventBus.
1 |
EventBus bus = EventBus.getDefault(); |
Para publicar un objeto, todo lo que necesita hacer es llamar el método post() del bus. Por ejemplo, así es cómo publicaría una instancia de la clase MyMessage:
1 |
bus.post(new MyMessage("Hello", "My first EventBus message")); |
Un componente de aplicación, tal como un activity o un servicio, puede registrarse como un subscriptor al llamar al método register() del bus. La siguiente muestra de código registra un servicio llamado MyService.
1 |
bus.register(MyService.this); |
Un componente que está actuando como un subscriptor, también debe tener un método subscriptor, que es cualquier método que tiene la anotación @Subscribe. Los métodos subscriptores se comportan como los controladores de eventos y son automáticamente llamados cada vez que los objetos nuevos están disponibles en el bus.
El siguiente fragmento de código le muestra cómo crear un método subscriptor sencillo que llamado de manera automática cada vez que una nueva instancia de la clase MyMessage está disponible en el bus:
1 |
@Subscribe
|
2 |
public void messageAvailable(MyMessage message) { |
3 |
Log.d("MYAPP", message.title + " [" + message.text + "]"); |
4 |
}
|
En conclusión
En este tutorial, aprendió a cómo enviar información desde un componente de aplicación a otro usando tanto los broadcasts globales como los locales. También aprendió cómo usar la popular biblioteca EventBus para la comunicación entre aplicaciones. Debido a que los broadcasts tiene una muy baja sobrecarga, usted tiene la libertad de enviarlos tan a menudo como sea necesario. De hecho, el sistema Android genera un nuevo broadcast android.intent.action.TIME_TICK cada minuto.
Para aprender más sobre los recibidores broadcast de Android, usted puede dirigirse a la documentación de BroadcastReceiver y de las clases Intent.



