Long network operation on Oreo - android

In my Android application the user has an option of using the application in offline mode. When the user opts to enter the offline mode, I download all the content from the server(which might take even upto 7 minutes) for offline usage. The usage of the application henceforth is dependent on the download of offline content.
I am using a service to download the offline content. But the service may not work in Android 8 if the app goes to the background. So what is the best approach to download the offline content for Android 8? Is it a foreground service or JobIntentService or a WorkManager?

Anything that is backed by JobScheduler — which includes JobIntentService and WorkManager — has a 10-minute limit. You indicate that your work may take up to 7 minutes, which makes me somewhat nervous.
In the short term, make your existing service be a foreground service, as that will keep your code working (other than any problems that Doze mode might impose).
If your 7-minute download work is really a series of smaller things that add up to 7 minutes, you might eventually migrate to WorkManager. Divide your work into smaller chunks and set up chained work with WorkManager, so you are certain to not go over the 10-minute limit for any of those chunks of work. Plus, WorkManager lets you establish constraints to say that your work should only be performed if you have an Internet connection. Right now (late August 2018), though, WorkManager is only 1.0.0-alpha07, so I would not ship a product based on WorkManager until it at least reaches a 1.0.0 final version.

The best approach would be to use WorkManager. As stated in the docs that:
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, or downloading data from server.
The benefits of using WorkManager over services includes handling of doze, standby, battery optimizations and constraint execution etc.
You can schedule a worker with WorkManager to download data for your app from server, and once data is available, you can go on with your offline mode.

Related

Android recommended and reliable API for periodic background work?

I've been using WorkManager to create notifications for my app. For my purposes I figured PeriodicWorkRequest is the most fitting, but after a bit of testing and reading online it's seems extremely unreliable. Using the minimal interval (15 minutes), and the app being closed, the worker woke up 5-6 times and then seems to be killed.
So how does one go about creating background work that wakes up in reasonable time intervals? What is the best approach for creating event-based notification? My idea was checking for the event (for example, checking for something new in the database) in small time intervals (with 15 minutes also being less than ideal), but seeing as it doesn't work well with PeriodicWorkRequest and is also the recommended approach as per the documentation, what exactly are my options?
Basically, the idea of Android is for you not to be able to do what you want to do because we as developers try to kill the battery.
You need to see how the evolution of the restrictions goes:
Version 6 - Doze:
https://developer.android.com/training/monitoring-device-state/doze-standby
https://developer.android.com/about/versions/marshmallow/android-6.0-changes#behavior-power
Version 7 Another state of Doze with even more restrictions:
https://developer.android.com/about/versions/nougat/android-7.0-changes#perf
Broadcast Restrictions:
https://developer.android.com/guide/components/broadcasts
https://developer.android.com/about/versions/nougat/android-7.0-changes#bg-opt
Version 8.0 Background execution limits:
https://developer.android.com/about/versions/oreo/background#services
Version 9 StandBy Buckets - where depending on how the app is used you have different resources to use - like time to wake up the app, time to use the Network, etc
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 Save improvements:
https://developer.android.com/about/versions/pie/power#battery-saver
Power Management Restrictions - really important.
https://developer.android.com/topic/performance/power/power-details
Version 11 and 12 App hibernation
https://developer.android.com/topic/performance/app-hibernation
Long story short - you need to prevent all these restrictions to harm your work. But you need to comply because it is better for the user.
But there is no API that will just say - "f**k all these restrictions and do whatever the dev wants to do."
If you need exact timing - you need AlarmManager.
If you do not know when you need to do your work and depend on the outside - Push Notifications which then can transfer the work to the WorkManager.
If you need periodic work that is not time-critical - you might not use the AlarmMangaer and be sure that the work is finished, but you can't be sure when, because there are many restrictions and the priority will be saving the resources.
Also, you can ask the user to be exempted from Battery Optimization:
https://developer.android.com/training/monitoring-device-state/doze-standby#support_for_other_use_cases
If you want to know why exactly the work is not executed you need to check the JS dump and see what restriction is not satisfied:
https://developer.android.com/topic/libraries/architecture/workmanager/how-to/debugging#use-alb-shell0dumpsys-jobscheduler

Background accumulated tasks executed periodically

I am devolping an Android App that need to execute an accumulation of internet tasks periodically (like a web bot). Those tasks need to get stored at a specific time so I thought about using Alarm Manager and a
embeded Database. Due to it, the app could be active much more time, although those save tasks do not need web connection. Later I will throw another Alarm Manager to execute all the tasks queued and do web stuff.
Otherwise I am not sure if it is better to use a foreground service. The app will be working all the day saving the tasks (each 5 or 15 min) but only running task queue with internet each 30mins.
I feel capable of developing both systems but I would like to know which one is better in terms of performance, of battery consumption.
Thank you very much.
Only a recommendation try to find and use a nice library to do it, every Android Update change something about foreground/background servicess.
one is
TimedDog
and for more
enter link description here

Proper way to tackle and resolve "Excessive network usage (background)"

Problem Background
Currently, we have facing "Excessive network usage (background)" from Android Vital report. Last 30 days is 0.04%, but we're only Better than 9%
Last 30 days - 0.04%
Benchmark - Better than 9%
Since only better than 9% looks like a scary thing. We decide to look into this issue seriously.
The app is a note taking app (https://play.google.com/store/apps/details?id=com.yocto.wenote), which provides an optional feature - sync to cloud in background after the app close.
This is how we perform sync to cloud in background.
We use WorkManager.
In Application onPause, Schedule OneTimeWorkRequest, with constraint NetworkType.CONNECTED. The worker is scheduled to start with delay 8 seconds.
In case failure, we retry using BackoffPolicy.LINEAR, with delay time 1.5 hours.
The maximum number of retry is 1 time. That's mean, after the app close till the app re-open again. The maximum number of execution, of sync to cloud process is 2.
The size of data is vary, can be few KB till few hundred MB.
Additional information how we perform sync
We are using Google Drive REST API.
We are performing downloading of a zip file from Google Drive App Data folder, perform data merging in local, then zip, and re-upload the single zip file back to Google Drive App Data folder.
The zip file size can ranged from few KB, to few hundred MB. This is because our note taking app supports image as attachment.
Analysis
The only information we have is https://developer.android.com/topic/performance/vitals/bg-network-usage .
When an app connects to the mobile network in the background, the app
wakes up the CPU and turns on the radio. Doing so repeatedly can run
down a device's battery. An app is considered to be running in the
background if it is in the PROCESS_STATE_BACKGROUND or
PROCESS_STATE_CACHED state.
...
...
... Android vitals considers background network usage excessive when an
app is sending and receiving a combined total of 50 MB per hour while
running in the background in 0.10% of battery sessions.
We start the background sync job, 8 seconds after Application's onPause. During that period, will the app inside or outside PROCESS_STATE_BACKGROUND/PROCESS_STATE_CACHED? How can we avoid running inside PROCESS_STATE_BACKGROUND/PROCESS_STATE_CACHED?
What does it mean by "running in the background in 0.10% of battery sessions."? How can we avoid such?
Another assumption, is sync file is too large, and using too much data. Soon, we notice this assumption might not be true. We notice according to "Hourly mobile network usage (background)", the data size is from 0MB to 5MB.
Questions
My questions are
What is the actual root cause for such "Excessive network usage (background)" warning? How can we accurately find out the root cause.
How does other apps (Like Google Photo, Google Keep, Google Doc, ...) which perform background sync, tackle this problem?
For your first question, "Excessive network usage (background)" is triggered when:
... an app is sending and receiving a combined total of 50 MB per hour while running in the background in 0.10% of battery sessions. A battery session refers to the interval between two full battery charges.
Source
To identify what is causing this, try using Battery Historian to analyse your app's battery usage over time. For us, it helped identify a repeating wakelock we didn't intend to introduce.
Here's an example of the output, showing us that excessive BLE scanning is causing a major battery impact:
For your second question, WorkManager is likely what you are after, as you correctly identified. This allows you to schedule a task, as well as a window you'd like it to occur in. Using this allows the OS to optimise task scheduling for you, along with other app's jobs. For example, instead of 6 apps all waking the device up every 10 minutes for their hourly task, it can be scheduled to happen for all 6 apps at the same time, increasing the time spent in doze mode.
Notice the screenshot above includes a "JobScheduler Jobs" tab. After running an analysis you'll be able to see how your jobs are actually performing:
I've previously used Firebase JobDispatcher with great success (tutorial I wrote), which extends the OS' JobScheduler API and is ultimately similar.
I see you're using WorkManager now (Jetpack's version of JobDispatcher), but with 8 seconds there's no chance for the OS to optimise your jobs. Is there any capacity of scheduling them with a minimum of a few seconds, and as large a maximum as possible?
Further improvements
However, your current task scheduling setup may not be the root cause. Here's a few additional ideas that may provide the battery improvement you need. The usefulness of them will become clearer after you've run Battery Historian and identified the root cause:
Consider whether wifi-only is a feasible default / option for data syncing. You'll experience better battery usage, fewer network issues, and likely better customer satisfaction.
Why does a note taking app need to sync a few hundred MB? Can you perhaps just sync the note that has changed, instead of the entire list of notes every time?

Why Using the JobScheduler API?

What is JobScheduler ? which type of android apps using this JobScheduler and why ? Please feedback with real example so that I could understand.
Here is a short summary:
1) AlarmManager.- Use it to post a notification or set off an alarm at a very specific time. Use this for executions that do not depend on condition.
2) JobScheduler.- Allows you to have execute jobs based on conditions. This is recommended if your app targets API>21.
3) JobDispatcher.- Similar behavior as JobScheduler, used as a JobScheduler-compatibility layer if your app targets versions lower than API<21. Note that this needs internet for real time execution, any task not executed because of internet not being available will be executed when internet becomes available.

Schedule a task on iOS every 15-30 mins

I have an application that i have developed for ios, android and windows phone 8. The client now requires that the application checks if there is any data to be uploaded to the server every 15-30 minutes and if so, upload it. This is needed because the application is used in areas where there will not be an internet connection. The user adds data into the application and that data needs to be uploaded to the server once an internet connection is available
I have implemented this on android using the AlarmManager to schedule the application to check if there is any data and upload it, and on windows phone i used a PeriodicTask.
Is there such functionality in iOS? When i try googling this, i get many different things appear like NSURLSession, Background Transfer Service and others that say it ain't possible.
So, it is possible and what classes do i need to look into to get this working? If i have to aim at a particular iOS version then that is fine.
You can use NSTimer:
[NSTimer scheduledTimerWithTimeInterval: 1800.0 target:self selector:#selector(yourselector) userInfo:nil repeats: YES];
Apple documentation
No, this is not possible, well may be. Since only specific apps can run in the background like: AudioStreamer, VOIP, Accessory companion or location tracking.
These apps can't really schedule a task. Also it would be really bad for the battery to check some server every 15-30 min.
You can use NSURLSessions to create an uploading task that will run on the background.
You will have to setup the session correctly with all the delegate methods implemented: Background Transfer Considerations.
There are mainly 3 things to consider:
1.) Will the app remain active (visible on the device screen) for 15-20 mins. I suppose that won't be the case.
2.) When the app enters background state (not visible on the app screen, but is in the background), you can perform/schedule tasks for a maximum of 3 minutes.
3.) If the user kills the app (the app is not in background mode) then you cannot do anything.
NSTimer *yourTimer = [NSTimer scheduledTimerWithTimeInterval: 1800.0 target:self selector:#selector(YourMethod) userInfo:nil repeats: YES];
please try this ... this will work...
The upload task supports background operations by default (refer : https://developer.apple.com/reference/foundation/urlsessionuploadtask).
But that is limited to as long as the app is in memory. This is to ensure no app consumes battery without absolute NEED.
What you can do is upload in the background mode and check for pending upload data every time you launch your app.

Categories

Resources