I'm trying to get location updates in my android app when in doze mode, this used to work up to android 5.x. With android 6 and the advent of doze, no matter what I do, the updates stop at some point. After reading a few articles and stackoverflow answers on the topic I made the following changes:
But still, I'm not getting location updates when doze kicks in. I've verified that my service thread keeps running when doze starts (by periodically logging a message), but somehow the location manager stops sending updates. The documentation on doze and the LocationManager is pretty scant in this regard, so I was wondering if somebody knows of a way to keep the location manager alive in doze? Is there some method on LocationManager that if called periodically will keep the LocationManager active? Note that I'm interested in GPS updates only, with a high update frequency, once every second.
In the end I found a workaround for the issue, after reading through the source code of com.android.internal.location.GpsLocationProvider I noticed that sending it an com.android.internal.location.ALARM_WAKEUP Intent prevented the location provider from dozing. So to keep the GPS from dozing I broadcast the Intent every 10 seconds, I added the following in my service class:
[...]
private Handler handler;
private PowerManager powerManager;
private PendingIntent wakeupIntent;
private final Runnable heartbeat = new Runnable() {
public void run() {
try {
if (isRecording && powerManager != null && powerManager.isDeviceIdleMode()) {
LOG.trace("Poking location service");
try {
wakeupIntent.send();
} catch (SecurityException | PendingIntent.CanceledException e) {
LOG.info("Heartbeat location manager keep-alive failed", e);
}
}
} finally {
if (handler != null) {
handler.postDelayed(this, 10000);
}
}
}
};
@Override
public void onCreate() {
handler = new Handler();
wakeupIntent = PendingIntent.getBroadcast(getBaseContext(), 0,
new Intent("com.android.internal.location.ALARM_WAKEUP"), 0);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TrackService");
[...]
}
If you test location and doze mode on the emulator with commands like "adb shell dumpsys deviceidle force-idle" etc. You probably noticed that location stops in Doze Mode.
But ... as "documentation" stands for :
"As soon as the user wakes the device by moving it, turning on the screen, or connecting a charger, the system exits Doze and all apps return to normal activity"
Source : https://developer.android.com/training/monitoring-device-state/doze-standby
So ... move Your emulator with GPS Joystick App or similar and You will notice that location wakes up from Doze Mode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With