Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Service from getting destroyed

Tags:

android

I have a Service that tracks 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");
    }


}
like image 938
Mateus Carvalho Avatar asked Aug 20 '16 03:08

Mateus Carvalho


1 Answers

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 line:

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().

like image 111
earthw0rmjim Avatar answered Sep 30 '22 22:09

earthw0rmjim