Utilizar un receptor de broadcast / broadcast para enviar mensajes de un servicio a una actividad

Así que entiendo (creo) acerca de las intenciones de difusión y recibir mensajes para ellos.

Así que ahora, mi problema / lo que no puedo resolver es cómo enviar un mensaje desde el método onReceive de un receptor a una actividad. Digamos que tengo un receptor como tal:

 public class ReceiveMessages extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(action.equalsIgnoreCase(TheService.DOWNLOADED)){ // send message to activity } } } 

¿Cómo enviaría un mensaje a una actividad?

¿Tendría que instanciar al receptor en la actividad a la que quiero enviar mensajes y supervisarla de alguna manera? ¿O que? Entiendo el concepto, pero no realmente la aplicación.

Cualquier ayuda sería absolutamente increíble, gracias.

Tom

EDITADO Corregido ejemplos de código para registrar / anular el registro de BroadcastReceiver y también eliminar la declaración de manifiesto.

Defina ReceiveMessages como una clase interna dentro de la Activity que necesita escuchar los mensajes del Service .

Entonces, declare variables de clase como …

 ReceiveMessages myReceiver = null; Boolean myReceiverIsRegistered = false; 

En onCreate() use myReceiver = new ReceiveMessages();

Entonces en onResume()

 if (!myReceiverIsRegistered) { registerReceiver(myReceiver, new IntentFilter("com.mycompany.myapp.SOME_MESSAGE")); myReceiverIsRegistered = true; } 

… y en onPause()

 if (myReceiverIsRegistered) { unregisterReceiver(myReceiver); myReceiverIsRegistered = false; } 

En el Service crear y difundir la Intent

 Intent i = new Intent("com.mycompany.myapp.SOME_MESSAGE"); sendBroadcast(i); 

Y eso es todo. Haz que la 'acción' sea única para tu paquete / aplicación, es decir, com.mycompany... como en mi ejemplo. Esto ayuda a evitar una situación en la que otras aplicaciones o componentes del sistema intenten procesarla.

Sin ofender, pero su pregunta sigue siendo vago. Por lo tanto, voy a esbozar un desorden de escenarios y espero que uno de ellos realmente golpea cualquier problema que usted piensa que tiene.

Escenario A: Sólo la Actividad

Si solo necesita recibir la transmisión cuando tiene una actividad en primer plano, haga que la actividad registre el BroadcastReceiver usando registerReceiver() . Como @MisterSquonk indicó, registraría el receptor en onResume() y onPause() su registro en onPause() .

Escenario B: Actividad Si En Primer Plano, Otra Otros; Transmisión ordenada

Si desea que la actividad de primer plano se encargue de la emisión, pero desea que suceda algo más si esa actividad no está en primer plano (por ejemplo, levantar una Notification ) y la emisión es una emisión ordenada (por ejemplo, SMS entrantes), entonces usted Aún usaría la solución Scenario A, pero con un IntentFilter mayor prioridad (vea setPriority() ). Además, se registraría un BroadcastReceiver través de un elemento <receiver> en el manifiesto, con un <intent-filter> priority <intent-filter> de menor prioridad para la misma emisión. En BroadcastReceiver la actividad, llame a abortBroadcast() para consumir el evento y evitar que llegue a su BroadcastReceiver registrado por el manifiesto.

Escenario C: Actividad Si En Primer Plano, Otra Otros; Radiodifusión regular

Si el Escenario B es casi idóneo, pero la emisión que está escuchando no es una emisión ordenada, tendrá que comenzar con el Escenario B. Sin embargo, tenga la difusión que ambos receptores tienen en sus respectivos filtros, uno de los suyos, usando un canal privado Cadena de acción como @MisterSquonk sugirió. Además, tiene otro BroadcastReceiver registrado en el manifiesto, cuyo <intent-filter> es para la emisión real que estás escuchando. Ese receptor simplemente llamaría sendOrderedBroadcast() para enviar la emisión ordenada que los otros receptores están escuchando.

Escenario D: Actividad Independientemente del Primer Plano

Si alguna actividad suya necesita saber acerca de la emisión, y no importa si está o no en primer plano, necesita repensar lo que quiere decir con eso. Normalmente esto significa que la transmisión afecta su modelo de datos de alguna manera, en cuyo caso su preocupación no debe ser dejar que las actividades lo sepan, sino más bien actualizar su modelo de datos, y utilizar su ya existente "que las actividades conozcan El cambio de modelo de datos "lógica manejar el resto.

Sin embargo, si está convencido de que esto no forma parte de su modelo de datos, puede implementar el Escenario B o el Escenario C, además de insertar alguna información en un miembro de datos estáticos. Sus actividades pueden examinar ese miembro de datos estáticos en onResume() para recoger la información sobre la transmisión cuando regresan al primer plano.

Si estás pensando "pero, ¿qué pasa si mi proceso se termina entre la transmisión y la otra actividad que viene al primer plano?", Entonces su transmisión realmente está actualizando su modelo de datos, por el párrafo de apertura de este escenario.

Si estás pensando "pero, quiero actualizar una actividad que está haciendo el trabajo en segundo plano", entonces la actividad en cuestión está rota. Las actividades nunca deben estar haciendo el trabajo en segundo plano. Ese trabajo debe ser delegado a alguna forma de servicio, y hay un conjunto de escenarios relacionados para obtener una difusión al servicio.

Para transmitir una intención:

 Intent intent = new Intent("com.yourcompany.testIntent"); intent.putExtra("value","test"); sendBroadcast(intent); 

Para recibir la misma intención, utilice:

 IntentFilter filter = new IntentFilter("com.yourcompany.testIntent"); BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String value = intent.getExtras().getString("value"); } }; registerReceiver(receiver, filter); 

Posiblemente no es relevante en el momento de la pregunta que se hace, pero ahora hay el LocalBroadcastManager en el paquete de soporte de Android.

Funciona prácticamente de la misma manera que las transmisiones normales, pero todas las "conversaciones" son locales de la aplicación en la que se está ejecutando.

Ventajas:

  • Sabes que los datos que estás difundiendo no dejarán tu aplicación, así que no tengas que preocuparte por la filtración de datos privados.
  • No es posible que otras aplicaciones envíen estas emisiones a su aplicación, por lo que no es necesario preocuparse por tener fallas de seguridad que puedan explotar.
  • Es más eficiente que enviar una emisión global a través del sistema.

Ejemplo:

 Intent i = new Intent("my.local.intent"); LocalBroadcastManager.getInstance(context).sendBroadcast(i); 

Y recibir

 receiver = new MyBroadcastReceiverToHandleLocalBroadcast(); IntentFilter i = new IntentFilter(); i.addAction("my.local.intent"); LocalBroadcastManager.getInstance(context).registerReceiver(receiver, i); 
  • BroadcastReceiver cómo iniciar una nueva intención
  • Seguimiento de la duración de una llamada telefónica
  • Permiso personalizado con intención implícita
  • Administrador de alarmas que no funciona en intervalos de tiempo específicos
  • Comunicación entre BroadcastReceiver y Activity - android
  • Android: detecta cuando la aplicación está instalada
  • Importante no es para un buen diseño de la aplicación android (principiante / nivel de principiante)?
  • ¿Necesito un bloqueo de despertador en mi transmisor-receptor si no estoy iniciando un servicio o una actividad?
  • Extensión Dashclock Widget sin actualizar
  • Broadcast receptor onReceive () recibiendo llamadas varias veces
  • TIMEZONE_CHANGED intención que se recibe cada pocos segundos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.