8

I am trying to get the current location. For that I implement a LocationListener and register it for both the network and the GPS provider:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

I block then for 30 seconds and use the first location that gets passed into the listener's

onLocationChanged()

method with an accuracy of 100 meters or better.

Most of the time this works fine. If the phone is connected to some Wifi network, it takes just a second to get a correct location with an accuracy of about 50 meters. If there is no Wifi but GPS is enabled, it can of course take a while to get a location.

Sometimes however, when connected to a Wifi and getting the current location, some old (cached?) previous "Wifi" location is provided - it might be 15 minutes old and 15 kilometers away from the current location. The problem is, that

location.getTime()

returns the current time - so it is impossible to know that the location is old.

I guess I have to implement a more elaborate solution - I would just like to know why these old "Wifi" locations have a current timestamp instead one from the time when it was originally retrieved.

Zaheer Ahmed
  • 28,160
  • 11
  • 74
  • 110
Torsten Römer
  • 3,834
  • 4
  • 40
  • 53
  • 1
    This isn't really an answer, but I just wanted to confirm you that this happens at least all the way up to API8, and that I also encountered the same problem. As someone did in one of the answers I implemented a simple "noise filter" for wifi locations in which I see if the distance traveled is likely to have happened, but this isn't perfect.. – rjam Nov 11 '11 at 12:33
  • I have the same problem. You have got to solve it? – Nik Aug 28 '13 at 06:00

3 Answers3

6

This is a known issue which I have encountered and did some research on why this happens.

Here are my observations:

  • Usually this happens when the mobile network hand-off is happening after losing network connectivity which may not necessarily be significant enough for the user to realize.
  • Consider you are taking a tube train and you get in at station A and get down at station B, now when you get down at station B the network cell ID may/maynot still be of station A and of course it will do a hands-off and move to station B.
  • However if you call for getLocation is active before the hand-off you would get station A location which might be like 10 km and 15 mins back.

First understand how network location works: Android has the cellId of the tower to which it is currently connected to and this id is then used by google to perform look-up and fetch approximate location information whose accuracy can range from 50 metres (one of the best) to a few thousand metres. If the cellId is incorrect as shown in the above example then you would receive wrong location.

There is not much you can do to avoid this except having a custom algorithm that can weed out this noise. Something like

if (location from network) {
    if (speed obtained from the difference between previous and current location is        greater than say 30 m/s) {
        ignore this location as noise
    } else {
       location is correct
    }
}
PravinCG
  • 7,688
  • 3
  • 30
  • 55
  • I might have a similar problem, just that it is rather about Wifi based locations: After being connected to Wifi A and moving away, and then being connected to Wifi B, I get the location of Wifi A which is old and far away. I'm going to check out the info provided by nickfox... – Torsten Römer Jul 16 '11 at 20:18
  • Yep it is pretty much the same just translate cellular network to wifi . – PravinCG Jul 16 '11 at 20:21
  • I also met this problem. Sometimes the location wasn't changed even after I ran more than 20km. During the trip, there might be many cell IDs. How can we explain this problem? – flypen May 30 '12 at 15:58
  • 1
    When my application had this problem, Google Map could get the location correctly. It's very hard to explain this if the cell id was wrong. – flypen May 30 '12 at 16:08
  • If Google Map can get the location correctly there is no reason why your application shall not get it. Are you sure you are listening to both Network and GPS location providers? – PravinCG May 30 '12 at 16:23
  • If GPS is enabled, my app can get the location correctly. My problem only occurs when the GPS is disabled. Today I repeated this problem. Even after the CELLID and LAC changed several times, the location was not changed. However, when I connected the WIFI, then the location became correct. – flypen May 31 '12 at 02:09
  • Do you have GPRS/EDGE data connection enabled on your device? Device will try to look up the location of your CELLID/LAC from the google servers. Most likely that is not happening. – PravinCG May 31 '12 at 04:28
  • Yes, I have data connection. This problem will happen when I am in subway and the connection is not stable. But after I get off the train, I still get the wrong place for more than 15 minutes. I am sure that the network is reachable after I get off the train. In the train, sometimes it can get data from several, sometimes it reports timeout. – flypen May 31 '12 at 07:28
  • Some more information for my problem: If the problem didn't occur: after I called requestLocationUpdates(), the callback function onLocationChanged() would be called right away or only several seconds later. If the problem occurred, after I called requestLocationUpdates(), the callback function onLocationChanged() would be called about one minute later. – flypen May 31 '12 at 08:31
  • Your problem is the classic case of what I have discussed. – PravinCG May 31 '12 at 13:58
  • When this problem happened, I used HTTP POST API to get location from Google server directly with cid and lac. I could get the correct location. It seemed that the cell information was correct but the network location provider had something wrong. – flypen Jun 01 '12 at 07:07
  • I posted a thread about this back in Oct'11 and its still the same. I never could get a working work-around for this, which is very unfortunate. It drives me CRAZY that the api returns old fixes with new timestamps. Anyone managed some sort of workaround? Pravin? – Mathias Jun 12 '12 at 08:22
2

This is helpful:

A Deep Dive Into Location

and lastly the source code for that talk:

android-protips-location

nickfox
  • 2,835
  • 1
  • 26
  • 31
  • Thanks, very interesting. Just unfortunately, most features only for Gingerbread and up. I'm developing against API 7, maybe going to 8. Still it is unclear to me why LocationManager passes an old location with a current timestamp. This suggests that it is the current location, while it isn't. – Torsten Römer Jul 16 '11 at 21:16
  • I was wrong, the source code to that you posted the link also covers older API levels and is indeed very useful. – Torsten Römer Aug 24 '11 at 20:45
  • GREAT LINK! fantastic tips on location updating and update frequency based on phone state, network availability, wifi vs cell, battery life. – tony gil May 31 '12 at 20:10
  • 1
    I follow all the recommendations of article "A Deep Dive Into Location", but I still have the same problem. – Nik Aug 28 '13 at 06:03
  • I/O link is no longer available. – pepyakin Jun 25 '14 at 10:17
  • @pepyakin I removed that link. Should have known better than to expect google to keep an important blog entry around... – nickfox Jun 25 '14 at 19:12
0

I have been facing the same issues until I made some changes to my code.

What happened is that I was attaching the same LocationListener when requesting for both GPS and Network location updates and I was getting "weird" issues including getting old WIFI location updates with current time.

Here's my old code:

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, locationListener);

Apparently that is a rather "unsafe" thing to do (sorry, Android newbie here) and so I changed it to:

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, networkLocationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, gpsLocationListener);

Of course I had to define 2 separate onLocationChanged block of codes to handle the 2 listeners.

Well, it did solve my problem. I tested this on Gingerbread (API Level: 8). Not sure if it works for you.

Dason Goh
  • 1
  • 1