Android Question RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()

AbdurRahman

Member
Hi, first of all, much thanks for such super IDE
Its tiny, but no less than rocket in pocket

I migrated my signage system from kotlin to b4a
and development pace yet shoot up 🚀

I had challenge, to keep app running 24h
I'm using auto restart code (by @OliverA 😍)
with little help from gpt

B4X:
B4A=true
Group=UI
ModulesStructureVersion=1
Type=Service
Version=9.9
@EndOfDesignText@
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: True
#End Region

Sub Process_Globals
    Private const FLAG_ACTIVITY_CLEAR_TOP As Int = 0x04000000
    Private const FLAG_ACTIVITY_CLEAR_TASK As Int = 0x00008000
    Private const FLAG_ACTIVITY_NEW_TASK As Int = 0x10000000
    Private const FLAG_ONE_SHOT As Int = 0x40000000
    Private const ALM_RTC As Int = 0x00000001
    Public AutoRestartEnabled As Boolean = True
    Public IsInForeground As Boolean = False
End Sub

Sub Service_Create
    EnsureNotificationChannel
    StartForegroundNotification
    StartServiceAt(Me, DateTime.Now + (5 * 1000), True)
    SaveMyLogs
End Sub

Sub Service_Start(StartingIntent As Intent)
    Log("Starter service started. Action=" & StartingIntent.Action)
    If StartingIntent.HasExtra("android.intent.extra.REASON") Or _
       StartingIntent.Action = "android.intent.action.BOOT_COMPLETED" Or _
       StartingIntent.Action = "android.intent.action.QUICKBOOT_POWERON" Or _
       StartingIntent.Action = "com.htc.intent.action.QUICKBOOT_POWERON" Then
        Log("Service restarted after boot")
    End If

    StartForegroundNotification

    If AutoRestartEnabled Then
        If IsPaused(Main) And IsPaused(PlayerWindow) And IsPaused(PasswordWindow) And IsPaused(DownWindow) Then
            Dim ctxt As JavaObject
            ctxt.InitializeContext
            Dim pm As JavaObject = ctxt.RunMethod("getPackageManager", Null)
            Dim launchIntent As Intent = pm.RunMethod("getLaunchIntentForPackage", Array(Application.PackageName))
            If launchIntent.IsInitialized Then
                launchIntent.Flags = Bit.Or(0x10000000, 0x20000000) ' NEW_TASK + CLEAR_TOP
                StartActivity(launchIntent)
            End If
        End If
        StartServiceAt(Me, DateTime.Now + (5 * 1000), True)
    End If
End Sub

Sub StartForegroundNotification
    If IsInForeground  Then Return
    Dim n As Notification
    n.Initialize
    n.Icon = "icon"
    n.AutoCancel = False
    n.SetInfo("App Running", "Monitoring…", Main)
    Service.StartForeground(1, n)
    IsInForeground = True
End Sub


Sub EnsureNotificationChannel
    Dim p As Phone
    If p.SdkVersion >= 26 Then
        Try
            Dim ctxt As JavaObject
            ctxt.InitializeContext
            Dim nm As JavaObject = ctxt.RunMethod("getSystemService", Array("notification"))
            Dim jc As JavaObject
            jc.InitializeNewInstance("android.app.NotificationChannel", Array("sig_channel_01", "Signal channel", 3))
            jc.RunMethod("setDescription", Array("Foreground service channel"))
            nm.RunMethod("createNotificationChannel", Array(jc))
        Catch
            Log("Notification channel creation failed: " & LastException.Message)
        End Try
    End If
End Sub


Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    SaveLog("Crash", Error.Message & CRLF & StackTrace)
    ScheduleRestartCrashedActivity(DateTime.Now + (2 * DateTime.TicksPerSecond), "Main", Error)
    ExitApplication
    Return True
End Sub

Sub ScheduleRestartCrashedActivity (Time As Long, ActivityName As String, message As String)
    Dim in As Intent
    in.Initialize("", "")
    in.SetComponent(Application.PackageName & "/." &  ActivityName.ToLowerCase)
    in.PutExtra("Crash", message)
    in.Flags = Bit.Or(FLAG_ACTIVITY_CLEAR_TASK, Bit.Or(FLAG_ACTIVITY_CLEAR_TOP, FLAG_ACTIVITY_NEW_TASK))
  
    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("getActivity", Array(ctxt, 0, in, FLAG_ONE_SHOT))
  
    Dim p As Phone
    If p.SdkVersion < 20 Then
        am.RunMethod("set", Array(ALM_RTC, Time, pi))
    Else If p.SdkVersion < 23 Then
        am.RunMethod("setExact", Array(ALM_RTC, Time, pi))
    Else
        am.RunMethod("setExactAndAllowWhileIdle", Array(ALM_RTC, Time, pi))
    End If
  
End Sub

Sub SaveLog(tag, text As String)
    Log($"ExtLOG(${tag},${text})"$)
    'Logger.addLogToDB2(tag, text)
End Sub
 
Sub ClearAdbLogs
    Try
        Dim jo As JavaObject
        jo.InitializeStatic("java.lang.Runtime")
        Dim runtime As JavaObject = jo.RunMethod("getRuntime", Null)
        runtime.RunMethod("exec", Array("logcat -c"))
        Log("Logcat cleared successfully")
    Catch
        Log("Error clearing logcat: " & LastException.Message)
    End Try
End Sub
 
Sub SaveMyLogs
    Try
        Dim jo As JavaObject
        jo.InitializeStatic("java.lang.Runtime")
        Dim runtime As JavaObject = jo.RunMethod("getRuntime", Null)
        Dim process As JavaObject
        process.InitializeStatic("java.lang.Runtime")
        Dim runtime As JavaObject = process.RunMethod("getRuntime", Null)
        Dim cmd As String = "logcat -d *:E"
        Dim proc As JavaObject = runtime.RunMethod("exec", Array(cmd))
        Dim br As JavaObject
        br.InitializeNewInstance("java.io.BufferedReader", Array( _
            br.InitializeNewInstance("java.io.InputStreamReader", Array(proc.RunMethod("getInputStream", Null))), _
            1024))
        Dim crashLogs As StringBuilder
        crashLogs.Initialize
        Do While True
            Dim line As String = br.RunMethod("readLine", Null)
            If line = Null Or line = "null" Then Exit
            crashLogs.Append(line).Append(CRLF)
            If crashLogs.Length > 5120 Then Exit
        Loop
        Dim base As String = File.DirRootExternal
        File.MakeDir(base, "Download")
        File.MakeDir(File.Combine(base, "Download"), "Signal")
        File.MakeDir(File.Combine(base, "Download/Signal"), "Logs")
        Dim filename As String = DateTime.Date(DateTime.Now) & "_" & DateTime.Time(DateTime.Now)
        filename = filename.Replace("/", "-").Replace(":", "-") & ".log"
        File.WriteString(File.Combine(base, "Download/Signal/Logs"), filename, crashLogs.ToString)
        ClearAdbLogs
    Catch
        Log("Error saving logs: " & LastException.Message)
    End Try
End Sub

My tester says same apk running fine on android 8
But close on android 11
Both are android boxes
B4X:
--------- beginning of main
--------- beginning of crash
09-30 14:16:17.473 29023 29023 E AndroidRuntime: FATAL EXCEPTION: main
09-30 14:16:17.473 29023 29023 E AndroidRuntime: Process: com.signal.android, PID: 29023
09-30 14:16:17.473 29023 29023 E AndroidRuntime: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{4a2abf8 u0 com.signal.android/.starter}
09-30 14:16:17.473 29023 29023 E AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2005)
09-30 14:16:17.473 29023 29023 E AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:106)
09-30 14:16:17.473 29023 29023 E AndroidRuntime:     at android.os.Looper.loop(Looper.java:223)
09-30 14:16:17.473 29023 29023 E AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:7664)
09-30 14:16:17.473 29023 29023 E AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
09-30 14:16:17.473 29023 29023 E AndroidRuntime:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
09-30 14:16:17.473 29023 29023 E AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
 
Top