HomeAndroidEasy Instance to Use WorkManager and Notification

Easy Instance to Use WorkManager and Notification


That is only a quite simple app that covers some primary WorkManager utilization. It reveals you the way to schedule:

  • one-time work request

  • periodic work request

and

  • submit a notification when the duty is completed.

For an entire information, seek advice from the official WorkManager information right here.

Add Work Supervisor Dependency

construct.gradle.kts instance

dependencies {
    
    implementation ("androidx.work:work-runtime-ktx:2.7.1")
}

Inherit CoroutineWorker Class

To run a background process, it’s essential to create a employee class that inherits the CoroutineWorker class. The overridden doWork() technique is the place you carry out your background duties.

class DemoWorker(
    non-public val appContext: Context, 
    params: WorkerParameters)
    : CoroutineWorker(appContext, params) {

    override droop enjoyable doWork(): End result {
        delay(5000) 
        Log.d("DemoWorker", "do work finished!")

        return End result.success()
    }
}

By default, the coroutine runs on Dispatchers.Default. To modify to a unique coroutine dispatcher you should use CoroutineScope.withContext(). For extra particulars, you’ll be able to go to my earlier weblog submit right here.

Instantiate WorkManager

WorkManager is a Singleton. You’ll be able to retrieve it by passing the applying context to the WorkManager.getInstance() API.

WorkManager.getInstance(applicationContext)

You’ll be able to go in exercise context too, it will get transformed to software context anyway.

After you have the WorkManager, you’ll be able to set the work constraints and schedule the work request.

Set Work Constraints

You’ll be able to specify work constraints for the work request. The next is an instance of making NetworkType constraints. NetworkType.CONNECTED means the work runs on when your cellphone is linked to the web.

non-public val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .construct()

For different work constraints, seek advice from the official doc right here.

Schedule One-time Work Request

The next examples assume you could have the next variable setup.

non-public lateinit var workManager: WorkManager
non-public val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .construct()
non-public val workName = "DemoWorker

This creates a one-time work request, with the NetworkType.CONNECTED constraint. To schedule the work request, you’ll be able to name WorkManager.enqqueneUniqueWork().

val workRequest = OneTimeWorkRequestBuilder<DemoWorker>()
    .setConstraints(constraints)
    .construct()

workManager.enqueueUniqueWork(
    workName,
    ExistingWorkPolicy.REPLACE,
    workRequest)

ExistingWorkPolicy.REPLACE enum worth means if the identical work exists, it cancels the present one and replaces it.

In case your work requires greater precedence to run, you’ll be able to name the WorkRequest.Builder.setExpedited() API. OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST means if the app is run out of expedited quota, it falls again to non-expedited/common work requests.

val workRequest = OneTimeWorkRequestBuilder<DemoWorker>()
    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    .setConstraints(constraints)
    .construct()

Schedule Periodic Work Request

val workRequest = PeriodicWorkRequestBuilder<DemoWorker>(
    repeatInterval = 15, 
    TimeUnit.MINUTES
)
    .construct()

workManager.enqueueUniquePeriodicWork(
    workName,
    ExistingPeriodicWorkPolicy.REPLACE,
    workRequest)

You employ PeriodicWorkRequestBuilder<>() to construct a periodic work request. Nevertheless, one crucial observe is the repeatInterval should be equal to or better than quarter-hour. This does not appear to be documented anyplace.

For those who specify repeatInterval lower than quarter-hour, it simply ignores your work request silently. Your app will not crash. There’s this warning in your log, however I wager you seemingly will not see it. Unhealthy resolution, it ought to simply crash the app for my part.

Interval period lesser than minimal allowed worth; Modified to 900000

If you name workManager.enqueueUniquePeriodicWork(), your process runs instantly and runs once more at a specified repeatInterval. Nevertheless, should you do not wish to run the duties instantly, you name the WorkRequest.Builder.setInitialDelay() API.

val workRequest = PeriodicWorkRequestBuilder<DemoWorker>(
    repeatInterval = 16, 
    TimeUnit.MINUTES
)
    .setInitialDelay(5, TimeUnit.SECONDS)
    .construct()

The above code runs the primary process after 5 seconds and repeats the duty each quarter-hour.

Cancel Work Request

You’ll be able to cancel the work request by passing in a novel work identify parameter to the WorkManager.cancelUniqueWork() API.

workManager.cancelUniqueWork(workName)

Declare POST_NOTIFICATIONS Permission

Beginning on Android 13 (API degree 33 / Tiramisu), it’s essential to declare the notification permission and request it at run time.

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:identify="android.permission.POST_NOTIFICATIONS" />
    
</manifest>

Request Runtime Permission

It is a easy runtime permission dialog composable perform that launches the permission request dialog in your app.

@Composable
enjoyable RuntimePermissionsDialog(
    permission: String,
    onPermissionGranted: () -> Unit,
    onPermissionDenied: () -> Unit,
) {

    if(Construct.VERSION.SDK_INT >= Construct.VERSION_CODES.TIRAMISU) {

        if (ContextCompat.checkSelfPermission(
                LocalContext.present,
                permission) != PackageManager.PERMISSION_GRANTED) {

            val requestLocationPermissionLauncher = 
                rememberLauncherForActivityResult(
                    ActivityResultContracts.RequestPermission()
            ) { isGranted: Boolean ->

                if (isGranted) {
                    onPermissionGranted()
                } else {
                    onPermissionDenied()
                }
            }

            SideEffect {
                requestLocationPermissionLauncher.launch(permission)
            }
        }
    }
}

To name it, you’ll be able to simply go within the permission string and the callback tells you whether or not your permission is granted or denied.

@Composable
enjoyable MainScreen(viewModel: MainViewModel) {
    RuntimePermissionsDialog(
        Manifest.permission.POST_NOTIFICATIONS,
        onPermissionDenied = {},
        onPermissionGranted = {},
    )
}

Create Notification Channel

Ranging from API 26 / Android Orea (Oeatmeal Cookie), a notification channel is required if you wish to submit a notification.

That is an instance of making a notification channel within the DemoWorker coroutine employee class.

class DemoWorker(
    non-public val appContext: Context, 
    params: WorkerParameters
) : CoroutineWorker(appContext, params) {

    non-public val notificationChannelId = "DemoNotificationChannelId"

    

    non-public enjoyable createNotificationChannel()
    {
        if (Construct.VERSION.SDK_INT >= Construct.VERSION_CODES.O) {

            val notificationChannel = NotificationChannel(
                notificationChannelId,
                "DemoWorker",
                NotificationManager.IMPORTANCE_DEFAULT,
            )

            val notificationManager: NotificationManager? =
                getSystemService(
                    applicationContext,
                    NotificationManager::class.java)

            notificationManager?.createNotificationChannel(
                notificationChannel
            )
        }
    }
}

Create the Notification

To create the notification, you name NotificationCompat.Builder() by passing within the software context and the notificationChannelId that’s used to create the notification channel within the earlier step.

class DemoWorker(
    non-public val appContext: Context, 
    params: WorkerParameters
) : CoroutineWorker(appContext, params) {

    non-public val notificationChannelId = "DemoNotificationChannelId"

    

    non-public enjoyable createNotification() : Notification {
        createNotificationChannel()

        val mainActivityIntent = Intent(
            applicationContext, 
            MainActivity::class.java)

        var pendingIntentFlag by Delegates.notNull<Int>()
        if (Construct.VERSION.SDK_INT >= Construct.VERSION_CODES.M) {
            pendingIntentFlag = PendingIntent.FLAG_IMMUTABLE
        } else {
            pendingIntentFlag = PendingIntent.FLAG_UPDATE_CURRENT
        }

        val mainActivityPendingIntent = PendingIntent.getActivity(
            applicationContext,
            0,
            mainActivityIntent,
            pendingIntentFlag)


        return NotificationCompat.Builder(
            applicationContext, 
            notificationChannelId
        )
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setContentTitle(applicationContext.getString(R.string.app_name))
            .setContentText("Work Request Carried out!")
            .setContentIntent(mainActivityPendingIntent)
            .setAutoCancel(true)
            .construct()
    }

    
}

The mainActivityPendingIntent is used to start out your app’s primary exercise when the notification is clicked.

Override getForegroundInfo()

For those who use notifications in your employee class, it’s essential to additionally override the getForegroundInfo() droop perform. Your app crashes with out this override.

override droop enjoyable getForegroundInfo(): ForegroundInfo {
    return ForegroundInfo(
        0, createNotification()
    )
}

Publish the Notification

To submit a notification, you utilize NotificationManagerCompat.Notify() API.

class DemoWorker(
    non-public val appContext: Context, 
    params: WorkerParameters
) : CoroutineWorker(appContext, params) {

    non-public val notificationChannelId = "DemoNotificationChannelId"

    override droop enjoyable doWork(): End result {

        

        if (ActivityCompat.checkSelfPermission(
                appContext,
                Manifest.permission.POST_NOTIFICATIONS) 
                    == PackageManager.PERMISSION_GRANTED
        ) {
            with(NotificationManagerCompat.from(applicationContext)) {
                notify(0, createNotification())
            }
        }

        return End result.success()
    }

    
}

Carried out

I additionally utilized a really comparable code to my easy RSS feed reader app to carry out background article sync each 24 hours.

That is finished by this SyncWorker class.

Supply Code

GitHub Repository: Demo_WorkManager

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments