My app lets people record routes when driving. To ensure locations are actually recorded, i use a service so that they are recorded even if the activity is killed. To avoid the device being put into Doze, which would mean not getting frequent location updates, i hold a wakelock.
Are these steps sufficient? Or do i need to explicitly disable battery optimization ( https://developer.android.com/training/monitoring-device-state/doze-standby.html ) to ensure i dont lose out on location updates? According to the docs, my app seems like an "acceptable" use-case for that.
Foreground services are not affected by doze - if you want to constantly be running and getting high accuracy location, you should be a foreground service.
Related
Premise
The user should always be informed of the use of his sensitive data (like collecting the location in the background), this question aims to better understand the latest limitations introduced on Android use of location and background operations.
Problem
Is it still possible (on Android latest versions) to create a location tracking service that would keep tracking the device location no matter the application state (foreground / background) nor the device state (doze or standby mode, app buckets) in order to be able to collect location in a consistent way ?
Assuming that the GPS and internet connection are enabled and available, is it possible to collect the location, let's say every 10 minutes, or the device going to doze mode or standby will anyway restrict the app possibilities after some time and defer the operations (like network operations), making it impossible to keep getting regular location updates ?
On latest android versions, starting from Android 8.0 (API 26), new ways to improve battery performance and secure the users privacy have been introduced:
Background limitations
Background location limits
App standby buckets
What I tried
From my understanding, a foreground service looks like the best option:
keep informing the user (notification)
the system does not kill the service after a few seconds (as for background services starting from API 26)
less likely to get stopped by the system (START_STICKY flag to restart otherwise)
can acquire a wake lock
Still it seems that the app needs to be whitelisted to avoid battery optimisations and even battery optimisation need to be disabled in order for the service not to be stopped/deferred.
Expected result
Receive location updates at regular intervals, every 10 minutes for instance
You have to use FusedLocationProviderClient in a service to give you location in specified time intervals or distances. If you choose distances you have to watch location accuracy as well. See this article.
I have an application that is required to log the user's location every couple of seconds, the entire time it is on.
On does not mean in the foreground,or that even the Android's screen is on.
What is the suggested way to accomplish it?
I've heard of background and foreground services, and also saw something about Jobs. I also saw this was possible with a WakeLock.
I am not sure what is the best method of choice.
The need to conserve Battery life is of course an issue.
You should use Service, you can choose that the service wil keep running even after your app was closed.
YET if the device is low on resources it might close your service.
you can use FOREGROUND service if you want to minimize the chance android will close your service.
inside the service use LocationManager / FusedLocation to get the location every X time.
you set it up with LocationListener so everytime it set onLocationChanged you upload to firebase.
Useful links:
Make your app loaction aware
Services
Does anyone know if a whitelisted app that is holding a partial wake-lock can receive location updates while the device is in Doze or the app is in Standby?
The Android docs (http://developer.android.com/training/monitoring-device-state/doze-standby.html) only state that CPU and network are deferred and do not mention any affect on location updates (i.e. from the LocationManager). Based on this, it would seem that location updates are not affected by Doze/Standby, so if an app is holding a partial wake-lock (to keep the CPU running) then the app should be able to receive location updates.
I've implemented this and tested it and found that an app does not appear to receive location updates in Doze even though it has a partial wake-lock and is whitelisted. Interestingly, when I left the device on my desk overnight running the app with the wake-lock, the battery was nearly empty in the morning, but when repeating with the app without the wake-lock, the battery was nearly full in the morning. So it does appear that the app was running the whole time, but was not receiving location updates.
A little extra background: The app is used for fleet tracking, so we're trying to figure out if there is anyway for an app to have a background service running that reliably receives location updates when running on battery power.
Thanks!
-Tom B.
Yes, this seems to be another undocumented restriction in Doze mode, as my test logs also show. My guess was that some hardware features like GPS are generally turned off in Doze, but maybe it's the LocationManager being disabled altogether.
As this might just be a severe lack of documentation, the battery drain you mention should definitely not happen in Doze, as that's exactly what Doze is meaning to prevent in the first place.
You may want to file a bug report about all this at https://code.google.com/p/android/issues/list
For getting location updates when phone is in idle mode, app should be whitelisted, had partial wake-lock and also should not be on the same locatoin (if you are in the same location you don't need updates). I tested this with Mock Locations, which was giving fake location while phone was on my desk.
In my experience location updates are still received when in Doze but only when you use a foreground notification together with the methods you described. Network calls don't work.
Be aware of some stackoverflow posts indicating to just use the permission REQUEST_IGNORE_BATTERY_OPTIMIZATIONS. Your app will be rejected from the play store when you define this permission in your manifest due to "device & network abuse" https://play.google.com/about/privacy-security/device-network-abuse/.
There's also a way to manually request this permission with an intent. I don't know if it's also prohibited that way. The whole whitelisting principle is a little vague to me.
My application requests for updates in a service on background when a boolean flag is set to true. If flag is set to true, then i acquire a PARTIAL_WAKE_LOCK to let my background service run.
My questions are:
Since I requested for updates from location manager ( i don't manually request updates but subscribed for locationManager.requestLocationUpdates )... does the locationManager keep working as normal/usual even if device goes to sleep with PARTIAL_WAKE_LOCK ?
I've read there is a WifiLock -> WIFI_MODE_SCAN_ONLY that I'm not acquiring. Since location manager uses wifi scans to detect location through wifi hotspots, should I acquire this as well ?
What about gps location updates when device goes to sleep ?
no, it does not. More (very good) info here, including possible solutions/ hacks.
regarding 1, I would have to make an educated guess and say it wouldn't make a difference
from what I can gather, it doesn't make a difference which provider you are using for the updates, LocationManager.NETWORK_PROVIDER or LocationManager.GPS_PROVIDER.
in danger of going a bit OQ, I am a bit curious which kind of application would need to aquire a wake lock to keep a service running at all. As far as I know, having a wake lock doesn't ensure your Service keeps running. The only thing which ensures a Service keeps running is to have it in the foreground (Service.startForeground()). Otherwise the system still might kill the service, regardless if it aquired a wake lock or not.
That being said, if it is running, it can do it's work with a Handler or something.
If you are using this approach, and I think you are based on the scenario, I would advise against it. Basically you are creating a service, have it run in the foreground (guess) AND you are aquiring a wake lock just to request for location updates when the screen is off. This seems a bit overkill.
There's a more efficient way, which has the benefit it has by far more accurate timing then the dreaded timing of Handler.postAtTime or Handler.postDelayed: AlarmManager.setRepeating(). Set type to ELAPSED_REALTIME_WAKEUP or RTC_WAKEUP so it will run if the device sleeps, then when the alarm event is fired and received by a BroadcastReceiver you will have to create, you could request for updates and handle other events.
If you're not using a Handler, but are merely requesting location updates, this approach still probably would be better, because it doesn't require you to have a running Service or to acquire a wake lock.
And it seems LocationManager.addProximityAlert() is the way to go here. Which is flawed as well (see 1)
Similar question here by the way: Android: GPS location updates when the cellphone is in sleep?
I've spent days trying to get WiFi and cell-based locations with locked screen with Android 6.0 on Nexus 6. And looks like the native android location service simple does not allow to do it. Once device got locked it still collects location update events for 10-15 minutes then stops to providing any of location updates.
In my case the solution was to switch from native Android location service to Google Play Services wrapper called com.google.android.gms.location: https://developers.google.com/android/reference/com/google/android/gms/location/package-summary
Yes, I know that some of Android devices lack of GMS, but for my application this is the only solution to perform.
It does not stop sending location updates even when in the background and device screen is locked.
Me personally prefer RxJava library to wrap this service into a stream (examples included): https://github.com/mcharmas/Android-ReactiveLocation
In my application, I have a service that has an active LocationListener and sends the location over the air. When the service is running, the phone never goes to sleep, and it keeps sending the locations, even though I don't have a wakelock. This is exactly what I want, but I was wondering if that's the expected behavior. I couldn't find any information on this in the SDK documentation. Can I rely on it, or is it safer to get my own wakelock ?
Running location services continuously is battery consuming.User do not like apps that consume their battery and they wont think twice before deleting the app.Best idea is to wake up service only when needed.
Please check this link for more information on battery usage trade offs