Alternative for alarm manager for periodic background tasks - android

I need to allow user to use my app even if network is not available and make server calls when network is available. I am using alarm manager-broadcast receiver- service pattern. I periodically retry to make api calls. I also added the boot receiver. But when user kills the app using overview screen, the alarms are not triggered again. Is there a better way to implement this common scenario?

You may use:-
1. JobScheduler
2. SyncAdapter
These will help you in case of periodically retry to make API calls

Related

How call webservice in every hour if internet connected to device

I want to call web service in the background when internet is connected. If it is connected I want to call in every one hour if internet is turned off then stop the service. How can I? It needs to work for all versions from 16 to 27.
There is broadcast in android which notifies you if network status changed. In there you can register alarm manager for a period of one hour and check if the internet was connected then call the web service.
If broadcast informed you the network was disconnected then you can cancel your alarm manager.
Here is documentation for listening to network status change:
https://developer.android.com/training/monitoring-device-state/connectivity-monitoring
and here is good tutorial about using alarm manager in android
https://en.proft.me/2017/05/7/scheduling-operations-alarmmanager-android/
also google introduced workManager which does this work for you in the very simple way
The WorkManager API makes it easy to specify deferrable, asynchronous
tasks and when they should run. These APIs let you create a task and
hand it off to WorkManager to run immediately or at an appropriate
time. For example, an app might need to download new resources from
the network from time to time. Using these classes, you can set up a
task, choose appropriate circumstances for it to run (like "only while
device is charging and online"), and hand it off to WorkManager to run
when the conditions are met. The task is still guaranteed to run, even
if your app is force-quit or the device is rebooted.
here is link to documentation :
https://developer.android.com/topic/libraries/architecture/workmanager

what is the best practice to use for background tasks?

I have a use-case where, whenever a transaction is completed or failed, I have to wait in background(not going to freeze the UI) for 5 minutes and call a piece of code without user intervention. So AFAIK I need to implement Background Service for this.
I want to know which would be better for my scenario.
Workermanager ( JetPack )
Jobscheduler ( for API 14 - 21, Firebase JobDispatcher)
IntentService
And in Oreo and above, if I run background service will it show in the notification that the App is running in the background?
Now the recommended way to do background processing would be Jetpack WorkManager API. I will cite official documentation for the reasons:
WorkManager chooses the appropriate way to run your task based on such factors as the device API level and the app state. If WorkManager executes one of your tasks while the app is running, WorkManager can run your task in a new thread in your app's process. If your app is not running, WorkManager chooses an appropriate way to schedule a background task--depending on the device API level and included dependencies, WorkManager might use JobScheduler, Firebase JobDispatcher, or AlarmManager. You don't need to write device logic to figure out what capabilities the device has and choose an appropriate API; instead, you can just hand your task off to WorkManager and let it choose the best option.
In addition, WorkManager provides several advanced features. For example, you can set up a chain of tasks; when one task finishes, WorkManager queues up the next task in the chain. You can also check a task's state and its return values by observing its LiveData; this can be useful if you want to show UI indicating your task's status.
So instead of worrying every time which background processing to choose (as every task has it's recommended and appropriate way), you can simply use WorkManager and it will do it's job.
This is considering the following gotcha:
WorkManager is intended for tasks that require a guarantee that the system will run them even if the app exits, like uploading app data to a server. It is not intended for in-process background work that can safely be terminated if the app process goes away; for situations like that, we recommend using ThreadPools.
P.S. As WorkManager API is using JobScheduler, Firebase JobDistpacher or AlarmManager under the hood, you must consider minimum API levels for used functionality. JobScheduler requires minimum API 21, Firebase JobDispatcher requires minimum API 14 and Google Play Services.
For the full documentation check: https://developer.android.com/topic/libraries/architecture/workmanager
For your second question: as far as I know you will always see that notification, as it is notifying user that your app is consuming battery. The notification may be disabled by the user from settings in Android Oreo 8.1.
Going forward, the official android documentation suggests that you use a JobScheduler in place of a background service.
In many cases, apps that previously registered for an implicit broadcast can get similar functionality by using a JobScheduler job. For example, a social photo app might need to perform cleanup on its data from time to time, and prefer to do this when the device is connected to a charger. Previously, the app registered a receiver for ACTION_POWER_CONNECTED in its manifest; when the app received that broadcast, it would check whether cleanup was necessary. To migrate to Android 8.0 or higher, the app removes that receiver from its manifest. Instead, the app schedules a cleanup job that runs when the device is idle and charging.
https://developer.android.com/about/versions/oreo/background#services
WorkManager is probably (eventually) the solution you are looking for. It acts as an abstraction, deciding whether to use JobScheduler (if it's available) Firebase JobDispatcher (if it's available) or falling back to a default implementation otherwise. This way, you get the best of all worlds. It's still in alpha, however, so you may want to at least consider other options.
If you choose not to use WorkManager, a combination of JobScheduler and JobDispatcher is probably appropriate (see here).
However, if you target devices without Google Play Services below API 22, you will need to use another solution. In that case AlarmManager may be what you are looking for, since you need a delayed task with guaranteed execution. Using an IntentService for this is possible, but not as easy. It involves introducing a delay mechanism of some kind, of which there are several choices.
Note that since you are using a batching mechanism if you use one of the Job APIs or WorkManager, you will not see a notification in Oreo. AlarmManager/IntentService based solutions may show a notification, but likely not for very long, since the tasks are fairly short. This is especially true for AlarmManager.

Intentservice in JobScheduler's context

In our app, we have periodic sync tasks. So we have implemented Job scheduler to fire every sync interval. When the job gets fired, we are starting an intent service and this job gets killed. Intent service starts the 3rd party sync from internet/Server
Questions:
Is this design ok for Oreo and Nougat?
If the intent service takes few mins to complete, will the system allow?
Ref: Medium link
If your job inent service depend on network restriciton you need to set setRequiredNetworkType as there are some new changes done in oreo developement for job scheduler you shold opt for that part as per your flow please take in to account that
Calling setRequiredNetworkType defines network as a strict requirement for your job. If the network requested is not available your job will never run. See setOverrideDeadline(long) to change this behavior. Calling this method will override any requirements previously defined by setRequiredNetwork(NetworkRequest); you typically only want to call one of these methods.
When your job executes in onStartJob(JobParameters), be sure to use the specific network returned by getNetwork(), otherwise you'll use the default network which may not meet this constraint.
for more details go to this source of the above answer https://developer.android.com/reference/android/app/job/JobInfo.Builder.html#setRequiredNetwork(android.net.NetworkRequest)

Best Practice for network operation at regular intervals?

I am making an application which contains performing network calls to look for updates. Can anyone help with some best practices to perform this task. I can make a service to run on background and perform network operation using Handler at regular intervals but this would consume a lot of data and battery. Is there any other way to do this?
Use an AlarmManager or JobScheduler (depending on API level), and pick a sane frequency. Doze mode will stop you from going too insane.
You could work with Push Notifications from any server when the backend recognizes an update. It's better for the server itself to listen to updates at a regular interval of time rather than the app, because of the reasons you listed.
When the app receives a push notification, it would mean that it needs updating.
There are a couple of options for you:
Azure Notifications Hub: https://learn.microsoft.com/en-us/azure/notification-hubs/
Firebase Cloud Messaging: https://firebase.google.com/docs/cloud-messaging/

How to use rx java's interval for background task

According to https://github.com/ReactiveX/RxAndroid/issues/257#issuecomment-164263215 . interval is just for active code, and if app is not wake up, it will not work. So how to use interval for background scheduling tasks?
Please DO NOT use this solution:
To use interval from RxJava you'll have to make sure your app's process stays alive. One way to do it is to put use the Observable in a foreground service. This is a bad idea because the service is NOT actively delivering value to the user. Waiting for time to pass is not delivering value for the user. Again please DO NOT use this.
AlarmManager and JobScheduler (or it's backport GcmNetworkManager) are far better choices for repeating background activities. If you use AlarmManager.setInexactRepeating() the system can batch jobs from multiple apps together to save battery. Using JobScheduler enables you to execute your background jobs in specific conditions, eg. when the device is connected to the internet or when battery is more than 20%. (Internet is required to check the weather).
interval from RxJava does have it's usage on Android. It's an excellent replacement for Runnable.postDelayed for relatively short durations. It makes the code shorter and more readable.
If you need to schedule a task that should be run even if app is not active anymore then use AlarmManager.
If you need to schedule a task that should be run only when app is active then you can use Observable.interval() and react on emission to execute some code and please don't forget to unsubscribe from the Observable when appropriate (when Activity is paused, etc) so app won't burn the battery!

Categories

Resources