Receptores de transmisión de Android (Broadcast Receivers)
Los receptores de transmisión se utilizan para responder a mensajes de difusión provenientes de otras aplicaciones o del sistema. Estos mensajes a veces se denominan eventos o intenciones. Por ejemplo, una aplicación puede iniciar una transmisión para que otras aplicaciones sepan que algunos datos ya se han descargado al dispositivo y están disponibles para ellas. De esta manera, el receptor de transmisión puede definir las acciones apropiadas para interceptar estas comunicaciones.
Hay dos pasos importantes para que las intenciones de transmisión del sistema funcionen con el receptor de transmisión.
- Crear un receptor de transmisión
- Registrar un receptor de transmisión
Hay un paso adicional: para implementar intenciones personalizadas, debes crear y transmitir esas intenciones.
Crear un receptor de transmisión
El receptor de transmisión debe implementarse como una subclase de la clase BroadcastReceiver y sobrescribir el método onReceive() para recibir mensajes que tienen un objeto Intent como parámetro.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
}
}
Registrar un receptor de transmisión
La aplicación registra el receptor de transmisión en AndroidManifest.xml para escuchar la intención de transmisión especificada. Supongamos que vamos a registrar MyReceiver para escuchar el evento ACTION_BOOT_COMPLETED generado por el sistema. Este evento se emite cuando el proceso de arranque del sistema Android se completa.

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
</intent-filter>
</receiver>
</application>
Ahora, cada vez que se inicie el dispositivo Android, MyReceiver lo interceptará y se ejecutará la lógica implementada en onReceive().
Hay muchos eventos generados por el sistema que se definen como valores constantes estáticos en la clase Intent. La siguiente tabla enumera los eventos importantes del sistema.
| Constante de evento | Descripción |
|---|---|
| android.intent.action.BATTERY_CHANGED | Transmisión persistente que contiene el estado de carga, el nivel y otra información de la batería. |
| android.intent.action.BATTERY_LOW | Indica la condición de batería baja del dispositivo. |
| android.intent.action.BATTERY_OKAY | Indica que la batería ya está bien después de haber estado baja. |
| android.intent.action.BOOT_COMPLETED | Se transmite una vez después de que el sistema complete el arranque. |
| android.intent.action.BUG_REPORT | Muestra la actividad para informar errores. |
| android.intent.action.CALL | Realiza una llamada a alguien especificado por los datos. |
| android.intent.action.CALL_BUTTON | El usuario hace clic en el botón 'Llamar' para abrir el marcador u otra interfaz adecuada para marcar. |
| android.intent.action.DATE_CHANGED | La fecha ha cambiado. |
| android.intent.action.REBOOT | Reinicio del dispositivo. |
Transmitir intenciones personalizadas
Si deseas generar y enviar intenciones personalizadas en tu aplicación, debes crearlas y enviarlas en la clase de actividad mediante sendBroadcast(). Si usas el método sendStickyBroadcast(Intent), la intención es persistente (sticky), lo que significa que la intención que enviaste se mantiene después de que se completa la transmisión.
public void broadcastIntent(View view)
{
Intent intent = new Intent();
intent.setAction("com.ejemplo.CUSTOM_INTENT");
sendBroadcast(intent);
}
La intención com.ejemplo.CUSTOM_INTENT se puede registrar de la misma manera que registramos las intenciones generadas por el sistema anteriormente.
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="com.ejemplo.CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
</application>
Ejemplo
Este ejemplo explicará cómo crear un receptor de transmisión para interceptar intenciones personalizadas. Una vez que estés familiarizado con las intenciones personalizadas, puedes programar la aplicación para interceptar intenciones generadas por el sistema. Sigamos los pasos a continuación para modificar la aplicación de Android que creamos en el capítulo de ejemplo Hello World.
| Pasos | Descripción |
|---|---|
| 1 | Usa Android Studio para crear una aplicación de Android, nómbrala broadcastreceiver y colócala en el paquete com.ejemplo.broadcastreceiver del capítulo de ejemplo Hello World. |
| 2 | Modifica el archivo de actividad principal MainActivity.java para agregar el método broadcastIntent(). |
| 3 | Crea un nuevo archivo Java llamado MyReceiver.java en el paquete com.ejemplo.broadcastreceiver para definir el receptor de transmisión. |
| 4 | La aplicación puede manejar una o más intenciones personalizadas o del sistema, sin ninguna restricción. Cada intención que desees interceptar debe registrarse en AndroidManifest.xml usando la etiqueta <receiver.../>. |
| 5 | Modifica el contenido predeterminado del archivo res/layout/activity_main.xml para incluir un botón para transmitir intenciones. |
| 6 | No es necesario modificar el archivo de cadenas; Android Studio se encargará del archivo strings.xml. |
| 7 | Inicia el emulador de Android para ejecutar la aplicación y verifica los resultados de los cambios realizados en la aplicación. |
A continuación se muestra el contenido del archivo de actividad principal modificado src/com.ejemplo.broadcastreceiver/MainActivity.java. Este archivo contiene todos los métodos básicos del ciclo de vida. Hemos agregado el método broadcastIntent() para transmitir un evento personalizado.
package com.ejemplo.broadcastreceiver;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.content.Intent;
import android.view.View;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
// 广播自定义意图
public void broadcastIntent(View view){
Intent intent = new Intent();
intent.setAction("cn.programmer.CUSTOM_INTENT");
sendBroadcast(intent);
}
}
A continuación se muestra el contenido de src/com.ejemplo.broadcastreceiver/MyReceiver.java:
package com.ejemplo.broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "检测到意图。", Toast.LENGTH_LONG).show();
}
}
A continuación, modifica el archivo AndroidManifest.xml. Aquí se incluye nuestro receptor de transmisión agregando la etiqueta <receiver.../>:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ejemplo.broadcastreceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="cn.programmer.CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
</application>
</manifest>
A continuación se muestra el contenido del archivo res/layout/activity_main.xml, que contiene el botón para transmitir intenciones personalizadas.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="广播实例"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="30dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="www.example.com"
android:textColor="#ff87ff09"
android:textSize="30dp"
android:layout_above="@+id/imageButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:src="@drawable/ic_launcher.html"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:text="广播意图"
android:onClick="broadcastIntent"
android:layout_below="@+id/imageButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
A continuación se muestra el contenido del archivo res/values/strings.xml, que define dos nuevas constantes.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Android Broadcast Receiver</string>
<string name="action_settings">Settings</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_main">Main Activity</string>
</resources>
Ejecutemos la aplicación Hello World! que acabamos de modificar. Supongo que ya creaste un AVD al instalar el entorno. Abre el archivo de actividad en tu proyecto y haz clic en el
icono para ejecutar la aplicación en Android Studio. Android Studio instala la aplicación en el AVD y la inicia. Si todo va bien, se mostrará lo siguiente en la ventana del emulador:

Ahora haz clic en el botón 'Transmitir intención' para transmitir nuestra intención personalizada. Esto transmitirá nuestra intención personalizada 'cn.programmer.CUSTOM_INTENT', que será interceptada por nuestro receptor de transmisión registrado MyReceiver y ejecutará la lógica que implementamos. Aparecerá un toast en la parte inferior del emulador. A continuación:

Puedes intentar implementar otros receptores de transmisión para interceptar intenciones generadas por el sistema, como el inicio del sistema, el cambio de fecha y la batería baja.
Otras extensiones