How to set the priority of android service? - android

Is there any way to set the priority of android service? I want to run the service in background after destroying App's main actvity. So i am returning "START_REDELIVERY_INTENT" from my service. But restarting of service is taking some time (around 1-3 minutes). I want to restart the service instantly. Is there any way to set the priority of android service.
FYI, I am creating service using startService and passing an object through intent.putExtra().
Below snapshot is taken from setting/apps/running apps by my android device, which shows that app is restarting... My app is real time specific, so i want to restart it instantly...

You cannot control this behavior of Service as it depends on the OS and available resources. However, for a continuously running background service, I would suggest you to return START_STICKY - which tries its best to re-run the service once its destroyed due to any reasons.

The priority depends on the component type and the current app that the user is using. The highest priority have the current Activity that is displayed to the user and all foreground services. Foreground services must have a notification that cannot be dismissed. To create a foreground service you have to call startForeground(...) method from the Service itself passing the id of the notification and the Notification object itself. You can use the id if you want to update the notification later.
I recommend you to make the service bound and bind your activity to the service. This way the you can start and stop the service in your onResume and onPause methods.

The only way to increase service priority in this case is to make it a foreground service.

Related

Having an Android service as both background and foreground service

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

Are bound services always foreground?

I need to start a foreground service for my app so that it keeps running and is unlikely to be killed even if the app is in the background. The is a method for this, startForeground.
I also need to communicate with the service, so I gather the easiest option would be to bind to it (I am planning for it to run in the same process to be able to just cast the returned IBinder to my class and just call methods on it). However, nowhere can I find information about bound foreground services.
Reading through the docs and tutorials I found information that one of the flags tobindService is https://developer.android.com/reference/android/content/Context.html#BIND_NOT_FOREGROUND to prevent the service from getting foreground priority.
Does this mean that by default every bound service is also a foreground one, and it needs notifications and the like (the docs never actually mention it so I guess not)?
If my app uses a foreground service, can the app be killed while in the background?
Well, let's talk about services. Service can be started, bound and both of them. So you actually can make startService() and make startForeground() after it, but when you're going to bindService(), you can remove notification and make service not foreground (seems like flag BIND_NOT_FOREGROUND for this situation). Bound service is not foreground by itself (they have priority of component that are bounding to service). As i know to make foreground bound service, you can't just call startForeground() (it will not work, no notification will be added in status bar), so the only way is to make startService() and in onStartCommand() handle action that will do only startForeground().
So by default bound service isn't foreground, you don't need notification. Your app can be killed in any time by the system or by user in app's settings (Force stop), but if you want to let system know that your service is really important for user and app, you make it foreground so system will not touch it until system has enough memory for your process.

Keep Android service running even after Activity is closed

I am building one of those SOS apps. Whenever the device is shaken above a threshold value (detected through accelerometer), I am showing a Toast (as of now)
1) App is launched. User gives name, email, etc.. and clicks finish on last screen.
2) Service is started which keeps listening for shake.
3) It detects the shake correctly if the App is running.
4) If I close the app (the activity), the service gets killed along with it.
How do I keep the service running even if app is closed, so that it can listen to shakes from background? (That's the whole purpose of this app)
[1.I am returning START_STICKY in onStartCommand
I also tried using a BroadcasterReciever which will restart service by receiving broadcast from onTaskRemoved
I am testing on ASUS Xenfone Max, Marshmallow OS
]
You have two options:
Start your service as foreground service (with startForeground(int id, Notification notification): docs. But in this case you will have to show Notification in notification tray for as long as your service is running
Use separate process for your service adding in manifest to your process android:process=":nameofyourprocess"
Try starting a service without binding it to the activity (Simple unbound service). Return null on your onBind() function. Sticky services attach itself to a activity and has a lifetime as long as the attachment survives. You might have a constant notification related to your application when you use foreground services.
You can put a Service in foreground, in which case it will always be considered as active (and it will therefore have its own notification, so the user knows that an active Service is running). It won't be stopped until it goes back to background. That is what you want in your case, as you want your Service to stay alive as long as possible. As described in the Android Service documentation:
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.
The idea is the same for Activities and Services, actually: when Android needs memory, it starts killing processes. The foreground processes (e.g. the Activity that is displayed on the screen, or foreground services) have a higher priority than the ones that are in background (say, a paused Activity), so they will be the last ones to be stopped by the system.
Using START_STICKY just tells the system that if it has to kill your Service, then you'd like it to restart it can. That doesn't say this Service is higher priority than the others.

How to prevent android service getting killed (Service with notification)

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.

can I start a service from another service in android?

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.

Categories

Resources