I'm trying to write a Service which sits and waits for SMS messages (using a BroadcastReceiver which the server registers) and will take some action depending on the details of the SMS message. I use an Activity to startService() and stopService() for the Service. After I close the Activity, the Service continues to sit there with its state kept and its BroadcastReceiver waiting, as it should... However, I find that over time, randomly, the Service will restart itself. That is, onCreate() and onStartCommand() will be called even when the Service has already been started. This happens sometimes when my phone sits idle overnight...
Can anyone provide insight on why this is (phone requests resources and kills a service?), what I can do to prevent it, or what I can do to prevent the state of the service from being lost?
Thanks in advance.
I don't think you need to start service from activity at all. Have a broadcast receiver that listens to your SMS messages and starts the service. After work is done, service should call stopSelf();
I'll try Service.startForeground()
Android sometimes (when it's low on resources, mem/cpu) removes running services and once it's high on resources again brings them back. This is why you see that your services has been restarted a couple of times during night.
Related
It always seemed some sort of black magic the way other apps keeps their services always running, but mine gets killed by the system every time.
My app should keep a TCP socket open to the server and send/receive data when it becomes available, so it has to stay always on.
This is what I have tried so far:
1) Running the service in another process using this line (also with an additional line stopWithTask):
android:process="package.name.custom_process_name"
android:stopWithTask="false"
2) Restarting the service when these methods get called:
onTaskRemoved()
onDestroy()
3) Add return START_STICKY to onStartCommand() method
4) Check if the service is still running when these events happen:
android.net.wifi.WIFI_STATE_CHANGED
android.net.conn.CONNECTIVITY_CHANGE
- Here I am stopping the socket connection to the server if the device does not have internet connection anymore and reopening it when it gets a connection.
Yet, my service always gets randomly killed (sometimes after few hours, sometimes after few days) by the system and doesn't restart automatically until I reopen the app.
How does other apps, say chat apps for example, keep their services available all the time?
P.S.: Having a persistent notification would be the least of options.
Override onDestroy() in your service, whenever your service destroys create Alarm using AlarmManager. When alarm trigger start your service again.
Second way is not recommended or proper way but create a separate service AlwaysAliveService which will do nothing but will remain available in android system.
Say I have an Activity that launches a Service using startService() when user presses a button. The service is stopped using another intent in startService() when user presses another button, or it can decide to stop itself. The service wants to run forever, so it returns START_STICKY from onStartCommand(). While the service is running, it connects to some server and receives messages. Activity binds to it and, when bound, displays those messages.
Now, when the Activity is started after an OOM kill, it doesn't know if the Service is started. One can use a static field set in onStartCommand() to tell if the Service is running, but that's prone to backfire sooner or later. Moreover, the Service can be started by the system after the activity has been launched, so using a static field is not an option at all.
The cleanest solution I can come up with is using SharedPreferences to store the state of the service. This is going to fail to be good when the service is killed between SharedPreferences.setBoolean("running", false) and stopSelf(), but such a thing will probably occur rarely.
Also I can try to bind to the Service at all times. This would be very ugly but still not impossible.
Any other solutions? Maybe the very idea is wrong in some way?
I wrote an app which monitors my signal strength via a PhoneStateListener. I want this app to start up at boot time and run forever.
The way I managed this is as follows, but I'd like to know if anyone can recommend a better way of doing this.
I have registered a BroadcastReceiver which runs upon BOOT_COMPLETED.
Within this BOOT_COMPLETED BroadcastReceiver, I start a Service.
The Service starts up my PhoneStateListener.
Within my BOOT_COMPLETED BroadcastReceiver, I also start a periodic alarm via AlarmManager.setInexactRepeating.
Whenever this alarm fires off, it checks if my Service is running. If it's not running, it restarts my Service, which in turn restarts my PhoneStateListener.
This all seems to be working for me, but I'm wondering if it's the best and most efficient way to ensure that a PhoneStateListener is running all the time (or at least most of the time).
Is there perhaps a better way to manage this?
Thanks in advance.
You can make your service a foreground service, in this case your service is really unlikely to be killed (only if the currently opened app needs more memory).
In this case your app must show an ongoing notification to the user while the service is in foreground.
To do so, you must call the startForeground() method of your service, providing a notification to it:
startForeground(ONGOING_NOTIFICATION_ID, notification);
Check for more info: http://developer.android.com/guide/components/services.html#Foreground
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 have intent service in my app. This service has some job to do - uploading some files. It runs only when there is something to do.
Service won't upload when some conditions are met, for example no Internet connection. For that reason it registers itself to on broadcast receiver to receive message about Internet connection changes.
The problem is that service is killed with app even if it is doing something, for example:
App is sending intent to service
Service started uploading something, everything fine
X% uploaded, app is killed, service is killed
Internet connection changed - service is woken up.
If service is woken up after app is killed, why is it killed with the app? Is there any way to prevent killing service when app is killed?
I'm killing app manually. I know android could kill my service anytime and I don't want to prevent it. I just want to have this service running after user closed or killed app.
"It runs only when there is something to do." only theoretically :) - maybe that is you what you want to achieve.
"The problem is that service is killed with app even if it is doing something, for example:"
Of course, there will be cases when the user action will end your Service or Intent service.
This is a fail answer.
"Is there any way to prevent killing service when app is killed?"
It is just watch for "parental control" task protection" keywords in Google!
Because you used an intentService that mean the intentService will destroy once the activty destroy
so you have to use Service instead of intentService, so you can uplaod your file in the backgroud.
According to manipuation between the Service and the activty via broadcast receiver or to bind the service to activty.
Edit :
The Service may be triggered from any thread.
The IntentService must be triggered from Main Thread.
If you don't mind showing notification (in your case, you can for example show notification with upload progress), then in your IntentService (or Service) you can call:
startForeground(int id, Notification notification)
This should prevent killing your service when your application is killed.
From documentation: "You can set this flag 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."