androidlocationandroid-fusedlocationfusedlocationproviderclient

FusedLocationProvider gives wrong location sometimes


I am using FusedLocationProviderClient to get location updates in a foreground service. On testing and observing for few days, I found wrong locations which was far away from my actual location by around 4 kms similar to thisimage, but the LocationResult had an accuracy of 24 meters. How is this even possible?

It can be eliminated if the accuracy was around 4 kms. This behavior does not occur very often but occurs atleast once in 4 among 10 devices. It becomes a problem when I calculate distance traveled.

I can tell it's not a cached location because I used to turn off and on Location Services everyday. (As per docs, turning off Location Services clears cache location.)

Any idea why it's giving wrong location and how to eliminate it? And also clearing cache locations without turning off Location Services?


Solution

  • FusedLocationProvider CAN give incorrect results like that when gps connectivity for device is down(or insufficient satellites are in "view" to provide accurate data). It will use the nearest cell tower/location data provided by the wifi router(google tracks this automatically) giving WILDLY incorrect results in places where google doesn't have a strong location mapping presence - which is anywhere outside an urban center.

    You have imho two options:

    1. Use the non googleplay based solution based on location service - this has an option for ignoring non-gps location data(wifi/cellular).

      LocationManager locationManager = (LocationManager)
      getApplicationContext().getSystemService(LOCATION_SERVICE);  
      Location location = locationManager.getLastKnownLocation(LocationManager.GPS_Provider);
      

      You can even specify the number of satellites required for acceptable data so you can get REALLY accurate location data. You will lose information when the gps doesn't receive coordinates (like indoors), but in exchange will have less "noise" from incorrectly mapped location, as per your requirement.

    2. Use a "snap to roads" API. There is a free version using open street map data called Project OSRM(Open Source Routing Machine) that provides a backend when hosted (locally or in cloud) using docker or building source yourself (details in link).

      curl "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"

    This request will return a location that is "snapped" to the nearest road. There are various options such as giving priority to highways etc. You can then discard the points that are not on the "path" that the user was previously on as rapidly shifting to a road 4km away and then coming back again is not likely.