Can't get HIGH_ACCURACY background locations in Android 8+ - android

Android 8 only allows background location updates a few times per hour. This isn't a problem since I only request them about once an hour and only if the device isn't STILL and there arn't already passive updates doing the job. So maybe a few times a day. No detectable battery use on Android 7.
However, I do have an accuracy requirement and I discard locations with horizontal accuracy worse than about 1000 feet (Basically cell tower locations). The problem is that the network location comes almost instantly, and then the app is throttled and never receives the next update which might come from the GPS. Typically I would wait a minute to get a location with the desired accuarcy and then give up. On Android 8, even if I wait an hour I just get the network location every 20 minutes or so because of the throttling.
I can't find any LocationRequest setting for miniumum accuracy which would solve the problem entirely. PRIORITY_HIGH_ACCURACY absolutley does NOT do this. It is only a "hint". setSmallestDisplacement() doesn't help because it doesn't affect the first update. Batching updates helps on rare occasions in my testing but not with any reliability.
Further, waiting in PRIORITY_HIGH_ACCURACY for any length of time is not reasonable from a user perspective since the location indicator will be active on the device the whole time, even if the app is being throttled.
Does anyone have suggestions on how I could solve this problem? Perhaps Android does not intend for PRIORITY_HIGH_ACCURACY to be used in the background at all, although I can find nothing about this in the documentation.

If you need GPS, just use the GPS provider. Don't screw around with the Criteria, request what you really need.

Related

Fused Location Provider - getting high accuracy

I'm trying to find a way to improve the accuracy obtained from Google Play Services's Fused Location Provider.
I'm testing an app that uses LocationServices and allows the user to choose from a set of update frequencies (every 30 seconds, every min, every 5 min, every 10 min). It then requests location updates from the fused location provider with the chosen interval, with a priority of PRIORITY_HIGH_ACCURACY.
It works, but the locations obtained don't seem to be as accurate as they could be. The accuracy values are typically more than 10 meters, while a third party GPS app (such as GPS test) typically reaches better accuracy if I wait long enough.
The Android documentation has the following to say:
The priority of PRIORITY_HIGH_ACCURACY, combined with the ACCESS_FINE_LOCATION permission setting that you've defined in the app manifest, and a fast update interval of 5000 milliseconds (5 seconds), causes the fused location provider to return location updates that are accurate to within a few feet. This approach is appropriate for mapping apps that display the location in real time.
Indeed, when I choose a very small frequency (such as 5 seconds or 2 seconds), I notice an overall improvement in the accuracy of the obtained locations - they sometimes get as good as 3-4 meters. However, it looks like choosing larger update intervals result in lower accuracy.
So I'm thinking of the following strategy: schedule a task that, at the interval chosen by the user: (1) starts requesting location updates every few seconds (2 seconds), (2) waits for 20 seconds, then (3) stop requesting updates.
I tried to use a Handler in foreground service to accomplish that. It works when the screen is on, but, as soon as the screen is turned off, the scheduling becomes seemingly unpredictable. So it looks like I'll have to resort to something like AlarmManager to schedule this task. This answer suggests a similar approach: https://stackoverflow.com/a/26298509/1131904 ; I also found this article, which tackles the similar problem of how to schedule periodic tasks in a battery efficient way: https://wangjingke.com/2016/09/23/Multiple-ways-to-schedule-repeated-tasks-in-android
Has anyone else run into a similar problem? Is using AlarmManager a good approach?
To answer you first question, we have made the some observation. In general, the occurrence of high-accuracy locations (3-10 m) decreases with increasing interval. However, the exact behavior seems to differ between vendors. On Samsung S9 and S8, the threshold appeared to be at 10 seconds. Above this interval, high-accuracy locations were very rare. On other devices (Pixel 3a, Xiaomi MI 8, OnePlus 6T) high-accuracy locations were still frequent at an interval of 30 seconds. All observations were made under open sky.

Battery impact of polling for location updates less often?

I've read a lot of conflicting information on this.
Suppose I use the Fused Location API in PRIORITY_HIGH_ACCURACY mode, does it make much difference if I set the interval to, say, 10 minutes vs 1 minute? 1 hour vs 10 seconds? If so, how drastically?
I don't know how it works internally so I'm just wondering what I can do to save battery if I need high accuracy location (and relative infrequency of polling isn't an issue).
https://developer.android.com/training/monitoring-device-state/index.html
The developer site has advice on how to save battery but they don't seem to give any concrete information on exactly how much polling frequency affects battery life.
Does enabling the service keep the GPS on all the time and therefore always using battery (and so the interval would be synthetic and solely for programmatic reasons)?
Thanks!
For Fused Location API, I'm not certain if they turn off GPS or adjust reporting interval while leaving it on, but I would assume they turn off GPS between updates, or else many others would complain about power drain.
As for what Android Location Service does, they do turn off GPS and allow the phone to idle between updates if the interval is greater than 0 (check out the source in LocationManagerService). I've done quite a bit of power testing on different android phones, and found that keeping the CPU from idling can draw a noticeable amount of power. Add the power draw of GPS (which keeps the CPU from idling) and you are looking at a decent power drain (about 50% of what the screen would draw for some devices).
In the end, I'd have to agree with Gabe Sechan and advise you on choosing whether accuracy is worth the battery drain. Just ask yourself these basic questions:
Do I need to know if my user is on one side of the street or the other?
If yes, use GPS, else use Network or low accuracy location.
How often do I need to check my user's location?
If you need it about once a minute, set your interval as such. If you only care when they leave a general area, setup a geofence, or use network locations. You can also listen to location updates from other apps, and make your app smarter about when to take updates.
If I can't get my user's location within X amount of time, can I skip this update altogether?
If you can, then put a timeout feature in your update logic. If not, I strongly recommend you re-evaluate the app logic in that case.

Android Location Updates get stuck

I am developing an android application wherein I need the user location updates pretty frequently. Say 2 times a minute.
Earlier I had been using Google Play Service's "Fused location service" but the location updates were not received as requested.
The location updates got stuck for sometime, the interval between updates jumped to 10min or so.Sometimes even if I put my priority to "PRIORITY_HIGH_ACCURACY" the same happened.
I then went back to the old "Location Manager" and when I used the "NETWORK_PROVIDER", I noticed that the location updates got stuck due to this provider. Also the GPS does not get activated immediately, it takes some time. I am trying to build my custom fused location provider. How can I efficiently switch between providers, without getting lags on location updates.
I want to know what are the best practices for getting location updates regularly, all the time, be it either NW, GPS or both. Like it should work for an application where location updates getting stuck cannot be afforded.
Battery drain is not an issue for me right now.I am aware of all the supporting docs that Google provides regarding location access.
Any help would be much appreciated.
Thankyou !
FusedLocationProvider really is the best option for obtaining locations at the moment, because it uses a lot more than just GPS or Network data to obtain location fixes. I have experienced issues regarding intervals being missed as well, but ultimately this is something down to luck depending on availability of GPS, Network, etc. etc.
My favourite usage of FusedLocationProvider so far is in conjunction with the AlarmManager class: Basically, the idea is to start location tracking at intervals specified by the Alarm Manager (this can be set to every 30 seconds such as in your case). Once the interval is hit, the location provider is to obtain a location fix as soon as possible (so in the setInterval method or whatever it's called, the parameter is a 0). This way, you can avoid having to wait another 30 seconds for a new location, instead having the location tracker attempt to provide a location as soon as possible after the interval specified by the Alarm Manager is hit.
By the way, when making custom location tracking wrappers, be careful of using the .getLastKnownLocation() method as it only uses cached locations - you could end up sending the same location to the user every 30 seconds.
Good luck!

Android location updates interval

I am experimenting with Androids location updates. The requestLocationUpdates is responsible for providing the updates. With the following code:
locationManager.requestLocationUpdates(provider, 300000, 10, this);
I am only supposed to receive updates 5 minutes and 10 meters apart. But the updates just keep coming in seconds apart and even when I am sitting still.
GPS is the provider I am using.
I need to space the updates out. What can I try?
The 10m is too small - I would increase that. GPS accuracy isn't great, and so every time it senses a small difference you will get another location. I'd bump it up to 100m and I expect you will then get a sensible number of locations coming through.
If you do want it more specific, then you'll need to handle the volume as more accurate means more volume.
Hers what i'd do:
First of all I check what providers are enabled. Some may be disabled on the device, some may be disabled in application manifest.
If any provider is available I start location listeners and timeout timer. It's 20 seconds in my example, may not be enough for GPS so you can enlarge it.
If I get update from location listener I use the provided value. I stop listeners and timer.
If I don't get any updates and timer elapses I have to use last known values.
I grab last known values from available providers and choose the most recent of them.
The 10m is too small for a GPS reading, try 100m. You'll also have issues with power saving mode, and app battery optimisation on most Android phones.
Android 10 and above has very strict background location updates, and may kill apps that run in the background. Later versions will also remove apps that have not be used recently.

GPS update interval is faster with good signal?

I'm trying to limit my program to take location updates every 10 seconds instead of constant updates in order to reduce battery drain. This works fine when i'm debugging indoors and the signal is weak (i.e. the GPS icon flashes), but if the phone gets a proper fix (i.e. the GPS icon is static) the update interval increases to roughly a second.
I know that the code mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, updateInterval*1000, 0, this); will not force the GPS to take updates exactly at the given interval, but in my opinion it shouldn't depend on the strength of the signal and fluctuate that much.
Any ideas?
UPDATE: see comment
I suspect that the GPS radio works in a manner where either it's connected to GPS satellites or it's not. When it's connected, the Android SDK sends you updates as frequently as they're available from the GPS hardware. When it doesn't have a full GPS connection it falls back to sending AGPS updates according to what you've requested.
If you only want updates every 10 seconds, you should save the last received Location's time value in your listener, and when you receive a new Location check its time against the old value; ignore it if it's too frequent (or do something smarter like checking the accuracy and replacing the old value, etc).
Maybe it works slower because you are debugging, but not because your signal is weak! Try to make tests with disconnected debugger indoors...

Categories

Resources