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:
- Android: la actividad se ha filtrado IntentReceiver
- ¿Es posible registrar un receptor en un caso de prueba?
- Cuando los incendios de Android ACTION_BATTERY_LOW
- AlarmManager: cómo programar una alarma diaria y hacer frente a cambios de tiempo
- Detectar el compartidor utilizado para compartir contenido
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
- BroadcastReceiver no recibe BOOT_COMPLETED
- ¿Es posible leer el historial de costos de llamadas desde el diálogo planteado después de finalizar la llamada de prepago?
- anular el registro de las llamadas de difusión antes de onReceive () listenens
- ¿Cómo detectar el cambio de estado Bluetooth con un receptor de difusión?
- deshabilitar el paquete que instala mediante programación
- ¿Cómo usar "goAsync" para broadcastReceiver?
- ¿AlarmManager requiere que PendingIntent sea del tipo BroadcastReceiver?
- Cómo detener SMS de pasar a Bandeja de entrada
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);