BroadcastReceiver. Parte 1
1. Introducción
Como comenté el otro dÃa la clase BroadcastReceiver es un componente Android que nos permite registrarnos para recivir eventos del sistema o eventos de ciertas aplicaciones. Los BroadcastReceiver que estén registrados para un cierto evento serán notificados por el runtime de Android cuando esto ocurra.
Para el ejemplo que propuse el otro dÃa, el del nivel de la baterÃa, tenemos que registrar nuestro BroadcastReceiver para el evento ACTION_BATTERY_LOW.
2. BroadcastReceiver
Los eventos que se producen, ya sean eventos del sistema o de aplicaciones, están representados mediante Intents. Estos son enviados por el sistema para que los BroadcastReceiver registrados para ese evento los recivan.
El Intent es recivido por el BroadcastReceiver en la llamada al método onReceive().
Vale, y ¿cómo registramos ahora el BroadcastReceiver? Pues existen dos maneras:
Estáticamente, en el AndroidManifest.xml
Dinámicamente, es decir, en tiempo de ejecución mediante el método registerReceiver()
2.1. Registración estática
Esta manera de registro se realiza en el AndroidManifest.xml. Con la etiqueta <receiver> le indicaremos a la aplicación el nombre del BroadcastReceiver y una serie de atributos opcionales
<receiver android:enabled=["true" | "false"] android:exported=["true" | "false"] android:icon="drawable resource" android:label="string resource" android:name="string" android:permission="string" android:process="string" > </receiver>
Para consultar el uso de estos atributos podeis consultar AndroidManifestReceiver.
Dentro de la etiqueta debemos especificar también el Intent filter para saber el evento que va a escuchar el BroadcastReceiver. Utilizaremos la etiquieta <intent-filter>.
Con este tipo de registración los BroadcastReceiver son registrados en el momento de arranque del sistema o cuando se añade la aplicación en tiempo de ejecución.
2.1.1. Aplicación
Vamos a dejar un poco la teorÃa a parte y ponernos a hacer un sencillo ejemplo para aplicar lo aprendido. Para explicar la registración estática de los BroadcastReceiver vamos a crear dos apps.
Sender. Esta aplicación será la responsable de desatar un evento que nosotros vamos a crear. Dispondrá de un botón para realizar la emisión del evento.
Receiver. Esta se registrará para recivir el evento que desencadena el Sender. Cuando recive el evento muestra una actividad en la que se muestra el número de veces que se ha recivido el evento.
Con estas dos apps creo que es más sencillo entender los BroadcastReceiver. Asà por un lado tenemos la aplicación que envÃa los eventos, la cual puede sustituir al controlador de la baterÃa en nuestro ejemplo inicial, y por otro lado el receptor del evento, el cual manejará el evento recivido para reaccionar a su antojo.
Empecemos por el Sender. En nuestro layout creamos un botón centrado en el centro, tal que asÃ:
<Button android:id="@+id/buttonSender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/button_send_event" />
Ahora pasamos a programar un poco. Vamos a la clase principal en la que buscaremos el botón a través del id y luego le añadimos el evento de click para que cuando el usuario pulse el botón envie nuestro evento al Receiver. El evento está representado con un Intent al que le vamos a dar el siguiente nombre.
final static String SEND_INTENT = "ble180.BroadcastReceiver.event";
Pues ya tenemos todo lo necesario, ahora simplemente tenemos que crear un Intent y enviarlo con el método sendBroadcast().
import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { final static String SEND_INTENT = "ble180.BroadcastReceiver.event"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Button buttonSender = (Button) findViewById(R.id.buttonSender); buttonSender.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // Send the intent that the other app received sendBroadcast(new Intent(SEND_INTENT)); } }); } }
Pues pasemos ahora al Receiver. Lo primero que tenemos que hacer es registrar el Receiver en nuestro AndroidManifest.xml para la recepción de nuestro evento ble180.BroadcastReceiver.event.
<receiver android:name=".Receiver" android:exported="true"> <intent-filter> <action android:name="ble180.BroadcastReceiver.event"/> </intent-filter> </receiver>
Al hacer esto nos saldrá un Warning indicando que al ser el Receiver exported cualquier aplicación podrá enviar eventos los cuales sean recividos por nuestra app. Para ello vamos a crear un permiso el cual se le daremos al Receiver. Asà solo los Sender que tengan este permiso en su AndroidManifest.xml podrán enviar el evento ble180.BroadcastReceiver.event y que sea recivido por la app. Entonces nuestro AndroidManifest.xml quedará asÃ:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ble180.BroadcastReceiver.BroadcastReceiverRec" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <permission android:name="ble180.BroadcastReceiver.START_RECEIVER"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="ble180.BroadcastReceiver.BroadcastReceiverRec.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".Receiver" android:exported="true" android:permission="ble180.BroadcastReceiver.START_RECEIVER"> <intent-filter> <action android:name="ble180.BroadcastReceiver.event"/> </intent-filter> </receiver> </application> </manifest>
Como hemos añadido el permiso ahora debemos añadirselo también al AndroidManifest.xml del Sender. Simplemente será añadir la linea <uses-permission android:name="ble180.BroadcastReceiver.START_RECEIVER"/>
Pues pasemos al código del Receiver. A parte de la clase principal vamos a crear una para implementar el Receiver que extienda de BroadcasReceiver. Esta clase tendrá el método onReceive() que será desencadenado cuando reciva el evento emitido por el Sender. Aquà es donde se realizan las operaciones que deseemos que se desencadenen con la recepción del evento.
Como dije antes, cuando reciva el evento queremos que inicie una actividad con el número de veces que se ha recivido el evento. Para ello creamos un Intent con la clase principal de nuestra aplicación, en este caso MainActivity.class. A este Intent le ponemos información extra, en este caso el número de veces que se ha recivido el evento, y lo lanzamos.
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class Receiver extends BroadcastReceiver{ // Times that we have received an event static int TIMES_RECEIVED = 0; @Override public void onReceive(Context context, Intent intent) { TIMES_RECEIVED++; // New intent with the main class Intent intentRec = new Intent(context, MainActivity.class); intentRec.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Put the times for the MainActivity can show the times // that we have received an event intentRec.putExtra("times", TIMES_RECEIVED); // Start the activity context.startActivity(intentRec); } }
Por último nos queda nuestra clase principal la MainActivity. Es la clase más sencilla de todas, solo obtenemos la información extra del Intent lanzado en la clase anterior para mostrarla por pantalla en un TextView que contiene la vista pricipal de la aplicación.
import android.os.Bundle; import android.widget.TextView; import android.app.Activity; import android.content.Intent; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int times = 0; Intent intent = getIntent(); Integer extraTimes = intent.getIntExtra("times", 0); // If there are times, we keep in times variable to show it if(extraTimes != null){ times = extraTimes; } // Change the TextView message TextView textViewReceiver = (TextView) findViewById(R.id.textViewReceiver); textViewReceiver.setText("Received Event num " + times + " by Receiver"); } }
Ahora es turno de vosotros probarlo. Simplemente teneis que instalar las dos apps en vuestro smartphone o en el simulador. Una vez que las dos estén instaladas, abrÃs el Sender y le dais al botón de enviar y seguidamente vereis como se abre una nueva actividad con un mensaje y el número de veces que se ha recivido el evento.
Github:Enlace al código
BroadcastReceiver Parte 1 by Abel MartÃnez is licensed under a Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional License.









