0

I use an alarm to take pictures at regular time intervals. I use a BroadcastReceiver as follows:

@Override
public void onReceive(Context context, Intent intent) 
{
    Log.d(TAG, "Capturing pic");

    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CAPPIC");
    wl.acquire();

    capturePicture();

    wl.release();
}

The capturePicture() calls Camera.takePicture(...) and then ends. Finally, as you can see, wl.release() is invoked.

Now, the problem is that the call back of the takePicture is very time consuming in my case. In fact, it performs some manipulations on the picture just taken that can take up to 5 seconds on my device.

My question is, since wl.release() is called while the computational intensive task into the takePicture callback is running, is there any side effect? That is, suppose that the device is in standby mode. The alarm starts --> wakelock is activated --> picture is taken and manipulated but in the meanwhile of the computation wakelock is released... is it safe or there is the risk that the device returns to its standby mode before the routines into the takePicture callback ends?

user2923045
  • 369
  • 2
  • 6
  • 16

1 Answers1

2

Your setup is wrong in that you should not be doing a lot in the receiver and in that the AlarmManager holds a wakelock while onReceive() runs anyway - and yes you should not release the wakelock while editing. You should delegate to a service and for reasons detailed here this must be a WakefulIntentService. Now in that service you should set up a mechanism for waiting for the processing to finish - maybe using CountDownLatch.

Community
  • 1
  • 1
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • Many thanks @Mr_and_Mrs_D for your reply suggestion. But with regard to the code I've reported in my post, how long the cpu will continue to run after the `release()`? I mean, suppose the device is in standby, then the alarm starts and `PowerManager.PARTIAL_WAKE_LOCK` is used. Based on this, from the API documentation I read: _"If you hold a partial wake lock, the CPU will continue to run, regardless of any display timeouts or the state of the screen and even after the user presses the power button."_ but when the `release()` is called the device returns in its standby mode instantaneously? – user2923045 Jan 15 '14 at 14:50
  • My question because my app works fine when the device is plugged to the power supply but it fails (time to time) when the device runs with batteries... – user2923045 Jan 17 '14 at 15:05
  • Your wakelock in onReceive does nothing. The AlarmManager holds one for you while onReceive. You need to use a WakefulIntentService as a say in my answer. In there you need to wait for the processing to finish (I don't know how - ask another question). While you wait in the WIS you are safe - the WIS holds a wake lock. The failure on batteries and not failure on power is expected - in batteries it fails asleep ASAP – Mr_and_Mrs_D Jan 18 '14 at 11:30