3

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;
        }
    }
}
pcs
  • 1,864
  • 4
  • 25
  • 49
bolt123
  • 39
  • 1
  • 12
  • how can i call the stopLocationUpdates() from my MainActivity. I think the service is stop after connecting to the mGoogleApiClient. – bolt123 Jun 09 '15 at 05:20

4 Answers4

3

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.

Community
  • 1
  • 1
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
  • thanks. yes i think the Service() class is a better solution. will try with Service() – bolt123 Jun 09 '15 at 05:34
  • I need to send the location stored in local db to server(after some time period or if network is available). can you please suggest some tutorial or a starting point? – bolt123 Jun 09 '15 at 05:41
  • 1
    @bolt123 For that you use `timerTask` – M D Jun 09 '15 at 05:41
  • @Daniel Nugent there is one problem for using IntentService. When i stop using intent action "stoplocationupdates" the mGoogleApiClient is always null.Solution Option 2 - Stick with the IntentService is not working. any idea? – bolt123 Jun 14 '15 at 14:29
  • @bolt123 Is it still giving you location updates at that point? – Daniel Nugent Jun 14 '15 at 15:10
  • @Daniel Nugent yes, it will give the location updates – bolt123 Jun 14 '15 at 15:24
  • @bolt123 I just realized that using solution 2, you will probably need to re-connect to the GoogleApiClient, I just updated the answer, and take a look at the solution in this answer: http://stackoverflow.com/questions/30562193/google-api-client-bug-sending-locations/30562317#30562317 – Daniel Nugent Jun 14 '15 at 15:26
  • @Daniel Nugent thnks, will check that. btw, now i stored the location in a db. i need to update the whole stored locations to server when stoping the service. which is the best practice. sending them all in a list? any suggestion – bolt123 Jun 14 '15 at 15:43
  • To prevent anybody from the 'GoogleApiClient is not connected yet.' -Bug: http://stackoverflow.com/questions/29343922/googleapiclient-is-throwing-googleapiclient-is-not-connected-yet-after-onconne – Force0234 Jan 18 '17 at 11:48
1
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
strike
  • 1,031
  • 8
  • 24
  • how can i call the stopLocationUpdates() from my MainActivity. I think the service is stop after connecting to the mGoogleApiClient. – bolt123 Jun 09 '15 at 05:21
0

call stopLocationUpdates() method in stopService()

NehaK
  • 2,639
  • 1
  • 15
  • 31
  • how can i call the stopLocationUpdates() from my MainActivity. I think the service is stop after connecting to the mGoogleApiClient. – bolt123 Jun 09 '15 at 05:21
0

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

locationManager.removeUpdates(this);
Jigar Shekh
  • 2,800
  • 6
  • 29
  • 54
  • how can i call the stopLocationUpdates() from my MainActivity. I think the service is stop after connecting to the mGoogleApiClient. – bolt123 Jun 09 '15 at 05:21