Android Question Android is killing my service

rleiman

Well-Known Member
Licensed User
Hi Everyone,

Android is killing my service if the app is running on battery power. Everything works perfectly if the phone is connected up to the mains. The phone is a Galaxy S7 Edge running Android 7.0 and I made sure the app is listed in the "Unmonitored app" section at least so I thought Android would not touch it. Also this service is a "sticky" service with notifications.

How do I stop Android from killing the app?

So far this is the coding for the service. This service chimes on the quarters such as 15 past, half past, etc. The service is restarted for each quarter.

B4X:
#Region  Service Attributes
    #StartAtBoot: False
   #StartCommandReturnValue: android.app.Service.START_STICKY   
#End Region

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

    Private kvs As KeyValueStore
    Private mpMediaPlayerInitialSound As MediaPlayer
    Private mpMediaPlayerHourlyChimes As MediaPlayer
    Private nNotify As Notification

    Private lngTheTimeNow As Long
    Private intHours As Int
    Private intMinutes As Int
End Sub

Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)

    ' Set defaults.
    '--------------

    ' Initialize.
    '------------
    kvs.Initialize(File.DirDefaultExternal, "Settings")

    ' Call the start service code and set the next time.
    '---------------------------------------------------
    SetExactAndAllowWhileIdle(TimeToNext15MinuteSlot(DateTime.Now), "ServiceChimes")

'    ToastMessageShow("Chiming will active from: " & _
'        DateTime.GetHour(TimeToNext15MinuteSlot(DateTime.Now)) & ":" & _
'       DateTime.GetMinute(TimeToNext15MinuteSlot(DateTime.Now)), True)
    
    ' Initialize.
    '------------
    mpMediaPlayerInitialSound.Initialize2("InitialSound")
    mpMediaPlayerInitialSound.SetVolume(.1, .1)
    nNotify.Initialize

    ' Notification setup.
    '--------------------
    nNotify.Icon = "icon"
    nNotify.Sound = False
        
    If kvs.Get("VibrationsAreOn") = False Then
        nNotify.Vibrate = False
    Else
        nNotify.Vibrate = True
    End If

    ' Break apart the time now.
    '--------------------------
    lngTheTimeNow = DateTime.Now
    intHours = DateTime.GetHour(lngTheTimeNow)
    intMinutes = DateTime.GetMinute(lngTheTimeNow)
                                                          
    Select intMinutes
        Case 15
            If mpMediaPlayerInitialSound.IsPlaying = False Then
                mpMediaPlayerInitialSound.Load(File.DirAssets,"quarter.mp3")
                mpMediaPlayerInitialSound.Play
                nNotify.SetInfo("", "It's a quarter after.", "")
                nNotify.Notify(2)
            End If
                            
        Case 30
            If mpMediaPlayerInitialSound.IsPlaying = False Then
                mpMediaPlayerInitialSound.Load(File.DirAssets,"half.mp3")
                mpMediaPlayerInitialSound.Play
                nNotify.SetInfo("", "It's half past.", "")
                nNotify.Notify(2)
            End If
                            
        Case 45
            If mpMediaPlayerInitialSound.IsPlaying = False Then
                mpMediaPlayerInitialSound.Load(File.DirAssets,"quarter_before.mp3")
                mpMediaPlayerInitialSound.Play
                nNotify.SetInfo("", "It's a quarter before.", "")
                nNotify.Notify(2)
            End If
                            
        Case 0
            If mpMediaPlayerInitialSound.IsPlaying = False Then
                mpMediaPlayerInitialSound.Load(File.DirAssets,"hourly.mp3")
                mpMediaPlayerInitialSound.Play
            End If
                            
    End Select ' intMinutes

End Sub

Sub Service_Destroy

End Sub

' Misc. sub routines.
'--------------------

' TIME TO NEXT 15 minutes slot
'-----------------------------
Sub TimeToNext15MinuteSlot(TimeNow As Long) As Long
   Dim minutes As Int = DateTime.GetMinute(TimeNow)  'ex. 09:12 --> 12
   Dim gap As Int
   gap = 15 - (minutes Mod 15)
   Return TimeNow + gap * DateTime.TicksPerMinute
End Sub

' SET EXACTLY
'------------
Sub SetExactAndAllowWhileIdle(Time As Long, ServiceName As String)
    Dim Phone As Phone
    If Phone.SdkVersion < 23 Then
        StartServiceAtExact(ServiceName, Time, True)
    Else
        Dim in As Intent
        in.Initialize("", "")
        in.SetComponent(Application.PackageName & "/." &  ServiceName.ToLowerCase)
      
        Dim Jin As JavaObject = in
        Jin.RunMethod("setAction", Array(Null))
      
        Dim ctxt As JavaObject
        ctxt.InitializeContext
      
        Dim Am As JavaObject = ctxt.RunMethod("getSystemService", Array("alarm"))
      
        Dim Pi As JavaObject
        Pi = Pi.InitializeStatic("android.app.PendingIntent").RunMethod("getService", _
    Array(ctxt, 1, in, 134217728))
        Am.RunMethod("setExactAndAllowWhileIdle", Array(0, Time, Pi))
    End If
End Sub

Sub InitialSound_Complete
'    ToastMessageShow("Ready to play chimes.", False)

    Dim intHoursToChime As Int

    If intMinutes = 0 Then
        mpMediaPlayerHourlyChimes.Initialize
        mpMediaPlayerHourlyChimes.SetVolume(.1, .1)

        Select intHours
            
            Case 1, 13
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "one_chime.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 1
    
            Case 2, 14
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "two_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 2
    
            Case 3, 15
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "three_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 3
    
            Case 4, 16
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "four_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 4
    
            Case 5, 17
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "five_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 5
    
            Case 6,    18
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "six_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 6
    
            Case 7, 19
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "seven_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 7
    
            Case 8, 20
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "eight_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 8
    
            Case 9, 21
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "nine_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 9
    
            Case 10, 22
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "ten_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 10
    
            Case 11, 23
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "eleven_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 11
    
            Case 12, 0
                mpMediaPlayerHourlyChimes.Load(File.DirAssets, "twelve_chimes.mp3")
                mpMediaPlayerHourlyChimes.Play
                intHoursToChime = 12
        End Select
    
        nNotify.SetInfo("", "It's " & intHoursToChime & " O Clock.", "")
        nNotify.Notify(2)
    End If
End Sub
 

rleiman

Well-Known Member
Licensed User
Hi,

After reading the link from Peter, I tried this instead of SetExactAndAllowWhileIdle.:

B4X:
    StartServiceAt("", TimeToNext15MinuteSlot(DateTime.Now), True)

At least now the service is waking up but the timing that the it's waking up is not to accurate. About half of the time it's over a minute late. Is there something I can do with StartServiceAt to make it more accurate?

It seems that instead of SetExactAndAllowWhileIdle does not always work like StartServiceAt does.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Hi Everyone,

So far StartServiceAtExact is giving me the best accuracy and not any skipped service startups. I will test it all day just to be sure.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Hi Erel,

Running the service as a foreground service and using SetExactAndAllowWhileIdle works well so my question now is with SetExactAndAllowWhileIdle vs StartServiceAtExact. Which one works best on most devices since on my phone the accuracy seems to be the same and both don't skip a scheduled wakeup of the service?
 
Upvote 0
Top