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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2682043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:55:19  来源:igfitidea点击:

How to check if Receiver is registered in Android?

androidapibroadcastreceiverandroid-broadcastandroid-broadcastreceiver

提问by Mikey

I need to check if my registered receiver is still registered if not how do i check it any methods?

我需要检查我注册的接收器是否仍然注册,如果没有,我该如何检查它?

采纳答案by VonC

I am not sure the API provides directly an API, if you consider this thread:

如果您考虑此线程,我不确定 API 是否直接提供 API :

I was wondering the same thing.
In my case I have a BroadcastReceiverimplementation that calls Context#unregisterReceiver(BroadcastReceiver)passing itself as the argument after handling the Intent that it receives.
There is a small chance that the receiver's onReceive(Context, Intent)method is called more than once, since it is registered with multiple IntentFilters, creating the potential for an IllegalArgumentExceptionbeing thrown from Context#unregisterReceiver(BroadcastReceiver).

In my case, I can store a private synchronized member to check before calling Context#unregisterReceiver(BroadcastReceiver), but it would be much cleaner if the API provided a check method.

我想知道同样的事情。
在我的情况下,我有一个BroadcastReceiver实现,Context#unregisterReceiver(BroadcastReceiver)它在处理它接收到的 Intent 之后调用 将自身作为参数传递。
接收者的onReceive(Context, Intent)方法被多次调用的可能性很小,因为它注册了 multiple IntentFilters,从而有可能IllegalArgumentException从 中抛出Context#unregisterReceiver(BroadcastReceiver)

在我的例子中,我可以在调用 之前存储一个私有的同步成员来检查Context#unregisterReceiver(BroadcastReceiver),但如果 API 提供了一个检查方法,它会更清晰。

回答by Daniel Velkov

There is no API function to check if a receiver is registered. The workaround is to put your code in a try catch block as done below.

没有 API 函数来检查接收者是否已注册。解决方法是将您的代码放在try catch block as done below.

try {

 //Register or UnRegister your broadcast receiver here

} catch(IllegalArgumentException e) {

    e.printStackTrace();
}

回答by ceph3us

simplest solution

最简单的解决方案

in receiver:

在接收器中:

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 code:

在代码中:

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

ad 1

广告 1

-- in reply to:

——回复:

This really isn't that elegant because you have to remember to set the isRegistered flag after you register. – Stealth Rabbi

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

-- "more ellegant way" added method in receiver to register and set flag

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

this won't work If you restart the device or if your app got killed by OS. – amin 6 hours ago

如果您重新启动设备或您的应用程序被操作系统杀死,这将不起作用。– 阿明 6 小时前

@amin - see lifetime of in code (not system registered by manifest entry) registered receiver :)

@amin - 请参阅代码(不是由清单条目注册的系统)注册接收器的生命周期:)

回答by slinden77

I am using this 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);
        }
    }
}

回答by chemalarrea

You have several options

你有几个选择

  1. You can put a flag into your class or activity. Put a boolean variable into your class and look at this flag to know if you have the Receiver registered.

  2. Create a class that extends the Receiver and there you can use:

    1. Singleton pattern for only have one instance of this class in your project.

    2. Implement the methods for know if the Receiver is register.

  1. 您可以在课堂或活动中放置一面旗帜。将一个布尔变量放入您的类中并查看此标志以了解您是否已注册接收器。

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

    1. 单例模式,因为您的项目中只有一个此类实例。

    2. 实现方法以了解接收器是否已注册。

回答by Mohsen mokhtari

You have to use try/catch:

你必须使用 try/catch:

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

回答by Biruel Rick

You can do it easy....

你可以轻松搞定......

1) create a boolean variable ...

1)创建一个布尔变量...

private boolean bolBroacastRegistred;

2) When you register your Broadcast Receiver, set it to TRUE

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

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

3) In the onPause() do it...

3) 在 onPause() 中做...

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

Just it, and now, you will not receive more exception error message on onPause().

就这样,现在,您将不会在 onPause() 上收到更多异常错误消息。

Tip1: Always use the unregisterReceiver() in onPause() not in onDestroy() Tip2: Dont forget to set the bolBroadcastRegistred variable to FALSE when run the unregisterReceive()

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

Success!

成功!

回答by eltheitroadobe

If you put this on onDestroy or onStop method. I think that when the activity has been created again the MessageReciver wasn't being created.

如果你把它放在 onDestroy 或 onStop 方法上。我认为当再次创建活动时,没有创建 MessageReciver。

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

}

回答by jarek

I used Intent to let Broadcast Receiver know about Handler instance of main Activity thread and used Message to pass a message to Main activity

我使用 Intent 让广播接收器知道主 Activity 线程的 Handler 实例,并使用 Message 将消息传递给 Main 活动

I have used such mechanism to check if Broadcast Receiver is already registered or not. Sometimes it is needed when you register your Broadcast Receiver dynamically and do not want to make it twice or you present to the user if Broadcast Receiver is running.

我已经使用这种机制来检查广播接收器是否已经注册。有时,当您动态注册广播接收器并且不想重复注册或在广播接收器正在运行时向用户展示时需要它。

Main activity:

主要活动:

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 Receiver:

广播接收器:

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

}

}

回答by ojf

Personally I use the method of calling unregisterReceiver and swallowing the exception if it's thrown. I agree this is ugly but the best method currently provided.

我个人使用调用 unregisterReceiver 并在抛出异常时吞下该异常的方法。我同意这是丑陋的,但目前提供的最好的方法。

I've raised a feature request to get a boolean method to check if a receiver is registered added to the Android API. Please support it here if you want to see it added: https://code.google.com/p/android/issues/detail?id=73718

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