0

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?

Mattia Campana
  • 509
  • 2
  • 6
  • 15
  • What version of Android are you testing on, and on what specific hardware? Android 6.0 introduced Doze mode, and various manufacturers have their own aggressive power savings modes that pre-dated Doze. Doing something every two minutes (using `ScheduledExecutorService`, `AlarmManager`, `JobScheduler`, etc.) will not be possible on modern Android devices, unless the user adds your app to the battery optimization whitelist. – CommonsWare Dec 14 '16 at 22:52
  • I am using a Nexus 5 (Android 6.0.1) and a Nexus 6 (Android 7). Is it possible to avoid the Doze mode? – Mattia Campana Dec 14 '16 at 22:55
  • @CommonsWare Does this apply to a worker thread created something like 'new MyThread().start()' too? I read the android developers guide but it only talks about AlarmManager and Network related jobs.. It just mentioned about 'deferring background CPU' once and no explanation for it at all. – Jenix Jun 20 '17 at 17:37
  • @Jenix: "Does this apply to something like 'new MyThread().start()' too?" -- yes. – CommonsWare Jun 20 '17 at 17:41
  • @CommonsWare Thanks!! You saved me.. I never thought it would :( – Jenix Jun 20 '17 at 17:41

1 Answers1

3

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.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thank you very much @CommonsWare. Yes, this information is very useful for my case. My objective is to be able to periodically perform in background a P2P peer discovery in order to find new devices in the nearby. With the AlarmManager (every 9 minutes) can I use the WifiP2P framework? – Mattia Campana Dec 14 '16 at 23:16
  • @MattiaCampana: I have not played with WifiP2P. However, unless you are also holding a `WifiLock`, I would expect WiFi to be unavailable during Doze, and I have no idea if a `WifiLock` is sufficient to keep it on during Doze. The interaction between `WifiLock` and Doze is undocumented AFAIK. – CommonsWare Dec 14 '16 at 23:20
  • @CommonsWare oh, one more thing! Still not sure about WifiLock? – Jenix Jun 20 '17 at 17:55
  • This(https://developer.android.com/guide/topics/media/mediaplayer.html) doesn't mention about Doze specifically but it suggests using WifiLock for streaming, so I guess WifiLock is sufficient enough. What do you think? – Jenix Jun 20 '17 at 18:00
  • @Jenix: "Still not sure about WifiLock?" -- correct. I have not played with this scenario. "What do you think?" -- I would say that `WifiLock` is probably necessary. Whether it is *sufficient* is another matter, and that I do not know, sorry. – CommonsWare Jun 20 '17 at 18:06
  • Thanks for your honest answer :) – Jenix Jun 20 '17 at 18:09
  • You're right! I mean, not sufficient! I just remembered what I read from someone's post a few days ago. He tried WifiLock but needed to configure the whitelist in Settings > Battery > Battery Optimization. – Jenix Jun 20 '17 at 18:18