https://developer.android.com/about/versions/oreo/background#migration
As per document, Google allows only below things as a background processes,
Handling a high-priority Firebase Cloud Messaging (FCM) message.
Receiving a broadcast, such as an SMS/MMS message. Executing a
PendingIntent from a notification. Starting a VpnService before the
VPN app promotes itself to the foreground.
also,
While an app is in the foreground, it can create and run both
foreground and background services freely. When an app goes into the
background, it has a window of several minutes in which it is still
allowed to create and use services. At the end of that window, the app
is considered to be idle. At this time, the system stops the app's
background services, just as if the app had called the services'
Service.stopSelf() methods.
Under certain circumstances, a background app is placed on a temporary
whitelist for several minutes. While an app is on the whitelist, it
can launch services without limitation, and its background services
are permitted to run. An app is placed on the whitelist when it
handles a task that's visible to the user, such as:
Query is,
My App (targetSdkVersion 26), which needs to be download a large file(~100 MB) in background (a state, app not exist in recent list even). I have create a Service to achieve this, but as I am removing my app from recent, my download get stops. So, Google does really means, an app cannot execute a download process in background with targetSdkVersion 26?
Google does really means, an app cannot execute a download process in
background with targetSdkVersion 26?
It imposes restriction on executing a Service in background. However you can still get your job done in background.
Approach 1:
If it really takes very long to download your necessary data, you can make use of new WorkManager API.
As the documentation say, 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.
You can schedule a work which can be one time job or periodic. Moreover it also allows you to specify constraints, like internet connectivity required. This should be preferred for deferrable or asynchronous tasks.
Approach 2: Create ForegroundService
Alternatively, you can start a ForegroundService immediately and execute the task before terminating the Service. You might need to request for partial wake lock in some cases.
You can also look at my answer on this SO for more details.
Related
In my app, I am using ffmpeg-kit and execute a command that record/capture any stream using the internet and writes it to the device's internal storage.
This command or stream can run until the user stops. And from here you can get an idea of this task that this execution can be 10 min, 30 mint or even 1 hr or more depending on the user till he wants to stop or the stream it self complete. e.g: video ends
Now my constraints are regarding this task that the app runs this FFmpeg command in the foreground and background but doesn't need to run when the app is killed by the user or system.
This task is only present and running while the app is running either in the foreground or background.
So now I need a suggestion from experts on which android services are best for use in this case.
I run across a few of them...
IntentService, JobScheduler and WorkManager
I've thought of using WorkManager here but my work is not persistent here and neither I need to run the FFmpeg and record stream while the app closed..so WorkManager is not suitable for this scenario.
None of those is the right answer. IntentService isn't a solution, as background services get killed in 2 minutes. JobScheduler would have the same problem- processing time limitations. As would Workmanager.
What you want is a foreground service. Foreground services are services that can run for long times (they will still also be eventually killed, but can run for hours). Foreground services are launched by using startForegroundService instead of startService, and require the Service to call startForeground and provide a notification that will be in the status bar as long as the service is running.
I have read many posts state that doze mode killed a running service at a particular moment e.x link or that they want to execute a long running thread.
I can't understand why you should use a service to do a background job that you know that in some point it will stop eventually.
For instance:
You could use a simple Thread:
new Thread(new Runnable).start()
and do some work in it. Using this:
In combination with a wake lock, device wont sleep and thread will keep running.
No doze mode restriction (except network but lets say we do local stuff)
So you can do background work with no restriction whatsoever. Although you should use services for these reasons link.
Is this another way (not better of course but a way nonetheless) of doing a background work? Am I wrong?
There are a lot of ways to do a background job aside of services check this link it may help you pick the best option for your work :
Job Scheduler vs Background Service
And services as #TheWanderer said will continue to work event after the app is closed for a period of time unlike a simple thread that will end immediately when the app is closed.
Read this part in the link that you linked
Services are given higher priority than other Background processes and
hence it’s less likely that Android will terminate it. Although it can
be configured to restart once there is ample resources available
again. You should go through the different processes and their
priority/important level in the documentation on processes and
threads. Assigning them the same priority as foreground activities is
definitely possible in which case it’ll need to have a visible
notification active (generally used for Services playing music).
If you are running a background thread that you start from an Activity, Android does not know that you are doing background work in the OS Process that is hosting your Activity. Android can kill the OS Process hosting your Activity at pretty much any time. If the user presses the HOME button or takes a phone call or opens a notification and goes to another application, Android can kill off the OS Process at any time. When the user returns to your application, Android will create a new OS Process and recreate all the relevant activities, but your background thread is hopelessly lost. This is the reason that Android has services.
If you start a Service to perform your background processing, the Service will also start background threads, but these are controlled. Your Service tells Android what to do if it kills the Service while it is processing an Intent. Your Service can therefore be informed and restart (or continue) the background processing as necessary. You can also run the Service in a different OS Process from the OS Process running your activities. This will prevent Android from killing the Service if the user removes your app from the list of recent tasks.
With newer Android SDKs there are other mechanisms you can use, like JobScheduler.
I am developing a chat application in android . and need to keep service running
even after exit from application .
I am usin
return START_STICKY;
in onStartCommand() of my service .
but because of limitation of services in android oreo , service will destroyed after seconds when exit from application.
So far users lost new messages notifications.
I can not use Fcm beacause of local networking and no access to internet.
And I can not use ForegroundService . (because Of Employer's request to not showing any notification) .
When I checked running service in android mobile setting , there are some
apps that their service not killing like Es file explorer , Zapya , ...
How they keep their service running without foreground service .
And What should i do .
Show in blow image , some apps services are running without any notification .
Based on the documentation:
The system distinguishes between foreground and background apps. An
app is considered to be in the foreground if any of the following is
true:
It has a visible activity, whether the activity is started or paused.
It has a foreground service.
Another foreground app is connected to the app, either by binding to one of its services or by making use of one of its content
providers.
Reason Es FileExplorer can do could be (its just my opinion) following:
Es FileExplorer (is quite cheeky when it comes to taking advantage of some loop holes) have several content providers but one provider, FileProveders which is some how manages to have com.android.providers.settings connected to it. I guess this connection makes it foreground. They virtually have all the possible intent-filter registered for almost all the scheme. Anything you try to share or access, could trigger them some or the other way which keeps its process in use (you can just click on the details and you will find LocalCService of app running).
But for your app:
If you can't use FCM, ForegroundService and can't have visibility to user, then only option is to perform task periodically. You can use WorkManager. The only limitation is minimum duration for scheduling is 15 minutes. Refer to my answer for scheduling work with WorkManager and WorkManager vs Service for usage of WorkManager.
I want to schedule nightly database updates. So I use new Android WorkManager. My understanding is that once scheduled it will always run in the background independently from the app's lifecycle.
Is that right? My first tests show that Work is only being performed when the app is running.
val locationWork = PeriodicWorkRequest.Builder(UpdateDatabaseWorker::class.java, 24, TimeUnit.HOURS)
.addTag("DATABASE_UPDATE_SERVICE")
.build()
WorkManager.getInstance().enqueue(locationWork)
Based on various issues reported on the WorkManager bugtracker, their documentation is not completely precise about the exact behavior of the WorkManager in such edge cases.
On certain devices, apps are force stopped when the app is cleared from task manager, so that part is expected. ... source
Unfortunately, some devices implement killing the app from the recents menu as a force stop. Stock Android does not do this. When an app is force stopped, it cannot execute jobs, receive alarms or broadcasts, etc. So unfortunately, it's infeasible for us to address it - the problem lies in the OS and there is no workaround. source
The only issue that we have come across is the case where some Chinese OEMs treat swipe to dismiss from Recents as a force stop. When that happens, WorkManager will reschedule all pending jobs, next time the app starts up. Given that this is a CDD violation, there is not much more that WorkManager can do given its a client library. source
To add to this, if a device manufacturer has decided to modify stock Android to force-stop the app, WorkManager will stop working (as will JobScheduler, alarms, broadcast receivers, etc.). There is no way to work around this. Some device manufacturers do this, unfortunately, so in those cases WorkManager will stop working until the next time the app is launched. source
With intense testing of a OneTimeWorkRequest (without constraints) on a Pixel 2 XL with stock android the behavior is the following:
Task manager close:
Work continues (after a bit)
Reboot device (work running):
Work continues after reboot done
App info "Force stop":
Work stops, will only continue when app is started again
Reboot device (work was "Force Stopped"):
Work does not continue until the app is started again
You can find a complete list of different OEM behaviors on dontkillmyapp.com. It seems the Android team also acknowledges this issue and added a test for this into their CTS test for Android Q. source
My understanding is that once scheduled it will always run in the
background independently from the app's lifecycle. Is that right?
Yes. Based on the documentation
The task is still guaranteed to run, even if your app is force-quit or
the device is rebooted.
WorkManager chooses the appropriate way to run your task based on factors such 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.
WorkManager might use JobScheduler, Firebase JobDispatcher, or AlarmManager depending on the API level. It will repect the Doze and conaider all other constraints before executing the Work. You can expect some delay in Doze mode since it could wait for maintenance window.
Note:
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.
This is what documentation is saying:
Note: 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.
But there must be some condition. if that condition meet then WorkManager will run the task (this is important). Conditions like "only while device is charging and online"
Read this carefully, The WorkManager attempts to run your task at the interval you request, subject to the constraints you impose and its other requirements.
Here I found a good tutorial about how to use WorkManager for scheduling tasks : https://android.jlelse.eu/how-scheduling-work-with-new-android-jetpack-component-workmanager-852163f4825b
I have a downloader application on Android.
It shows a notification(in-progress, not dismissable) during the download
and it also catches a wakelock.
I even asks the user to disable Doze for my app.
However, battery-saving feature from various vendors seem to ignore it and kill it randomly.
Is there a way to mark my app process "busy",
so that it has a higher priority in the not-to-kill list?
Note that I'm not using a service in my app.
Regular activity spawns up a thread and download is handled from there.
Note that I'm not using a service in my app
That would be the lion's share of your problem.
Regular activity spawns up a thread and download is handled from there.
That means that Android has no idea that you are doing anything that the user would value, when you're not in the foreground. Android will happily terminate your process to free up system RAM for other processes.
Use a service, perhaps an IntentService (since it already has a background thread for you, and it automatically shuts down once your work is complete). Convert your Notification into one for startForeground() on the service.
If you are keeping a wakelock for a longish time then it is better to let the user know about it, use a foreground service as CommonsWare pointed out.
However, if your use case does not warrant any foreground behavior then I would recommend you use framework JobScheduler that plays very well with doze and app standby as well.
For earlier than API 21 you may use JobDispatcher API.
You can read the more details here.