Search code examples
androidandroid-locationlocation-client

android - repeat same location without WiFi connection


I use LocationClient to get Location. With WiFi connection it works fine, but without WiFi, it repeats same location (even with mobile data connection!). I used LocationManager but it didn't work.

I'm wondering how google maps works fine (with mobile data connection) but I can't get the right location.

Using "LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY" or "LocationRequest.PRIORITY_HIGH_ACCURACY" makes same result.

here is my code:

public class LocationTracker implements
    GooglePlayServicesClient.ConnectionCallbacks,
    GooglePlayServicesClient.OnConnectionFailedListener {

LocationClient mLocationClient;
Location mCurrentLocation;
LocationRequest mLocationRequest;
LocationListener locationListener;
Handler handler = new Handler();

private static final int MILLISECONDS_PER_SECOND = 1000;
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND
        * UPDATE_INTERVAL_IN_SECONDS;
private static final int FASTEST_INTERVAL_IN_SECONDS = 5;
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND
        * FASTEST_INTERVAL_IN_SECONDS;

Context context;

public LocationTracker(Context context) {
    this.context = context;

}

public void getLocation() throws Exception {
    try {
        final int result = GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(context);
        if (result != ConnectionResult.SUCCESS) {
            Toast.makeText(
                    context,
                    "Google Play service is not available (status="
                            + result + ")", Toast.LENGTH_LONG).show();

        }
    } catch (Exception e) {
        throw new Exception(e);
    }    

    mLocationClient = new LocationClient(context, this, this);
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

    mLocationClient.connect();

}

private final class MyLocationListener implements LocationListener {
    @Override
    public void onLocationChanged(Location location) {
        mCurrentLocation = location;
    }
}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
    Toast.makeText(context, "Connection Failed", Toast.LENGTH_LONG).show();

}

@Override
public void onConnected(Bundle connectionHint) {

    locationListener = new MyLocationListener();
    mLocationClient.requestLocationUpdates(mLocationRequest,
            locationListener);
    mCurrentLocation = mLocationClient.getLastLocation();

}

@Override
public void onDisconnected() {

}

Solution

  • I resolve it. LocationClient.getLastLocation() returns last cached location. I have to check location in LocationListener.onLocationChanged() and if location is not equal with last cached location, I can use it.

    here is the code:

    import android.content.Context;
    import android.location.Location;
    import android.location.LocationManager;
    import android.os.Bundle;
    import android.os.Handler;
    import android.widget.Toast;
    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GooglePlayServicesClient;
    import com.google.android.gms.common.GooglePlayServicesUtil;
    import com.google.android.gms.location.LocationClient;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.location.LocationRequest;
    
    public class LocationTracker implements
        GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener {
    
    LocationClient mLocationClient;
    Location mCurrentLocation;
    LocationRequest mLocationRequest;
    LocationListener locationListener;
    Handler handler = new Handler();
    
    
    private static final int MILLISECONDS_PER_SECOND = 1000;
    public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
    private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND
            * UPDATE_INTERVAL_IN_SECONDS;
    private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
    private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND
            * FASTEST_INTERVAL_IN_SECONDS;
    
    Context context;
    
    public LocationTracker(Context context) {
        this.context = context;
    
    }
    
    public void getLocation() throws Exception {
        try {
            final int result = GooglePlayServicesUtil
                    .isGooglePlayServicesAvailable(context);
            if (result != ConnectionResult.SUCCESS) {
                Toast.makeText(
                        context,
                        "Google Play service is not available (status="
                                + result + ")", Toast.LENGTH_LONG).show();
    
            }
        } catch (Exception e) {
            throw new Exception(e);
        }
    
        mLocationClient = new LocationClient(context, this, this);
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    
        mLocationClient.connect();
    
    }
    
    private final class MyLocationListener implements LocationListener {
        @Override
        public void onLocationChanged(Location location) {
            // Report to the UI that the location was updated
    
            // sendLocation(location);
    
            if (!(location.getLatitude() == mCurrentLocation.getLatitude() && location
                    .getLongitude() == mCurrentLocation.getLongitude())) {
    
                mLocationClient.removeLocationUpdates(locationListener);
                mLocationClient.disconnect();
    
                //use location as answer
    
            }
        }
    }
    
    @Override
    public void onConnectionFailed(ConnectionResult arg0) {
        Toast.makeText(context, "Connection Failed", Toast.LENGTH_LONG).show();
    
    }
    
    @Override
    public void onConnected(Bundle connectionHint) {
    
        final LocationManager manager = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
    
        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
    
            //GPS provider is not enabled
            return;
        }
    
        locationListener = new MyLocationListener();
        mLocationClient.requestLocationUpdates(mLocationRequest,
                locationListener);
        mCurrentLocation = mLocationClient.getLastLocation();
        handler.postDelayed(new Runnable() {
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                if (mLocationClient.isConnected()) {
                    mLocationClient.removeLocationUpdates(locationListener);
                    mLocationClient.disconnect();
    
                    //GPS can not find the location
    
                }
            }
        }, 2 * 60 * 1000);
    
    
    }
    
    
    @Override
    public void onDisconnected() {
    
    }
    

    }