android / location-samples

Multiple samples showing the best practices in location APIs on Android.
Apache License 2.0
2.71k stars 2.77k forks source link

fusedlocationproviderclient gaves wrong location sometimes #221

Open jiya4frd opened 4 years ago

jiya4frd commented 4 years ago

I am testing location tracking app using fusedlocationproviderclient.But it gave me wrong location sometimes almost 1km way from my current location.what will be solution for such case?

necavit commented 4 years ago

@jiya4frd we've been facing these issues for months now and Google has not provided neither fixes nor guidelines on how to fix it.

I can tell you that it's not an easy task, though. One of the things you can check is the location's accuracy: discard all locations that go over a certain threshold (its value will depend on the application).

Some other things that can point to a wrong location is the timestamp of the fix. We noticed that the Fused Location Provider returns (probably cached?) locations minutes/hours/days! older than the current time. Discard those as well!

Finally, we do post-processing to filter out these weird location fixes. We can do it because we record a full track (sports app), so we end up with a whole trajectory. However, if you only expect a single location... that might not be useful.

In case you need a single location, you could request location updates and wait until they converge on a given area. You could then be relatively sure that the location is correct. But trust me, not entirely sure: we've gotten "location clusters" hundreds of meters away from the real user location.

Hope this helps!

MrFuFuFu commented 4 years ago

Hi, @necavit thanks for the great explanation. We encountered the same issue for our app. When our app doing is checking the location on a foreground service every 10 minutes and we found sometimes the location just jumps to another location even when you sit there. We're using Fused Location as well, and discard those locations that older than 20 seconds and accuracy less than 200 meters. But still, it returns a new location with newest fetched and very high accuracy, but totally wrong location (sometimes 100 meters away sometimes a few km away.)

I guess what I can do following your suggestion is, save these locations and find a logic to discard these "jumped" locations. The question is how to do "you could request location updates and wait until they converge on a given area." as you said? how to wait until the locations coverage on a given area.

And yeah. it's not entirely sure, you got locations hundreds of meters away from the real user location....which is still annoying... not sure if "android.location.LocationManager" can help that?

cheers, Yuan

necavit commented 4 years ago

Hi @MrFuFuFu! It's great to see that we're not alone in this regard!

A quick update: we opened a bug in Google's issue tracker a while ago: https://issuetracker.google.com/issues/156938572 It seems it's being investigated... or at least there's someone aware of this at Google. If you want to ping them too, it always helps!

Regarding the idea of having location converge: you could request a stream of locations with a listener/pending intent and then only start accepting those locations whenever they all belong to a circle with a certain radius and the center being the average of accepted locations.

However, that approach does not work if you need to track continuous movement. We've arrived to a compromise solution on our own. Please let me know if you'd like to hear more about it!

Finally, regarding the use of Location Manager... We have planned to use it and test/compare its performance against the Fused Location stack, but still haven't found the time for it. We do believe that it'd be better in our case, because we're an outdoor sports tracking app.

However, if the app was to be used in urban areas or in "static" situations... not so sure, because GPS reflections are even worse! Besides, Fused Location uses Wifi and cell tower sources as well, so it probably performs better in dense urban areas.

I hope it was useful!

Cheers,

David

jiya4frd commented 4 years ago

Finally I switched to Location manager as I was getting wrong location(almost 2km way from my location)due to network conflict here with fusedlocationproviderclient .LocationManager worked great in this scenario.I got perfect location if its accuracy is less than 25.

MrFuFuFu commented 4 years ago

Hi David @necavit

Thanks for the detailed explanation. Mind if I ask an irrelevant question about app running on the background?

In our app, the use case is a geofence similar feature. But since Geofence isn't reliable on Google Provided API, so we have to check user's locations frequently. We need to keep our app running on the background, Wondering have you tested this API: requestLocationUpdates (LocationRequest request, PendingIntent callbackIntent) The document claimed This method is suited for the background use cases ..... it's even when the app has been killed by the system But I won't give a full trust of this claim. Do you have experience with this method? Does it work with Doze Mode? And Doe it works with Huawei devices or OnePlus etc? Or is it reliable running on the background all the time?

Sorry, the question is irrelevant to this issue, but I've encountered issues more seriously than "Location Jumping", it would be a huge help if you have any tips with this issue.

Best, Yuan

MrFuFuFu commented 4 years ago

@jiya4frd I did test the Android Location Manager these days, and it turns out it drains more batteries in some devices like Huawei, our app constantly checking user's location every 10 minutes with a foreground service running. On Huawei's device during our test, the battery drains more than 20% with Android Location Manager but it only drains about 10% with FusedLocationProviderClient. So in our case, we have to choose FusedLocationProviderClient unfortunately.

necavit commented 4 years ago

Hi Yuan! @MrFuFuFu

On Background/Foreground service reliability

We do work with the API that receives a PendingIntent as a parameter. It works more or less equally well for us, compared to the one that gets a Listener. However, regarding reliability on those devices you mention... Not so great. Don't get me wrong, though: we have found NO API that works reliably in those devices.

The issue with Huawei's, OnePlus'es, etc. is that these manufacturers add a custom battery optimizer layer to the already bundled Doze system in stock Android. They basically block all apps from running for any extended period of time... especially when using high-power features like the GPS antennae. It seems to be confirmed that they also white-list some popular apps, to avoid users being too angry at the device.

Here are some more resources about all this hassle:

On LocationManager vs FusedLocationProvider

It's great to hear both your experiences @MrFuFuFu and @jiya4frd ! We suspected about an increase in battery usage that would stem from using LocationManager... It'll be interesting to see how we can optimize for it!

Best regards,

David

jiya4frd commented 4 years ago

@jiya4frd I did test the Android Location Manager these days, and it turns out it drains more batteries in some devices like Huawei, our app constantly checking user's location every 10 minutes with a foreground service running. On Huawei's device during our test, the battery drains more than 20% with Android Location Manager but it only drains about 10% with FusedLocationProviderClient. So in our case, we have to choose FusedLocationProviderClient unfortunately.

Yes its true location manager drains battery than fusedLocationProviderClient but in term of accuracy location manager is reliable than fused one as I tested.I added location updates alongwith activity recognition so it saves from battery drain at some extend.