如何检查Receiver是否在Android中注册?

我需要检查我的注册接收者是否仍然注册,如果不是我如何检查任何方法?

我不确定API是否提供了直接的API,如果你考虑这个线程 :

我想知道同样的事情。
在我的情况下,我有一个BroadcastReceiver实现调用Context#unregisterReceiver(BroadcastReceiver)作为parameter passing自己作为参数后,处理它收到的意图。
接收方的onReceive(Context, Intent)方法被调用的次数很less,因为它被多个IntentFilters注册,从Context#unregisterReceiver(BroadcastReceiver)引发IllegalArgumentExceptionexception。

在我的情况下,我可以在调用Context#unregisterReceiver(BroadcastReceiver)之前存储一个私有的同步成员来检查,但是如果API提供了一个检查方法,它将会更加干净。

没有API函数来检查接收者是否被注册。 解决方法是将您的代码放在try {...} catch(IllegalArgumentException e) {...}块中。

我正在使用这个解决scheme

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

你有几个select

  1. 你可以在你的class级或活动中join一个标志。 把一个布尔variables放入你的class级,看看这个标志,知道你是否有接收者注册。

  2. 创build一个扩展Receiver的类,在那里你可以使用:

    1. 单例模式只在你的项目中有这个类的一个实例。

    2. 实现知道接收方是否注册的方法。

最简单的解决scheme

在接收器中:

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

在代码中:

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

编辑我

– 回复

这真的不是那么优雅,因为你必须记住在注册后设置isRegistered标志。 – 隐形拉比

– “更优雅的方式”在接收器中添加方法来注册和设置标志

如果你把这个onDestroy或onStop方法。 我认为当活动已经被创build时,MessageReciver没有被创build。

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

你可以做到这一点容易….

1)创build一个布尔variables…

 private boolean bolBroacastRegistred; 

2)当您注册广播接收器时,将其设置为TRUE

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

3)在onPause()做…

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

就这样,现在,你不会在onPause()上收到更多的exception错误信息。

提示1:始终在onPause()中使用unregisterReceiver()而不是onDestroy()提示2:不要忘记在运行unregisterReceive()时将bolBroadcastRegistredvariables设置为FALSE

成功!

你必须使用try / catch:

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

我使用Intent让Broadcast Receiver知道主Activity活动线程的Handler实例,并使用Message将消息传递给Main活动

我已经使用这种机制来检查广播接收器是否已经注册。 有时,当您dynamic注册广播接收器时,如果广播接收器正在运行,则不需要进行两次或者向用户展示广播接收器。

主要活动:

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

广播接收机:

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

就我个人而言,我使用调用unregisterReceiver的方法,并在引发exception时吞下exception。 我同意这是丑陋的,但目前提供的最好的方法。

我已经提出了一个function请求,以获得一个布尔方法来检查接收器是否注册添加到Android API。 请在这里支持它,如果你想看到它添加: https : //code.google.com/p/android/issues/detail?id=73718

这是我做了什么来检查广播公司是否已经注册,即使你closures你的应用程序(完成())

首先运行你的应用程序,首先发送一个广播它将返回true / false取决于广播者是否仍在运行。

我的广播员

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

我的主动性

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

这是我如何做到的,它是由ceph3us给出的答案的修改版本,并由slinden77编辑(除其他事项外,我已经删除了我不需要的方法的返回值):

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

然后在一个Activity类上:

 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()); } } 
 if( receiver.isOrderedBroadcast() ){ // receiver object is registered } else{ // receiver object is not registered } 

我把这个代码放在我的父母活动中

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

只要检查NullPointerException。 如果接收器不存在,那么…

 try{ Intent i = new Intent(); i.setAction("ir.sss.smsREC"); context.sendBroadcast(i); Log.i("...","broadcast sent"); } catch (NullPointerException e) { e.getMessage(); }