Recommend a realiable way to continue running after the app is closed - android

I am recording output from a accelerometer.
Can anyone recommend a reliable way to monitor onSensorChanged after the app has been closed (running the app in the background).
WorkManager
I have experimented with WorkManager. WorkManager appears to run only when the app is open. I read that this may be device specific as some devices force stop the app on close or otherwise prevent background tasks from executing once the app is closed.
sticky-notifications
I am curious about using sticky-notifications, although this would not be my first choice. I am now researching this option. I have noticed a few apps which implement this option. The downside is the sticky-notification can be viewed as annoying and the user may disable sticky-notifications.
Other options?

You should use a service if you want to run in the background. But probably the Android won't allow it because keep listening to a sensor in the background will consume too much battery. Mainly on Android P that is more rigorous with battery consumption.

WorkManager is not the right solution in this case as a Worker has an execution limit of 10 minutes, then it's stopped by the OS. But, time limit aside, WorkManager has been developed for other use case, so using for something like this (using some hack to reschedule a worker when you're close to the 10 minutes limit) seems a fight against the library design. To have an introduction behind the use cases that WorkManager is designed to solve you can take a look at this blog: Introducing WorkManager.
A Foreground service is an option, but I'm afraid that continuously monitoring the sensor can have a very bad impact on the battery life of the device. For more information on the available options, to run code in the background, your can check this blog: Modern background execution in Android
An alternative, depending on what you need to do with the sensor data, is to use the Activity Recognition API:
You can tell the API how to deliver results by using a PendingIntent, which removes the need to have a service constantly running in the background for activity detection purposes. Your app receives the corresponding Intents from the API, extracts the detected activities, and decides if it should take an action.
March 2021 Update
There have been a couple of updates since I originally wrote this answer:
WorkManager v2.3.0 introduced support for longer Workers with the option to "promote" them to Foreground Services using setForeground() for CoroutineWorkers and ['setGoregroundAsync()][5] for all kind of Worker`s. This is allows to overcome the 10 minutes limit and is documented in Support for long-running workers.
Android 12 is planning to introduce some changes to Foreground Services and this has some impact on WorkManager. The new v2.7.0, currently in alpha, is adding the concept of expedite work to provide support for Android 12 in a backward compatible way.
Overall, I still think that having your app monitoring the sensors while in background is going to have a bad impact on the battery of the device and you should look for alternatives.

Related

Which is better alarm manager or workmanager

I want to show notification at certain time and day by using retrofit2 networking.
But in alarm manager doc. It mentioned that isn't proper fpr networkong job. But in workmanager doc it says for the exact time job use alarm manager. What would be better for me to use? Alarm manager nor work manager
Android has introduced so many things that need to save battery life like:
Doze version 1 - API 6.0
Doze version 2 - API 7.0
https://developer.android.com/about/versions/nougat/android-7.0-changes#perf
Removing CONNECTIVITY_CHANGE Manifest declaration and others in - API 7.0
https://developer.android.com/guide/components/broadcasts
Background execution limitations in API 8.0
https://developer.android.com/about/versions/oreo/background#services
App Standby Buckets API 9.0 (Upgraded in Android 12)
https://developer.android.com/about/versions/pie/power#buckets
https://developer.android.com/about/versions/12/behavior-changes-all#restrictive-app-standby-bucket
https://developer.android.com/topic/performance/appstandby
Battery Saver improvements in API 9.0
https://developer.android.com/about/versions/pie/power#battery-saver
https://developer.android.com/topic/performance/power/power-details
App Hibernation in 11 and 12 API.
All this stuff were not done for us to be able to do whatever we want by using the WorkManager. WorkManager was created to integrate all this requirements in a single API.
That is why the idea behind it is:
do some work
finish it at some point for sure(even if the device is restarted)
SAVE THE BATTERY AND NETWORK USAGE BY COMPLYING WITH THE ABOVE
Before that you had the AlarmManager to wake up in exact time
Services to keep the app process alive by giving your application priority. You still have them with the exclusion that now the starting services in the background are problematic. As per:
https://developer.android.com/about/versions/oreo/background#services
So if you want to do things like this you need to fully understand the Android API and limitations.
If you need help in StackOverflow - you need to fully understand your use case, you should have really put your mind into trying to understand it, communicate all these limitations with your PMs and explain to them that the Android Ecosystem is pretty complicated, there are a lot more applications besides the one you are writing and they all compete for resources. We can't do everything that we want. It is highly unlikely for the user itself to want to do long-running operations in exact timing starting from the background. But it might need it. Also, you have the option to ask to be exempted from battery optimization:
https://developer.android.com/training/monitoring-device-state/doze-standby#support_for_other_use_cases
Also, some people try to use Push notifications, but it is highly unlikely that it will work in your case. You can send high-priority ones, but if android detects that the user is not interacting with the notification they will lose its priority. And if you do not have the priority and also want to do a long-running operation - you need to create... a Work in the WorkManager :)
But long story short:
what will wake you up:
AlarmManager is exact
WorkManager is not
what will keep you alive:
Service
WorkManager(it uses its own service)

Foreground service vs WorkManager for location tracking

Let's say I want to build an app which requests current location periodically (e.g., every 10 minutes, this number should be configurable) and submits to a server.
I'm aware that Foreground Service and WorkManager are normally suggested for this kind of scenario. However which is would suit more? Below are my thoughts and doubts.
WorkManager - is mainly for deferrable background work whose execution is guaranteed. However I know that from Android 8 (API 26) background location was introduced and that restrict location to be updated only a few times every hour https://developer.android.com/about/versions/oreo/background-location-limits. Thus this perhaps doesn't meet the periodical updates as per the requirement.
ForegroundService - is perfect for something that runs and needs to make users aware of. It's recommended for this kinda scenario (location tracking) for privacy purpose. Google also creates a sample app to promote this practice https://github.com/android/location-samples/tree/master/LocationUpdatesForegroundService.
From the above analysis, it seems ForegroundService is the one. However I also found that WorkManager has a built-in support to use Worker in conjunction with ForegroundService via androidx.work.impl.foreground.SystemForegroundService https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running#long-running-kotlin
That makes me confused as to what should I use and what Google really recommend for this specific scenario.
Anyone has any idea?
If you want to communicate somehow with the service then use foreground service and if you want to have some processed input based on something else you did in that work manager then choose work manager.
Work manager doesn't have option to redeliver intents and all other commands like start sticky etc...
Since work manager is more suitable for syncing data with db, processing a file etc..
If you were to ask me, I'd choose foreground service since you can add a type location to the xml tag when you register it in the manifest.
Both of these solutions don't survive OEMs aggressive battery restrictions since WorkManager's work can be deferred and if I want instant execution combined with wake locks I can easily do it in the foreground service since it also has a binder option that works well for UI sync.

Best approach to achieve guaranteed repeating background work Android

I'm in the process of developing an app which would mainly just be doing background work to read data from a nearby BLE (Bluetooth Low Energy) sensor every 15 minutes (if Bluetooth is not switched on, it'll need to prompt the user to switch it on from the background service) and sync the data into the server once a day. I'm not sure of which approach would be most suited to do the background work as I need to have guaranteed timely execution of the background tasks as that's very critical to the purpose of the app.
I've looked at the following approaches:
Using a ServiceIntent instant with a WakefulBroadcastReceiver. But I found out that WakefulBroadcastReceiver has been deprecated and there has been more restrictions to run background work since Android O.
AlarmManager
JobScheduler
WorkManager (seems to be a good candidate but it's still in alpha and It doesn't seem to be production ready)
Any help will be much appreciated.
Thanks
My suggestion is to use WorkManager even in alpha. I am alredy use it for similar task and it works. First time i started to use it, there where crashes, but after new version become released no more crashes occurs. Google provide a good support to its library, so use WorkManager since its the best option for background tasks execution.

Should a WorkManager be used with a SyncAdapter?

Previously one could assure a series of updates using an IntentService or SyncAdapter w/ a WakeLock.
Now with the new Doze mode, and limitations to save battery, is WakeLock still reliable enough, or should longer processes be started in the IntentService or SyncAdapter using WorkManager?
Also is WorkManager api production-ready?
As far as I understand it, the WorkManager can replace IntentService and SyncAdapter completely. E.g. everything you're doing in SyncAdapter.onPerformSync() can now be in WorkManager.doWork().
It got a stable release 2.4.0 and is ready for production.
Regarding wake locks: In Android 8.0 there is the following change:
As one of the changes that Android 8.0 (API level 26) introduces to improve battery life, when your app enters the cached state, with no active components, the system releases any wakelocks that the app holds.
So I wouldn't rely on wake locks anymore. I think they will be completely removed in future Android versions. And most of the time you don't need them with the WorkManager.
I wouldn't bother using JobScheduler or AlarmManager. WorkManager sits on top of these, and handles everything for you, doesn't matter what android version your app runs on.
https://codelabs.developers.google.com/codelabs/android-workmanager
Here's a good example about WorkManager, where they use a Worker for image processing, but it's perfectly good to do any long-running tasks.
You can specify constraints on various things, including if you want the device to be idle to run the worker. You can also chain the workers, pass data from one to other, even group them and run some parallel, wait for all to finish and then continue with another (or more) worker(s).
Depending on your use case, you can basically start a worker from anywhere (activity, broadcast receiver, stc).
In fact I use workers started from a broadcast receiver to do some api calls, only when you have internet connection of course (settable constraint) and it's so easy to set up and works so well, I only can recommend it to use (and bless Google for finally making these AC libraries).
I also really like the fact that the WorkManager saves works to db with room, so it can pick it up whenever all the conditions check out, even if you restart the device between. If you have some monitoring set up (like for example stetho), you can actually see how it saves the jobs to its own database.
It's still in alpha, but it's so solidly built, I don't think they'll change too much until they release the final version.

How to keep alive socket connection in android 7.0 and above?

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.

Categories

Resources