Before API 31, we are using the following guideline, to implement a delayed started long running task, when user "quit" the app.
public class XXXApplication extends MultiDexApplication implements DefaultLifecycleObserver {
@Override
public void onPause(LifecycleOwner owner) {
startCloudWorker();
}
}
public static void startCloudWorker() {
OneTimeWorkRequest oneTimeWorkRequest =
new OneTimeWorkRequest.Builder(CloudWorker.class)
.setInitialDelay(..., TimeUnit.MILLISECONDS)
...
.build();
WorkManager workManager = getWorkManager();
workManager.enqueue(oneTimeWorkRequest);
}
public class CloudWorker extends Worker {
public CloudWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
final ForegroundInfo foregroundInfo = createForegroundInfo(...)
setForegroundAsync(foregroundInfo);
// Some busy job here...
return Result.success();
}
}
Due to restriction imposed by new API 31
Apps that target Android 12 (API level 31) or higher can't start foreground services while running in the background, except for a few special cases. If an app tries to start a foreground service while the app is running in the background, and the foreground service doesn't satisfy one of the exceptional cases, the system throws a ForegroundServiceStartNotAllowedException.
https://developer.android.com/guide/components/foreground-services#background-start-restrictions
I thought using setExpedited
might be a good workaround to overcome such limitation.
How does setExpedited work and is it as good&reliable as a foreground service?
However, when I start to adopt the new requirement
public static void startCloudWorker() {
OneTimeWorkRequest oneTimeWorkRequest =
new OneTimeWorkRequest.Builder(CloudWorker.class)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.setInitialDelay(..., TimeUnit.MILLISECONDS)
...
.build();
WorkManager workManager = getWorkManager();
workManager.enqueue(oneTimeWorkRequest);
}
I am getting
java.lang.IllegalArgumentException: Expedited jobs cannot be delayed
I was wondering, what is the right way, to have a delayed started long running task when app is in background for API 31?