I need to periodically run a task in background, and to keep awake the CPU. According to the Android documentation i used the PARTIAL_WAKE_LOCK for this purpose. In order to test the wake lock, i wrote a Service which starts a thread every 2 minutes using a ScheduledThreadPoolExecutor. This thread just write a string on a log file in the sdcard.
Then, i performed the following simple test: run the application and unplug the device from the power. After 2 or 3 hours of correct execution, the Service stops to run the thread and no new strings are written in the log file.
Service's code:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Service onStartCommand");
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiOpp wakeLock");
wakeLock.acquire();
TestTask testTask = new TestTask(getApplicationContext());
ScheduledThreadPoolExecutor monitorPool = new ScheduledThreadPoolExecutor(1);
monitorPool.scheduleAtFixedRate(testTask, 0, 120, TimeUnit.SECONDS);
return START_STICKY;
}
TestTask's code:
@Override
public void run() {
//write on log file
LogManager.getInstance().logData("I am running!");
}
I expect that the thread is also executed when the display is turned off, but looking my log file it seems not to be so. Where am I wrong?
On Android 6.0+, Doze mode basically will undo your wakelock. Pre-6.0 devices from some manufacturers do similar things.
Is it possible to avoid the Doze mode?
The user can add your app to the battery optimization whitelist. Note that asking users to do this via ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
may result in your app being banned from the Play Store, if that was to be one of your distribution channels.
Or, the user can keep their device on a charger all the time.
If you can get by with a less-frequent polling period, you can try setAndAllowWhileIdle()
or setExactAndAllowWhileIdle()
with AlarmManager
. At best, you will get control every 9 minutes. You may not have Internet access, though.
Otherwise, a device-side poll-every-N-minutes approach is doomed.
Google wants you to use GCM/FCM and avoid the polling, by having your server push down information if and when this is needed. I do not know if that is relevant for your use case.