4

I am trying to get the current position of the phone, for this I use the GPSTracker tutorial, the problem is always use the method getLastKnownLocation and return older position.

                if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network");
                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    }
                }
            }
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
            }

You can see the tutorial use getLastKnownLocation when use Network or GPS provider, but I realy realy need the current position.

I dont know how get it!

TuGordoBello
  • 4,350
  • 9
  • 52
  • 78

5 Answers5

6

Use Fused Location Provider APIs in conjunction with GoogleApiClient. You can find the apis here. They are designed to give locations with high accuracy. Use it using GoogleApiClient.

new GoogleApiClient.Builder(context)
         .addApi(LocationServices.API)
         .addConnectionCallbacks(this)
         .addOnConnectionFailedListener(this)
         .build()

There are other approaches to using location providers. You should not restrict yourself to locations obtained using GPS and Mobile Network. Rather iterate over all the location providers and depending on your accuracy requirement choose those which give you high accuracy. The following code does this:

    Location bestResult = null;
    float bestAccuracy = Float.MAX_VALUE;
    long bestAge = Long.MIN_VALUE;
    List<String> matchingProviders = mLocationManager.getAllProviders();

    for (String provider : matchingProviders) {

        Location location = mLocationManager.getLastKnownLocation(provider);

        if (location != null) {

            float accuracy = location.getAccuracy();
            long time = location.getTime();

            if (accuracy < bestAccuracy) {

                bestResult = location;
                bestAccuracy = accuracy;
                bestAge = time;

            }
        }
    }

    // Return best reading or null
    if (bestAccuracy > minAccuracy
            || (System.currentTimeMillis() - bestAge) > maxAge) {
        return null;
    } else {
        return bestResult;
    }

You can also use the location object directly after checking them for accuracy. You should take advantage of the locations accessed by other apps and not just rely on the locations obtained by GPS/Mobile Networks.

If you want to continuously listen to location updates implement the Locationlistener callbacks to continuously get location updates.

Roadblock
  • 2,041
  • 2
  • 24
  • 38
1

If I recall correctly, that tutorial is rather old and do not use fused locations. In case you develop in Android Studio, consider trying this library: https://github.com/mcharmas/Android-ReactiveLocation

Way less code and fused location using the latest API.

To get the last known location simply:

ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(context);
locationProvider.getLastKnownLocation()
    .subscribe(new Action1<Location>() {
        @Override
        public void call(Location location) {
            // doSthImportantWithObtainedLocation(location);
        }
    });

Thats it!

cYrixmorten
  • 7,110
  • 3
  • 25
  • 33
1

I think one of the answeres used the locationListner, but here is a simple solution that will return the location even if GPS is not available by calling get getBestProvider,

Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);

String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(provider, 2000, 0, locationListener);

private final LocationListener locationListener = new LocationListener() 
{
  public void onLocationChanged(Location location) 
  {
    Double latitude = location.getLatitude();
    Double longitude = location.getLongitude();
  }

};
faljbour
  • 1,367
  • 2
  • 8
  • 15
1
The method mentioned above is the deprecated method and Android has asked developers to use the below method.

https://developer.android.com/training/location/retrieve-current.html

Sample Code


onCreate(){
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            buildAlertMessageNoGps();
        }
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

@Override
    protected void onStart() {
        super.onStart();
        // Connect the client.
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        // Disconnecting the client invalidates it.
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    public void onConnected(Bundle bundle) {

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        mLocationRequest.setInterval(1000 * 60 * 5);

        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    }
@Override
    public void onLocationChanged(Location location) {

        Geocoder geocoder;
        List<Address> addresses;
        geocoder = new Geocoder(this, Locale.getDefault());
        try {
            addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
            String address = addresses.get(0).getAddressLine(1);

        } catch (IOException e) {
            e.printStackTrace();
        }


        editor.commit();
    }
Arun Shankar
  • 2,295
  • 16
  • 20
1

Use below code -

private class LocationListener extends Activity implements android.location.LocationListener{
    Location mLastLocation;
    public LocationListener(String provider){
        Log.e(TAG, "LocationListener " + provider);
        mLastLocation = new Location(provider);
    }


   LocationListener[] mLocationListeners = new LocationListener[] {
        new LocationListener(LocationManager.GPS_PROVIDER),
        new LocationListener(LocationManager.NETWORK_PROVIDER)
   };

    private void initializeLocationManager() {
        Log.e(TAG, "initializeLocationManager");
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        }
    }


    @Override
    public void onLocationChanged(Location location) {
        Log.e(TAG, "onLocationChanged: " + location);
        mLastLocation.set(location);
        Toast.makeText(mContext, "Driver location :"+location.getLatitude()+" , "+location.getLongitude(), Toast.LENGTH_SHORT).show();
        //TODO call web service to update driver location to server
        driverLocationUpdateServerRequest(location);
    }

    @Override
    public void onProviderDisabled(String provider){
        Log.e(TAG, "onProviderDisabled: " + provider);            
    }

    @Override
    public void onProviderEnabled(String provider){
        Log.e(TAG, "onProviderEnabled: " + provider);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras){
        Log.e(TAG, "onStatusChanged: " + provider);
    }



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initializeLocationManager();
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[1]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "fail to request location update, ignore", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "network provider does not exist, " + ex.getMessage());
    }
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[0]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "fail to request location update, ignore", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "gps provider does not exist " + ex.getMessage());
    }

 }
} 
Ravi Bhandari
  • 4,682
  • 8
  • 40
  • 68