WorkManager在任务完成后保留通知

6
我希望在 Worker 后台运行时显示通知。我可以使用类似以下代码的东西来实现:
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()
}

但我也希望在通知中显示工作者的结果,并使其保持到用户查看和清除为止,但是通知总是在工作结束时被清除。

我该如何保持通知的活性? .setOngoing(true).setAutoCancel(false) 没有起到帮助作用。

2个回答

6
我认为找到的更简单的方法是,通过使用不同的ID (使用.setOngoing(false)) 发送最终通知:
manager.notify(
    id + 1,
    builder.setContentText("Done!")
        .setAutoCancel(true)
        .setOngoing(false)
        .build()
)
return Result.success()

或者,稍微延迟一下再发送:
CoroutineScope(Main).launch {
    delay(200)
    manager.notify(
        id,
        builder.setContentText("Done!")
            .setAutoCancel(true)
            .setOngoing(false)
            .build()
    )
}
return Result.success()

0
我发现的一个解决方法是使用一个BroadcastReceiver来接收最终的通知并显示它。这是可能的,因为Notification扩展了Parcelable。注意:让NotificationReceiver使用与Worker不同的通知ID,否则Worker将关闭通知。
class NotificationReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == ACTION_SEND_NOTIFICATION) {
            val notification = intent.getParcelableExtra<Notification>(EXTRA_NOTIFICATION)
            val id = intent.getIntExtra(EXTRA_ID, DEFAULT_ID)
            if (notification == null)
                Log.e(TAG, "EXTRA_NOTIFICATION ($EXTRA_NOTIFICATION) was not provided!")
            else
                NotificationManagerCompat.from(context).notify(id, notification)
        }
    }

    companion object {
        const val TAG = "NotificationReceiver"

        const val ACTION_SEND_NOTIFICATION = "intent.action.SEND_NOTIFICATION"

        const val EXTRA_NOTIFICATION = "notification_parcel"
        const val EXTRA_ID = "notification_id"
        const val DEFAULT_ID = 1010
    }

}

<receiver android:name=".NotificationReceiver" android:enabled="true" />

    // At the end of doWork, before returning
    applicationContext.sendBroadcast(
        Intent(applicationContext, NotificationReceiver::class.java).setAction(
            NotificationReceiver.ACTION_SEND_NOTIFICATION
        ).putExtra(NotificationReceiver.EXTRA_NOTIFICATION, builder.build())
    )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接