9

I have registered my LocationManager for location updates, every 10 seconds

mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10 * 1000, 50, this);

But the onLocationChanged callback returns a location every 10 secs, which(the location) is more than 2 hours old. And that time-stamp is never changing.

The problem is:

2 hours back I was in a complete different location(home) where I used the device on a wifi. Now currently I am in some other location(office) on a different wifi where my application shows my current location as home. Same thing happened at home yesterday, when it was showing office as my current location. It got to work(started showing correct location) when I closed my app, opened FourSquare app and re-opened my app.

Complete Code:

public class LocationService extends Service implements LocationListener {

    public static double curLat = 0.0;
    public static double curLng = 0.0;
    private LocationManager mgr;
    private String best;
    private Location location;

    @Override
    public IBinder onBind(Intent arg0) {

        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
        best = LocationManager.NETWORK_PROVIDER;
        location = mgr.getLastKnownLocation(best);
        if (location != null) {

            dumpLocation(location);
            mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                    10 * 1000, 50, this);
        }
        return START_NOT_STICKY;
        }
    }

    private void dumpLocation(Location l) {

        SimpleDateFormat s = new SimpleDateFormat("dd/MM/yyyy:hh:mm:ss",
                Locale.ENGLISH);
        String format = s.format(l.getTime());
        //The above time is always 28/03/2013:09:26:41 which is more than 2 hrs old
        curLat = l.getLatitude();
        curLng = l.getLongitude();
    }

    @Override
    public void onLocationChanged(Location location) {

        dumpLocation(location);
    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }
}

Being started in an Activity this way:

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent i = new Intent(this, LocationService.class);
pi = PendingIntent.getService(this, 0, i,
        PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime(), 10000, pi);

Permissions in manifest:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

I can get the correct location now, by opening some other location based app like Maps, Navigator, Foursquare etc.., But why my app isn't able to get a new/fresh fix from the provider.

Thank You

Archie.bpgc
  • 23,812
  • 38
  • 150
  • 226

3 Answers3

4

You are getting old location because of this line

  location = mgr.getLastKnownLocation(best);

because if GPS is not enabled then it will show you the old location . So remove this code It will work like a champ You can also refer to this library

https://github.com/nagendraksrivastava/Android-Location-Tracking-Library

On the basis of your comments I have edited the answer Okay Let me explain line by line location = mgr.getLastKnownLocation(best); it will give you object of last know location then it will go inside if condition and it will call dumplocation and will get last location data and after that you called

mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                10 * 1000, 50, this);

but suppose GPS provider is disabled then it will not fetch new location so you will get old location only . So either you can change it like

if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
                   {
                    locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER,new NagendraSingleLocationListener(),null);
                   }
                   else
                   {
                       locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER,new NagendraSingleLocationListener(),null);
                   }
Naga
  • 1,931
  • 4
  • 25
  • 42
  • But even if I am using `mgr.getLastKnownLocation(best);` `requestLocationUpdates` is meant to give new location right? Its recommended to start with `mgr.getLastKnownLocation(best);` and later register for updates. AFAIK – Archie.bpgc Mar 28 '13 at 06:40
  • You can check out my edited answer and please let me know if your problem has been solved – Naga Mar 28 '13 at 06:48
  • Yeah. So, the problem is not with `mgr.getLastKnownLocation(best)`. I am using wrong/disabled provider to request updates. +1 thanks a lot. – Archie.bpgc Mar 28 '13 at 06:56
  • Yeah exactly .. My pleasure Archie – Naga Mar 28 '13 at 06:57
0

I think because you cancel your pending intent right away, thus the requestLocationUpdate would not start update before you cancel. Why don't you sleep may be for 2 second before cancel.

Hoan Nguyen
  • 18,033
  • 3
  • 50
  • 54
  • Actually that `cancel` is to remove any similar pending intents assigned previously. Also no problem in running the service. Even `onLocationChanged` is called every 10 secs. The only problem is with the `location it returns`. – Archie.bpgc Mar 28 '13 at 06:49
0

From my experience android will give you a location when you request the updates even if gps has not enough sattelites to work. So even if gps is on - if you are inside or in a location that is bad (like under a bridge) android will deliver an old fix to you. Can be a very old one indeed.

The only thing I found to be working 100% is to generelly not use the first position but only remember the time. When new positions arrive you can check that the time is newer than the last. If you want to only use very precise positions you may also need to check that location.getAccuracy() is low (the lower the better).

I use gps to get my timestamps for a soap interface as the android clock can be very off sometimes and this was the only way for me to get a valid time from gps.

FrankKrumnow
  • 501
  • 5
  • 13