Mateus Carvalho Mateus Carvalho - 3 months ago 14
Android Question

Service auto destroy

I have a

Service
that Track the location of user, in a time I get the location of user though of GoogleApiClient.

It Happen some times
Service
stop, depend of internet or model phone the
Service
stop sending location to webservice. It seems like it was destroyed.

How can I prevent this?

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

private static final String TAG = "LocationService";
public long UPDATE_MILLISECONDS_DEFAULT = 180000;

private boolean currentlyProcessingLocation = false;
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;

@Override
public void onCreate() {
Log.d(TAG,"Location service create");
super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// if we are currently trying to get a location and the alarm manager has called this again,
// no need to start processing a new location.
if (!currentlyProcessingLocation) {
currentlyProcessingLocation = true;
startTracking();
}

return START_NOT_STICKY;
}

private void startTracking() {
Log.d(TAG, "startTracking");

if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();

if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
googleApiClient.connect();
}
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}

protected void sendLocationToServer(Location location) {
// here I call my webservice and send location
Log.d(TAG, "Update to Server location");
}

@Override
public void onDestroy() {
Log.d(TAG,"Destroy service");
stopLocationUpdates();
super.onDestroy();

}


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

@Override
public void onLocationChanged(Location location) {
sendLocationToServer(location);
}

public void stopLocationUpdates() {
if (googleApiClient != null && googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}

/**
* Called by Location Services when the request to connect the
* client finishes successfully. At this point, you can
* request the current location or start periodic updates
*/
@Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");

locationRequest = LocationRequest.create();
locationRequest.setInterval(UPDATE_MILLISECONDS_DEFAULT); // milliseconds for default
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);


//locationRequest.setFastestInterval(1000); // the fastest rate in milliseconds at which your app can handle location updates

LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, locationRequest, this);
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");

stopLocationUpdates();
stopSelf();
}

@Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "GoogleApiClient connection has been suspend");
}


}

Answer

You're returning START_NOT_STICKY from onStartCommand().

Because of this, whenever the OS kills your Service (to reclaim memory, for example) it will not get re-created.

Change the following:

return START_NOT_STICKY;

To this:

return START_STICKY;

From the documentation of START_STICKY:

Constant to return from onStartCommand(Intent, int, int): if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance; if there are not any pending start commands to be delivered to the service, it will be called with a null intent object, so you must take care to check for this.

NOTE: START_STICKY does not prevent your Service from being killed. It just tells the OS to restart it as soon as possible (depending on the available resources). To make your Service less likely to be killed, you can make it run in the foreground by calling startForeground().