17

I have developed an application for Android, for storing user's GPS location.

One of my customers gave me his device and I noticed that sometimes the accuracy of the device is really bad and unbelievable. Sometimes the device returns points about 200 kilometers away from the actual location.

You can see this in the following GPS location samples for that device. You see that two points are about 200 km away from the real location.

The device is Samsung SM-T111 with Android 4.2.2, and I only use a GPS provider for getting locations (LocationManager.GPS_PROVIDER).

I want to know what causes the problem, for this kind of inaccuracy?

I directly store the points received from the provider. This is my code in onLocationChanged:

UPDATE

        @Override
        public void onLocationChanged(Location location) {
            try {

                    if (location.getAccuracy() <= MAX_DISTANCE_TOLERANCE) {

                        gotLocation(new GPSLocation(location.getLatitude(),
                                location.getLongitude(), location.getTime(),
                                location.getAccuracy(),
                                location.getProvider(), location.getSpeed()));
                    }               

            } catch (Exception e) {
                MessageBox.showExceptionToast(_context, e);
            }
        }

enter image description here

enter image description here

jacefarm
  • 6,747
  • 6
  • 36
  • 46
Bob
  • 22,810
  • 38
  • 143
  • 225
  • One possibility is the onLocationChanged method not being properly written/executed. Please look into that logic and we can further investigate. – paul_hundal Nov 06 '16 at 10:21
  • What is `GPSLocation` ? What is `gotLocation()` doing? – greenapps Nov 06 '16 at 12:51
  • You use only gps? – greenapps Nov 06 '16 at 12:52
  • 2
    If it is only one device then blame the gps chip in the device. – greenapps Nov 06 '16 at 12:56
  • I also having similar problem,But not this much different.Sometimes the next point would be 1-2 km from previous. – Noufal Nov 08 '16 at 06:34
  • What are the reported horizontal accuracies for these points? Also, I see a huge variance in time between getting those two inaccurate points and the rest of the points. Did you turn off GPS during that time? If so, for how long? – Pablo Baxter Nov 14 '16 at 19:41
  • @greenapps Yes I only use GPS provider and `gotLocation()` method only save the location in the database. – Bob Nov 15 '16 at 07:01
  • @PabloBaxterNo I did not turn off GPS. No There is no huge variance in times. Those locations are received in a minute. – Bob Nov 15 '16 at 07:04
  • Is this a samsung device? Some samsung devices dont work well with Google Play Service location service. They report blantly wrong locations like your example. – Jonas Köritz Nov 16 '16 at 14:59
  • duplicate search for gps accuracy you should find my answers. – danny117 Nov 17 '16 at 14:47
  • Looks like its within your tollerance – danny117 Nov 17 '16 at 14:49
  • @breceivemail I was asking about the time variance since the timestamp for the point before the two in question appears to have been received 30 minutes beforehand, and the point after the two in question were received 4 hours afterwards. – Pablo Baxter Nov 17 '16 at 17:09

7 Answers7

15

I want to know what can be the problem for this kind of inaccuracy?

Hardware/firmware, most likely. In other words, blame Samsung.

It's unlikely to be your app. Assuming that the accuracy values that you are getting for those failed points are within MAX_DISTANCE_TOLERANCE, and assuming that MAX_DISTANCE_TOLERANCE is less than 200km, you are faithfully using the data that you get. If that data is flawed, those flaws are coming from the system itself.

You could create a more adaptive filter. In addition to testing the accuracy for MAX_DISTANCE_TOLERANCE, you could:

  • Calculate the time between the last location you were given and the new one that you are processing now
  • Calculate the maximum distance that could be covered in that time, based on some maximum speed that you expect the device to be going
  • Calculate the distance reported between those two locations (there's a static method on Location for this)
  • Reject locations where the reported distance is further than you think the device could have moved in this period of time

For example, your first bad fix comes 20 minutes after the previous one. Unless you think the device might travel at 600 km/hour, you would reject the bad fix as being unrealistic.

This algorithm will only work after you have a few consistent fixes. You might ask for rapid location updates for a few minutes, examine that data, throw out any outliers, then apply the "could the device really have travelled that far?" test for future fixes.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Same question as to AndroidHacker. What happens if the first readout is wrong (or few next, if you're collecting them and checking them if they are near) and you mark it as "valid"? Next location readouts will then be flagged as not valid, because they will have too large distance, even if they are now real and good locations. – Beemo Feb 15 '17 at 14:46
  • @Beemo: There is nothing much that you can do in this case. It is not like a `Location` has a method `isThisLocationFlawedBeyondAllUsefulness()` or something. There *is* `getAccuracy()`, and you probably want to blend that into your algorithm. But, a flawed device may well report locations that are wrong but that it claims are accurate. You have no means of detecting that. In the end, app developers have to assume that the hardware is decent, and if it is not, that is the hardware's issue, not yours. – CommonsWare Feb 15 '17 at 14:49
  • Yea, that is what I was afraid of. Then we, as app developers, are useless/fools in the eyes of our users. – Beemo Feb 16 '17 at 10:25
6

If you don't trust Google's Fused API, or any other algorithm, and you have some knowledge about NMEA formatted, raw GPS data, then I recommend you take a deep dive into the raw GPS data, and see what is actually going on.

You can get NMEA_0183 GPS messages from the GPS chipset, and analyze satellite constellation, SNR, DOP, lat, lon, etc.

LocationManager LM = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        ((LocationManager)getSystemService(Context.LOCATION_SERVICE)).requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,new LocationListener(){
            @Override
            public void onLocationChanged(Location loc) {}
            @Override
            public void onProviderDisabled(String provider) {}
            @Override
            public void onProviderEnabled(String provider) {}
            @Override
            public void onStatusChanged(String provider, int status,Bundle extras) {} });

        //for API23 and below
        LM.addNmeaListener(new GpsStatus.NmeaListener() {
        public void onNmeaReceived(long timestamp, String nmea) {
            Log.d(TAG, nmea+"\n");
        }});

       //for API24 and above
       LM.addNmeaListener(new OnNmeaMessageListener() {
        public void onNmeaMessage(String nmea, long timestamp) {
            Log.d(TAG, nmea+"\n");
        }});

Here are some useful NMEA sentences:

GGA - Global Positioning System Fix Data

GSA - GPS DOP and active satellites

GSV - Satellites in view

ZDA - Time & Date - UTC, day, month, year and local time zone

jacefarm
  • 6,747
  • 6
  • 36
  • 46
ugur
  • 3,604
  • 3
  • 26
  • 57
3

If you're using Google fused location provider then those errors are bound to happen, so if you want the most accurate results and restrict them to GPS only, then use Android location framework instead of Google Play services Location API.

You can also filter major distance changes if you want to continue using Google's Location API.

Mohammad Abbas
  • 245
  • 2
  • 13
  • "If you're using Google fused location provider then those errors are bound to happen" -- do you have any evidence for this claim? Also, the OP is already using the Android location framework, based on what is written in the question. – CommonsWare Nov 14 '16 at 13:49
  • Yes, I have developed two applications on top of the fused location provider and it usually happens in third world coutries like Egypt and I think he is living in such a country as well. I can't give you a reason for the problem but our wifi hotspots and locations of interest are so little sometimes which leads to inaccurate data when there is no gps available – Mohammad Abbas Nov 14 '16 at 16:18
  • I didn't see that he used the Android location framework, sorry about that – Mohammad Abbas Nov 14 '16 at 16:20
  • 1
    "our wifi hotspots and locations of interest are so little sometimes which leads to inaccurate data when there is no gps available" -- yes, but if GPS is not available, using GPS directly ("then use Android location framework instead of Google Play services Location API") will not help. I agree that the network-based location tracking will vary in reliability. – CommonsWare Nov 14 '16 at 16:23
  • @MohammadAbbas These inaccurate locations are from GPS provider. The fused location provider returns more acceptable locations. It is strange that the GPS locations have these types of inaccuracy. – Bob Nov 15 '16 at 06:58
  • @MohammadAbbas How can I filter major distance changes using Google's Location API? Can you give me a sample? – Bob Nov 15 '16 at 06:59
  • It totally depends on the application you're try to develop, if you want to track a location from a driving car in the city you usually don't accept location updates that have a wide distance in a short amount of time – Mohammad Abbas Nov 15 '16 at 08:10
3

There may be many reasons for this. Listing some of them.

(1) GPS hardware used with in device.
(2) Weather condition( This will not generate much difference in distance. This may make a difference of about 20-30 KM as per my testing )
(3) Nearby location. This includes buildings and all other.

It is true that some time Android GPS starts behaving wired. I also faced this problem while creating a cab based application.

Solution by CommonsWare is almost a solution to your problem. There you may come up with some more specific algo to do the task.

While testing this scenario, I found this problem with One-Plus-One devices while there was no issue with in One-Plus-Two devices.

SOLUTION : You should check for maximum distance a user can travel within your time frame. Here time frame is the time of update of your GPS Location. This distance should be calculated on behalf of your previous valid Latitude and Longitude with respect to your current Latitude and Longitude.

As per you logs I see the time difference between updates of your Location. Make sure that you have fix time intervals for your update.

AndroidHacker
  • 3,596
  • 1
  • 25
  • 45
  • 2
    What to do if the first location readout is wrong and you mark it as "valid". Every other location readout will be inspected with that "valid" location and will fail. How to handle that? – Beemo Feb 15 '17 at 14:38
  • 1
    That's really a billion dollar question. I will get back to you on this ASAP. – AndroidHacker Feb 16 '17 at 04:37
1

The most important take away I hope to leave you with is take time to understand your accuracy requirements and your user’s basic geographic behavior patterns. I’ve tried to liberally sprinkle example use cases to help illustrate some of the concepts.

This is accomplished using the overloaded LocationManager.requestLocationUpdates() method. These properties adjust how aggressively the device will request location updates by minimum time elapsed and minimum distance traveled.

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,listener);

This method will resolve your issue a very basic set of technical requirements for dynamically changing requestLocationUpdates() settings:

public void onLocationChanged(Location location) {
     if(location.getAccuracy() < 100.0 && location.getSpeed() < 6.95){
          //Do something
     }
     else{
          //Continue listening for a more accurate location
     }
}
   
  • Start application using minTime= 0 and minDistance = 0. Use an aggressive setting to get accurate location as quickly as possible.

  • Once accuracy is less than 50 meters and speed less than 45 mph set minTime = 5000 and minDistance = 25.

  • Speed equals 0 for greater than 1 hour. Shut off location listeners and notify user.

  • Battery gets low. Shut off location listeners and notify user.

Community
  • 1
  • 1
1

You can opt technique of Fused Location Api for better results,

Nowdays which used commonly for location updates ,it always gives almost accurate or near about results in some meters not km.

You can follow this Link

Ramkesh Yadav
  • 987
  • 2
  • 11
  • 16
1

How to get more accuracy by GPS_PROVIDER

You have to check the location has accuracy before you can use accuracy.

Good luck.

Community
  • 1
  • 1
danny117
  • 5,581
  • 1
  • 26
  • 35