2022 年如何安排适用于 Android 的本地通知

use*_*912 6 android

首先,这里的大多数答案都有2年多的历史了。经过如此多的 API 更改,它们似乎都不再起作用了。

当我说工作时,我的意思是它应该在以下情况下工作:

  • 应用程序已关闭(如杀死)
  • 手机已重启,应用程序尚未重新启动。

我正在构建一个日历样式的应用程序,它发送本地通知和准确的时间作为提醒。

我尝试使用 AlarmManager 但当我关闭应用程序时它不起作用。如果通知安排在 10 分钟后出现,它会以某种方式起作用。但如果超过这个数量(如第二天安排的那样),它就会停止工作。然而,当我打开应用程序的那一刻,你瞧,所有这些过去的预定通知都出来了!

说真的,Android 需要整理他们的通知!

通知是制作移动应用程序的主要原因之一。如果没有,网站/网络应用程序可以正常工作。

我发现的 2019 年建议之一是使用前台服务。说真的什么?仅发送每周一次的通知(或我的应用程序的情况)就太过分了

Hsi*_*ing 0

我写了一些关于 Ragesh Ramesh 提到的 WorkManager 的代码片段。

它可以在 Pixel 6 中运行以满足您的用例。

  1. 应用程序已关闭(如杀死)
  2. 手机已重启,应用程序尚未重新启动。

根据文档,WorkManager应该满足您的要求

计划的工作存储在内部管理的 SQLite 数据库中,WorkManager 负责确保该工作持续存在并在设备重新启动时重新安排

附加说明,WorkManager 的限制

因此,即使满足 WorkRequest 上设置的所有约束,您的 Work 仍然可以在一些额外的延迟下运行。

如果您仍然遇到问题,请查找google-labs(WorkManager),我的意见可能与 OEM 问题有关。

class OneTimeScheduleWorker(
    val context: Context,
    workerParams: WorkerParameters
) : Worker(context, workerParams) {

    override fun doWork(): Result {
        val builder = NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.android_cupcake)
            .setContentTitle("Scheduled notification")
            .setContentText("Hello from one-time worker!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)

        with(NotificationManagerCompat.from(context)) {
            notify(Random.nextInt(), builder.build())
        }
        
        return Result.retry()
    }

}

fun schedulePeriodicNotifications() {

    val periodicWork = PeriodicWorkRequestBuilder<OneTimeScheduleWorker>(
        15, TimeUnit.MINUTES
    ).addTag("WORK_TAG").build()

    WorkManager.getInstance(this)
        .enqueueUniquePeriodicWork(
            "WORK_NAME",
            ExistingPeriodicWorkPolicy.KEEP,
            periodicWork
        )
}
Run Code Online (Sandbox Code Playgroud)

并根据需要添加以下代码作为构建通知

   // You must create the notification channel before posting any notifications on Android 8.0 and higher,
    // you should execute this code as soon as your app starts
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.appwidget_text)
        val descriptionText = getString(R.string.looper_event)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
Run Code Online (Sandbox Code Playgroud)