I have a location service which I want to run at all times when the app is in the foreground, or in the background, but to stop when the app is closed (removed from the app tray)
My solution has been to start the service using START_NOT_STICKY and this seems to work, but I'm concerned by what the service documentation says about this command
START_NOT_STICKY says that, after returning from onStartCreated(), if the process is killed with no remaining start commands to deliver, then the service will be stopped instead of restarted. This makes a lot more sense for services that are intended to only run while executing commands sent to them. For example, a service may be started every 15 minutes from an alarm to poll some network state. If it gets killed while doing that work, it would be best to just let it be stopped and get started the next time the alarm fires.
So it seems that Android may kill off services when memory is low, and if using START_NOT_STICKY the service will not be restarted.
I tried using START_STICKY but this keeps the service running even after the app is closed.
What can I do to keep the service running at all times while the app is in the foreground or background, and stop after being closed, but without worrying about Android terminating it while the app is running?
Code here if it matters:
#Override
public int onStartCommand(Intent intent, int flags, int startId){
if (intent != null) {
extras = intent.getExtras();
// takes the messenger object and makes it local so when the messagereceiver sends an intent here, it won't overwrite the extras object
// and get rid of the messenger. Otherwise, getting an update from the notification controls would null out the messenger object
if (intent.hasExtra("MESSENGER")) {
Timber.e("MESSENGER ");
messenger = (Messenger) extras.get("MESSENGER");
}
}
return START_NOT_STICKY;
}
What can I do to keep the service running at all times while the app is in the foreground or background, and stop after being closed, but without worrying about Android terminating it while the app is running?
I'm not sure what "app tray" you're referring to or what exactly you mean by "closed" (Android apps are not things that are "closed", per se.
But, from your description, I'd think you want to do something like:
Start your Service when the user starts your app and bind to while the activity is in the foreground
If your activity is paused (or stopped), unbind from the service and start a foreground notification to keep the service alive and the user aware that it's still running
Instead of trying to detect when the app is "closed", which you can't really do, attach a "cancel" action to the foreground notification so the user can cancel it whenever they want
If that doesn't solve your issue, please elaborate on your use case and why you want to do this. I or others may be able to provide more / better / alternate suggestions with more specifics about what you're actually ultimately trying to achieve.
Hope that helps!
Related
I have coded a simple app in Android Studio. What it does is not important but it starts a Service with Context.startService(Intent i). Till now everything is allright BUT when I kill all tasks with my Task Manager of my phone the Service is killed, too and with it the notification ist creates! I don't understand why.
By the way: I used return START_STICKY at the end of my Service. And it has been started/sheduled by the Timer class with Timer.scheduleAtFixedRate(TimerTask task, int delay, int period). The Service has been started by my Main Application or by the BroadcastReceiver which received BOOT_COMPLETED. The timer has also not been canceled.
Hope you will pardon my english.
Services that are started with startService does not stop until an explicit call - stopService is done on that particular service. Another case when the service stops is when the phone needs more memory its stops the background services and applications. In your case, you are doing the exact same thing. Clicking on the kill all tasks clears the memory which is the exact thing that happens when phone is out of memory and wants more memory. In that case - services are stopped and sticky services are restarted. Now, how to handle the restart of the service properly, kindly search clearing memory stops services android and you will be shown a bunch of answers on stackoverflow !
This question already has an answer here:
Android Service run indefenitely
(1 answer)
Closed 7 years ago.
Can anyone explain me suppose I have an Accessibility Service defined by my application. It starts running when the Accesibility permission is given to the App. Suppose due to some reason memory issues the service is stopped. How can I make the Service start again cannot find any way to do it. Please help.
Thank u very much.
Hi Oblivion, I am new to asking questions untill today i used to just refer Stack Overflow :-) . Sorry I ll make sure I ll be putting the complete description. Now my problem.
I am thinking of two approaches
Start as Sticky service
Run the Service in a different process
first approach -> Suppose the app crashes and due to the fact it is sticky it restarts and due to some bug of previous crash it crashes again with some exception after that Android will not start the service
Posible Soln -> Make the Service logic as much error free as possible
second approach -> Run the Service in a different process as http://mindtherobot.com/blog/37/android-architecture-tutorial-developing-an-app-with-a-background-service-using-ipc/
and make sure you take all the solutions mentioned for first approach.
All these things I have done and it is solving my problem.
My original question is suppose I have bound a client to the Accesibility service and I have come to know that my Accesibility service is not running, is there a way by which I can fire an intent and tell Android to start my AccesibilityService.
I need to do this because I want to control the lifecycle of my Accesibilityand not Android.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
//your code!!!
// If we get killed, after returning from here, restart
return START_STICKY;
}
Change your return statement like above. It will restart your service again.
START_NOT_STICKY
If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.
START_STICKY
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.
START_REDELIVER_INTENT
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file.
we can return any of above, depends on our requirement.
Source:Here!!!
I have a function that reads the content of the Android clipboard every two seconds and communicates all changes with a remote server.
This works fine in the app is opened. But I need to be able to continue to log the clipboard changes after the app has been closed.
So I tried an IntentService but it doesn't appreciate long loops.
How can I run my infinite loop in the background?
I have a function that reads the content of the Android clipboard every two seconds and communicates all changes with a remote server.
Polling? You are doing it VERY wrong. You should use OnPrimaryClipChangedListener instead.
EDIT
communicates all changes with a remote server.
I just realised you are basically doing some bad things there and I am bit sceptical believing your users aware you literaly spying on them? Is your app in Google Play if so what's your app package id?
IntentService should be used to process single "request", from another application component, at time.
Use started service which should be more suitable for problem you describe. Started service runs until you manually stops it or until system gets out of resources and kill whole process.
Use START_STICKY as return from onStartCommand() method to automatically start it again when system kills it.
If you also start it in BroadcastReceiver with ACTION_BOOT_COMPLETED action service will be started after device boot.
Implement a Service and make it sticky by returning START_STICKY in onStartCommand (see Documentation):
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
I would like to start my foreground service when my application is closed.
I tryed OnStop() but it's not a good idea for me because it can trigger multiple times and i which it to run only one instance.
I tryed OnDestroy() but it's simply doesn't trigger since i'm only using one activity in my whole app and most of time it is being kill with the SWIPE.
Is there a way i can detect when my application being kill or close ?
Thanks!
Only one instance of the service will run no matter how many times you start it. Each time a client starts the service the onStartCommand method fires. return Service.START_STICKY; to have your service stay running in the back ground after your app exits. But be warned if things get busy and the phone needs memory your service will be killed and you'll have to restart it like #Onur suggests with a conservative periodic AlarmManager intent.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// the service is started so after all clients are unbound it stays
// running
return Service.START_STICKY;
}
You can add your services description in manifest.xml stopWithTask="false" and in your sevice override the onTaskRemoved (Intent rootIntent) to know when activity that started the service is stopped for API level 14 and later.
Or you can set an alarm for some periods to check if your application is still running using AlarmManager. You should be careful with this tho, because it might consume battery based on the period you choose.
Can I run a background service Indefinitely ? Will android kill my service if i run it for indefinitely ? How Facebook android application keep running in background for a long time ?? please help me to know about it .
You can use for that these features:
1) Auto-restart service after reboot (Start intent after Reboot)
2) Sticky service mode (http://developer.android.com/reference/android/app/Service.html#START_STICKY)
These features both helps to leave your service started all time as possible.
Android will kill your service if it's running out of memory, but you can do a couple of things to recover from it.
The first thing you can try is to use foreground services, a foreground service is a high priority services that won't be killed unless is completely necessary (note that these services increase battery consumption). You can find an example here using compatibility with older devices, otherwise you only need to call startForeground inside your service.
Another thing you can do is to use some flags in your service to restart it when it gets killed by the OS. You can use 2 different flags (depending on which behaviour you want to reproduce).
START_STICKY will restart your service with an empty intent so everytime you have to recover the data you need to run your service.
START_REDELIVER_INTENT in this case your service will be restarted with the last intent information (it could be that you run your service several times with different information when you want different behaviour).
The flags can be used as follows:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Do your service work
return START_STICKY; //or return START_REDELIVER_INTENT;
}
Depending on what you need use one or another.
Hope it helps :)
There's no way to absolutely protect a Service from being killed.
If you return START_STICKY from onStartCommand(), then even if Service is killed, android will try its best to start it again, when resources are free.