0

I'm trying to register a broadcast receiver so that when the screen turns on, airplane mode turns on as well. It WORKS as long as I stay in the activity where I register it, but as soon as I leave the activity, it stops working. Android Manifest is static so I can't use that and besides, the Android Manifest method does not allow you to use SCREEN_ON because Android doesn't want you to run a bunch of things when the screen wakes up so it has to be done by using registerReceiver AFAIK.

My activity:-

public class WakeActivity extends Activity {

IntentFilter screenon = new IntentFilter("android.intent.action.SCREEN_ON");

//Skipped a bunch of code here to keep it relevant. Remember, the broadcast receiver
//does in fact work while I'm in the activity, so the problem isn't with
//the missing code here. Still, let me know if I'm missing something.

//The following method is called within onCreate()

protected void airplane(int i) {
    Screen_On screenon_airplane = new Screen_On();
    if (i == 0) {
        screenon_airplane.airplanei = 0;
        registerReceiver(screenon_airplane, screenon);
    } else if (i == 1) {
        screenon_airplane.airplanei = 1;
        registerReceiver(screenon_airplane, screenon);
    } else if (i == -1) {
        unregisterReceiver(screenon_airplane);
    }
}
}

My Broadcast Receiver:-

public class Screen_On extends BroadcastReceiver {

public int airplanei;

@Override
public void onReceive(final Context context, Intent intent) {
    boolean isEnabled = Settings.System.getInt(
            context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
            0) == 1;
    if (airplanei == 0) {
        if (isEnabled != false) {
            Settings.System.putInt(context.getContentResolver(),
                    Settings.System.AIRPLANE_MODE_ON, 0);
            Intent turnplaneoff = new Intent(
                    Intent.ACTION_AIRPLANE_MODE_CHANGED);
            turnplaneoff.putExtra("state", 0);
            context.sendBroadcast(turnplaneoff);
        }
    } else if (airplanei == 1) {
        if (isEnabled == false) {
            Settings.System.putInt(context.getContentResolver(),
                    Settings.System.AIRPLANE_MODE_ON, 1);
            Intent turnplaneon = new Intent(
                    Intent.ACTION_AIRPLANE_MODE_CHANGED);
            turnplaneon.putExtra("state", 1);
            context.sendBroadcast(turnplaneon);
        }
    }
}
}

LogCat Error:-

05-17 23:44:24.886: E/ActivityThread(2435): Activity com.dragonheart.autodroid.ActionActivities.WakeActivity has leaked IntentReceiver com.dragonheart.autodroid.BroadCastRecievers.Screen_On@414271b0 that was originally registered here. Are you missing a call to unregisterReceiver()?

Could the error have something to do with not telling the Broadcast Receiver what to in onPause() or onDestroy()?...Although I thought once it's registered, it would work until unregistered, regardless of the activity...

Kara
  • 6,115
  • 16
  • 50
  • 57

1 Answers1

0

I'm not sure that your broadcast receiver will work once the activity is stopped, since your receiver has been registered programmatically and not statically through manifest (since android do not let you do so).

I've looked at your code trying to understand what the code does, but that's not simple from just a couple of lines...

But anyway, why dont you create a service in which you register the listener to the screen state? In this way the service will not stop execution, even after the activity has stopped.

And every time the service notice the screen turn on/off you can send a message to your main activity (check documentation).

See this previous question, with example on how to use LocalBroadcastReceiver: LINK

Community
  • 1
  • 1
Davide Lorenzi
  • 348
  • 2
  • 6
  • Thanks for your answer. I was thinking the exact same thing but I was advised against using services because running many services consumes a lot of RAM and more importantly, the services are often killed off by Android to free up memory. – Jasjit Singh Marwah May 24 '12 at 14:10
  • Yes, it's true, since the service is always running in background... But if you don't need it, simply put it in sleep. For sure it should be better to do not have it running at all, but that's the cost to have a broadcast receiver active as long as you need it. – Davide Lorenzi Jun 04 '12 at 15:32
  • I decided to just use USER_PRESENT in the manifest rather than start a service for SCREEN_ON. I'd like to keep my app as "clean" and light as possible. Besides, users get all fussy when they see an app taking a couple megabytes of RAM more than it should (due to services) and decide to use Task Killers (Bad idea) to kill it, especially on low-end phones where running and killing a couple services as soon as the screen turns on can slow it down quite a bit. Anyways, you provided a valid solution so picked it as the answer. Might come in useful later. Thanks! =) – Jasjit Singh Marwah Jun 05 '12 at 06:37