Android - BroadcastReceiver解除注册问题(未注册)

7
我是一名有用的助手,可以对文本进行翻译。

我遇到了注销 BroadcastReceiver 的问题。我首先注册它,但是当我想用 unregisterReceiver(); 命令注销它时,会出现大量错误。错误提示我没有注册我的 BroadcastReceiver

代码:

public class Receiver extends BroadcastReceiver implements Variables {

    CheckConexion cc;

    @Override
    public void onReceive(Context contxt, Intent intent) {

        // Cuando hay un evento, lo diferenciamos y hacemos una acción.

        if (intent.getAction().equals(SMS_RECEIVED)) {
            Sms sms = new Sms(null, contxt);
            sms.uploadNewSms(intent);
        } else if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW)) {
            // st.batterylow(contxt);
        } else if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
            // st.power(1, contxt);
        } else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
            // st.power(0, contxt);
        } else if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)
                || intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)
                || intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
            Database db = new Database(contxt);
            if (db.open().Preferences(4)) {
                Uri data = intent.getData();
                new ListApps(contxt).import_app(intent, contxt, data,
                        intent.getAction());
            }
            db.close();
        } else if (intent.getAction().equals(
                ConnectivityManager.CONNECTIVITY_ACTION)) {
            cc = new CheckConexion(contxt);
            if (cc.isOnline()) {

                /*Database db = new Database(contxt);
                db.open();
                if (db.move() == 1) {
                    new UploadOffline(contxt);
                }
                db.close();*/

            }
        }

    }

    public void register(Context c) {
        Receiver r = new Receiver();
        IntentFilter i = new IntentFilter();
        i.addAction(SMS_RECEIVED);
        i.addAction(Intent.ACTION_BATTERY_LOW);
        i.addAction(Intent.ACTION_POWER_CONNECTED);
        i.addAction(Intent.ACTION_POWER_DISCONNECTED);
        i.addAction(Intent.ACTION_CALL_BUTTON);
        i.addAction(Intent.ACTION_CAMERA_BUTTON);
        i.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        c.registerReceiver(r, i);
        IntentFilter apps = new IntentFilter();
        apps.addAction(Intent.ACTION_PACKAGE_ADDED);
        apps.addAction(Intent.ACTION_PACKAGE_CHANGED);
        apps.addAction(Intent.ACTION_PACKAGE_REMOVED);
        apps.addDataScheme("package");
        c.registerReceiver(r, apps);
    }

    public void unregister(Context c) {
        BroadcastReceiver r = new Receiver();
        if (r != null) {
            c.unregisterReceiver(r);
        }
    }
}
4个回答

7

首先,使用thisReciever类的对象一起工作。

移除所有r对象,不要在扩展类中调用构造函数。

然后:

定义

boolean isRegistered = false;

在你的注册方法中:
c.registerReceiver(this);
isRegistered = true;

在你的注销方法中:
if (isRegistered) {
    c.unregisterReceiver(this);
    isRegistered = false;
}

然后在你的activity中,使用类Reciver的实例。

希望对您有所帮助!


这个解决方案应该可以工作。但是,为每个注册的接收器拥有一个成员变量并不总是方便的。如果你想避免为每个接收器使用成员变量,你可以看一下我下面的解决方案。基本上就是使用 try catch 块。 - jfmg
为了避免保留另一个变量,声明一个内部类,该内部类是BroadcastReceiver的子类。在注册时构造一个新的内部类,在注销后将其设置为null - gladed

6
最好的解决方案是将 unregisterReceiver 方法放入 try catch 块中。
try {
    this.unregisterReceiver(myReceiver);
}
catch (final Exception exception) {
    // The receiver was not registered.
    // There is nothing to do in that case.
    // Everything is fine.
}

很遗憾,当unregisterReceiver失败时不会抛出具体的异常,所以您需要使用Exception。此外,Android API中没有像isReceiverRegistered(BroadcastReceiver receiver)这样的方法,我认为这是对Android API的增强。

另外,查看ReceiverLifecycle也是值得一试的。


3
最好只捕获“IllegalArgumentException”异常。 - gladed

4

您无法注销新的广播接收器实例。您需要使用已注册的BroadcastReceiver的同一实例。

因此,请使用

 c.registerReceiver(this, apps);

并且。
 c.unregisterReceiver(this);

当您调用register和unregister时,它是从相同的实例中完成的吗? - nandeesh

0
在unregister方法中,您正在创建一个新的BroadcastReceiver实例并注销它。相反,在register方法中将实例设置为全局,并调用。
if (r != null) {
        c.unregisterReceiver(r);
        r = null;
 }

在注销方法中。


当您的变量r不为空且未注册时,这可能会引发异常。 - jfmg
1
如果这是唯一调用unregisterReceiver()的地方,那么如果它抛出异常,那就是Android的缺陷。 - gladed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接