I'd like to know more about the setForeground() method in the Service class.
Can any one explain it in detail?
setForeground() is deprecated, and I think simply does not work on newer versions of Android. You want the newer startForeground() instead.
Quoting myself from one of my books:
However, some services will be missed
by the user if they mysteriously
vanish. For example, the default music
player application that ships with
Android uses a service for the actual
music playback. That way, the user can
listen to music while continuing to
use their phone for other purposes.
The service only stops when the user
goes in and presses the stop button in
the music player activity. If that
service were to be shut down
unexpectedly, the user might wonder
what is wrong.
Services like this can declare
themselves as being part of the
"foreground". This will cause their
priority to rise and make them less
likely to be bumped out of memory. The
trade-off is that the service has to
maintain a Notification, so the user
knows that this service is claiming
part of the foreground. And, ideally,
that Notification provides an easy
path back to some activity where the
user can stop the service.
To do this, in onCreate() of your
service (or wherever else in the
service's life it would make sense),
call startForeground(). This takes a
Notification and a locally-unique
integer, just like the notify() method
on NotificationManager. It causes the
Notification to appear and moves the
service into foreground priority.
Later on, you can call
stopForeground() to return to normal
priority.
Related
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?
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
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
I am working on an application which need to show notification constantly.
I've a service to show the notification every seconds.
When the resources goes low android is killing my service.
I've given the return START_STICKY from onStartCommand().
So after some time the service is getting restarted.
But in the mean time the notification look stoped.
I red somewhere that it is possible for a service showing notification prevented from getting stoped by android. I dint get any example for it.
Use
startForeground(int,Notification);
in onCreate of service. It requires a notification number and a notification object which it will display in the notification bar.
To remove the notification, use
startForeground(0,Notification);
As written above you need to use startForeground(int,Notification) method to aware user about your service. It also get more privilage for it.
You can read more about it here (example inside).
There is no way to completely stop it from ever being killed. Making it a foreground service helps. Returning start_sticky means it will be restarted if it is stopped (so it should do a startService on itself in its onCreate to make sure it restarts and not just gets recreated). But Android has the right to kill any service at any time due to resources.
Update:
You can use Foreground Service in the scenario. From the docs:
A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
In my knowledge there is no bulletproof way of preventing your service from being stopped by the android system. If the device is critical on memory/resources then your service has to be stopped for GC. This is also not recommended because your service will drain the device battery.
I am developing an app which will keep track of the time when a user's phone is "not used".
Basically, an app which gets activated as soon as a user presses unlock or in the event of an incoming call. I have written a BroadcastReceiver which notifies a background service to start keeping track of time during which the phone is not being used, and will show the activity as soon as the user presses to lock.
My problem is that the services sometimes gets shut down without notifying. Can I write one more service which can periodically check whether the master service is running and toggle it in case it's shutdown? Or is there any other better way to do so?
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
Yes you can start another services within your service. Actually you always do this but you are not aware of it. I mean when you call getSystemService(....) initializer in your service , you use another service which is declared by android.
i am not that experienced but yes you should be able to start another service by sending an intent to the other service if you like, service may be killed by the system if it is under heavy memory pressure according to http://developer.android.com/reference/android/app/Service.html.
You should be able to check if your service is running or not.
I'm looking into implementing an over-Bluetooth video streaming service for Android.
How can I ensure that:
the service runs with a high priority? I'd like to minimize latency.
the service is low of the list of things to be killed when memory is tight?
There are two important things you need to do to make sure your service keeps running:
Make sure you call startService() instead of (or in addition to) binding. This will make sure that the service continues running, even if the Activity that created it is killed.
Use startForegroud() to run the service in the foreground, so that Android won't reclaim it when memory is needed. It requires that you also create a Notification that gets published when the service actually starts, putting an icon in the notification area and letting the user know your service is still running.
For more information:
http://developer.android.com/reference/android/app/Service.html
http://developer.android.com/guide/topics/fundamentals/bound-services.html
If you are/were in the same situation as me, being forced to use bindService(), the solution was to set the
Context.BIND_IMPORTANT
flag in that call. That raises the service's priority to that of the binding app, which if it is the foreground app, is the highest possible. If you don't use that flag, the service needs to fight over a measly 10% of resources with all the other background services. (the other 90% are reserved for the foreground app).
Note that manually setting the service's thread priority, without setting this flag during bindService(), makes no difference.
I am currently writing my first Android application and I keep running into references to background and foreground services. Since I intend on using a service in my application I was hoping to get a clarification between the two and how they are used.
Perhaps this will answer your question:
A started service can use the startForeground API to put the service
in a foreground state, where the system considers it to be something
the user is actively aware of and thus not a candidate for killing
when low on memory. By default services are background, meaning that
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.
More info can be found here
Foreground: The process relies on onPause() and onResume()...i.e you play music player and pressing pause and play
Background: The process which runs without user interaction i.e receiving a message, incoming call, receiving mails, or setting alarms. The method used here is onStart() and onStop().
For example, check it on your phone. Create an alarm at 6:30am. When the system clock reaches 6:30am it fires. In order to kill the alarm service, just go to menu-->settings-->application-->Running service-->click stop service. It stops the alarm service even when your system reaches the time it won't fire.
Foreground Service is used when User is interaction with application and when Service is doing something visible to user. Background Service is used when even user close application (discard from recents) and when Service is doing something not visible to user like downloading data from server, load data from a ContentProvider etc.. And Foreground Service is less likely to be killed by system on low memory.