Android Question [SOLVED] - Blocked messages in queue when using CallSubDelayed

rleiman

Well-Known Member
Licensed User
Longtime User
Greetings,

I made an app that plays songs based on a user set song start and ending period. That part works perfectly as long as the app is displayed on the phone screen. The app also runs quite well in the background and is not easily killed by Android because it's using the technique used in this app tutorial. The problem I'm having is when the phone screen is off or the app is not in focus the song is not played during the user set time period. When the app doesn't have focus, the log shows the schedule starts but then puts a message to a queue and never plays the song. The song is played by using CallSubDelayed. As soon as I get the app in focus be having it open on screen the message in the queue is released and the song plays.

How do I get the app not to block up the queue?

B4X:
** Activity (main) Create, isFirst = false **
running waiting messages (1)
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **

This is when the app is running with the phone screen off.

Schedule For Song 1 is running.
sending message to waiting queue (CallSubDelayed - ImageViewPlayCurrentSong_Click)

This is when I load up the app on screen.

running waiting messages (2)
** Activity (main) Resume **
** Receiver (servicewidget) OnReceive **
** Service (servicewidget) Start **
Service started in foreground mode.

This code works only if the app is on screen.:
Sub tmrForSchedules_Tick
   
    ' Loop through all songs.
    ' We will exit the loop if the time now is within any scheduled song period to play a song.
    ' If any is found regardless of wether or not the user is listening to a song, these will be
    ' played.
    '-------------------------------------------------------------------------------------------
    For intSongNumber = 1 To 3
       
        ' Check if the song has a schedule that's ok to test (light bulb is on).
        '-----------------------------------------------------------------------
        If kvs.Get("Song" & intSongNumber & "ScheduleIsActivated") Then ' The light bulb is on.

            ' Get the ticks value for the songs starting period.
            '----------------------------------------------------
            Dim lngScheduleFrom As Long = _
                DateTime.DateTimeParse(DateTime.Date(DateTime.Now), _
                kvs.Get("Song" & intSongNumber & "ScheduleActiveFrom") & ":00")

            ' Check if the ending period is set for the next day.
            '--------------------------------------------------
            If kvs.Get("Song" & intSongNumber & "ScheduleIsOvernight") Then
               
                ' Get the ticks value for the ending period for tomorrow.
                '--------------------------------------------------------
                Dim lngScheduleUntil As Long = _
                    DateTime.Add(DateTime.DateTimeParse(DateTime.Date(DateTime.Now), _
                    kvs.Get("Song" & intSongNumber & "ScheduleActiveUntil") & ":00"),0,0,1)
            Else
                ' Get the ticks value for the ending today.
                '------------------------------------------
                Dim lngScheduleUntil As Long = DateTime.DateTimeParse(DateTime.Date(DateTime.Now), _
                    kvs.Get("Song" & intSongNumber & "ScheduleActiveUntil") & ":00")
            End If

            Select intSongNumber
               
                Case 1
                   
                    ' Go here only if a song is not playing for schedule 2 or 3.
                    '-----------------------------------------------------------
                    If blnSchedule2IsPlayingSong = False And _
                            blnSchedule3IsPlayingSong = False Then
   
                        ' Go here if the time now is inside the schedul period for song 1.
                        '-----------------------------------------------------------------
                        If DateTime.Now >= lngScheduleFrom And _
                        DateTime.Now <= lngScheduleUntil Then

                            ' Go here if the schedule is not running. This ensures the song is only
                            ' played the first time the time now is in the schedule period.
                            '----------------------------------------------------------------------
                            If blnSchedule1IsPlayingSong = False Then
                           
                                blnSchedule1IsPlayingSong = True
                                blnScheduleIsPlayingSong = True ' Flag used in the Main module.
                                Main.blnAsongIsPlaying = False ' Toggle to make the song play.
                                CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                                Log("Schedule For Song " & intSongNumber & " is running.")
                            End If
                        Else

                            ' Go here if the schedule is running. This ensures the song is only
                            ' stopped the first time the time now is outside of the schedule period.
                            '-----------------------------------------------------------------------
                            If blnSchedule1IsPlayingSong = True Then
                           
                                blnSchedule1IsPlayingSong = False
                                blnScheduleIsPlayingSong = False ' Flag used in the Main module.
                                Main.blnAsongIsPlaying = True ' Toggle to make the song stop.
                                CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                                Log("Schedule For Song " & intSongNumber & " has ended.")
                            End If
                        End If
                    End If

                Case 2

                    ' Go here if the time now is inside the schedul period for song 2.
                    '-----------------------------------------------------------------
                    If blnSchedule1IsPlayingSong = False And _
                            blnSchedule3IsPlayingSong = False Then

                        ' Go here only once if the time now is inside the schedul period for song 2.
                        '---------------------------------------------------------------------------
                        If DateTime.Now >= lngScheduleFrom And _
                        DateTime.Now <= lngScheduleUntil Then

                            ' Go here if the schedule is not running. This ensures the song is only
                            ' played the first time the time now is in the schedule period.
                            '----------------------------------------------------------------------
                            If blnSchedule2IsPlayingSong = False Then
                           
                                blnSchedule2IsPlayingSong = True
                                blnScheduleIsPlayingSong = True ' Flag used in the Main module.
                                Main.blnAsongIsPlaying = False ' Toggle to make the song play.
                                CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                                Log("Schedule For Song " & intSongNumber & " is running.")
                            End If
                        Else

                            ' Go here if the schedule is running. This ensures the song is only
                            ' stopped the first time the time now is outside of the schedule period.
                            '-----------------------------------------------------------------------
                            If blnSchedule2IsPlayingSong = True Then
                           
                                blnSchedule2IsPlayingSong = False
                                blnScheduleIsPlayingSong = False ' Flag used in the Main module.
                                Main.blnAsongIsPlaying = True ' Toggle to make the song stop.
                                CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                                Log("Schedule For Song " & intSongNumber & " has ended.")
                            End If
                        End If
                    End If

                Case 3
                   
                    ' Go here if the time now is inside the schedul period for song 3.
                    '-----------------------------------------------------------------
                    If blnSchedule1IsPlayingSong = False And _
                            blnSchedule2IsPlayingSong = False Then

                        ' Go here only once if the time now is inside the schedul period for song 3.
                        '---------------------------------------------------------------------------
                        If DateTime.Now >= lngScheduleFrom And _
                        DateTime.Now <= lngScheduleUntil Then

                            ' Go here if the schedule is not running. This ensures the song is only
                            ' played the first time the time now is in the schedule period.
                            '----------------------------------------------------------------------
                            If blnSchedule3IsPlayingSong = False Then
                           
                                blnSchedule3IsPlayingSong = True
                                blnScheduleIsPlayingSong = True ' Flag used in the Main module.
                                Main.blnAsongIsPlaying = False ' Toggle to make the song play.
                                CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                                Log("Schedule For Song " & intSongNumber & " is running.")
                            End If
                        Else

                            ' Go here if the schedule is running. This ensures the song is only
                            ' stopped the first time the time now is outside of the schedule period.
                            '-----------------------------------------------------------------------
                            If blnSchedule3IsPlayingSong = True Then
                           
                                blnSchedule3IsPlayingSong = False
                                blnScheduleIsPlayingSong = False ' Flag used in the Main module.
                                Main.blnAsongIsPlaying = True ' Toggle to make the song stop.
                                CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                                Log("Schedule For Song " & intSongNumber & " has ended.")
                            End If
                        End If
                    End If
            End Select
       
        Else ' The light bulb is off.
           
            Select intSongNumber
               
                Case 1
                   
                    ' Go here if the schedule is running. This ensures the song is only
                    ' stopped the first time the turns off the light bulb for the schedule.
                    '----------------------------------------------------------------------
                    If blnSchedule1IsPlayingSong = True Then
                       
                        blnSchedule1IsPlayingSong = False
                        blnScheduleIsPlayingSong = False ' Flag used in the Main module.
                        Main.blnAsongIsPlaying = True ' Toggle to make the song stop.
                        CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                        Log("Schedule For Song " & intSongNumber & " has ended.")
                    End If

                Case 2

                    ' Go here if the schedule is running. This ensures the song is only
                    ' stopped the first time the turns off the light bulb for the schedule.
                    '----------------------------------------------------------------------
                    If blnSchedule2IsPlayingSong = True Then
                       
                        blnSchedule2IsPlayingSong = False
                        blnScheduleIsPlayingSong = False ' Flag used in the Main module.
                        Main.blnAsongIsPlaying = True ' Toggle to make the song stop.
                        CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                        Log("Schedule For Song " & intSongNumber & " has ended.")
                    End If

                Case 3

                    ' Go here if the schedule is running. This ensures the song is only
                    ' stopped the first time the turns off the light bulb for the schedule.
                    '----------------------------------------------------------------------
                    If blnSchedule3IsPlayingSong = True Then
                       
                        blnSchedule3IsPlayingSong = False
                        blnScheduleIsPlayingSong = False ' Flag used in the Main module.
                        Main.blnAsongIsPlaying = True ' Toggle to make the song stop.
                        CallSubDelayed(Main, "ImageViewPlayCurrentSong_Click")

                        Log("Schedule For Song " & intSongNumber & " has ended.")
                    End If
            End Select
        End If
    Next
End Sub
 

rleiman

Well-Known Member
Licensed User
Longtime User
If you can, switch to B4XPages.
Thanks for the reply. I will do that. For B4XPages, will I need to add any special coding to make sure Android will not kill the app? The one I currently made is based on the part of the tutorial by Erel that won't be killed by Android.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
Same way-service.

Just to make sure, it means I will need to add the previous "keep awake" coding in my service module like before?

Thanks.

B4X:
Sub Service_Create

    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER 'we are handling it ourselves
    lock.PartialLock
End Sub

Sub Service_Start (StartingIntent As Intent)
    Service.StartForeground(nid, CreateNotification("Tapping this notification will open the app."))
    StartServiceAt(Me, DateTime.Now + 30 * DateTime.TicksPerMinute, True)   
End Sub
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
Yes, you have to use the same gimmick/method as the Background location tracking tutorial, as already you did.
No more blocked queue! The song schedule can in and the song played and when the schedule ended the song stopped. From now on all new projects will be B4XPages.

I will be opening another thread related to the migration. It seems that loading layouts is done differently in B4XPages. They load but not the way I expected.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…