Question

Je dois vérifier si mon récepteur enregistré est toujours enregistré sinon comment puis-je le vérifier toutes les méthodes?

Était-ce utile?

La solution

Je ne suis pas sûr de l'API fournit directement une API, si vous considérez ce fil :

  

Je me demandais la même chose.
  Dans mon cas, j'ai une implémentation BroadcastReceiver que les appels   Context#unregisterReceiver(BroadcastReceiver) se passe comme argument après avoir manipulé l'intention qu'il reçoit.
  Il y a une petite chance que la méthode de onReceive(Context, Intent) du récepteur est appelé   plus d'une fois, puisqu'il est inscrit sur plusieurs IntentFilters, créant ainsi le potentiel d'un IllegalArgumentException être projetés de Context#unregisterReceiver(BroadcastReceiver).

     

Dans mon cas, je peux stocker un membre synchronisé privé à vérifier avant d'appeler Context#unregisterReceiver(BroadcastReceiver), mais il serait   beaucoup plus propre si l'API a fourni une méthode de vérification.

Autres conseils

Il n'y a pas de fonction API pour vérifier si un récepteur est enregistré. La solution est de mettre votre code dans un try catch block as done below.

try {

 //Register or UnRegister your broadcast receiver here

} catch(IllegalArgumentException e) {

    e.printStackTrace();
}

solution la plus simple

Récepteur:

public class MyReceiver extends BroadcastReceiver {   
    public boolean isRegistered;

    /**
    * register receiver
    * @param context - Context
    * @param filter - Intent Filter
    * @return see Context.registerReceiver(BroadcastReceiver,IntentFilter)
    */
    public Intent register(Context context, IntentFilter filter) {
        try {
              // ceph3us note:
              // here I propose to create 
              // a isRegistered(Contex) method 
              // as you can register receiver on different context  
              // so you need to match against the same one :) 
              // example  by storing a list of weak references  
              // see LoadedApk.class - receiver dispatcher 
              // its and ArrayMap there for example 
              return !isRegistered 
                     ? context.registerReceiver(this, filter) 
                     : null;
            } finally {
               isRegistered = true;
            }
    }

    /**
     * unregister received
     * @param context - context
     * @return true if was registered else false
     */
     public boolean unregister(Context context) {
         // additional work match on context before unregister
         // eg store weak ref in register then compare in unregister 
         // if match same instance
         return isRegistered 
                    && unregisterInternal(context);
     }

     private boolean unregisterInternal(Context context) {
         context.unregisterReceiver(this); 
         isRegistered = false;
         return true;
     }

    // rest implementation  here 
    // or make this an abstract class as template :)
    ...
}

dans le code:

MyReceiver myReceiver = new MyReceiver();
myReceiver.register(Context, IntentFilter); // register 
myReceiver.unregister(Context); // unregister 

Annonce 1

- en réponse à:

  

Ce qui est vraiment pas élégant parce que vous devez vous rappeler de régler la   drapeau isRegistered après votre inscription. - Rabbi Furtif

- « plus façon ellegant » méthode ajoutée dans le récepteur à l'inscription et le drapeau ensemble

  

cela ne fonctionnera pas si vous redémarrez l'appareil ou si votre application a été tué par   OS. - il y a 6 heures amin

@amin - voir durée de vie dans le code (non enregistré par le système d'entrée manifeste) récepteur enregistré:)

J'utilise cette solution

public class ReceiverManager {

    private static List<BroadcastReceiver> receivers = new ArrayList<BroadcastReceiver>();  
    private static ReceiverManager ref;
    private Context context;

    private ReceiverManager(Context context){
        this.context = context;
    }

    public static synchronized ReceiverManager init(Context context) {      
        if (ref == null) ref = new ReceiverManager(context);
        return ref;
    }

    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter){
        receivers.add(receiver);
        Intent intent = context.registerReceiver(receiver, intentFilter);
        Log.i(getClass().getSimpleName(), "registered receiver: "+receiver+"  with filter: "+intentFilter);
        Log.i(getClass().getSimpleName(), "receiver Intent: "+intent);
        return intent;
    }

    public boolean isReceiverRegistered(BroadcastReceiver receiver){
        boolean registered = receivers.contains(receiver);
        Log.i(getClass().getSimpleName(), "is receiver "+receiver+" registered? "+registered);
        return registered;
    }

    public void unregisterReceiver(BroadcastReceiver receiver){
        if (isReceiverRegistered(receiver)){
            receivers.remove(receiver);
            context.unregisterReceiver(receiver);
            Log.i(getClass().getSimpleName(), "unregistered receiver: "+receiver);
        }
    }
}

Vous avez plusieurs options

  1. Vous pouvez mettre un drapeau dans votre classe ou activité. Mettez une variable booléenne dans votre classe et regardez ce drapeau savoir si vous avez le récepteur enregistré.

  2. Créer une classe qui étend le récepteur et là, vous pouvez utiliser:

    1. modèle Singleton pour seulement avoir une instance de cette classe dans votre projet.

    2. Mettre en œuvre les méthodes pour savoir si le récepteur est registre.

Vous devez utiliser try / catch:

try {
    if (receiver!=null) {
        Activity.this.unregisterReceiver(receiver);
    }
} catch (IllegalArgumentException e) {
    e.printStackTrace();
}

Vous pouvez le faire facilement ....

1) créer une variable booléenne ...

private boolean bolBroacastRegistred;

2) Lorsque vous enregistrez votre récepteur de diffusion, réglez TRUE

...
bolBroacastRegistred = true;
this.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
....

3) Dans le OnPause () le font ...

if (bolBroacastRegistred) {
    this.unregisterReceiver(mReceiver);
    bolBroacastRegistred = false
}

Juste, et maintenant, vous ne recevrez pas plus message d'erreur d'exception sur OnPause ().

Astuce1: Toujours utiliser le unregisterReceiver () dans OnPause () pas dans OnDestroy () Tip2: Ne pas oublier de définir la variable bolBroadcastRegistred FALSE lorsque exécuter le unregisterReceive ()

Succès!

Si vous mettez cette méthode sur OnDestroy ou onStop. Je pense que lorsque l'activité a été créé à nouveau la MessageReciver n'a pas été créé.

@Override 
public void onDestroy (){
    super.onDestroy();
LocalBroadcastManager.getInstance(context).unregisterReceiver(mMessageReceiver);

}

J'utilisé intention de laisser savoir au sujet de diffusion récepteur par exemple gestionnaire de thread principal d'activité et un message utilisé pour transmettre un message à l'activité principale

Je l'ai utilisé ce mécanisme pour vérifier si le récepteur de radiodiffusion est déjà enregistré ou non. Parfois, il est nécessaire lorsque vous enregistrez votre récepteur de diffusion dynamique et ne veulent pas faire deux fois ou vous présenter à l'utilisateur si le récepteur de diffusion est en cours d'exécution.

Activité principale:

public class Example extends Activity {

private BroadCastReceiver_example br_exemple;

final Messenger mMessenger = new Messenger(new IncomingHandler());

private boolean running = false;

static class IncomingHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        running = false;    
        switch (msg.what) {
        case BroadCastReceiver_example.ALIVE:
    running = true;
            ....
            break;
        default:

            super.handleMessage(msg);
        }

    }
    }

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    IntentFilter filter = new IntentFilter();
        filter.addAction("pl.example.CHECK_RECEIVER");

        br_exemple = new BroadCastReceiver_example();
        getApplicationContext().registerReceiver(br_exemple , filter); //register the Receiver
    }

// call it whenever you want to check if Broadcast Receiver is running.

private void check_broadcastRunning() {    
        /**
        * checkBroadcastHandler - the handler will start runnable which will check if Broadcast Receiver is running
        */
        Handler checkBroadcastHandler = null;

        /**
        * checkBroadcastRunnable - the runnable which will check if Broadcast Receiver is running
        */
        Runnable checkBroadcastRunnable = null;

        Intent checkBroadCastState = new Intent();
        checkBroadCastState .setAction("pl.example.CHECK_RECEIVER");
        checkBroadCastState .putExtra("mainView", mMessenger);
        this.sendBroadcast(checkBroadCastState );
        Log.d(TAG,"check if broadcast is running");

        checkBroadcastHandler = new Handler();
        checkBroadcastRunnable = new Runnable(){    

            public void run(){
                if (running == true) {
                    Log.d(TAG,"broadcast is running");
                }
                else {
                    Log.d(TAG,"broadcast is not running");
                }
            }
        };
        checkBroadcastHandler.postDelayed(checkBroadcastRunnable,100);
        return;
    }

.............
}

Diffusion du récepteur:

public class BroadCastReceiver_example extends BroadcastReceiver {


public static final int ALIVE = 1;
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Bundle extras = intent.getExtras();
    String action = intent.getAction();
    if (action.equals("pl.example.CHECK_RECEIVER")) {
        Log.d(TAG, "Received broadcast live checker");
        Messenger mainAppMessanger = (Messenger) extras.get("mainView");
        try {
            mainAppMessanger.send(Message.obtain(null, ALIVE));
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    .........

}

}

Personnellement, j'utiliser la méthode d'appeler unregisterReceiver et à avaler l'exception si elle est levée. Je suis d'accord ce qui est laid, mais la meilleure méthode actuellement fourni.

J'ai soulevé une demande de fonctionnalité pour obtenir une méthode booléenne pour vérifier si un récepteur est enregistré ajouté à l'API Android. S'il vous plaît soutenir ici si vous voulez voir ajouté: https://code.google.com/p/android/issues/detail ? id = 73718

Je reçois votre problème, je fait face au même problème dans ma demande. J'ai appelé registerReceiver () temps multiples dans l'application.

Une solution simple à ce problème est d'appeler le registerReceiver () dans votre classe d'application personnalisée. Cela garantira que votre récepteur de diffusion sera appelée une seule dans votre cycle de vie des applications.

public class YourApplication extends Application
{
    @Override
    public void onCreate()
    {
        super.onCreate();

        //register your Broadcast receiver here
        IntentFilter intentFilter = new IntentFilter("MANUAL_BROADCAST_RECIEVER");
        registerReceiver(new BroadcastReciever(), intentFilter);

    }
}

Voici comment je l'ai fait, il est une version modifiée de la réponse donnée par ceph3us et édité par slinden77 (entre autres choses que j'ai des valeurs de retour retirées de méthodes que je n'ai pas besoin):

public class MyBroadcastReceiver extends BroadcastReceiver{
    private boolean isRegistered; 

    public void register(final Context context) {
        if (!isRegistered){
            Log.d(this.toString(), " going to register this broadcast receiver");
            context.registerReceiver(this, new IntentFilter("MY_ACTION"));
            isRegistered = true;
        }
    }
    public void unregister(final Context context) {
        if (isRegistered) {            
            Log.d(this.toString(), " going to unregister this broadcast receiver");
            context.unregisterReceiver(this);
            isRegistered = false;
        }
    }
    @Override
    public void onReceive(final Context context, final Intent intent) {        
        switch (getResultCode()){
        //DO STUFF
        }        
    }        
}

Ensuite, sur une classe d'activité:

public class MyFragmentActivity extends SingleFragmentActivity{
    MyBroadcastReceiver myBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        registerBroacastReceiver();       
    }

    @Override
    protected Fragment createFragment(){
        return new MyFragment();
    }

    //This method is called by the fragment which is started by this activity, 
    //when the Fragment is done, we also register the receiver here (if required)
    @Override
    public void receiveDataFromFragment(MyData data) {
        registerBroacastReceiver();
        //Do some stuff                
    }

    @Override
    protected void onStop(){        
        unregisterBroacastReceiver();
        super.onStop();
    }

    void registerBroacastReceiver(){
        if (myBroadcastReceiver == null)
            myBroadcastReceiver = new MyBroadcastReceiver();
        myBroadcastReceiver.register(this.getApplicationContext());
    }

    void unregisterReceiver(){
        if (MyBroadcastReceiver != null)
            myBroadcastReceiver.unregister(this.getApplicationContext());
    }
}

i mettre ce code dans mon activité parent

Liste registeredReceivers = new ArrayList <> ();

@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    registeredReceivers.add(System.identityHashCode(receiver));
    return super.registerReceiver(receiver, filter);
}

@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
    if(registeredReceivers.contains(System.identityHashCode(receiver)))
    super.unregisterReceiver(receiver);
}

Voici ce que je l'ai fait pour vérifier si le Broadcaster est déjà enregistré, même si vous fermez l'application (finition ())

Firstime exécuter votre application, envoyer une émission d'abord il retourne vrai / faux dépend si votre diffuseur en cours d'exécution ou non encore.

Mon Broadcaster

public class NotificationReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getExtras() != null && intent.getStringExtra("test") != null){
            Log.d("onReceive","test");
            return;
        }
    }
}

Mon MainActivity

// init Broadcaster
private NotificationReceiver nr = new NotificationReceiver();


Intent msgrcv = new Intent("Msg");
msgrcv.putExtra("test", "testing");
boolean isRegistered = LocalBroadcastManager.getInstance(this).sendBroadcast(msgrcv);

if(!isRegistered){
    Toast.makeText(this,"Starting Notification Receiver...",Toast.LENGTH_LONG).show();
    LocalBroadcastManager.getInstance(this).registerReceiver(nr,new IntentFilter("Msg"));
}

Vous pouvez utiliser Dagger pour créer une référence de ce récepteur.

Tout d'abord lui fournir:

@Provides
@YourScope
fun providesReceiver(): NotificationReceiver{
    return NotificationReceiver()
}

Alors injectent où vous avez besoin (en utilisant constructor ou d'un champ injection)

et il suffit de passer à registerReceiver.

En outre, il a mis dans le bloc de try/catch aussi.

if( receiver.isOrderedBroadcast() ){
     // receiver object is registered
}
else{
     // receiver object is not registered
}

Il suffit de vérifier NullPointerException. Si le récepteur n'existe pas, ...

try{
    Intent i = new Intent();
    i.setAction("ir.sss.smsREC");
    context.sendBroadcast(i);
    Log.i("...","broadcast sent");
}
catch (NullPointerException e)
{
    e.getMessage();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top