I am working on an application in android that starts a service on BOOT_COMPLETED. Everything is working fine, but while logging some messages I noticed that after I kill the application it starts up again anywhere from immediately to a minute later.
The only receiver that could be starting the service is registered to BOOT_COMPLETED. So my question is why is my application starting up on it's own after the phone has already booted up.
From the Android Site:
Broadcast Action: This is broadcast once, after the system has finished booting. It can be used to perform application-specific initialization, such as installing alarms. You must hold the RECEIVE_BOOT_COMPLETED permission in order to receive this broadcast.
To my understanding this event should only ever be broadcasting once so what else could be causing this event.
Edit: This is the code I am using in my BootReceiver (extends BroadCastReceiver) to start the service. This code is not duplicated anywhere else.
Intent serviceIntent = new Intent(context, RandomToneService.class);
context.startService(serviceIntent);
To check should I override it and Log it?
Not necessarily, but you need to read about services and their lifecycle.
What you are doing by swiping away the app from the recent-tasks list is the same thing that Android would do when your process gets terminated due to low memory conditions. A Service can request to Android that it be automatically restarted in those cases, and that is done through the return value from onStartCommand().
The default return value from onStartCommand() for a Service is START_STICKY, which tells Android to restart your service sometime later when there is memory. The default return value from onStartCommand() on an IntentService is either START_NOT_STICKY or START_REDELIVER_INTENT, depending upon whether or not you called setIntentRedelivery() and what you supplied there.
Hence, if you do not want your service to be automatically restarted in these conditions, you need to do something to get onStartCommand() to return START_NOT_STICKY, either:
Call setIntentRedelivery(false) on your IntentService, or
Override onStartCommand(), chaining to the superclass for default behavior, but then returning START_NOT_STICKY
Related
I have a Service which handles downloading a list of simple files which it receives via the intent upon creation. I stop the Service once all the items have been downloaded. However if the System decides to kill the Service, upon recreation (because of START_STICKY) I will receive a null intent (http://developer.android.com/guide/components/services.html#START_STICKY). Is there a way to continue on where the Service was stopped without having to manually persist the list.
You could use the flag START_REDELIVER_INTENT, which will call again the onStartCommand method of the service with the last sent intent if the service's process is killed before it calls stopSelf. Anyway I don't know how and what your service exactly does, so it could be that you still have to save in a persistent way some information.
I was using a service which will update my application whenever new update is available in server. So my service run and it always check with server for version update and if i get new version update it will install.
My issues whenever i closed my application form taskmanager my service is getting killed. I used START_STICKY in onstartcommand() also even though it is not working. Is their is any chance to restart my service once it is stopped by taskmanager.
You can use AlarmManager to periodically wake up your application (i.e. activity or a service). This way you won't need to run service in the background all the time.
Just set AlarmManager to wake your app/service every day/week, check for an update, and then close the service. Check out this tutorial on how to use AlarmManager.
This approach will be better than running your own service, because it'd use no memory or battery power. Your users will thank you for that!
If your application is designed to run on API level 21 or newer (which means Android 5.0 Lollipop), you can also take advantage of JobScheduler. It might be useful, i.e. it could schedule update check to run when device is plugged in, to further save power.
From the docs:
Notice that the onStartCommand() method must return an integer. The integer is a value that describes how the system should continue the service in the event that the system kills it (as discussed above, the default implementation for IntentService handles this for you, though you are able to modify it). The return value from onStartCommand() must be one of the following constants:
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.
Have you tried to return the onStartCommand() with START_REDELIVER_INTENT ?
You can owerride this method onTaskRemoved to start service again via BroadcastReceiver.
For example, I create a Service and using the onStartCommand method I return START_REDELIVER_INTENT. This means that if the service didn't finish handling the Intent, then the Service will be scheduled to be restarted with that same intent until that intent is completely handled. If this happens, but the phone is rebooted before the phone has a chance to restart that service, will the same intent be delivered to the service the next time the service is started (after the phone has rebooted, or the next time the user runs the application that created the service)? Or will that intent disappear and never be handled by that service?
EDIT: I was able to test it and the answer is that the intent disappears and does not get handled by the service. One more thing I noticed while testing is that if an application is FORCE STOPPED by the user, then any Intents that were not handled will never be handled by the service, whether or not the phone goes through a reboot. Even though the service can be restarted by manually opening the app again, the previously unhandled Intents will still not be handled, only new intents will be handled after the app is manually started.
I have a Service running in the foreground, and an Activity that interacts with it. If the Activity crashes, Android kills the entire process, including the foreground Service and its associated Threads.
However, the ongoing notification provided by the Service does not go away, and upon closer inspection, Android's task manager reveals that the Service itself is still running.
How can I kill the foreground Service in this circumstance?
Have you override onStartCommand method of the Service? What value is it returning? If not, try to override it and return START_NOT_STICKY from it.
START_STICKY: If this service's process is killed while it is started, then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service.
START_NOT_STICKY: If this service's process is killed while it is started, and there are no new start intents to deliver to it, then take the service out of the started state and don't recreate.
Not sure, as I have never worked on foreground services, but this might be the reason.
Are you sure the service is not running it its own process...
Also can you confirm whether the service is getting restarted..If its getting restarted-it is because you are returning START_STICKY from onStartCommand()
I have a service that has started by startService and binded with BIND_AutoCreate , I want my service runs automatically when android kill it for low memory , how can I implant that ?
thanks'
If the service is created because of the BIND_AUTO_CREATE binding, it will be stopped if it does not have any activities bound to it.
According to the docs (service lifecycle), you can both start explicitly a service and then bind with the autocreate flag enabled.
If you start explicitly the service as STICKY (returning START_STICKY in its * onStartCommand* method, it will be automatically restarted back whenever the system has more resources.
You have to register broadcast receiver for the ACTION_DEVICE_STORAGE_OK which indicates low memory condition on the device no longer exists. In the onReceive() method check your service if it is stopped, start it.
The DEVICE_STORAGE_OK action is broadcast when the device has recovered from a low memory state(internal memory). I think this is a perfect event for you to check if your service was killed during memory recovery by the system, and start it if was killed.
Please read documentation here.