Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WorkManager keep notification after work is done

I want to display a notification while a Worker is running in the background. I can do that with something like the code below:

override suspend fun doWork(): Result {
    val manager = NotificationManagerCompat.from(applicationContext)
    val channel = "some_channel"
    val id = 15
    val builder = NotificationCompat.Builder(applicationContext, channel)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        manager.createNotificationChannel(NotificationChannel(channel, "DefaultName", NotificationManager.IMPORTANCE_LOW))

    builder
        .setOnlyAlertOnce(true)
        .setOngoing(true)
        .setAutoCancel(false)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setSmallIcon(android.R.drawable.ic_dialog_alert)
        .setTicker("Background Task")
        .setContentText("Starting")
        .setProgress(0, 0, true)

    setForeground(ForegroundInfo(id, builder.build()))

    delay(500)

    manager.notify(id, builder.setContentText("Progress A").setProgress(20, 0, false).build())
    for (i in 1..20) {
        delay(100)
        manager.notify(id, builder.setProgress(20, i, false).build())
    }

    delay(500)

    manager.notify(id, builder.setContentText("Progress B").setProgress(2, 0, false).build())
    delay(1000)
    manager.notify(id, builder.setProgress(2, 1, false).build())
    delay(1000)
    manager.notify(id, builder.setProgress(2, 2, false).build())

    delay(1000)

    manager.notify(id, builder.setContentText("Done!").setProgress(0, 0, false).build())

    delay(500)

    return Result.success()
}

But I also want to display the result of the worker in the notification and keep it until the user sees and clears it, yet the notification is always cleared at the end of the work.

How can I keep the notification alive? .setOngoing(true) and .setAutoCancel(false) didn't help.

like image 204
Guiorgy Avatar asked May 23 '26 17:05

Guiorgy


1 Answers

A much simpler way I think I found is to either notify the final notification with a different id (use .setOngoing(false)):

manager.notify(
    id + 1,
    builder.setContentText("Done!")
        .setAutoCancel(true)
        .setOngoing(false)
        .build()
)
return Result.success()

Or, send it after a bit of delay:

CoroutineScope(Main).launch {
    delay(200)
    manager.notify(
        id,
        builder.setContentText("Done!")
            .setAutoCancel(true)
            .setOngoing(false)
            .build()
    )
}
return Result.success()
like image 145
Guiorgy Avatar answered May 26 '26 12:05

Guiorgy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!