49 votes

BroadcastReceiver Android au sein d'une activité

J'essaie juste ce petit projet d'exemple, tout ce qu'il fait : L'activité 1 a un bouton qui envoie une diffusion. L'activité 2 affiche un toast lorsqu'il est reçu. Voici le code, la diffusion n'est jamais reçue. Qu'est-ce qui ne va pas ?

Envoi de la diffusion

public class SendBroadcast extends Activity {

    public static String BROADCAST_ACTION = "com.unitedcoders.android.broadcasttest.SHOWTOAST";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void sendBroadcast(View v){
        Intent broadcast = new Intent();
        broadcast.setAction(BROADCAST_ACTION);
        sendBroadcast(broadcast);
    }
}

Le recevoir

public class ToastDisplay extends Activity {

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
        }
    };

    @Override
    protected void onResume() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(SendBroadcast.BROADCAST_ACTION);
        registerReceiver(receiver, filter);
        super.onResume();
    }

    @Override
    protected void onPause() {
        unregisterReceiver(receiver);
        super.onPause();
    }
}

Manifeste

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".SendBroadcast" android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".ToastDisplay">
        <intent-filter>
            <action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"></action>
        </intent-filter>
    </activity>
</application>

0 votes

Avez-vous trouvé une réponse à cette question ? J'ai le même problème. J'ai en fait un service local qui diffuse une intention que l'activité actuellement ouverte écoute (en enregistrant un récepteur de diffusion, comme vous le faites ci-dessus). L'activité ne reçoit jamais le message. Je n'ai rien mis dans le manifeste, mais comme j'enregistre le récepteur de diffusion, je ne pensais pas avoir besoin de le faire. Avez-vous réussi à faire fonctionner le vôtre ?

0 votes

Merci. Il s'avère que mon question en était une autre, qui consistait à spécifier des types MIME.

0 votes

Je suis en train de chercher la même chose et j'ai implémenté le code ci-dessus, mais il ne fonctionne pas, ce qui signifie que Broadcat envoie des données à d'autres activités.

42voto

geekQ Points 8796

Qu'est-ce qui ne va pas ?

Le code source de ToastDisplay est correct (le mien est similaire et fonctionne), mais il ne recevra quelque chose que s'il est actuellement au premier plan (vous enregistrez le récepteur dans onResume). Mais il ne peut rien recevoir si une activité différente (dans ce cas l'activité SendBroadcast) est affichée.

Au lieu de cela, vous voudrez probablement startActivity ToastDisplay de la première activité ?

BroadcastReceiver et Activity sont utiles dans un cas d'utilisation différent. Dans mon application J'ai besoin de recevoir des notifications d'un service de suivi GPS en arrière-plan et de les afficher dans l'activité (si l'activité se trouve dans la section premier plan ).

Il n'est pas nécessaire de enregistrer le récepteur dans le manifeste . Il serait même néfaste dans mon cas d'utilisation - mon récepteur manipule l'interface utilisateur de l'activité et l'interface utilisateur ne serait pas disponible pendant onReceive si l'activité n'est pas actuellement affichée. Au lieu de cela, j'enregistre et désenregistre le récepteur pour l'activité dans onResume et onPause comme décrit dans Documentation de BroadcastReceiver :

Vous pouvez soit enregistrer dynamiquement une instance de cette classe avec Context.registerReceiver(), soit publier statiquement une implémentation via la balise dans votre AndroidManifest.xml.

0 votes

Comment vérifier dans la méthode onReceive() de BroadcastReceiver quelle activité est au premier plan ?

2 votes

@zmeda ce n'est pas comme ça qu'il faut penser : soit on sait quelles activités peuvent être impactées par un boradcastreceiver et on enregistre un récepteur pour toutes, soit on ne veut pas interagir avec les activités et on enregistre le récepteur dans le manifeste de l'app.

0 votes

Une question. Y a-t-il une raison d'appeler le super à la fin des deux méthodes ? Ou bien cela n'a-t-il pas d'importance ? Je vous remercie.

39voto

rfsk2010 Points 5333
 Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);

fait le toast, mais ne le montre pas.

Vous devez faire Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT).show();

2 votes

+1 : Je mettrais plusieurs fois un upvote si je le pouvais - combien de fois ai-je eu l'habitude de le faire. Je pense que c'est une erreur TELLEMENT commune.

5 votes

Qui veut créer un toast et ne veut pas le montrer. Commande inutile : show(). lol

3 votes

@alicanbatur bien que tardive : Parce qu'on peut manipuler l'objet toast

5voto

Tushar Bapte Points 31

Étend la classe ToastDisplay avec BroadcastReceiver et enregistre le récepteur dans le fichier manifest, et n'enregistre pas le récepteur de diffusion dans onResume().

<application
  ....
  <receiver android:name=".ToastDisplay">
    <intent-filter>
      <action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
    </intent-filter>
  </receiver>
</application>

si vous voulez vous enregistrer dans l'activité, faites-le dans la méthode onCreate(), par exemple :

onCreate(){

    sentSmsBroadcastCome = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "SMS SENT!!", Toast.LENGTH_SHORT).show();
        }
    };
    IntentFilter filterSend = new IntentFilter();
    filterSend.addAction("m.sent");
    registerReceiver(sentSmsBroadcastCome, filterSend);
}

4voto

Vitaly Polonetsky Points 5264

Vous devez définir le récepteur comme une classe dans le manifeste et il recevra l'intention :

<application
  ....
  <receiver android:name=".ToastReceiver">
    <intent-filter>
      <action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
    </intent-filter>
  </receiver>
</application>

Il n'est pas nécessaire de créer manuellement la classe à l'intérieur de ToastDisplay.

Dans le code que vous avez fourni, vous devez être dans l'activité ToastDisplay pour recevoir l'intention.

0 votes

Mais que dois-je faire si je veux que ce soit une activité, parce que par exemple je veux changer certaines étiquettes ?

0 votes

Veuillez expliquer plus en détail ce que vous essayez de faire. Il se peut que vous n'ayez pas besoin d'utiliser BroadcastReceiver et que vous lanciez simplement une autre Thread pour cela (AsyncTask est la meilleure solution) ? Vous pouvez également renvoyer une intention à l'activité.

0 votes

Supposons que l'activité 2 (la partie réceptrice) soit une activité affichant des données statistiques. Chaque fois qu'un utilisateur effectue un événement spécial dans l'activité 1 ou qu'un service d'arrière-plan dispose de nouvelles informations, je veux mettre à jour les informations dans l'activité 2.

1voto

daigoor Points 468

Je pense que votre problème est que vous envoyez la diffusion avant que l'autre activité ne commence ! l'autre activité ne recevra donc rien.

  1. La meilleure pratique pour tester votre code est d'envoyer un message à partir d'un thread ou d'un service afin que l'activité soit ouverte et qu'elle soit enregistrée en tant que récepteur et que le processus en arrière-plan envoie un message.
  2. démarrer l'activité ToastDisplay à partir de l'activité de l'expéditeur ( je n'ai pas testé cela mais cela peut probablement fonctionner )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X