Android Question [COULD BE SOLVED]Huawei Y6 Android 8 - Background Services not operating correctly

Jmu5667

Well-Known Member
Licensed User
Longtime User
Hello All

I am struggling to keep background services running correctly on Android 8+, I have already use this https://www.b4x.com/android/forum/threads/background-location-tracking.99873/#content and in the settings on the device enabled the app to run in the background.

Has anyone successfully got BG tasks running on android 8+, I would like to hear from you.

Some strange things:

1. I have a timer in the service will gets ticked every 2 seconds.
2. In the timer I update the notification every 10 seconds, it also tracks the time when it should occur, and if it is out by more then 30 seconds a notification is triggered, and it does happen. Its like the service is being paused.

B4X:
Sub tmrServiceHook_tick

  '   updateNotification is set to now time when the service start

   ' // update the notification to keep everything alive
   ' // https://www.b4x.com/android/forum/threads/background-services-in-android-8-observations.103533/
   If updateNotification < DateTime.Now Then
   
       Dim secondsDiff As Period = DateUtils.PeriodBetween(updateNotification, DateTime.now)
       ' // log by exception
       If secondsDiff.Seconds > 30 Then
           mod_functions.writelog("svc_service(), tmrServiceHook_tick, Still Alive, running, abnormally, Seconds " & secondsDiff.Seconds)
           Dim n5 As Notification
           n5.Initialize
           n5.Icon = "app_logo_4_notification_bar_issue"
           n5.Number = 999
           n5.Insistent = True
           ' // always last prop to be set
           n5.SetInfo("ATLAS HELLO WARNING", "DEVICE IS PREVENTING NORMAL OPERATION", Main)
           n5.Notify(999)
       End If
           
       updateNotification = DateTime.Now + (DateTime.TicksPerSecond * 10)
       mod_functions.writelog("svc_service(), tmrServiceHook_tick, Still Alive, Next Marker @ " & DateTime.Time(updateNotification))
       settNotification = 1 ' this is checked further on in this function for a non zero value and does the notification.

   End If

Here is the service code:

B4X:
Sub Service_Create
   
   Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER
   nNewMessage.Initialize
   PE.InitializeWithPhoneState("PE", PhoneId)
   
   ' // set the service hook to be called every 2 seconds
   tmrServiceHook.Initialize("tmrServiceHook",2000)
   
   
End Sub

Sub Service_Start (StartingIntent As Intent)

   ' // setup the notification   
   Service.StartForeground(51042,CreateNotification("Atlas Hello","Offline","app_logo_4_notification_bar_offline",Main,False,False))
   pw.PartialLock
   mlWifi.holdWifiOn
   
   ' // main data is not available
   If Not(Main.APPSET.IsInitialized) Then
       mod_functions.writelog("svc_service(), Service_Start, Death is so painful, we have been Destroyed ! , restarting app")
       StartServiceAt(svc_bootup,DateTime.Now + (3 * DateTime.TicksPerSecond),True)
       kill_me
   Else
       mod_functions.writelog("svc_service(), Service_Start")   
       tmrServiceHook.Enabled = True   
   End If       
  

   updateNotification = DateTime.now
   
End Sub

Regards

John.
 

OliverA

Expert
Licensed User
Longtime User
StartServiceAt(svc_bootup,DateTime.Now + (3 * DateTime.TicksPerSecond),True)
Reading several posts here on the forum, it looks like the minimum value for StartServiceAt on newer Androids is 15 minutes. Anything below that just gets ignored. What A way around that, and I've did a post about it here (https://www.b4x.com/android/forum/t...don’t-kill-my-app-”.101495/page-2#post-640096), may be using an intent to restart your service/application instead of StartServiceAt.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
I think I have solved the issue. It has to do with service inheritance. If you have a primery service that is the background service that launches other service, but each service that is launched does not acquire locks or anything special like foreground access etc, it seems to work.

I have been running a test for over 2 hrs now and have not experienced any faults....fingers cross :)
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
Can you explain better what did you do to have the background service always running ?

Hi

Firstly, I never use starter server. All our app have a service called svc_service. This is the master control service that handles all the stuff we need to do in relation to what need to run or what should be running. The code below is a stripped down version of it.

B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   
   Public nID As Int = 51042
   Public n As Notification

   Dim pw As PhoneWakeState
   
End Sub

Sub Service_Create
   
   Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER
   pw.PartialLock
   
End Sub

Sub Service_Start (StartingIntent As Intent)

   ' // setup the notification   
   Service.StartForeground(nID,CreateNotification("Atlas Hello","Offline","app_logo_4_notification_bar_offline",Main,False,False))

   
End Sub

Sub Service_Destroy
       
   pw.ReleasePartialLock
   n.Cancel(nID)   
   Service.StopForeground(nID)
   Service.StopAutomaticForeground
   
End Sub


Private Sub CreateNotification(Title As String, Content As String, Icon As String, TargetActivity As Object, Sound As Boolean, Vibrate As Boolean) As Notification
   
   Dim p As Phone
   
   If n.IsInitialized Then
       n.Cancel(nID)
   End If
   
   If p.SdkVersion >= 21 Then
       Dim nb As NotificationBuilder ' // Library v3.50
       Dim Channel As NotificationChannelBuilder
       Dim ChannelID As String = "your_app_id"
       Dim ChannelName As String = "Your App Name"
       
       ' // Build a Channel
       If Channel.ChannelsSupported Then
           Channel.Initialize(ChannelID, ChannelName, Channel.IMPORTANCE_LOW)
           Channel.Build
       End If
       
       nb.Initialize(ChannelID)
       nb.AutoCancel = False
       nb.OnGoingEvent = True
       nb.DefaultSound = False ' sound
       nb.DefaultVibrate = False ' vibrate
       nb.DefaultLight = False
       nb.ContentTitle = Title
       nb.ContentText = Content
       nb.setActivity(TargetActivity)
       nb.SmallIcon = Icon
       nb.ShowTime = False
       nb.Number = nID       
       ' //set the return object for the notification object (n1) in this service
       n = nb.GetNotification
   Else
       n.Initialize
       n.Number = nID
       n.Light = False
       n.Vibrate = False
       n.Sound = False
       n.OnGoingEvent = True
       n.Icon = Icon
       n.SetInfo(Title, Content, TargetActivity)
   End If
   n.Notify(nID)
   Return n
   
End Sub

From my discussions with Erel, it you create 1 background service correctly and you need to launch an other long running service DO IT FROM your primary service. The reason being, when you launch other services they inherit the properties of the parent service, also they will not try to create a new notification which is important.

Give it ago and see what happens

Regards

John.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
also turn doze mode off

B4X:
Sub dozemode_off()
   
   Dim p As Phone

   If p.SdkVersion>=23 Then
        Dim JavaObject1 As JavaObject
        JavaObject1.InitializeContext
        Dim Ignoring As Boolean=JavaObject1.RunMethod("isIgnoringBatteryOptimizations", Null)
        If Ignoring=False Then
            Dim JavaObject1 As JavaObject
            JavaObject1.InitializeContext
           JavaObject1.RunMethod("ShowPermissionDialog", Null)
       End If
   End If

           
End Sub

I have this in my activity resume, so if the user turn it off, you can request it on again.

J.
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
Thank you. I have added a timer that make an http request every 5 seconds. Not tested for long time but looks like it works.
But I have not solved my problem....
I need to receive realtime firebase notifications, that are actually delayed also of several minutes when the device sleep.
Ignoring battery optimization has no effects. Also disabling doze mode via ADB has no effects.
So I was thinking: If I make a second app with a background service that make a dummy http request every 15 seconds I have chanches that in that window the device wake up and the primary app can receive notifications. But It isn't ...
I will try to implement this background service in the same primary app, but I feel it will not work as I need.
Probably it is better to abandon firebase notifications and manage a persistent communication with my server and generate local notifications when needed.
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
do you think a 10 seconds timer (that would be an important but acceptable delay) has few chanches to survive forever ?
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
I mean a timer that make an http request to my server and generate a local notification if needed (based on what the server reply).
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
Basing on the "background location tracking" tutorial and the other info in this thread, I have put togheter the app that make an http request to my server every 10 seconds and have the answer back.
As I told above I didn't test it for long time but looks like it continues to work when the devices enter in sleep.
Do you say I'm wasting time because sooner or later the app will be killed ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Do you say I'm wasting time because sooner or later the app will be killed ?
Please note that Android is user/Google/Device manufacturer centric, not developer (with never versions of Android, the developer will lose more and more control. See this latest nugget of info: https://www.b4x.com/android/forum/threads/startactivity-from-service.108771/#post-679735) If one of the former three want to kill your app, your app will be killed. Not only that, your app may not even be notified of the fact that it is being killed and therefore you cannot "catch" that event (even with the workaround I pointed out in this post https://www.b4x.com/android/forum/t...don’t-kill-my-app-”.101495/page-2#post-640096).
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
sigh .... it's very frustrating not to have any solution to obtain instant notifications. There are so many people complaining about this.
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
Try to send a Firebase notification after some minutes the screen device is off, not moving, not charging. You will experience delay also of 2/3 minutes in receiving it.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
Try to send a Firebase notification after some minutes the screen device is off, not moving, not charging. You will experience delay also of 2/3 minutes in receiving it.

I do not use Firebase, we have developed out own messaging service(B4J). This maybe Firebase not your app. We have built a number of app's, all using background task, one in particular is our version of whats-app for corporation's and to-date since releasing it have not experienced any delays in sending for receiving messages, even though a phone may be on a desk for hours, not plugged in, not charging. As I said before we do use Firebase, so I suspect either your background service is not setup correctly or it is a Firebase issue.

Do you have a small project you could upload to demonstrate how you are doing your background task. Please do not post code, just upload a project.

Thanks.
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
Thank you.
I don't think it's a firebase issue. Notification to IOS device are always instant, within a couple of seconds. Notification to older Android version also are instant. Notifications to recent Android devices are instant if the device is working but can have long delay after some minutes the device is in sleep.

But now, because me too have my own B4J server, I would like to know how did you do to setup your messaging service.
Does the device use background service with a timer (which interval ?) that communicate with your server ?
If yes, what do you think about what Erel and OliverA say in this thread ?
 
Upvote 0
Top