6

I use the following code to get Current Location from a Network provider in my application:

LocationManager mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean network_enabled = mgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(network_enabled){
Location location = mgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

But it gives a location approximately 300-700 meters away from my actual location.

This is expected from a Network provider. But the problem is:

with only this Network provider enabled, and no GPS, I openned Foursquare application where it shows my current location exactly where I am. Now when I come back to my application, it shows the accurate current location or say the same location which Foursquare showed.

Same thing happens with Google apps like Navigator, Maps etc..,

How can this be done? How are other apps able to get the exact location, based on just the Network provider?

Complete Code:

public class MyLocationActivity extends Activity implements LocationListener {
    private LocationManager mgr;
    private String best;
    Location location;
    public static double myLocationLatitude;
    public static double myLocationLongitude;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        best = mgr.getBestProvider(criteria, true);
        location = mgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        dumpLocation(location);
    }

    public void onLocationChanged(Location location) {

        dumpLocation(location);
    }

    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    @Override
    protected void onPause() {

        super.onPause();
        mgr.removeUpdates(this);
    }

    @Override
    protected void onResume() {

        super.onResume();
        mgr.requestLocationUpdates(best, 15000, 10, this);
    }

    private void dumpLocation(Location l) {

        if (l != null){

            myLocationLatitude = l.getLatitude();
            myLocationLongitude = l.getLongitude();
        }
    }
}

Thank You

Archie.bpgc
  • 23,812
  • 38
  • 150
  • 226
  • if you are using android 4.2 Compared to previous versions of Android, user location results may be less accurate if your app requests the ACCESS_COARSE_LOCATION permission but does not request the ACCESS_FINE_LOCATION permission. To meet the privacy expectations of users when your app requests permission for coarse location (and not fine location), the system will not provide a user location estimate that’s more accurate than a city block. – Athul Harikumar Mar 26 '13 at 10:17
  • I tried it on `4.1.2`. But anyways I am asking for both `ACCESS_COARSE_LOCATION` and `ACCESS_FINE_LOCATION` permission. – Archie.bpgc Mar 26 '13 at 10:19
  • Can you try to reduce the time between updates? Are the latter locations sent more accurate than the first ones? – Ovidiu Latcu Mar 26 '13 at 10:42
  • Yeah. I tried setting it to 5 seconds. Still the same results.`mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10, this);` – Archie.bpgc Mar 26 '13 at 15:41

1 Answers1

3

You are getting just the last known location. You should request location updates from the LocationManager. Use LocationManager.getLocationUpdates.

On your LocationListener on the onLocationChanged(Location location) method, you can check on the Location object, how accurate this location is, like this :

float accuracy=location.getAccuracy();

then, if this Location is accurate enough for you, you can stop receiving location updates from the LocationManager using removeUpdates() , and use the received Location. If the Location is not accurate enough, you can wait for a more precise Location, and stop the updates latter on.

Ovidiu Latcu
  • 71,607
  • 15
  • 76
  • 84
  • Sorry that is just part of the code in question. Actually I have a `LocationListener` which **requests updates** and implements `onLocationChanged`. Which is `mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 15000, 10, this);` – Archie.bpgc Mar 26 '13 at 10:22
  • Instead of waiting for updates, is there a way to get a fresh fix from the provider. – Archie.bpgc Mar 26 '13 at 15:43
  • actually... this will try to give you a fresh fix from the provider. but it will happen async. – Ovidiu Latcu Mar 26 '13 at 15:46
  • @OvidiuLatcu: I'm using the same code for accessing current location for lat & long. I'm using FragmentActivity as parent. It never called onLocationChanged() method for getting updated location.. So can you please help me to find solution ? – Manann Sseth May 19 '14 at 06:00