Imran Hakeem
Imran Hakeem

Reputation: 191

Stop location updates if the device has not moved and if it moves a distance of 300m then get it's location

i am making an android application. I want to stop location updates if the device is still and if it moves a distance of 300 or 400m then get it's location again. I don't want to check continuously for location updates and measure distance between previous location and current location because it consumes battery. My Location service class code:

public class LocationService extends Service implements
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }
}

@Override
public void onCreate() {
    HandlerThread thread = new HandlerThread("ServiceStartArguments",
            Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();

    // Get the HandlerThread's Looper and use it for our Handler
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

public void buildGoogleApiClient() {
    createLocationRequest();
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }
}

protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(500);
}

public void startLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
    mGoogleApiClient.disconnect();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
    buildGoogleApiClient();
    return START_STICKY;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    // The service is no longer used and is being destroyed
    stopLocationUpdates();
}

@Override
public void onLocationChanged(Location location) {
    System.out.println("Latitude: " + location.getLatitude());
    System.out.println("Longitude: " + location.getLongitude());
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

I am using locationRequest.setSmallestDisplacement(500) but it continuously receives location updates only the onLocationChanged method is not called if the distance between previous and current location is less than 500m e.g.

Should i use geofencing for this purpose? What is the best possible way to achieve this using FusedLocationApi with minimum battery consumption?

Upvotes: 2

Views: 659

Answers (1)

Shailen Tuli
Shailen Tuli

Reputation: 14171

There are a few things to note here:

  1. When your device isn't moving, Location Services optimizes for battery and does not necessarily do expensive new location lookups. So, you don't really have to try to optimize for this yourself.
  2. Consider passing a smaller value to LocationRequest#setSmallestDisplacement.
  3. To optimize for battery, consider using batched location updates, where location is computed for you in at the interval described in LocationRequest#setInterval, but delivered to your device based on the value in LocationRequest#setMaxWaitTime. This greatly helps with battery.

Not part of your question, but I should note that I would structure the code for requesting and removing location updates a little differently. I would connect GoogleApiClient in onStart(), and disconnect it in onStop(). I would call requestLocationUpdates() in onResume() of in onConnected(), and call removeLocationUpdates() in onPause() or onStop(), but not as late as onDestroy().

Upvotes: 2

Related Questions