2

I have implemented an Android service (START_STICKY) which starts on device boot and runs in background. Functionality of this service is to interact with SD card. As it is running continuously, started with sticky it consumes battery. To solve heavy battery consumption I wanted to start this service when user is using device.

Ideally start/stop service based on the ACTION_SCREEN_ON & ACTION_SCREEN_OFF intents.

When I have tested this found that I can't register for ACTION_SCREEN_OFF & ACTION_SCREEN_ON in the Manifest, so I have created a Broadcast Receiver in my service to capture the ACTION_SCREEN_OFF & ACTION_SCREEN_ON.

But, since I cannot register for the intents in the manifest, when I stop my service on ACTION_SCREEN_OFF. How can I possibly start it when the screen comes back on?

Note : As I have already mentioned SCREEN_ON + SCREEN_OFF cannot be registered in manifest file. It is registered like

// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC 

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
broadcastReceiver = new TestReceiver();
registerReceiver(broadcastReceiver, filter); 

So when service is not running then this intent will not fire.

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
Sachin
  • 501
  • 10
  • 18
  • Well, in your BroadcastReceiver for SCREEN_ON + SCREEN_OFF, simply forward these to the service via startService with the same action. In the service, you can check in onStartCommand which action the intent has, if it's screen_on -> start the service, if it's screen_off, the service should already be running, so you shut it down. – damian Oct 10 '13 at 11:34
  • As I have already mentioned SCREEN_ON + SCREEN_OFF cannot be registered in manifest file. SO when service not running it will not get called. – Sachin Oct 10 '13 at 12:06
  • Similar question: http://stackoverflow.com/questions/9477922/android-broadcast-receiver-for-screen-on-and-screen-off and the answer was that you have to use long run service (sticky). – aleung Jan 13 '14 at 17:16

2 Answers2

1

you can use BroadCastReciever to call your service based on the type of broadcast

public class MyReceiver extends BroadcastReceiver {

     public static boolean wasScreenOn = true;

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

        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {

            // do whatever you need to do here

        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
              // and do whatever you need to do here

        }
       else if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
        {
          // and do whatever you need to do here
       }

    }
r4jiv007
  • 2,974
  • 3
  • 29
  • 36
  • As I have already mentioned SCREEN_ON + SCREEN_OFF cannot be registered in manifest file. It is registered like // REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); broadcastReceiver = new TestReceiver(); registerReceiver(broadcastReceiver, filter); So when service is not running then it will start. – Sachin Oct 10 '13 at 12:13
  • see i am developing a custom lock screen and i too have to detect screen state, its working for me .. and i have register the receiver in manifest with : – r4jiv007 Oct 10 '13 at 12:18
  • Yes, you are right. BOOT_COMPLETED can be registered in manifest and this works. But when we register SCREEN_ON & SCREEN_OFF in manifest then you wont get fired on screen on/off. you can try. So then I cant start service if it is killed by android system. I have seen that even though it is sticky, when device is in sleep mode it get killed and doesnt start again. – Sachin Oct 11 '13 at 05:59
0

Have a Broadcast Receiver for ACTION_SCREEN_ON, ACTION_SCREEN_OFF and ACTION_USER_PRESENT.

onResume of the activity will be called when ACTION_SCREEN_ON is fired. Create a handler and wait for ACTION_USER_PRESENT. When it is fired, implement what you want for your activity.

Register receiver as below:

private void registBroadcastReceiver() {
    final IntentFilter theFilter = new IntentFilter();
    /** System Defined Broadcast */
    theFilter.addAction(Intent.ACTION_SCREEN_ON);
    theFilter.addAction(Intent.ACTION_SCREEN_OFF);

    mPowerKeyReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String strAction = intent.getAction();

            if (strAction.equals(Intent.ACTION_SCREEN_OFF) || strAction.equals(Intent.ACTION_SCREEN_ON)) {
                // > Your playground~!
            }
        }
    };

    getApplicationContext().registerReceiver(mPowerKeyReceiver, theFilter);
}
Brijesh Patel
  • 676
  • 1
  • 5
  • 13