GPS icon disappear when open location popup or the app is killed

158 views Asked by At

I am developing an app that should send gps data to a server once every 10 minutes. The problem is that when I kill the app when the GPS is ON, the GPS icon disappear from the status bar (while the GPS is still ON) and the data are not sent anymore. If I do the same with the google maps app the icon doesn't disappear. Can someone explain me why this is happening? here is the code that I use

AlarmManager

/**
 * ALARM_MANAGER_GPS_TIME_INTERVAL = 10 min
 */
PendingIntent mPendingIntent = PendingIntent
            .getService(
                    context,
                    PENDING_INTENT_REQUEST_CODE_FOR_GPS,
                    new Intent(context, GpsDataService.class),
                    PendingIntent.FLAG_IMMUTABLE);
    AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    mAlarmManager.setInexactRepeating(
            AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime(),
            ALARM_MANAGER_GPS_TIME_INTERVAL,
            mPendingIntent);

Service

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

/**
 * Provides the entry point to Google Play services.
 */
protected GoogleApiClient mGoogleApiClient;

/**
 * Stores parameters for requests to the FusedLocationProviderApi.
 */
protected LocationRequest mLocationRequest;

/**
 * Represents a geographical location.
 */
protected Location mCurrentLocation;

private String mPayLoad;
private GpsPojoBuilder mGpsPojoBuilder;

@Override
public void onCreate() {
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {


    if(mGoogleApiClient == null)
        buildGoogleApiClient();

    mGoogleApiClient.connect();

    if (mGoogleApiClient.isConnected())
        startLocationUpdates();

    return Service.START_NOT_STICKY;
}
protected synchronized void buildGoogleApiClient() {

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    createLocationRequest();
}
/**
 * UPDATE_INTERVAL_IN_MILLISECONDS = 4 sec
 * FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 2 sec
 */
protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest
            .setInterval(UPDATE_INTERVAL_IN_MILLISECONDS)
            .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
    // The connection to Google Play services was lost for some reason. Call connect() to
    // attempt to re-establish the connection.
    mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
/**
 * Requests location updates from the FusedLocationApi.
 */
protected void startLocationUpdates() {
    checkForPermission();
}
private void checkForPermission() {

    Location location;

    if (Build.VERSION.SDK_INT >= 23) {

        if (ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            //permission denied
        } else {
            location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (location != null)
                handleLocation(location);
            else
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }else {
        location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(location != null)
            handleLocation(location);
        else
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }
}
@Override
public void onLocationChanged(Location location) {
    handleLocation(location);
}
private void handleLocation(Location location){

    mCurrentLocation = location;

    Toast.makeText(this, "location foound: " + location.toString(), Toast.LENGTH_SHORT).show();

    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                mGpsPojoBuilder = new GpsPojoBuilder(getApplicationContext());
                mPayLoad = mGpsPojoBuilder
                        .getCheckInJson(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
                sendJSON(mPayLoad, CHECKINS_URL);
            } catch (GooglePlayServicesRepairableException e) {
                e.printStackTrace();
            } catch (GooglePlayServicesNotAvailableException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(mGoogleApiClient.isConnected()) {
                    stopLocationUpdates();
                    mGoogleApiClient.disconnect();
                }
            }
        }
    };
    thread.start();
}
public void sendJSON(String payLoadData, String url_suffix) {
    HttpConnectionCreator mHttpConncectionClass = new HttpConnectionCreator(payLoadData, url_suffix);
    mHttpConncectionClass.connect();
}
/**
 * Removes location updates from the FusedLocationApi.
 */
protected void stopLocationUpdates() {
               LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}

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

@Override
public void onDestroy() {

    if (mGoogleApiClient.isConnected()) {
        stopLocationUpdates();
        mGoogleApiClient.disconnect();
    }
    super.onDestroy();
  }
}
1

There are 1 answers

1
omriherman On

According to android.developer, if you want to keep your services alive, you need to use START_STICKY.

int 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.

inside the following function:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {


if(mGoogleApiClient == null)
    buildGoogleApiClient();

mGoogleApiClient.connect();

if (mGoogleApiClient.isConnected())
    startLocationUpdates();

return Service.START_NOT_STICKY;

}

change to this:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {


if(mGoogleApiClient == null)
    buildGoogleApiClient();

mGoogleApiClient.connect();

if (mGoogleApiClient.isConnected())
    startLocationUpdates();

return Service.START_STICKY;

}