I'm building a music streaming app for Android.
In this app, I have a Service which is responsible for playing audio from an HTTP server. Before playing, I make sure to startForeground() and acquire a partial WakeLock, so that my service isn't killed. I also get a WifiLock, just in case.
The service works fine... as long as my phone isn't on "battery saving mode". The minute I turn on battery saving and disconnect my phone from power source, my service is killed with fire!
Unfortunately it doesn't even seem that onDestroy() is called, so my notification from startForeground() stays visible, even if the service is dead.
The phone is a Samsung Galaxy S6, with Android 6.0.1 on it.
Two questions:
Is there a way I can keep the service alive despite the battery saver thingy?
If not, I'd like to know at least when my service is killed, so that I can do a bit of cleanup (remove notification & internal stuff).
Any suggestions?
This is possible by using a foreground service in a separate process holding a partial wakelock.
android:process="process_name"
(documentation: http://developer.android.com/guide/topics/manifest/service-element.html)
Note that you shouldn't use SharedPreferences in a multi-process environment.
See also this issue: https://code.google.com/p/android/issues/detail?id=193802
Related
It has been observed that when android 4.4 device is gone in sleep/stand by mode then application background service is forcibly stopped by Android System.
I tried below things:
Started service with START_STICKY
Made service as Foreground service
Used Work Manager
But nothing worked so far. Please suggest if any other options could be checked.
In order to bring your app to the foreground, you must call startActivity() from another context (either a Service or a BroadcastReceiver). Just calling startActivity() from within an Activity won't bring your app to the foreground.
You don't need the ACTION and CATEGORY in your Intent, but you do need to set Intent.FLAG_ACTIVITY_NEW_TASK.
Have you tried using wake locks in your background service.
From the documentation :
If you need to keep the CPU running in order to complete some work
before the device goes to sleep, you can use a PowerManager system
service feature called wake locks. Wake locks allow your application
to control the power state of the host device.
Note: Using wakelocks causes battery drain, go through the
documentation and use alternatives such as WorkManager if this work
can be deferred.
References :
https://developer.android.com/training/scheduling/wakelock
https://developer.android.com/reference/android/os/PowerManager.WakeLock.html
I have written an VPN using android's VPNService and it works perfectly. When I run it, it creates a foreground service and sends all traffic through my VPN server. It also has an internal reconnecting mechanism to reconnects VPN server if it disconnects for any reason without stopping service itself.
I like to have this VPN service working all the time. But my problem is that this VPN service is stopped occasionally after a completely random period(sometime it takes just 10 minutes, but other times it works for 2-3 days before stopping).
Since the stopping time is completely random and I cannot find any place in code that creates this situation (I have been debugging for weeks), I thought maybe android OS itself stops my VPNService for some reason. I wonder if there is a way to detect if system has stopped my service from outside or not. Any idea?
Unfortunately, Android OS still can terminate the service in low memory and possibly other situations, even if it's a background running service !
It is not only Android, but all Mobile Operating Systems optimize RAM usage by killing background apps.
This is done so that the foreground app can be given top priority. It ensures smooth functioning of the current app and reduces load on the system.
There's are two approaches as mentioned in this post: Background Service getting killed in android
If you are implementing the service, override onStartCommand() and
return START_STICKY as the result. It will tell the system that even
if it will want to kill your service due to low memory, it should
re-create it as soon as memory will be back to normal.
If you are not sure 1st approach will work - you'll have to use
AlarmManager
http://developer.android.com/reference/android/app/AlarmManager.html
. That is a system service, which will execute actions when you'll
tell, for example periodically. That will ensure that if your service
will be terminated, or even the whole process will die(for example
with force close) - it will be 100% restarted by AlarmManager.
I had this issue previously and I've solved it by creating the service running forever even if it's killed manually or from the system it recreates itself.
So I've made an Android video-calling app that tries to be available in the background so that the user may receive calls when the screen is off. I've noticed however that the app would be paused when the device went to sleep.
The solution I've found that worked was to rewrite everything to a service and then request a wakelock so the service wouldn't be paused during sleep.
Surely, since there are so many of these types of apps, there is a more elegant way to do this? A periodic check wouldn't work since you would want to take the call in real-time.
It depends on the Android version, for version older than 6 a partial wakelock is enough to keep the device awake, for Android 6 you also need a foreground service, that's a Service that calls startForeground() and shows a notification, but to keep the device awake has a big impact in battery usage.
You do not necessarily need to transfer all the code to the Service due it is the whole application that stays awake.
A more elegant solution to replace all this would probably be to use Push Notifications, it is what most messaging applications use. Firebase has Push Notifications.
This is similar to another question I asked where I was wondering how other apps like drupe dialer keep their service running forever when it is not in foreground. Because I've used job services, alarm manager, START_STICKY and everything else to try to keep my service alive but it always gets stopped by the OS.
You can run the service as "Foreground" and it will be not candidate to be killed by the system under low memory conditions. The gotcha is that you will need to show that behavior to the user with a notification. This is the way that music players uses to go background and alive when you start another apps.
Foreground Services
The app you mentioned (Drupe Dialer) is a Dialer. It might be listening to broadcasts and turning the service up every time by checking whether its up.
To answer your question, you need to keep the service started as START_STICKY to make it restart after the OS kills it. But AlarmManager does not work at device sleep states, and doze will stop it from running in the background nevertheless.
The real question is; WHY you want to keep it running? That might answer your question on HOW you want to do that.
If its a communication type app, you will need to use something like
GCM.
If its running background work based on some event, you might
want to start the service inside the BroadcastReceiver.
etc.
it depends on what app you're writing.
I have an app that plays audio streamed from a server (or locally).
According to what we've seen*, if playing audio through a background Service, the audio will keep playing. However, some users report that the audio will stop when their device goes to sleep. I haven't seen any documentation on audio behaviour while sleeping, definitely the API docs don't mention anything: http://developer.android.com/reference/android/media/MediaPlayer.html . Are there any guarantees that the MediaPlayer will continue playing while sleeping, and if not, should I enable the WAKE_LOCK while playing?
*(and this question seems to support it: Playing music in sleep/standby mode in Android 2.3.3)
I don't think setting the wake lock will matter, in my experience it has nothing to do with keeping a service alive. The Android Service documentation states that services that don't use the startForground() method can be killed to free up memory. It's likely the service is either being killed to free up resources or an exception is causing it to silently crash.
If you app goes into the background, it can be killed by the OS. This is most likely what is happening. You can reduce the chance of this happening greatly by making your Service a foreground service by using startForeground(). A wake lock will not help. Under intense memory strain, your foreground service may be killed, but this is very unlikely when the phone is asleep.