4

I've been using the fused location provider since its release and I am pretty happy with it (way better than the old system). But I ran into a peculiar problem when using geofencing in combination with LocationClient.lastKnownLocation(). The setup is as follows:

I drop several geofences around some home location (with increasing ranges). When I get the intent that a fence is crossed I retrieve the last known location from LocationClient and work with it. Apart from than I also registered for regular location updates with update mode PRIORITY_BALANCED_POWER_ACCURACY.

Most of the times this works perfectly fine, but sometimes this happens:

Time 000 s - (Lat,Lon,Accuracy) = (48.127316,11.5855167,683.0)

Time 120 s - (Lat,Lon,Accuracy) = (48.1260497,11.5731745,31.823)

Time 300 s - (Lat,Lon,Accuracy) = (48.1217455,11.5641666,143.81)

Time 420 s - (Lat,Lon,Accuracy) = (48.1189942,11.559061,36.0)

Time 600s - (Lat,Lon,Accuracy) = (48.127316,11.5855167,683.0)

Notice that all these locations are retrieved by getLastKnownLocation(). What seems fishy here is that the first and the last location are identical (even in the other attributes), to be more specific:

* intent at time 0: *

component: ComponentInfo{package.Class}
key [location]: Location[mProvider=fused,mTime=1373524391934,mLatitude=48.127316,mLongitude=11.5855167,mHasAltitude=false,mAltitude=0.0,mHasSpeed=false,mSpeed=0.0,mHasBearing=false,mBearing=0.0,mHasAccuracy=true,mAccuracy=683.0,mExtras=Bundle[mParcelledData.dataSize=352]]

* intent at time 600: *

component: ComponentInfo{package.Class}
key [location]: Location[mProvider=fused,mTime=1373524994871,mLatitude=48.127316,mLongitude=11.5855167,mHasAltitude=false,mAltitude=0.0,mHasSpeed=false,mSpeed=0.0,mHasBearing=false,mBearing=0.0,mHasAccuracy=true,mAccuracy=683.0,mExtras=Bundle[mParcelledData.dataSize=352]]

* note the ~600 s difference in the timestamp * 

I do not understand how this can happen, as there have been locations in between that were both more recent and more accurate. Also the new timestamp on an old location makes me curious... apparently similar things happened when using the old API, but this new location provider is just called fused, so I can not distinguish GPS from WPS from sensors... If it is the cell tower switching problem (outlined in the linked question concerning the old API) then why would the phone connect to a "far away" tower if it has seen closer towers?

Why is this happening?

Community
  • 1
  • 1
NemoOudeis
  • 332
  • 3
  • 15

3 Answers3

1

The first and last points were gotten using cell triangulation. The error/accuracy is typical of cell-based location, and it looks like the Google power saving logic decided that switching to cell would be OK, even as you say its recent history included points much closer.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • that's probably right... But for users I would like to filter these bogus fixes (I have observed more extreme examples of this over the last week). But i don't see a way to identify the fixes that are "old" except for keeping old location in memory and checking them manually, which i'd prefer not to do.. – NemoOudeis Jul 24 '13 at 08:57
0

Aw, SHUCKS! I got this too today... And I moved to the new Google Play Services location precisely to AVOID this... And I was so thrilled up until just now when I got it too. You may or may not know that the old one had these kind of problems, and it was a pain.

There are lots of threads regarding this, including one of my own :(

Why is locationmanager returning old location fixes with new gettime-timestamp?

I guess the only thing to do is avoid using cached location...

Community
  • 1
  • 1
Mathias
  • 3,879
  • 5
  • 36
  • 48
  • I've added several filters and sanity checks before using the locations, which greatly improved the performance of my app. What I ran into most was that the API would give me old cell tower locations (accuracy > 500) which messed up my tracking. To avoid this I started clustering the cell tower locations and filter new cell towers that lie in those clusters (locations used to create clusters are removed periodically). Maybe this helps – NemoOudeis Oct 07 '13 at 12:24
  • Wow, so you keep a database over cell tower id's? Thats a *lot* of hassle for something that really just should work... :( – Mathias Oct 13 '13 at 06:42
  • I do not use a db for it as mobile context is very transient, locations older than 1 hour are forgotten. But you are right, I'd be a lot happier if it just worked as I hoped for – NemoOudeis Oct 15 '13 at 08:14
  • What i ended up doing was just never ask for last cached location. Our app always just want a really fresh location, but since that one seems erratic, we always fire up and connect the client and starts polling actively until we have one, then shut down again. We have so far only seen those stale locations when asking through latestknownlocation. The user experience will suffer, but whatcha gonna do... – Mathias Oct 15 '13 at 08:22
0

Instead of polling, one can work around one or more sources of inaccuracy using this subscription mechanism.

LocationListener locListener = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        if (location == null)
            return;
        // process these:
        // location.getLatitude();
        // location.getLongitude();
        // location.getAccuracy();
        ...
    }
    ... 
}

((LocationManager) getSystemService(Context.LOCATION_SERVICE)
        .requestLocationUpdates(LocationManager.GPS_PROVIDER,
                minTimeMilliSec,
                minDistanceMeters,
                locListener));
Douglas Daseeco
  • 3,475
  • 21
  • 27