The above hints don't seem to mention the 'Scheduler'. I had saved an original post by Erel on 'Service'.
https://www.b4x.com/android/forum/threads/service-modules.7542/
but I can't seem to find how I added the 'Scheduler' to create an alert system.
I have been using the logic below for 2 years. It gives me an alert every morning at 7:00am (user defined) whether there are alerts or not. If my calendar events include alert times, an earlier time will override tomorrow's 7am alert. When the earlier alert is fired, than the next alert, etc. If there are no other alerts in the day, the 7am tomorrow alert is set.
The alerts are fired whether the app is active or not so long as the phone is on. I have noticed that the 7am alerts can fire anytime from 7am to 7:04am, so if you need an exact time, you might want to subtract 5 minutes or so from the time to give a little lee-way. I have not noticed any degradation of the battery as I leave my phone on charging all night.
This is the 'FSService' routine in its entirety. Not much there except it fires the 'Scheduler'. You can load it from the attachments below. It must be loaded as a 'service'.
#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)
' Service.StopAutomaticForeground 'Call this when the background task completes (if there is one)
' logic of FSService changed on 6/24/19 cwm
StartServiceAt (Scheduler, DateTime.now,False)
End Sub
Sub Service_Destroy
End Sub
This is the 'Scheduler'.
1. Note that it calls starter.GetNotifications to read a sql file of events/times/alert times.
2. There is also a public variable in Starter (Starter.SNotifTime) that is set in my setup to store the default alert time (mine is 7:00am).
3. As you will note, Scheduler finds the next alert time including that in starter.snotiftime and then chooses the next time.
4. You can use normal datetimes for all this. My data happened to use strings of date time as you will note.
5. Also note that I have set up starter variables for the sound/vibrate combinations. These are in my setup.
6. Once all this is set you can actually format a message as shown. I have kept mine generic but you could put the event title in the message if you want.
7. Also note you can issue multiple alerts.
8. Finally, the logic fires the alert and schedules the next alert.
Again, you can load it from the attachment below as a 'Service'.
#Region Service Attributes
#StartAtBoot: true
#End Region
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Public NextStartTime, OtherStartTime As Double
Public X1, X2, sNotes1, sNotes2 As String
Public i As Int
End Sub
Sub Service_Create
End Sub
Sub Service_Start (StartingIntent As Intent)
' Service.StopAutomaticForeground 'Call this when the background task completes (if there is one)
StartSchedule
'
End Sub
public Sub StartSchedule
' sub to schedule the next notification pretty well finished on 6/3/19 cwm
Dim ITime As Int
' get notifications for next alert/notif time
Starter.getnotifications
' only notif if SNotifTime is non zero
If Starter.SNotifTime.trim.CompareTo("")=0 Then Starter.SNotifTime=0
If Starter.SNotifTime>0 Then
' get the current time and compare to the notif time
' this was very tricky-had to add seconds to itime and compare to our time with '00' added
' in order not to loop and do multiple notifications.
DateTime.DateFormat="HHmmss"
ITime=DateTime.date (DateTime.Now+DateTime.TicksPerMinute)
' Log ("Comparing Notification times " & ITime & " " & Starter.SNotifTime & "00")
If ITime< Starter.SNotifTime & "00" Then
' not yet the time for the notify-keep it to today's date
NextStartTime=DateTime.Now
Else
' bump the notify to tomorrow
NextStartTime=DateTime.Add(DateTime.now,0,0,1)
End If
' now change the hhmm to use the SNotifTime
DateTime.DateFormat="yyyyMMddHHmm"
X1=DateTime.Date (NextStartTime)
' get string for Snotiftime
X2=NumberFormat(Starter.SNotifTime,4,0)
' note numberformat puts commas in a 4 digit number
X2=X2.SubString2(0,1) & X2.SubString2(2,5)
' now put together the date and hhmm
X1=X1.SubString2(0,8) & X2
NextStartTime=DateTime.DateParse(X1)
' test every 15 seconds
' NextStartTime=DateTime.Now+ DateTime.TicksPerMinute/4
' now compare the nextstarttime to the alertstarttime 6/13/19 cwm
If Starter.NextAlerttime.CompareTo("300012312400") <>0 Then
' we have a valid next alert time
If Starter.NextAlertTime.CompareTo(X1) <0 Then
NextStartTime=DateTime.DateParse(Starter.nextalerttime)
End If
End If
' get final x1 formated
DateTime.DateFormat="yyyy/MM/dd HH:mm"
X1=DateTime.Date (NextStartTime)
' set up the notification
Dim n As Notification
n.Initialize
n.Sound=False
n.Vibrate=False
n.Icon="icon"
' mod to vary the display depending if alerts are available 6/24/19 cwm
If Starter.SNotif.Size>0 Then
sNotes1="FS has alerts for you. Touch here."
If Starter.SnotifSound=1 Then n.Sound = True
If Starter.SnotifSound=3 Then n.Sound = True
If Starter.SnotifSound=2 Then n.Vibrate = True
If Starter.SnotifSound=3 Then n.vibrate = True
' check if the notification situation has changed- 10/8/20 cwm
' if so mod the starter.nextstarttime to force a notif
If Starter.Notifications=False Then
Starter.NextStartTime=0
Starter.Notifications=True
End If
Else
sNotes1="FS has no alerts for today."
' check if the notification situation has changed- 10/8/20 cwn
' if so mod the starter.nextstarttime to force a notif
If Starter.Notifications=True Then
Starter.NextStartTime=0
Starter.Notifications=False
End If
End If
sNotes2= "Next Notification at: " & X1
' fire the notification
' only if the starter.nextStartTime has changed or the notification status changed 10/8/20 cwm
' Log ("Before:" & Starter.NextStartTime & " " & NextStartTime & " " & Starter.Notifications)
If Starter.NextstartTime<>NextStartTime Then
n.SetInfo(sNotes1,sNotes2, "Main")
Log (sNotes1 & CRLF & sNotes2)
' note the significance of the '1'/it indicates to replace any other notification from FS with a '1' in it
' if you wanted multiple notifications you could use '2', '3', etc.
n.Notify(1)
' start the next service-
StartServiceAt (FSService, NextStartTime,False)
' save the nextstarttime so we don't repeat unless it does change 10/8/20 cwm
Starter.NextStartTime=NextStartTime
' Log ("After:" & Starter.NextStartTime & " " & NextStartTime & " " & Starter.Notifications)
End If
End If
End Sub
Sub Service_Destroy
End Sub
This code is in B4XMainPage.b4xpage_appear to fire the scheduler if there has been an update to an event and possibly reset the alert time.
1. Updates to events in my system turn off the boolean starter.bnotif and then return to the main menu.
2. sub BuildNotify populates a clv on the main menu with the events for the next 3 days in date/time order.
' rebuild notifications in case an update changed them
' Log ("starter.bnotif:" & Starter.bNotif)
If Starter.bNotif=False Then
' get alerts
Starter.getnotifications
StartServiceAt (Scheduler, DateTime.now,False)
Log ("Notifications rebuilt")
Starter.bNotif=True
End If
' redisplay the notifications
BuildNotif
FSService and Scheduler are attached. You can load them and modify as desired. Both have to be loaded as 'Services'.
Hope this helps. Cliff