I'm developing Android app with background service. Service is running in its own process (like com.example.app:extProccess). Service creating WebSockets connection. But after less than 1 min after service started there is a disconnection on WebSockets, but service is alive (not killed by Android). After 20-30 min a connection is recovering.
Seem like device entered in Doze, but very soon.
This is observed only on some Nougat devices.
If I prevent battery optimization (android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) for this app service and websockets working correctly without disconnects.
My question is why Android limits network so quickly if my app in foreground? So how to hold networking for background service in this case without using android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS?
Starting from Android API 21(Lollipop), Google started giving more focus on battery optimisations. The problem comes is any service. One way to overcome this is to use Job Schedulers for your background tasks(documentation available here). Also, any task that uses android resources a lot will be terminated by the Android Framework. The only solution for your particular use case is to either optimise your code or use "IGNORE BATTERY OPTIMISATIONS" as done by you.
Related
My main app supports different hardware attachments. It ranges from RFID readers to stepper motors controllers.
Because the app is quite independent and the scenarios where attachments are used is rare, I have decided to remove all the code from the main app and move it to services which are installed on specific devices.
The services used to communicate using the Intents.
Recently the devices running the app were upgraded to Android 8 and I can no longer use a background service as I used to because it's killed after a few moments.
I went through the docs in here: https://developer.android.com/guide/background
It seems I should use the Foreground Service, however when searching for more info about foreground services I have found that it is not a suitable solution for long-running processes (the RFID reading process runs from boot to shutdown).
When developing the first solution a while back I have decided not to use the Bound services as they are far less convenient than just waiting for the incoming intents.
I don't mind at all the notification icon, I actually like it as it will allow us to easily see what's running and what's not when interacting with a device.
I just don't want to invest time in rebuilding the app and then ending up with something that does not work.
What should I do to make sure that the service will run indefinitely and will not be killed? I will not be able to monitor it from my main app and restart when needed.
I am developing an application in which we maintain a mqtt connection to the server to receive jobs from server in real-time.
Currently we are using an approach in which we use a foreground service to keep the connection alive even when the app is killed.
The problem is that the long running service drains battery so fast. And also I'm not sure how it is gonna react in devices from different vendors.
For example in Xiaomi devices, if the auto-start setting is not enabled for the app, the service can not start in foreground when the application gets killed. I've solved this problem, but I'm not sure if it is going to work on all other versions of MIUI and other vendors.
Beside I've read that newer android versions are going to use machine learning algorithms to put battery consuming applications to sleep.
So I'm looking for another solution instead of foreground service. So I'm asking is it possible to implement this scenario with WorkManager? Is it a good idea to use WorkManager instead of foreground service? Is there a better solution for this?
Currently we are using an approach in which we use a foreground service to keep the connection alive even when the app is killed.
Android ensures that foreground Services keep running and if killed, starts them again soon. However it's required for foreground Services to post a sticky notification that for an always running background app, it may be annoying. There's another way! You can request Android to ignore battery optimizations for your app. Ignored battery optimizations apps are exempted from Android O+ background restrictions and can start normal Services (not foreground Services) at any time.
The problem is that the long running service drains battery so fast.
The Service doesn't drain the battery, it's the network activity that drains the battery. The network activity comes from the MQTT keepalive property. Also note that battery consumption depends heavily on the underlying network transport technology too. WiFi uses less power, but cellular networks use much more power. So, in order to maintain a reliable connection to the broker and also lower the battery usage, you should trade off the keepalive against battery usage. Here's a good article to tune the keepalive parameter:
Power Profiling: MQTT on Android
So I'm asking is it possible to implement this scenario with WorkManager?
No, WorkManager jobs are one-shot jobs, Android schedules them and runs them at a particular time in the future. In the meantime, your app's process may be killed and the broker sends you a message, then you'll receive the message when your JobService starts again, so that's not real-time anymore, it's now polling not pushing.
In my current application for a company Im having a ForegroundService that is running while the workers are on duty (logged in to the app).
It is important to keep that foreground service running while users are logged in. To recover from cases where this foreground service gets killed somehow (User task swipe accidently or System kill) ive implemented a periodic JOB with Jobscheduler which reactivates the ForegroundService in case it gets shut down. This technique works well pre Android 8 OREO. START_STICKY and other techniques alone did not do the trick for me.
In Android 8, as soon as the foreground service gets killed, the periodic job gets killed as well. Im getting the notification in logcat that the job is not allowed to run. To my understanding, Jobs schould be able to run even when app is in background or killed. And its working on pre OREO devices the way it should.
To my knowledge, I can fix that by enable the option "autostart" in app settings. But since there is no way to know if employees tunred that on, its not a reliable thing as well.
So my questions:
- Why does the Job scheduler stops working as it should in Android 8?
- Are there any other reliable techniques I could use to let my ForegroundService recover from shutdowns in ANDROID OREO?
Ive read https://medium.com/exploring-android/exploring-background-execution-limits-on-android-oreo-ab384762a66c but that did not answer my questions
Thank you very much
did you try to put
.setPersisted(true)
Note: Requires the RECEIVE_BOOT_COMPLETED permission.
you can also see this question.
Job Scheduler not running on Android N
reading some references:
1- The services in andreo oreo if posses a buggle oreo will kill it for energy loss in 7 is a warning but in 8 applies more strict
2 - The jobs scheduler has a time of 15 minutes and avaces is not executed in the precise time debit that they look for the precise moment to execute the event without that the battery of the cellular one is descaste
I recommend that you use this library that provides evernote that is very good and very specific:
https://github.com/evernote/android-job
I am developing multiplayer game using Socket.io library. it Works Well.
But, in android 7.0 and above, system automatically suspend all network work when my app is in background. (And I must need to keep alive my socket connection).
I research about it as described here.
but, i can't understand. So, Please provide solution for that.
Unfortunately there's bad news and some good news for you on this.
Bad:
Since android marshmallow and above, there's a concept of a doze mode. If the device stays put for some time (can't confirm the duration for this and not disclosed by google), the device will go into doze mode and will suspend all network activity. There will be short maintenance windows where in you will be able to do syncs and stuff. Small workaround, do not target 23+ apis, i say small because i have observed this to not work on some phones. Another way to potentially bypass this would be to whitelist your app from battery restrictions but according to google guidelines, i don't think your app will qualify for that.
Worse news is that start from API 26, background services will also get suspended completely when app is totally backgrounded and has no visible component (a notification or a foreground service etc...). So oreo will be worse.
Good:
You might not really want to constantly keep the socket open. Instead opt for bursts of syncs. I personally have a job run every 30 - 60 mins or so to try and sync up.
You can leverage the JobScheduler apis and it will automatically handle the doze modes and stuff and you can make them run periodically when there is internet connection. While the job is running, you can connect to your server, do your thing and shut the socket. This is what google wants and is pushing all devs towards.
UPDATE 19-Apr-2021
WorkManager is the new and the best way to deal with doze mode and background limit restrictions.
Another alternative would be to have a foreground service with an active notification displayed which would constantly be connected via your socket. This will be visible to the user and it will not only annoy them that you are constantly using their data, it can also be bad for the battery. Alternative to this again is using the job scheduler to schedule and run a foreground service periodically so as to be transparent while also syncing your data every once in a while. The latter approach is what WhatsApp does, they have a job running which syncs all incoming messages with a foreground service once in a while.
In Short:
You will not be able to keep it alive always. You can try doing it in bursts using one of the methods that i described and know currently (maybe there are other alternatives that i don't know, i have tested these and they work) You will have to compromise, sorry.
I am working on an application related to Voip & IM (chatting application). Till android OS 5.0 it is working good and no issues from client also. But from android OS 5.1.1 onwards we are facing issues.
Issues:
If the app is in foreground and if device goes to sleep mode it is working good.
If the app is in background and if device goes to sleep mode after 10 minutes all the services are stopping automatically.
Testing:
For testing I created one timer task to print logs for every 1 minute. So when I close the application (means if the app is in background)
Till android OS 5.0 logs are printing continuously.
From android OS 5.1.1 onwards after going to sleep mode, after 10 minutes logs are not printing. Timer task is stopping
Same problem I am facing for my application also.
After doing some R&D I came to know regarding doze mode and app optimization. Is it anyhow related to stop services automatically running in background.
If yes, can anyone please let me know how to overcome this issue.
This is new thing which google done to prevent unwanted battery usage.
For new versions the background services are restricted for better battery life. The android service consumes almost same as the application running in foreground. So even though app is not running its services may be running and using memory and battery.
If you have to use any kind of background process try to use Job Scheduler which may be something useful for you.
The Job Scheduler groups the task and execute the background task based on the constraints we provide in the implementation.
This have a limitation it support on minimum API 21
To support on lower version you can use Firebase JobDispatcher which support from API 9.
I personally prefer Firebase JobDispatcher
This link help you to understand more about scheduler and its implementation.