Android Question ShortService DataSync and Problems with SDK > 34

Magma

Expert
Licensed User
Longtime User
Hi Fam!

Well I thought my problems end when Erel show us the perfect: Service.StopForeground(51042)

but i have some error at Android 15+ devices...

My Service name is "gggService" and i have got permissions after checks from Google for DataSync (Into Service module using some timer_tick to do my API posts)

in manifest i have the:
B4X:
SetServiceAttribute(gggService, android:foregroundServiceType, "dataSync")

And for the Android 15+ using the following as suggested:
B4X:
Private Sub Service_Timeout(Params As Map)

        Service.StopForeground(51042)
        started=0

End Sub


other code into service is that:

B4X:
Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.
    Dim Phone As Phone
    aver=Phone.SdkVersion
 
    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER
 
    If Provider.IsInitialized=False Then Provider.Initialize
 
    xtimer.Initialize("xtimer",20000)
 
 
    If Main.secureit=True Then
        mytimer.Initialize("mytimer",5000)
    End If
 
End Sub

Sub Service_Start (StartingIntent As Intent)
 
    If onlyonetime=0 Then
 
    StartForegroundWithType("...")

    n.Initialize("default", Application.LabelName, "LOW").AutoCancel(True).SmallIcon(LoadBitmap(File.DirAssets,"icon4app.png"))'.LargeIcon(LoadBitmap(File.DirAssets,"icon2.png"))
 
    n.Build("ggg", "Η εφαρμογή εκτελείται!", "tag1",  Main).Notify(1)
    shownot=True

        xtimer.Enabled=True
        If Main.secureit=True Then
            mytimer.Enabled=True
        End If

    End If
 
    onlyonetime=1

End Sub

Sub Service_TaskRemoved
    'This event will be raised when the user removes the app from the recent apps list.
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return False
End Sub

Sub delayedstops
 
    If Main.isexited=False Then
    Main.isexited=True
    xtimer.Enabled = False
    mytimer.Enabled = False

    ToastMessageShow("Η εφαρμογή θα κλείσει...",True)

     ' Stop manual foreground mode (and remove the notification)
 
    If shownot=True Then
        started=0
        Service.StopForeground(51042)
        Sleep(500)
        ' Cancel any future scheduled starts
        CancelScheduledService(Me)
        Sleep(500)
    End If
 
    CallSubDelayed2(Main, "ServiceStopped", "gggService")
    End If
 
End Sub


Sub Service_Destroy
    If Main.isexited=False Then
        If shownot=True Then
            started=0
            CallSubDelayed(Me,"delayedstops")
        End If
    End If
End Sub


Sub CreateNotification (Body As String) As Notification
    Dim notification As Notification
    notification.Initialize2(notification.IMPORTANCE_LOW)
    notification.Icon = "icon2"
    notification.SetInfo("ggg", Body,  Main)
    Return notification

End Sub


Sub StartForegroundWithType(notif As Notification)
    Dim oContext As JavaObject
    Dim serviceType As Int = 1
 
    Dim RunningPhone As Phone
 
    oContext.InitializeContext
 
    If RunningPhone.SdkVersion >= 29 And RunningPhone.SdkVersion<35 Then
       
        Try
            oContext.RunMethod("startForeground", Array As Object(1, CreateNotification(notif), serviceType))
            started=1
        Catch
            Log(LastException)
            Service.StartForeground(1, notif)
            started=1
        End Try
    Else
        Service.StartForeground(1,  CreateNotification(notif))
        started=1
    End If
End Sub

Also when exiting my app - from menu I want to stop services if it is possible...
So from b4xpages - calling this:
B4X:
Private Sub exitopt_Click
    'reverse
    Main.inprogress=True
    Main.secureit=False
    Try
    StopService(gggService)
    Catch
        ExitApplication
    End Try
End Sub

and in Main:
B4X:
'to emulate exiting from app - sometimes need to have services running... not stopping the same time..

Sub ServiceStopped(name As String)
        Dim iHome As Intent
        iHome.Initialize("android.intent.action.MAIN", "")
        iHome.AddCategory("android.intent.category.HOME")
        iHome.Flags = 0x10000000   ' FLAG_ACTIVITY_NEW_TASK
        Dim joIntent As JavaObject = iHome
        Dim joContext As JavaObject
        joContext.InitializeContext
        Dim pm As Object = joContext.RunMethod("getPackageManager", Null)
        If joIntent.RunMethod("resolveActivity", Array(pm)) <> Null Then
            StartActivity(iHome)
            Else
            ToastMessageShow("Press Home to exit - Bye bye!",True)
        End If
End Sub


But in Android Vitals, getting many errors in Android 15 about services !!!!!

many of:

Exception android.app.RemoteServiceException$ForegroundServiceDidNotStopInTimeException:
at android.app.ActivityThread.generateForegroundServiceDidNotStopInTimeException (ActivityThread.java:2339)
at android.app.ActivityThread.throwRemoteServiceException (ActivityThread.java:2301)
at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException (Unknown Source)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2616)
at android.os.Handler.dispatchMessage (Handler.java:107)
at android.os.Looper.loopOnce (Looper.java:232)
at android.os.Looper.loop (Looper.java:317)
at android.app.ActivityThread.main (ActivityThread.java:8849)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:681)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:902)

---------


not so much... (1,2..3):

Exception java.lang.RuntimeException:
at anywheresoftware.b4a.keywords.Common$12.run (Common.java:1268)
at android.os.Handler.handleCallback (Handler.java:959)
at android.os.Handler.dispatchMessage (Handler.java:100)
at android.os.Looper.loopOnce (Looper.java:249)
at android.os.Looper.loop (Looper.java:337)
at android.app.ActivityThread.main (ActivityThread.java:9592)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:936)
Caused by android.app.ForegroundServiceStartNotAllowedException:
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:50)
at android.os.Parcel.readParcelableInternal (Parcel.java:5089)
at android.os.Parcel.readParcelable (Parcel.java:5071)
at android.os.Parcel.createExceptionOrNull (Parcel.java:3251)
at android.os.Parcel.createException (Parcel.java:3240)
at android.os.Parcel.readException (Parcel.java:3223)
at android.os.Parcel.readException (Parcel.java:3165)
at android.app.IActivityManager$Stub$Proxy.startService (IActivityManager.java:6780)
at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1971)
at android.app.ContextImpl.startForegroundService (ContextImpl.java:1946)
at android.content.ContextWrapper.startForegroundService (ContextWrapper.java:848)
at anywheresoftware.b4a.keywords.Common.StartServiceImpl (Common.java:977)
at anywheresoftware.b4a.keywords.Common.StartService (Common.java:964)
at anywheresoftware.b4a.keywords.Common$12.run (Common.java:1236)
 

Magma

Expert
Licensed User
Longtime User
51042 is the id of the automatic foreground notification.

As you are disabling it with:
B4X:
Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER

It will never show. I guess that you are calling StartForeground somewhere else and should then use the correct id.
...

???
which is the right call ? (right now: hitting my head at wall!)
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
@Erel

also make this change too ?

'Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER
Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_ALWAYS


- if you see the code "Service.StartForeground":


you mean here change the id with 51042 (is it the dataSync? ID or no matter) :

B4X:
Sub StartForegroundWithType(notif As Notification)
    Dim oContext As JavaObject
    Dim serviceType As Int = 1
 
    Dim RunningPhone As Phone
 
    oContext.InitializeContext
 
    If RunningPhone.SdkVersion >= 29 And RunningPhone.SdkVersion<35 Then
     
        Try
            oContext.RunMethod("startForeground", Array As Object(1, CreateNotification(notif), serviceType))
            started=1
        Catch
            Log(LastException)
            Service.StartForeground(1, notif)
            started=1
        End Try
    Else
        Service.StartForeground(1,  CreateNotification(notif))
        started=1
    End If
End Sub

also at this line:
oContext.RunMethod("startForeground", Array As Object(1, CreateNotification(notif), serviceType))

1 must be also 51042 ?
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. No, better to disable "automatic foreground mode".
2. Delete StartForegroundWithType and use Service.StartForeground. StartForeground uses the service type declared in the manifest editor, which is what you want. The only case where a code such as StartForegroundWithType is needed is if you have a service with multiple foreground types and you want to choose the specific type.

BTW, your code uses the id = 1.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
...well after some days... google updated my version...
1759729811835.png


but still - even I ve changed all like we ve said getting the same error:

Exception android.app.RemoteServiceException$ForegroundServiceDidNotStopInTimeException:
at android.app.ActivityThread.generateForegroundServiceDidNotStopInTimeException (ActivityThread.java:2504)
at android.app.ActivityThread.throwRemoteServiceException (ActivityThread.java:2466)
at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException (Unknown Source)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2820)
at android.os.Handler.dispatchMessage (Handler.java:107)
at android.os.Looper.loopOnce (Looper.java:257)
at android.os.Looper.loop (Looper.java:342)
at android.app.ActivityThread.main (ActivityThread.java:9638)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:619)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:929)


ps: ofcourse still users trying at the first devices of Android 15... so I will inform when 100% of users update... to check if there is any difference at least at percentage of errors...
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
I am searching a little the web and AIs... found this:


The error occurring only on Android 15 devices relates to Android 15 introducing new strict limitations and behavior changes for foreground services, which cause exceptions like ForegroundServiceDidNotStopInTimeException if not complied with properly.

Key Android 15 Foreground Service Changes Affecting Your Case​


  • Android 15 enforces a 6-hour runtime limit on specific foreground service types (dataSync and the new mediaProcessing). After the limit, the system calls your service's onTimeout() callback, and the service must call stopSelf() within seconds, or the system throws an exception.
  • Services must implement the new Service.onTimeout(int, int) callback to handle graceful shutdown and resource cleanup when this timeout occurs. Failure to respond promptly triggers the exception.
  • There are new mandatory foreground service types and permissions declarations required (like foregroundServiceType="dataSync") in the manifest for better system control and user privacy.
  • Apps holding SYSTEM_ALERT_WINDOW permission can only start foreground services if the app has a visible overlay in the foreground, limiting background starts.
  • Strict enforcement on timely calling of stopForeground() and stopSelf() when the service is to be stopped to prevent resource hogging.

Why It Only Happens on Android 15​


  • Android 15 enforces these runtime limits and timeout callbacks that did not exist on previous versions.
  • Older Android versions may allow longer or indefinite foreground service runtimes without throwing exceptions.
  • Thus, service code that works fine on Android 13/14 can still throw these exceptions on Android 15 if it does not implement the new timeout handling and immediate stop calls.

What to Do to Fix Your Service for Android 15​


  1. Implement Service.onTimeout(int, int) callback in your service to handle timely shutdown when the system triggers the timeout for your foreground service type (likely dataSync in your case). In this callback, call stopSelf() promptly.
  • Ensure your service calls stopForeground() and stopSelf() immediately when the work is done or the service must stop, without delay or blocking operations (e.g., avoid delays or sleeps after these calls).
  • Declare correct foregroundServiceType attribute in your manifest for the service, matching the service's usage, such as dataSync if your service does data synchronization.
  • Consider offloading long-running background work to alternatives like WorkManager or JobScheduler to avoid prolonged foreground service usage.
  • If your app has SYSTEM_ALERT_WINDOW permission, ensure foreground services start only when your app has a visible overlay.


So reading "Android 15 enforces a 6-hour runtime limit" - and I am thinking that may be need to stop the service some hours before and start it again... but how ?
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
OK I am thinking aloud... now... all problems are only in Android 15 with the limit of some hours (lets say 6)

My thoughts - my view:

When using stopservice(myservice) - taking this log:
** Service (myservice) Destroy **
*** Service (myservice) Create ***
** Service (myservice) Start **
Because is automatic... i think starts again.. i am ok with that - i can live with that...

But when I manually (Service.StopForeground(51042)) or when time arrive - using:
B4X:
Private Sub Service_Timeout(Params As Map)
    Service.StopForeground(51042)
End Sub
No log at all!
think: May be not a log, because Erel didn't want to show it... or have it in a next version...

Ok i can leave it like that - into Service_Timeout with stopforeground... but what if have a timer that will check every 4 hours... and use manually the stopservice(myservice) - will automatically restart... so timeout will never come - right ?

Is it a solution to my problem - what do you think - try it in Production or will make bigger problems ?

Thanks in advance
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Just my thoughts:

i am ok with that - i can live with that...
In fact you should NEVER let your service running for >6H in a 24 Timespan. This is a big mistake and not allowed in Android.
But when I manually (Service.StopForeground(51042)) or when time arrive - using
If you run into timeout then you are ALREADY >6H running your service. It is to late to do anything now. You should have done it earlier already.

Rethink your service usecase in total.
Why you need it run for this long time?
If you just want to sync a dababase it should be done in a few minutes. No more.
If you need to upload something this should be done in less than a few minutes too.

Do NOT use a automatically starting services at all.

If you need to sync something let the service start every 6 hours by resheduling the service. When it starts do your small timespan sync or upload and stop the service and reshedule it again to run in 6h again.

PD: As already written this is just my thoughs.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Just my thoughts:


In fact you should NEVER let your service running for >6H in a 24 Timespan. This is a big mistake and not allowed in Android.

If you run into timeout then you are ALREADY >6H running your service. It is to late to do anything now. You should have done it earlier already.

Rethink your service usecase in total.
Why you need it run for this long time?
If you just want to sync a dababase it should be done in a few minutes. No more.
If you need to upload something this should be done in less than a few minutes too.

Do NOT use a automatically starting services at all.

If you need to sync something let the service start every 6 hours by resheduling the service. When it starts do your small timespan sync or upload and stop the service and reshedule it again to run in 6h again.

PD: As already written this is just my thoughs.
Yes, I understand and I agree - general I also don't like services at all... but...

The whole idea using services is in case that if GOVerment webservices don't work at time needed (or user not having good signal of wifi)... So I am creating a queue of works not completed (in a db)... for that reason this service must be trying for ever "posting" XML jstrings/files again and again (every some mins) to the webservices and then receiving the answers-signatures that all gone OK.

so you mean...
If you need to sync something let the service start every 6 hours by resheduling the service. When it starts do your small timespan sync or upload and stop the service and reshedule it again to run in 6h again.

Well... hmmm mean something like this :
B4X:
Sub ScheduleServiceEvery4min '4 minutes
    ' Cancel any existing scheduled service
    CancelScheduledService(myservice)
  
    ' Schedule to run every 4min
    Dim nextRun As Long = DateTime.Now + (4 * DateTime.TicksPerMinute)
    StartServiceAt(myservice, nextRun, True)
  
    Log("Service scheduled to run at: " & DateTime.Date(nextRun))
End Sub
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
' Schedule to run every 4min Dim nextRun As Long = DateTime.Now + (4 * DateTime.TicksPerMinute)
No. You are trying to start it in 4 Minutes, not 4 Hours

B4X:
Dim nextRun As Long = DateTime.Now + (4 * DateTime.TicksPerHour)
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
No. You are trying to start it in 4 Minutes, not 4 Hours

B4X:
Dim nextRun As Long = DateTime.Now + (4 * DateTime.TicksPerHour)
Yes (thinking) using 4mins because I want to be sure to bypss these two problems:
1) If user not having internet
2) If webservices of GOV are dead for many reasons

...
The whole idea using services is in case that if GOVerment webservices don't work at time needed (or user not having good signal of wifi)... So I am creating a queue of works not completed (in a db)... for that reason this service must be trying for ever "posting" XML strings/files again and again (every some mins) to the webservices and then receiving the answers-signatures that all gone OK.

For that reason used automatic services
 
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
Android does NOT ALLOW such short spans
So... That's why I ve used automatic Service...

But sure, if rethink the whole way... may be find a different way to achieve that...

So in case of automatic services... for that i ve said not seeing stopping the service at log - any idea ?
 
Upvote 0
Top