Android Question WorkManager, AlarmManager, JobScheduler, JobIntentService - which is reliable?

JohnC

Expert
Licensed User
I have a Foreground Service that needs to run every minute all day long.

I designed the below system that does two things:

1) Sets up a 1 minute timer that hopefully will run reliably in a foreground service every minute
2) Sets up a backup "StartServiceat" schedule for 2 minutes in the future so it will "kick start" the service again in case the service stalls for some reason (and the timer stops ticking).

NOTE: because I am constantly resetting the service start at time, it won't accidently trigger if the timer keeps triggering every 1 minute - it will only trigger if the timer fails. So the start servicestartat is sort of a watchdog timer.

B4X:
Sub Service_Create

    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER 'we are handling it ourselves

    tmrMain.Initialize("tmrMain", 60000)        'task needs to run every 1 minute all the time

End Sub

Sub Service_Start (StartingIntent As Intent)

    SetupRestart    'sets up backup startserviceat for 2 minutes from now

    Service.StartForeground(nid,  CreateNotification("MyApp","Starting..."))

    If StartingIntent.HasExtra("android.intent.extra.ALARM_COUNT") = True Then
        LogAppEvent("Timer_Service: Started via Schedule *******")
    End If

    MainProcess

End Sub

Sub tmrMain_Tick

    LogAppEvent("tmrMain_Tick < < < < < <")    'this should log every 1 minute

    MainProcess

End Sub

Sub MainProcess

    SetupRestart        'respecify 2min backup servicestartat

    LogAppEvent("MainProcess running")    'this should log every 1 minute

    'do stuff here every minute

    Dim N As Notification = CreateNotification(blablabla)    'update notification
    N.Notify(nid)

    SetupRestart        'respecify 2min backup servicestartat

End Sub

Sub SetupRestart()

    Dim P As Period
    Dim N As Long

    P.Initialize
    P.Minutes = 2
    N = DateUtils.AddPeriod(DateTime.Now,P)

    StartServiceAt(Me, N, True)    'setup a 2-min rerun just in case something goes wrong in the mean time

    tmrMain.Enabled = False
    tmrMain.Enabled = True        'restart timer in case its about to trigger again and mainprocess did not finish yet

End Sub

Sub LogAppEvent(EventText As String)

    Dim LL As Long
    Dim P As Period

   'this service should run every minute (and thus do a 'log' at least every minute)
    'so see if last log was more then 5 min ago and if so put big divider bar in log file
    LL = Misc.GetSetting("LastLogEvent",0)
    P = DateUtils.PeriodBetween(LL,DateTime.Now)
    If P.Hours > 0 Or P.Minutes > 5 Then
       Log"###################### LONG PAUSE (" & P.Hours & ":" & Misc.Pad(P.Minutes,2,"0") & ":" & Misc.Pad(P.Seconds,2,"0") & ") ######################")
    End If

    Log(EventText)

    Misc.SetSetting("LastLogEvent",DateTime.Now)

End Sub

NOTE: The above code shows that events are logged using the standard B4A "Log()" function, but it fact I am saving them to sequential text files because I wanted the phone to NOT have any active connections to it (USB or B4A Bridge) so that the phone would be operating in a real-world mode and would be able to go to sleep when needed.

On an Android 5.0 device I will get the Timer_Tick log once or twice reliably, then I will see the "Service started via schedule" which indicates that the timer was suspended, and the backup startserviceat had to kick start it again. And then the timer tick will work for 1-3 times on its own, then the servicestartat has to restart things again. But a "LONG PAUSE" will NEVER trigger.

However, on an Android 8.1 device, something really weird happens. Late at night it will run fine for 2-3 minutes, then everything pauses (even the startserviceat) for about 8 mins and then starts running normally for another 3-5 mins, the pauses again for 7-8 mins (see below log). It's like the OS is choosing a time on it's own to start the service (which the docs say the time specified in startserviceat might not happen exactly on time).

I tried replacing the startserviceat with startserviceatexact and got the same results.

So, can any of the other schedule methods (WorkManager, JobScheduler, JobIntentService) work more reliably every 1 minute and not have these 7-8 min pauses?

B4X:
03/29/20 01:58:56 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 02:07:57 am ###################### LONG PAUSE (0:06:29) ######################
03/29/20 02:16:59 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 02:26:00 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 02:35:00 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 02:44:02 am ###################### LONG PAUSE (0:07:00) ######################
03/29/20 02:53:04 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 03:02:05 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 03:11:07 am ###################### LONG PAUSE (0:08:01) ######################
03/29/20 03:20:07 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 03:29:09 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 03:38:10 am ###################### LONG PAUSE (0:06:42) ######################
03/29/20 03:47:11 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 03:56:12 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 04:05:13 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 04:14:14 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 04:23:14 am ###################### LONG PAUSE (0:07:24) ######################
03/29/20 04:32:15 am ###################### LONG PAUSE (0:07:00) ######################
03/29/20 04:46:00 am ###################### LONG PAUSE (0:07:44) ######################
03/29/20 04:55:02 am ###################### LONG PAUSE (0:07:00) ######################
03/29/20 05:04:03 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 05:13:05 am ###################### LONG PAUSE (0:07:01) ######################
03/29/20 05:22:06 am ###################### LONG PAUSE (0:07:00) ######################
03/29/20 05:31:07 am ###################### LONG PAUSE (0:07:54) ######################
03/29/20 05:40:09 am ###################### LONG PAUSE (0:07:00) ######################
03/29/20 05:49:10 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 05:58:12 am ###################### LONG PAUSE (0:08:01) ######################
03/29/20 06:07:13 am ###################### LONG PAUSE (0:06:45) ######################
03/29/20 06:16:14 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 06:25:16 am ###################### LONG PAUSE (0:08:01) ######################
03/29/20 06:34:17 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 06:43:18 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 06:52:19 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 07:01:20 am ###################### LONG PAUSE (0:07:55) ######################
03/29/20 07:10:22 am ###################### LONG PAUSE (0:08:01) ######################
03/29/20 07:19:24 am ###################### LONG PAUSE (0:07:00) ######################
03/29/20 07:28:25 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 07:46:27 am ###################### LONG PAUSE (0:08:00) ######################
03/29/20 07:55:29 am ###################### LONG PAUSE (0:07:00) ######################
03/29/20 08:04:30 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 08:13:31 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 08:22:32 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 08:31:34 am ###################### LONG PAUSE (0:08:01) ######################
03/29/20 08:40:35 am ###################### LONG PAUSE (0:07:23) ######################
03/29/20 08:49:36 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 08:58:37 am ###################### LONG PAUSE (0:06:59) ######################
03/29/20 09:07:38 am ###################### LONG PAUSE (0:06:09) ######################
03/29/20 09:16:39 am ###################### LONG PAUSE (0:06:59) ######################
 
Last edited:

JohnC

Expert
Licensed User
You should instead keep the foreground service running all the time and it will work on most devices.
When the MainProcess sub ends, it doesn't kill the service, so I was hoping it would keep the foreground service running.

But it appears the OS has it own plan on how often it will allow the service to run.

My 8.1 device is a Nexus 5X.

My app can deal with 7-8 minute pauses. But if the pauses will be much longer depending on different versions of Android or different manufactures, it will effect the purpose of my app.

I was hoping that one of those other services would run more reliably.
 
Upvote 0

JohnC

Expert
Licensed User
My code is based a lot on that project code.

What about setting up a static broadcast receiver to catch the Time Tick intent (that happens every minute)?
 
Upvote 0
Top