3

I found several posts regarding the return_sticky problem when using KitKat.

It seems like that the service can be killed and don't come back even when return_sticky.

I'm talking about a background service, not a foreground service.

I've tried several approaches but everything seems to fail. Heres a bit of code for demonstrating. After a while it gets killed and it won't come back:

public class RestPushService extends Service {

@Override
public void onDestroy() {
        MainApplication.getDevice().writeBoolean("REST_PUSHSERVICE_RUNNING", false);
}

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    if ((intent != null) && (intent.getBooleanExtra("ALARM_RESTART_SERVICE_DIED", false))) {

        if (MainApplication.getDevice().readBoolean("REST_PUSHSERVICE_RUNNING", false)){
            ensureServiceStaysRunning();
            return START_STICKY;
        }
    }
   MainApplication.getDevice().writeBoolean("REST_PUSHSERVICE_RUNNING", true);
/** doing other stuff like creating a thread **/
    return START_STICKY;
}

    private void ensureServiceStaysRunning() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        final int restartAlarmInterval = 20 * 60 * 1000;
        final int resetAlarmTimer = 2 * 60 * 1000;
        final Intent restartIntent = new Intent(this, RestPushService.class);
        restartIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        restartIntent.putExtra("ALARM_RESTART_SERVICE_DIED", true);
        final AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Handler restartServiceHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 0, restartIntent, 0);
                alarmMgr.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + restartAlarmInterval, pintent);
                sendEmptyMessageDelayed(0, resetAlarmTimer);
            }
        };
        restartServiceHandler.sendEmptyMessageDelayed(0, 0);
    }
}

@Override
public void onTaskRemoved(Intent rootIntent) {
    Intent restartService = new Intent(getApplicationContext(), this.getClass());
    restartService.setPackage(getPackageName());
    PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
}
}

Now another receiver which gets called when the device starts.

public class myReceiver extends BroadcastReceiver { 

    @Override
    public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action == null || action.equals("com.myapp.START_ALARM")) {
                if (MainApplication.getDevice().hasInternet()) {
                    if (!MainApplication.getDevice().hasServiceRunning(RestPushService.class)) {
                        context.startService(new Intent(context, RestPushService.class));
                    } else {
                        Log.d(TAG, "RestPushService was aready running. Do nothing");
                    }
                }
            }


    }

    public void startRepeating(Context context) {
            if (alarmManager == null) alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);


            Intent i = new Intent("com.myapp.START_ALARM");
            PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 30, pi); // Millisec * Second * Minute
         }

    public void stopRepeating(Context context) {
              Intent intent = new Intent("com.myapp.START_ALARM");
            PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
            alarmManager.cancel(sender);
       }
}

I've truncated much code because I think it is not relevant. I removed all try catches and null initializations to make sure it's easily readable. So what may be caused the "don't come back" crap?

I refer also to START_STICKY does not work on Android KitKat

paulina_glab
  • 2,467
  • 2
  • 16
  • 25
Emanuel
  • 8,027
  • 2
  • 37
  • 56

0 Answers0