0

I'm at my wits end with this issue. Can't find a good solution for it! In my app I have a service within which a timer gets scheduled over and over. That means after each timerTask is executed, another is started (first, both the timer and timerTask are canceled and then are assigned a new Timer and TimerTask). This is done 24 hours a day! I need this: First launch the app, start the service, then turn off the display and leave the device alone. But trouble is every time I come back to the device, I find my app has finished some tasks then is stuck on a timer although its time interval is passed! I think this is because of CPU sleeping.

For more explanation, suppose I have a list of time intervals in seconds: {60,100,40,120,80}. I start the service and leave the device alone for 5 minutes. Then I come back and see that tasks at 60 and 100 secs are done. But the service is stuck at the task at 40!

Each task includes a very simple network job that takes 5 secs at most. I tried a wakelock but It's not gonna help. I don't know why!

Here is a code of my service:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    startForeground(id, new Notification());
    pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
    wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,"");
    wl.acquire();
    doAction();
    return START_STICKY;
}

private void doAction(){
    if (timer != null)
        timer.cancel;
    if (timerTask != null)
        timerTask.cancel;
    timer = new Timer();
    timerTask = new TimerTask() {
            @Override
            public void run() {
                doAction();
                //Do some network job!
            }
    };
    timer.schedule(timerTask, getNewInterval());
}
Jay
  • 11
  • 4
  • Is this device always going to be connected to a charger? – CommonsWare Oct 27 '16 at 16:31
  • Nope! It's not. – Jay Oct 27 '16 at 16:55
  • Trying to do network I/O every ~40-120 seconds, continuously throughout the day, is why Google has taken steps in Android 6.0+ to prevent such apps from running. Users have complained consistently for the past several years about the poor battery performance on Android devices, and a lot of that comes back to developers doing what you propose to do. Will users value your app enough to be willing to deal with having to charge their devices a few times per day? – CommonsWare Oct 27 '16 at 17:03
  • Thanks for the advice! But it's not a generic application! It is a personal app which is going to serve an organization! The users themselves insert time steps and they expect my app to do the task exactly at their defined intervals! :) – Jay Oct 27 '16 at 19:10
  • Nothing of what you wrote will cause your app to use less power. Follow imash's advice. Use `AlarmManager` and a `WakefulBroadcastReceiver`. Users will need to add your app manually to the battery optimization whitelist on Android 6.0+ (Settings > Apps > [gear icon]). Encourage users to have as few time steps as possible with as big of intervals as possible, to minimize the power consumption when your app does get to do work. – CommonsWare Oct 27 '16 at 19:15
  • Dude! Thanks again! But I didn't ask about battery consumption issues!!! This app is going to run on specific devices which are solely provided for it! No one cares for batteries! By the way, all the users are professional app developers! They are aware of what they do! – Jay Oct 27 '16 at 19:19
  • That does not change the fact that your process cannot run forever, and that Doze mode (and app standby) will interfere with your ability to use the wakelock. While *you* may not care about the battery, *Google* does, because *most Android users do*, and you need to adjust your plans accordingly to fit within what Google offers to developers. Hence, the suggestion to use `AlarmManager`, `WakefulBroadcastReceiver`, and the battery optimization whitelist. – CommonsWare Oct 27 '16 at 19:41
  • Ok Granpa! Say hi to Google :) – Jay Oct 27 '16 at 19:58

1 Answers1

1

You shouldn't keep the wakelock and maybe some power managing system feature kills your service because of this. Read documentation for:

WakefulBroadcastReceiver

and

AlarmManager

and see if first option or second one combined for example with IntentService can't fulfill your requirements. You can reset your alarm when trigerred by AlarmManager to another moment in time, even precisely, using setExact()

ilmash
  • 174
  • 2
  • 12