Je comprends donc (je pense) les intentions de diffusion et la réception de messages à leur intention.
Alors maintenant, mon problème/ce que je ne peux pas résoudre, c'est comment envoyer un message de la méthode onReceive
d'un récepteur à une activité. Disons que j'ai un récepteur en tant que tel:
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
}
}
}
Comment envoyer un message à une activité?
Dois-je instancier le récepteur dans l'activité à laquelle je veux envoyer des messages et le surveiller d'une manière ou d'une autre? Ou quoi? Je comprends le concept, mais pas vraiment l'application.
Toute aide serait absolument incroyable, merci.
À M
ÉDITÉ Exemples de code corrigé pour l'enregistrement/le désenregistrement de BroadcastReceiver
et également suppression de la déclaration de manifeste.
Définissez ReceiveMessages
comme classe interne au sein du Activity
qui doit écouter les messages du Service
.
Ensuite, déclarez des variables de classe telles que ...
ReceiveMessages myReceiver = null;
Boolean myReceiverIsRegistered = false;
Dans onCreate()
utilisez myReceiver = new ReceiveMessages();
Puis dans onResume()
...
if (!myReceiverIsRegistered) {
registerReceiver(myReceiver, new IntentFilter("com.mycompany.myapp.SOME_MESSAGE"));
myReceiverIsRegistered = true;
}
... et dans onPause()
...
if (myReceiverIsRegistered) {
unregisterReceiver(myReceiver);
myReceiverIsRegistered = false;
}
Dans le Service
créez et diffusez le Intent
...
Intent i = new Intent("com.mycompany.myapp.SOME_MESSAGE");
sendBroadcast(i);
Et c'est tout. Rendez l'action unique à votre package/application, c'est-à-dire com.mycompany...
Comme dans mon exemple. Cela permet d'éviter une situation où d'autres applications ou composants système pourraient tenter de le traiter.
Aucune offense, mais votre question est encore sacrément vague. Donc, je vais décrire tout un tas de scénarios et j'espère que l'un d'eux rencontrera le problème que vous pensez avoir.
Si vous avez seulement besoin de recevoir la diffusion lorsque vous avez une activité au premier plan, demandez à l'activité d'enregistrer le BroadcastReceiver
à l'aide de registerReceiver()
. Comme @MisterSquonk l'a indiqué, vous devez enregistrer le récepteur dans onResume()
et le désinscrire dans onPause()
.
Si vous voulez que l'activité de premier plan gère la diffusion, mais vous voulez que quelque chose d'autre se produise si cette activité n'est pas au premier plan (par exemple, élevez un Notification
), et la diffusion est une diffusion ordonnée (par exemple, entrante SMS), alors vous utiliseriez toujours la solution du scénario A, mais avec une priorité plus élevée IntentFilter
(voir setPriority()
). De plus, vous enregistreriez un BroadcastReceiver
via un élément <receiver>
Dans le manifeste, avec une priorité inférieure <intent-filter>
Pour la même diffusion. Dans BroadcastReceiver
de l'activité, appelez abortBroadcast()
pour consommer l'événement et l'empêcher d'atteindre votre BroadcastReceiver
enregistré par manifeste.
Si le scénario B correspond presque, mais que la diffusion que vous écoutez n'est pas une diffusion ordonnée, vous devrez commencer par le scénario B. Cependant, la diffusion que les deux récepteurs ont dans leurs filtres respectifs soit la vôtre, en utilisant une chaîne privée chaîne d'action comme l'a suggéré @MisterSquonk. De plus, ayez un autre BroadcastReceiver
enregistré dans le manifeste, dont <intent-filter>
Est pour la vraie émission que vous écoutez pour. Ce récepteur appellerait simplement sendOrderedBroadcast()
pour envoyer la diffusion ordonnée que les autres récepteurs écoutent.
Si une de vos activités a besoin d'être informée de la diffusion, et qu'elle importe ou non au premier plan, vous devez repenser ce que vous entendez par là. Habituellement, cela signifie vraiment que la diffusion affecte votre modèle de données d'une manière ou d'une autre, auquel cas votre souci ne devrait pas être de faire savoir aux activités, mais plutôt pour mettre à jour votre modèle de données et utiliser votre logique "informer les activités sur le changement de modèle de données" déjà existante pour gérer le reste.
Si, toutefois, vous êtes convaincu que cela ne fait pas partie de votre modèle de données, vous pouvez implémenter le scénario B ou le scénario C, ainsi que coller des informations dans un membre de données statiques. Vos activités peuvent examiner ce membre de données statiques dans onResume()
pour récupérer les informations sur la diffusion à leur retour au premier plan.
Si vous pensez "mais, que se passe-t-il si mon processus se termine entre la diffusion et les autres activités qui arrivent au premier plan?", Alors votre diffusion est vraiment est mise à jour de votre modèle de données, selon le premier paragraphe de ce scénario.
Si vous pensez "mais, je veux mettre à jour une activité qui fait du travail en arrière-plan", alors l'activité en question est interrompue. Les activités ne devraient jamais faire de travail en arrière-plan. Ce travail devrait être délégué à une certaine forme de service, et il existe tout un ensemble de scénarios connexes pour obtenir une diffusion sur le service.
Pour diffuser une intention:
Intent intent = new Intent("com.yourcompany.testIntent");
intent.putExtra("value","test");
sendBroadcast(intent);
Pour recevoir la même intention, utilisez:
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);
Peut-être pas pertinent au moment de la question, mais il y a maintenant LocalBroadcastManager dans le Android Support Package).
Fonctionne à peu près de la même manière que les émissions normales, mais tous les "bavardages" sont locaux à l'application dans laquelle ils s'exécutent.
Avantages:
Exemple:
Intent i = new Intent("my.local.intent");
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
et recevoir
receiver = new MyBroadcastReceiverToHandleLocalBroadcast();
IntentFilter i = new IntentFilter();
i.addAction("my.local.intent");
LocalBroadcastManager.getInstance(context).registerReceiver(receiver, i);