Reputation: 657
I've read that I should call
startForegroundService(intent)
if I want to properly start a service that can run as a foreground service. But how should I think if I want it to start without it being a foreground service but potentially becoming one later on? Some info on how we have it right now:
We have an App which uses a service for many tasks. It performs all of these task when the user interacts with the app in the foreground but depending on if the user has enabled a certain feature we want to keep performing these tasks in the background. So when the app is launched (and obviously is in foreground) we start the service using
startService(intent);
When the app transitions into background we check whether the feature is enabled, and if so, run startForeground(id, notificiation);
which effectively adds the non-removable notification out in the OS and the service keeps on running. When the app goes back into foreground we call stopForeground(true)
. If the feature isn't enabled the service will never be set as a foreground service and we won't try to perform these tasks in the background.
So my question is: Is this sufficient to get the "full foreground service performance"? Or am I losing something by not calling startForegroundService(intent)
? My impression is that we actually do have a fully working foreground service but I'm getting confused when I read statements that foreground services must be started using startForegroundService(intent)
which we're not doing. If we really need to use startForegroundService(intent)
, the only solution I can think of would be to initially start a normal instance of the service and when the app enters background we start a new one using startForegroundService(intent)
. But do we need to do this or is running startForegund(id, notification)
on a service started using startService(intent)
sufficient to achieve a foreground service?
NOTE: One difference I find is that if the application itself is in background when start the service I then need startForegroundService(intent)
for API >= 26. In our case we always start the service when the app is in foreground. I do however recall some instances where I've seen the exception thrown when we try to start the service using startService(intent)
, somehow the app (very very rarely) still think it's in background (perhaps something from the OS comes up just when app is launched). So if I catch when that happens I could run startForegroundService(intent)
to start the service. But is it possible to run stopForeground(true)
on that service when the app comes back into foreground? Or is it bound to be a foreground service forever since we started it that way?
Upvotes: 2
Views: 4543
Reputation: 2243
Seems like you don't have to call startForegroundService
and startService
is sufficient:
If your service is started (running through Context#startService(Intent)), then also make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state. By default started services are background, meaning that their process won't be given foreground CPU scheduling (unless something else in that process is foreground) and, if the system needs to kill them to reclaim more memory (such as to display a large page in a web browser), they can be killed without too much harm. You use startForeground(int, Notification) if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing.
From Documentation
Upvotes: 1
Reputation: 1695
I read your question multiple time and I think (hopefully) the answer to your question is :
According to the official document of Android 8.0 Background Execution Limits:
Android 8.0 introduces the new method startForegroundService() to start a new service in the foreground. After the system has created the service, the app has five seconds to call the service's startForeground() method to show the new service's user-visible notification. If the app does not call startForeground() within the time limit, the system stops the service and declares the app to be ANR.
So, make sure you have started ongoing notification by calling startForeground (int id, Notification notification) in the onCreate() method of your service.
Note: Apps targeting API Build.VERSION_CODES.P or later must request the permission Manifest.permission.FOREGROUND_SERVICE in order to use this API.
And there is great medium article posted by Maciej Witowski that help you understand how really new services API works : https://proandroiddev.com/pitfalls-of-a-foreground-service-lifecycle-59f014c6a125
Upvotes: 0