0

I´m trying to have a service that executes some code in a Handler at every second. While the phone is connected to the PC everythings running fine. However as soon as I start the service while not connected to the PC and I lock the phone, the periodic task just stops executing and executes all posted events when the app is opened again.

I´ve tried adding a PARTIAL_WAKE_LOCK in the onCreate of the Service but it doesn´t help at all.

Service.java

private PowerManager.Wakelock mWakeLock;
private Handler mHandler;
private Timer mTimer;

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

    Notification notification = createNotification();
    startForeground(1, notification);

    // create and acquire the WakeLock
    PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "APP:LockName");
    mWakeLock.acquire();

    // create Handler for periodic code execution
    HandlerThread thread = new HandlerThread("PeriodicThread", THREAD_PRIORITY_BACKGROUND);
    thread.start();
    Looper looper = thread.getLooper();
    mHandler = new Handler(looper);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    mTimer = new Timer();
    mTimer.scheduleAtFixedRate(new PeriodicTask(), 0, 1000);

    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    mTimer.cancel();
    mWakeLock.release();
}


private class PeriodicTask extends TimerTask {
    @Override
    public void run() {
        mHandler.post(() -> { // periodic task here});
    }
}

I would expect the service to execute normally when the screen is locked, since the whole execution is protected by the PARTIAL_WAKE_LOCK. Or are WakeLocks Thread-specific and I need to acquire a lock for the newly created Thread?

Many Thanks for your help

Edit 1:

I´ve tried adding the permission REQUEST_IGNORE_BATTERY_OPTIMIZATIONS to the app and even then the behavior is phone dependent. On a Samsung phone it works now as intended and the task is executed each second. on Huawei phone there´s no change and the periodic task is only executed when the app is opened again. Is there a way to at least secure the same behaviour on different phones?

  • Are you using Service or IntentService? – feridok Aug 04 '19 at 10:44
  • Service. That´s why I´m creating a new Thread for execution. – Maximilian Speicher Aug 04 '19 at 10:45
  • Use IntentService I think its better for your case. – feridok Aug 04 '19 at 10:45
  • and check this: https://stackoverflow.com/questions/41953458/aquire-partial-wakelock-in-a-intentservice – feridok Aug 04 '19 at 10:46
  • The problem is, that I also need binding between the active fragment and the service, which the IntentService doesn´t support. And as far as I know, shouldn´t an IntentService only handle short tasks and therefore not be running for a long time? – Maximilian Speicher Aug 04 '19 at 10:57
  • No service is for short tasks and it runs on main thread, but intent service is for long tasks. also you can communicate with your activity from intent service with broadcasts. – feridok Aug 04 '19 at 11:00
  • https://stackoverflow.com/questions/15524280/service-vs-intentservice – feridok Aug 04 '19 at 11:01
  • 1
    How is this a foreground service? You need to explicitly call `startForeground(int id, Notification notification)`? https://developer.android.com/about/versions/oreo/background - wakelocks are ignored if the phone enters doze mode – Mark Aug 04 '19 at 11:12
  • @FaridForootan but how do I start the periodic task in the IntentService? If i create a TimerTask in the `onHandleIntent` it never executes because the IntentService stops itself. @MarkKeen The service is started via `startForeground`. I´ve just excluded it for clarity. It should be added now. – Maximilian Speicher Aug 04 '19 at 11:47

0 Answers0