Frage

Ich muss überprüfen, ob mein registrierte Empfänger noch registriert ist, wenn nicht, wie kann ich es irgendwelche Methoden überprüfen?

War es hilfreich?

Lösung

Ich bin nicht sicher, dass die API direkt eine API, wenn man bedenkt, dieses Thema :

  

Ich habe das Gleiche fragen.
  In meinem Fall habe ich eine BroadcastReceiver Implementierung dass Anrufe   Context#unregisterReceiver(BroadcastReceiver) vorbei selbst als Argument nach der Intention der Handhabung, die es empfängt.
  Es gibt eine kleine Chance, dass der onReceive(Context, Intent) Methode des Empfängers aufgerufen   da es mit mehreren IntentFilters mehr als einmal registriert ist, das Potenzial für eine IllegalArgumentException Schaffung von Context#unregisterReceiver(BroadcastReceiver) geworfen.

     

In meinem Fall kann ich ein eigenes synchronisiert Mitglied Check speichern, bevor Context#unregisterReceiver(BroadcastReceiver) anrufen, aber es wäre   viel sauberer, wenn die API ein Kontrollverfahren bereitgestellt.

Andere Tipps

Es gibt keine API-Funktion zu überprüfen, ob ein Empfänger registriert ist. Die Abhilfe ist Ihr Code in einem try catch block as done below.

setzen
try {

 //Register or UnRegister your broadcast receiver here

} catch(IllegalArgumentException e) {

    e.printStackTrace();
}

einfachste Lösung

in Empfänger:

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 :)
    ...
}

in dem Code ein:

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

ad 1

- in Antwort auf:

  

Dieser wirklich nicht so elegant, weil Sie daran zu erinnern, haben die festlegen   isRegistered Flagge nach der Registrierung. - Stealth Rabbi

- „mehr ellegant Art und Weise“, fügte Verfahren in Empfänger zu registrieren und Einstellmerker

  

das wird nicht funktionieren, wenn Sie das Gerät oder wenn Ihre Anwendung neu starten, wurde getötet von   O. - amin Vor 6 Stunden

@amin - siehe Lebensdauer in Code (System nicht mit offensichtlichem Eintrag registriert) registrierte Empfänger:)

Ich bin mit dieser Lösung

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);
        }
    }
}

Sie haben mehrere Möglichkeiten

  1. Sie können eine Flagge in Ihrer Klasse oder Aktivität setzen. Legen Sie eine boolean Variable in die Klasse und Blick auf diese Flagge zu wissen, ob der Empfänger registriert haben.

  2. Erstellen Sie eine Klasse, die den Receiver und es erstreckt können Sie:

    1. Singleton-Muster für nur eine Instanz dieser Klasse haben in Ihrem Projekt.

    2. Implementieren Sie die Methoden für wissen, ob der Empfänger-Register ist.

Sie haben try / catch verwenden:

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

Sie können es einfach ....

1) erstellen Sie eine boolean Variable ...

private boolean bolBroacastRegistred;

2) Wenn Sie Ihren Sendungs-Empfänger registrieren, setzen Sie sich auf TRUE

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

3) Im onPause () zu tun ... es

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

Just, und jetzt, Sie erhalten nicht mehr Ausnahmefehlermeldung auf onPause ().

Tip1: Verwenden Sie immer die unregisterReceiver () in onPause () nicht in onDestroy () Tip2: Vergessen Sie nicht, die bolBroadcastRegistred Variable auf FALSE zu setzen, wenn die unregisterReceive run ()

Erfolg!

Wenn Sie diese setzen auf onDestroy oder OnStop Methode. Ich denke, dass, wenn die Aktivität wieder erstellt wurde die MessageReciver wurde nicht erstellt werden.

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

}

I verwendet Intent Broadcast-Empfänger wissen über Handler Instanz Hauptaktivität Thread und gebrauchte Nachricht lassen Sie eine Nachricht an Haupttätigkeit zu übergeben

habe ich solchen Mechanismus zu überprüfen, ob Broadcast-Receiver ist bereits registriert oder nicht. Manchmal ist es erforderlich, wenn Sie Ihren Broadcast-Empfänger dynamisch registrieren und will es nicht zweimal machen oder Sie präsentieren den Benutzer, wenn Broadcast-Empfänger ausgeführt wird.

Haupttätigkeit:

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;
    }

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

Broadcast-Empfänger:

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();
        }
    }
    .........

}

}

Ich persönlich verwende die Methode der unregisterReceiver Aufrufs und beim Schlucken der Ausnahme, wenn es geworfen wird. Ich bin damit einverstanden dies ist hässlich, aber die beste Methode, die derzeit zur Verfügung gestellt.

Ich habe einen Feature-Request angehoben ein boolean Verfahren zu überprüfen, um zu bekommen, wenn ein Empfänger registriert ist mit dem Android-API hinzugefügt. Bitte unterstützen Sie hier, wenn Sie sehen möchten, hinzugefügt: https://code.google.com/p/android/issues/detail ? id = 73718

ich Ihr Problem bekommen, stand ich das gleiche Problem in meiner Anwendung. Ich rufe registerReceiver () mehrere Zeit innerhalb der Anwendung.

Eine einfache Lösung für dieses Problem ist es, den registerReceiver () in der Custom Application Klasse zu nennen. Dadurch wird sichergestellt, dass Ihr Rundfunkempfänger wird nur ein in der gesamten Application Lifecycle aufgerufen werden.

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);

    }
}

Dies ist, wie ich es getan haben, es ist eine modifizierte Version der Antwort von ceph3us und herausgegeben von slinden77 (unter anderem habe ich entfernt Rückgabewerte von Methoden, die ich nicht notwendig):

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
        }        
    }        
}

Dann auf einer Aktivitätsklasse:

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());
    }
}

ich diesen Code setzen in meiner Eltern Aktivität

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);
}

Hier ist, was ich tat, zu überprüfen, ob der Sender bereits registriert ist, auch wenn Sie schließen Sie Anwendung (finish ())

Firstime Ihre Anwendung ausgeführt wird, eine Broadcast sendet erste wird es wahr / falsch zurückgeben hängt davon ab, ob Ihre Broadcaster in noch laufen oder nicht.

Meine 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;
        }
    }
}

Meine 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"));
}

Sie können mit Dagger einen Verweis von diesem Empfänger schaffen.

Zunächst bieten sie:

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

Dann spritzen sie, wo Sie (mit constructor oder Feld injection) benötigen

und einfach übergibt es an registerReceiver.

es auch zu in try/catch Block setzen.

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

Just Nullpointer überprüfen. Wenn der Empfänger nicht existiert, dann ...

try{
    Intent i = new Intent();
    i.setAction("ir.sss.smsREC");
    context.sendBroadcast(i);
    Log.i("...","broadcast sent");
}
catch (NullPointerException e)
{
    e.getMessage();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top