Android - BroadcastReceiver unregisterReceiver iss

2019-07-05 09:23发布

问题:

I'm having some problems unregistering a BroadcastReceiver. I'm first registering it but then when I want to unregister it by using unregisterReceiver(); command gives me tons of errors. The error says that I've not registered my BroadcastReceiver.

Code:

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

回答1:

First of all,

Use this to work with the object of the class Reciever

remove all r objects, don't call constructors in the extending class.

Then:

Define

boolean isRegistered = false;

In your register method:

c.registerReceiver(this);
isRegistered = true;

In your unregister method:

if (isRegistered) {
    c.unregisterReceiver(this);
    isRegistered = false;
}

Then in your activity use instance of the class Reciver.

Hope, it was helpful!



回答2:

The best solution is to put the unregisterReceiver method into a try catch block.

try {
    this.unregisterReceiver(myReceiver);
}
catch (final Exception exception) {
    // The receiver was not registered.
    // There is nothing to do in that case.
    // Everything is fine.
}

Unfortunately, there is no specific exception thrown when unregisterReceiver fails, so you got to use Exception. Also, there is unfortunately no method like isReceiverRegistered(BroadcastReceiver receiver), which in my opinion would be an enhancement to the Android API.

Besides, it won't hurt to take a look at ReceiverLifecycle



回答3:

You cannot unregister a new instance of broadcast Receiver. You will need to use the same instance of BroadcastReciever which has been registered.

So use

 c.registerReceiver(this, apps);

and

 c.unregisterReceiver(this);


回答4:

In unregister method, you are creating a new BroadcastReceiver instance and unregistering that. Instead make the instance in register method global and call

if (r != null) {
        c.unregisterReceiver(r);
        r = null;
 }

in unregister method.