Android Question I would like the user to set a time in my app to receive a notification.

mscientist33

Active Member
Licensed User
I would like the user to set a time in my app to receive a notification. Example: The can set a time in the app to say 7:00pm. Even with the app closed, at 7:00pm they would get a notification that reminds them of something. That something can be like, time to pray reminder, or something like that. The only examples I see is from the NB6 tutorial but in it you actually click a CLV then the notification appears. Is there an example for a notification when your app isn't running in the background?
 

JohnC

Expert
Licensed User
Longtime User
You could use the StartServiceAt function to start your app at a specific time:

 
Upvote 0

mscientist33

Active Member
Licensed User
I have found the code that looks like it comes close to what I want:

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.
    Public pHour As Int
End Sub

Sub Service_Create
        pHour= 15
End Sub

Sub Service_Start (StartingIntent As Intent)
    
    StartServiceAt(Me, NextTimeInstance(pHour, 0) ,True)
    
    
    Service.StopAutomaticForeground 'Call this when the background task completes (if there is one)
End Sub

Sub Service_Destroy

End Sub

Sub NextTimeInstance (Hours As Int, Minutes As Int) As Long
    Dim today As Long = DateTime.Now
    today = DateUtils.SetDateAndTime(DateTime.GetYear(today), DateTime.GetMonth(today), _
     DateTime.GetDayOfMonth(today), Hours, Minutes, 0)
    If today < DateTime.Now Then
        Dim p As Period
        p.Days = 1
        Dim tomorrow As Long = DateUtils.AddPeriod(today, p)
        Return tomorrow
    Else
        Return today
    End If
End Sub

The question is how do I pass the actual hour into the service and how does it display something like the following:

B4X:
Dim n As NB6
    n.Initialize("default", Application.LabelName, "DEFAULT")
    n.Build("Title", "Content", "tag1", Me).Notify(1)

Does that NB6 code go in the service or in my app?
 
Upvote 0

mscientist33

Active Member
Licensed User
You have now lost me, Is there a difference between notifications using this StartServiceAtExact and "push notifications"? My app is an offline app.
 
Last edited:
Upvote 0

aeric

Expert
Licensed User
Longtime User
Thanks for the clarification @aeric. So back to the other question in post #3. Any help would be appreciated. I am stalled at this point.

You can put inside a service or Activity.
B4X:
 Sub Simple_Notification
   Dim n As NB6
   n.Initialize("default", Application.LabelName, "DEFAULT").AutoCancel(True).SmallIcon(smiley)
   n.Build("Title", "Content", "tag1", Me).Notify(4) 'It will be Main (or any other activity) instead of Me if called from a service.
End Sub
 
Last edited:
Upvote 0

Cliff McKibbin

Member
Licensed User
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'.

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)
    
    ' 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'.

B4X:
#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.


B4X:
    ' 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
 

Attachments

  • FSService.bas
    686 bytes · Views: 98
  • Scheduler.bas
    4.5 KB · Views: 98
Upvote 0

mscientist33

Active Member
Licensed User
@Cliff McKibbin , Could you do a small example app? It would be most helpful as I am not the brightest bulb in the pack... I know you put those two items in post #15 but how it actually works inside the B4X program is still confusing me. My B4X app will have the option settings from the user and I send their choice of time to the B4XMainPage.b4xpage_appear which then starts the services?
 
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…