Can able to stop location update, Android service

1.9k views Asked by At

I am trying to create a route tracking app. it need to track location even if the app is in background. so i created a service and add code to this service. Following are my code. but there is one problem. I start the service from my main activity.

public void startTracking(View view) {
    startService(new Intent(MainActivity.this, LocationIntentService.class));
}

public void stopTracking(View view) {
    stopService(new Intent(MainActivity.this, LocationIntentService.class));
}

It start the service and locations are inserted to a local db. But i cant stop these service. When i stop service using above code it still track the location. How can i stop location update.

public class LocationIntentService extends IntentService implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = LocationIntentService.class.getSimpleName();
    private static final long INTERVAL = 1000 * 10;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    private static int DISPLACEMENT = 10;

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    DBAdapter dbAdapter;

    public LocationIntentService() {
        super("LocationIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.e(TAG, " ***** Service on handled");
        if (isGooglePlayServicesAvailable()) {
            createLocationRequest();
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
            mGoogleApiClient.connect();
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.e(TAG, " ***** Service on connected");
        startLocationUpdates();
        openDB();
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.e(TAG, " ***** Service on suspended");
        mGoogleApiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.e(TAG, "Location changed");
        mLastLocation = location;

        String latitude = String.valueOf(mLastLocation.getLatitude());
        String longitude = String.valueOf(mLastLocation.getLongitude());
        Log.e(TAG, " ##### Got new location"+ latitude+ longitude);

        Time today = new Time(Time.getCurrentTimezone());
        today.setToNow();
        String timestamp = today.format("%Y-%m-%d %H:%M:%S");

        dbAdapter.insertRow(latitude, longitude, timestamp);
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.e(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
                + connectionResult.getErrorCode());
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "Service is Destroying...");
        super.onDestroy();
        if (mGoogleApiClient.isConnected()) {
            stopLocationUpdates();
            mGoogleApiClient.disconnect();
        }
        closeDB();
    }

    protected void stopLocationUpdates() {
        Log.d(TAG, "Location update stoping...");
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
    }

    protected void startLocationUpdates() {
        Log.d(TAG, "Location update starting...");
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);

    }

    private void openDB() {
        dbAdapter = new DBAdapter(this);
        dbAdapter.open();
    }

    private void closeDB() {
        dbAdapter = new DBAdapter(this);
        dbAdapter.close();
    }

    protected void createLocationRequest() {
        Log.e(TAG, " ***** Creating location request");
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
    }

    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            Log.e(TAG, " ***** Update google play service ");
            return false;
        }
    }
}
4

There are 4 answers

9
Daniel Nugent On BEST ANSWER

The reason that it's not working for you is that you are using an IntentService, so calling stopService() will not cause onDestroy() to be called, presumably because it was already called after onHandleIntent() has completed. There is no need to ever call stopService() on an IntentService see here.

It looks like you should probably just use Service instead of IntentService. That way, when you call stopService(), it would call onDestroy() and unregister for location updates, as you expect.

The only other change you would need to make would be to override onStartCommand() instead of onHandleIntent().

You would have your class extend Service instead of IntentService, and then move your code to register for location updates to onStartCommand:

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, " ***** Service on start command");
        if (isGooglePlayServicesAvailable()) {
            createLocationRequest();
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
            mGoogleApiClient.connect();
        }
        return Service.START_STICKY;
    }

This way you can still call startService() and stopService(), and it should work as you are expecting.

1
strike On
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
1
NehaK On

call stopLocationUpdates() method in stopService()

1
Jigar Shekh On

When you stop your services. Then called this line in LocationIntentService.class.

locationManager.removeUpdates(this);