Android Question Scheduled Events

Declan

Well-Known Member
Licensed User
Longtime User
Reading this topic about Calculating the next scheduled time:
How can I incorporate this into a Service where I can use CallSubDelayed to trigger an event in Activity Main when one of the three times are met?
The code from above link:
B4X:
Dim t As Long = FindNextTime(Array As Double(5, 6.5, 20))
Log($"Next time is: $DateTime{t}"$)

Sub FindNextTime(Times As List) As Long
   Times.Sort(True)
   For Each st As Double In Times
     If SetHours(st) > DateTime.Now Then
       Return SetHours(st)
     End If
   Next
   Return DateTime.Add(SetHours(Times.Get(0)), 0, 0, 1)
End Sub

Sub SetHours(st As Double) As Long
   Dim hours As Int = Floor(st)
   Dim minutes As Int = 60 * (st - hours)
   Return DateUtils.SetDateAndTime(DateTime.GetYear(DateTime.Now), _
       DateTime.GetMonth(DateTime.Now), DateTime.GetDayOfMonth(DateTime.Now), hours, minutes, 0)
End Sub


 

Declan

Well-Known Member
Licensed User
Longtime User
I have two Services - Service "Starter" and Service "Schedule"
From "Starter" I am starting the "Schedule" Service:
B4X:
#Region  Service Attributes
    #StartAtBoot: True
    #ExcludeFromLibrary: True
#End Region

Sub Process_Globals

End Sub

Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
    StartService("Schedule")
End Sub

Sub Service_TaskRemoved
    'This event will be raised when the user removes the app from the recent apps list.
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub

In Service "Schedule" I have:
B4X:
#Region  Service Attributes
    #StartAtBoot: False
  
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
    Dim t As Long = FindNextTime(Array As Double(10.75,11, 12))
    Log($"Next time is: $Time{t}"$)  
    Dim now = DateTime.Time(DateTime.Now) As String
  
    If now = $"$Time{t}"$ Then
        Log ("Gotcha The current time is: " & now)
        Log($"Gotcha Next time is: $Time{t}"$)
    '        CallSubDelayed(Main, "ActionPop")
    Else
        Log("Not Time The Time now is: " & now)
        Log($"Not Time Next Time is: $Time{t}"$)
    '     Do Nothing
    End If
End Sub

Sub FindNextTime(Times As List) As Long
   Times.Sort(True)
   For Each st As Double In Times
     If SetHours(st) > DateTime.Now Then
       Return SetHours(st)
       Log("This is SetHours: " & SetHours(st))
     End If
   Next
   Return DateTime.Add(SetHours(Times.Get(0)), 0, 0, 1)
End Sub

Sub SetHours(st As Double) As Long
   Dim hours As Int = Floor(st)
   Dim minutes As Int = 60 * (st - hours)
   Return DateUtils.SetDateAndTime(DateTime.GetYear(DateTime.Now), _
       DateTime.GetMonth(DateTime.Now), DateTime.GetDayOfMonth(DateTime.Now), hours, minutes, 0)
End Sub

Sub Service_Destroy

End Sub

The "Schedule" Service does start, but I do not get a "trigger" on the next time?
Log:
B4X:
** Service (starter) Create **~i:** Service (starter) Start **
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (schedule) Create **
** Service (schedule) Start **
Next time is: 10:45:00
Not Time The Time now is: 10:41:08
Not Time Next Time is: 10:45:00
 
Last edited:
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
Where is the call to StartServiceAt?
In my app (Service "Starter") I have:
B4X:
Sub PE_BatteryChanged (Level As Int, Scale As Int, Plugged As Boolean, BatteryIntent As Intent)
    CallSub3(Menu, "BatteryChange",Level,Plugged)
    StartService("Schedule")
End Sub
I am using this to StartService
This does work, but will it cause any other problems?

IfAbs(DateTime.Now - t) < 30 * DateTime.TicksPerSecond Then
This works, thanks
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
I don't see how this code is related
The code that I posted in #3 is from a small app to test the scheduling.
The code in #5 is from my actual app that I wish to include the scheduling function.
As I am using the PhoneEvents in this app and the BatteryChanged function to monitors the battery state etc.
As BatteryChanged "fires" every 10sec, I thought I would use this to StartService("Schedule").
So, this would use StartService("Schedule") and not StartServiceAt.
I don't know if I am going about this correctly?
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
StartServiceAtto schedule the other service to start at the specified time.
I do not understand where I get the time from for StartServiceAt(Schedule,time,True)
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
You need to calculate the time by yourself. You can use the sub you already posted above (FindNextTime).
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
I now have the following.
Service "Starter":
B4X:
#Region  Service Attributes
    #StartAtBoot: True
    #ExcludeFromLibrary: True
#End Region

Sub Process_Globals
Dim t As Long
End Sub

Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
    t = FindNextTime(Array As Double(16.7,16.8, 16.9))
    Log($"Next time is: $Time{t}"$)   
   
    StartServiceAt(Schedule,t,True)

End Sub
Sub FindNextTime(Times As List) As Long
   Times.Sort(True)
   For Each st As Double In Times
     If SetHours(st) > DateTime.Now Then
       Return SetHours(st)
       Log("This is SetHours: " & SetHours(st))
     End If
   Next
   Return DateTime.Add(SetHours(Times.Get(0)), 0, 0, 1)
End Sub

Sub SetHours(st As Double) As Long
   Dim hours As Int = Floor(st)
   Dim minutes As Int = 60 * (st - hours)
   Return DateUtils.SetDateAndTime(DateTime.GetYear(DateTime.Now), _
       DateTime.GetMonth(DateTime.Now), DateTime.GetDayOfMonth(DateTime.Now), hours, minutes, 0)
End Sub

Sub Service_TaskRemoved
    'This event will be raised when the user removes the app from the recent apps list.
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub

Service "Schedule":
B4X:
#Region  Service Attributes
    #StartAtBoot: False
   
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
   
    If Abs(DateTime.Now - Starter.t) < 30 * DateTime.TicksPerSecond Then
        LogColor("Gotcha",Colors.Magenta)
    '        CallSubDelayed(Main, "ActionPop")
    Else
        LogColor("NOT Time",Colors.Magenta)
    '     Do Nothing
    End If
End Sub


Sub Service_Destroy

End Sub

I only receive the first time of t = FindNextTime(Array As Double(16.7,16.8, 16.9))

Log:
B4X:
** Service (starter) Create **
** Service (starter) Start **
Next time is: 16:41:00
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **~i:** Service (schedule) Create **
** Service (schedule) Start **
Gotcha

The Service "Schedule" never starts on the additional times.
What am I doing wrong?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
I only receive the first time of t = FindNextTime(Array As Double(16.7,16.8, 16.9))
That´s how the sub works... it calculates the NEXT time... Set a servicestartat to this time....

When the service starts at the given time you calculate the next... It should then point you to the next shedule...
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
That´s how the sub works... it calculates the NEXT time... Set a servicestartat to this time....

When the service starts at the given time you calculate the next... It should then point you to the next shedule...
That is where I am stuck.
How do I calculate the next...
Once I have "LogColor("Gotcha",Colors.Magenta)"
How do I restart the Service("Schedule") at the next time?
 
Last edited:
Upvote 0

lemonisdead

Well-Known Member
Licensed User
Longtime User
Where in my code do I place the ServiceStartAt to get the NextTime?
I hope to have understood, so please forgive me if I don't reply correctly : I would say you could put it Inside your Schedule service or at the end of Service_Start or in Service_Destroy (depending of your workflow of course).
 
Upvote 0
Top