Workmanager not working with delay in android 12 Android kotlin
Asked Answered
E

1

6

Hey I am working WorkManager in kotlin. I didn't understand some code and getting me this error. Could you someone explain me in more details.

2022-01-06 16:48:33.501 14483-14483/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.app, PID: 14483
        java.lang.IllegalArgumentException: Expedited jobs cannot be delayed
            at androidx.work.WorkRequest$Builder.build(WorkRequest.java:326)
            at com.example.app.tracker.TrackerHelper.setupNotificationWorkerForNextLaunch(TrackerHelper.kt:124)
            at com.example.app.tracker.TrackerHelper.setReminderOff(TrackerHelper.kt:36)
            at com.example.app.tracker.TrackerHelper.switchReminder(TrackerHelper.kt:70)
            at com.example.app.tracker.TrackerSettingsViewModel.switchReminder(TrackerSettingsViewModel.kt:34)
            at com.example.app.tracker.TrackerSettingsViewModel.enableReminder(TrackerSettingsViewModel.kt:100)
            at com.example.app.tracker.TrackerSettingsViewModel.setupReminderRow$lambda-1(TrackerSettingsViewModel.kt:85)
            at com.example.app.tracker.TrackerSettingsViewModel.lambda$5Q3PVjBphM6lb1pU0jZdN9GXKaE(Unknown Source:0)
            at com.example.app.tracker.-$$Lambda$TrackerSettingsViewModel$5Q3PVjBphM6lb1pU0jZdN9GXKaE.onCheckedChanged(Unknown Source:2)
            at android.widget.CompoundButton.setChecked(CompoundButton.java:222)
            at androidx.appcompat.widget.SwitchCompat.setChecked(SwitchCompat.java:1095)
            at androidx.appcompat.widget.SwitchCompat.toggle(SwitchCompat.java:1090)
            at android.widget.CompoundButton.performClick(CompoundButton.java:144)
            at android.view.View.performClickInternal(View.java:7418)
            at android.view.View.access$3700(View.java:835)
            at android.view.View$PerformClick.run(View.java:28676)
            at android.os.Handler.handleCallback(Handler.java:938)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loopOnce(Looper.java:201)
            at android.os.Looper.loop(Looper.java:288)
            at android.app.ActivityThread.main(ActivityThread.java:7839)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

I tried this solution it working in android 11 or below. After that I tried this medium post to run android 12 but I am getting above error.

I tried code is

AndroidManifest.xml

    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:ignore="ExportedContentProvider"
        tools:node="merge">
        <meta-data
            android:name="androidx.work.WorkManagerInitializer"
            android:value="androidx.startup"
            tools:node="remove" />
    </provider>

1. Can someone explain what is doing above code in details please.

WorkerClass.kt

class WorkerClass(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams){

    override fun doWork(): Result {
         // calling function
        return Result.success()
    }
}

HelperClass.kt

fun setupNotificationWorkerForNextLaunch() {
        val delayDuration = currentDate.timeInMillis
        val dailyWorkRequest = OneTimeWorkRequestBuilder<WorkerClass>()
            .setInitialDelay(delayDuration, TimeUnit.MILLISECONDS)
            .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
            .addTag(REMINDER_WORK_TAG)
            .build()
        WorkManager.getInstance(Application.appContext).enqueue(dailyWorkRequest)
}

I added this code from medium post

.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)

2. Can someone explain how to work this in android 12 as well. I want to create a notification at particular time every day. How can I achieved this through WorkManager. Thanks

Elbrus answered 6/1, 2022 at 17:16 Comment(2)
The XML addition to AndroidManifest.xml removes WorkManager's default initialization and allows you to have a custom initialization: developer.android.com/topic/libraries/architecture/workmanager/… You should use it only if you have your own custom initialization.Mclain
@Mclain do you know how to use setExpedited with delay in workmanager ?Elbrus
G
3

WorkManager doesn't guarantee that your work runs at an exact time. And most apps don't need that in the first place, unless your app is an alarm or a calendar app.

If you want to run something regularly on a roughly 24 hourly basis, PeriodicWorkRequest is the API to use.

Using the setExpedited API lets WorkManager know that the request is potentially important to the user and should run ASAP. Hence the restriction on delays on that API.

Gulledge answered 7/1, 2022 at 16:11 Comment(6)
I want to use work manager like a alarm clock. So it could be possible with PeriodicWorkRequest?Elbrus
It won't. WorkManager executes work when the device allows it to, rather than waking it up unnecessarily.Gulledge
So which api need to use to work like alarm manager?Elbrus
I want user to choose time according to his convenience to trigger work manager.Elbrus
May I know, in Android 12, how does setExpedited work under the hood? Pre-12, to mark a job as important and not killed by OS, it is using Foreground service + notification under the hood. In Android 12, background app can no longer launch foreground service. So, what mechanism setExpedited is using, to tell OS this is an important job and shouldn't be killed? Thanks.Papacy
Just a note that PeriodicWorkRequests cannot be expedited. There is a runtime crash: Caused by: java.lang.IllegalArgumentException: PeriodicWorkRequests cannot be expeditedFeer

© 2022 - 2024 — McMap. All rights reserved.