web-dev-qa-db-fra.com

Annulation de l'enregistrement du récepteur de diffusion Android dans onReceive émet le message "Récepteur non enregistré"

J'ai un BroadcastReceiver pour un usage unique. 

Je l'enregistre dans une activité. Je ne peux pas mettre la unregisterReceiver() dans onPause car elle doit rester en marche même lorsque l'activité est suspendue ou détruite. 

Je veux que BroadcastReceiver se désenregistre quand il est terminé, quelque chose comme ceci:

public class SmsReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
           // do some code..
           context.unregisterReceiver(this)
        }
}

Mais cela provoque une exception: Receiver not registered. 

21
shaimagz

Une BroadcastReceiver n'existe que lors de l'exécution de sa méthode onReceive(). Ainsi, this est évalué comme une instance à jeter chaque fois que la diffusion est déclenchée/reçue. Voir Cycle de vie du récepteur de radiodiffusion . Pour enregistrer/désenregistrer dynamiquement BroadcastReceivers, vous devez vous rappeler l'instance de votre récepteur dans onPause() pour la réenregistrer pendant onResume().

24
tichy

Je sais que cette question a déjà une réponse Mais essayez ce code

Ce code est pour BatteryInfo. Et ça a marché. 

private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context arg0, Intent intent) {
        // TODO Auto-generated method stub
        int level = intent.getIntExtra("level", 0);
        Log.i("Battery", String.valueOf(level) + "%");
        arg0.unregisterReceiver(mBatInfoReceiver);
    }

};

//Below code is the Code which attaches the reciever put this code in which ever place you want. 

this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(
                Intent.ACTION_BATTERY_CHANGED));

Référence pour attacher StackOverFlow / Tutorial

10
MDMalik

Ajoutez simplement un appel de méthode à l'activité dans laquelle vous l'avez enregistrée et, dans la méthode that, annulez l'inscription du destinataire. De cette façon, vous savez que son travail a été fait.

Cependant, le récepteur ne fonctionnera pas si l'activité est suspendue ou détruite de toute façon. Vous devez le déclarer dans le manifeste ou l'enregistrer dans un service de longue durée pour qu'il continue de fonctionner en dehors de la durée de vie d'une activité. Autant que je sache, vous ne pouvez pas désenregistrer un récepteur déclaré dans le manifeste, car vous ne recevez pas l'instance avec laquelle il est enregistré. Mais l'appel de méthode au service pour l'annuler doit fonctionner.

Si vous avez simplement besoin d'un opérateur pour une utilisation unique, déclarez un IntentService exporté dans le manifeste avec l'action que vous diffusez. Ce service IntentService sera lancé dès que l'intention sera reçue et compte tenu de l'intention qui l'a lancé, puis, une fois son travail accompli, il s'arrêtera tout seul. 

3
Austin B

J'ai rencontré le même problème, en fait, la bonne réponse est LocalBroadcastManager.getInstance(context).unregisterReceiver(this); mais pas context.unregisterReceiver(this)

2
user2966072

Vous l'avez probablement déjà enregistrée ailleurs dans votre programme, aussi improbable que cela puisse paraître. Peut-être quelque part avant votre context.unregisterReceiver, mais dans la méthode onReceive, vous appelez une action, ce qui entraîne l'annulation de l'enregistrement du récepteur avant d'atteindre context.unregisterReceiver

Assurez-vous simplement de désenregistrer le récepteur du moins possible d’endroits, de préférence exactement un.

0
George

Le problème est peut-être que vous essayez de désenregistrer le destinataire du contexte récepteur au lieu du contexte dans lequel il a été enregistré à l'origine.

0
hvuoltee

Avez-vous essayé de désenregistrer le récepteur d'un service/d'une activité? Peut-être y at-il un problème si vous appelez le destinataire pour annuler sa propre inscription.

0
mdelolmo