Android Question Stop ShortService, StartForeground, Service and ExitApplication...

Magma

Expert
Licensed User
Longtime User
Well Receivers change the game... also every sdk get difficult to follow...

But for some reason can't stop (kill) my services at all...

here how i am starting them:

B4X:
MyReceiver:

Sub Process_Globals
    
End Sub

'Called when an intent is received. 
'Do not assume that anything else, including the starter service, has run before this method.
Private Sub Receiver_Receive (FirstTime As Boolean, StartingIntent As Intent)
    If StartingIntent.IsInitialized Then
        Dim cs As CSBuilder
        cs.Initialize.Bold.Size(20).Append($"Action: ${StartingIntent.Action}"$).PopAll
        Log(cs)
        ToastMessageShow(cs, True)
    End If
End Sub


somewhere in one b4xpage:
'calling Myservice
    StartService(Myservice)

#Region  Service Attributes 
    #StartAtBoot: False
    #ExcludeFromLibrary: 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 xtimer As Timer
    Public mytimer As Timer
    Dim n As NB6
    Dim pqid As Int = 5
    Dim sw As Int = 0
    Public Provider As FileProvider
    Dim onlyonetime As Int=0
    
End Sub

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.
    
    
    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER

End Sub

Sub Service_Start (StartingIntent As Intent)
    
    If onlyonetime=0 Then
    
    If Provider.IsInitialized=False Then Provider.Initialize
    
    Service.StartForeground(1, CreateNotification("..."))

    n.Initialize("default", Application.LabelName, "LOW").AutoCancel(True).SmallIcon(LoadBitmap(File.DirAssets,"icon4app.png"))'.LargeIcon(LoadBitmap(File.DirAssets,"icon2.png"))
    
    n.Build("my app", "some info", "tag1",  Main).Notify(1)


    StartServiceAt(Me, DateTime.Now +  30 * DateTime.TicksPerMinute, True)

    xtimer.Initialize("xtimer",20000)
    xtimer.Enabled=True
    
    If Main.secureit=True Then
        mytimer.Initialize("mytimer",5000)
        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
    xtimer.Enabled = False
    mytimer.Enabled = False

    ' If using automatic foreground mode, stop it first
    Service.StopAutomaticForeground
    Sleep(2000)

    ' Cancel any future scheduled starts
    CancelScheduledService(Me)
    Sleep(2000)

    ' Stop manual foreground mode (and remove the notification)
    Service.StopForeground(1)
    Sleep(2000)

    ' Fully stop the service -hmm again ? - check the last part of 'code' calling stopservice ?
    StopService(Me)
    Sleep(2000)
    
    Return 
End Sub


Sub Service_Destroy
    CallSubDelayed(Me,"delayedstops")
    ExitApplication
End Sub


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

End Sub



Sub mytimer_tick
    
    If Main.lastcheck=0 Then Return
    

    mytimer.Enabled=False

    Try

'doing some jobs

    Catch
    End Try
    
    mytimer.Initialize("mytimer",30000)
    mytimer.Enabled=True
End Sub


Sub xtimer_tick
    xtimer.Enabled=False

    Try

'doing my stuff
    
    Catch
    End Try
    
    xtimer.Enabled=True
End Sub

Private Sub Service_Timeout(Params As Map)
    Service.StopForeground(1)
End Sub


My manifest for my service:
B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="35"/>

..
CreateResourceFromFile(Macro, Core.NetworkCleartext)
...

AddPermission(android.permission.SCHEDULE_EXACT_ALARM)
AddPermission(android.permission.POST_NOTIFICATIONS)
AddPermission(android.permission.FOREGROUND_SERVICE)

...
AddPermission(android.permission.FOREGROUND_SERVICE_DATA_SYNC)
SetServiceAttribute(Myservice, android:foregroundServiceType, "dataSync")

AddPermission(android.permission.SYSTEM_ALERT_WINDOW)

To end my service and exit - calling for a b4xpage that:
B4X:
    StopService(Myservice)

The app seems exiting... hides notification
but after a while (~4-5min the app reloads at notification)
any idea ?
 

drgottjr

Expert
Licensed User
Longtime User
for what it's worth, words (of wisdom) from our leader, may 16, 2017:
"The OS will treat your app as if it has crashed when you call ExitApplication. In some cases it will try to restart it automatically."
 
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
for what it's worth, words (of wisdom) from our leader, may 16, 2017:
"The OS will treat your app as if it has crashed when you call ExitApplication. In some cases it will try to restart it automatically."
Hmm... so is it better to stop services, close b4xpage....

And never exit ?
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
In most cases yes.

Why are you using a service? Most of the use cases for services are gone with B4XPages (and new Android restrictions).
Well I need to data sync.. actually uploading some xml to gov ...so when android system not having wifi or gov platform is offline need to upload them when online with a flag ofcourse and without user intervention
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Why are you calling Timer.Initialize multiple times? No need. It can cause bad side effects.

It isn't clear from the documentation, how the service behaves with dataSync. Try it without stopping the service.

Another option is to use StartReceiverAt to start your app every X hours and try to synchronize the data. You can start a shortService foreground service from the receiver.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
You mean move it at Service_Create ?

I was using "onlyonetime' to do that...

StartReceiverAt ?
An example ... on my case ?
Need extra permission too ?

Already asked Google and got datasync permission after posting some videos.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
StartReceiverAt replaced StartServiceAt. It allows you to schedule a receiver to run at some point. You can use it to start your app in the background from time to time and make the synchronization.

With that said, I don't fully understand your configuration, so maybe your current solution is better.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
StartReceiverAt replaced StartServiceAt. It allows you to schedule a receiver to run at some point. You can use it to start your app in the background from time to time and make the synchronization.

With that said, I don't fully understand your configuration, so maybe your current solution is better.
...Well... for sure I want the end user has a service running after get in (first time) at app... and when hiding the app for his reason (a call, talking to messenger, viber..) app sending/uploading (data-sync)

But when selecting "Exit" from app at hiding notification, stop timers and service... when restarting app or appears (start timers and service work again)

Thanks for your answers...
 
Upvote 0
Top