You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android中使用Work Manager按时间列表推送通知

用WorkManager实现多时间点通知调度

针对你需要在指定时间列表(如[08:00,10:11,11:20,11:21])推送通知的需求,可以通过以下步骤基于WorkManager实现:

1. 核心思路

遍历每个目标时间,计算当前时间到目标时间的延迟时长,为每个时间点创建OneTimeWorkRequest,让WorkManager在延迟后执行通知推送任务。如果目标时间已过当天当前时间,可选择跳过或顺延至次日(根据业务需求调整)。

2. 实现步骤

2.1 创建通知工具类(处理通知发送)

Android 8.0+必须创建通知渠道,先实现一个工具类处理通知的创建与发送:

object NotificationUtil {
    private const val CHANNEL_ID = "scheduled_notification"
    private const val CHANNEL_NAME = "定时通知"

    fun createNotificationChannel(context: Context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                CHANNEL_NAME,
                NotificationManager.IMPORTANCE_DEFAULT
            )
            val manager = context.getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }

    fun showNotification(context: Context, title: String, content: String) {
        val notification = NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(title)
            .setContentText(content)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()

        val manager = NotificationManagerCompat.from(context)
        manager.notify(System.currentTimeMillis().toInt(), notification)
    }
}

2.2 创建Worker类(执行通知任务)

继承CoroutineWorker,在doWork()方法中触发通知发送:

class NotificationWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        val title = inputData.getString("title") ?: "定时通知"
        val content = inputData.getString("content") ?: "这是一条定时推送的通知"
        NotificationUtil.showNotification(applicationContext, title, content)
        return Result.success()
    }
}

2.3 处理时间转换与任务调度

编写方法解析时间字符串,计算延迟后逐个调度任务:

fun scheduleNotifications(context: Context, timeList: List<String>) {
    // 初始化通知渠道
    NotificationUtil.createNotificationChannel(context)
    
    val currentTime = System.currentTimeMillis()
    val calendar = Calendar.getInstance()

    timeList.forEach { timeStr ->
        // 拆分时间字符串为小时和分钟
        val (hour, minute) = timeStr.split(":").map { it.toInt() }
        calendar.set(Calendar.HOUR_OF_DAY, hour)
        calendar.set(Calendar.MINUTE, minute)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)

        val targetTime = calendar.timeInMillis
        var delayMillis = targetTime - currentTime

        // 若目标时间已过当天,可选择顺延至次日或跳过
        if (delayMillis < 0) {
            delayMillis += 24 * 60 * 60 * 1000L
            // 不需要顺延则直接跳过:return@forEach
        }

        // 构建WorkRequest,传入通知内容
        val workRequest = OneTimeWorkRequestBuilder<NotificationWorker>()
            .setInitialDelay(delayMillis, TimeUnit.MILLISECONDS)
            .setInputData(
                workDataOf(
                    "title" to "定时提醒",
                    "content" to "当前时间:$timeStr"
                )
            )
            .build()

        // 提交任务到WorkManager
        WorkManager.getInstance(context).enqueue(workRequest)
    }
}

2.4 调用调度方法

在合适的时机(如Application启动、用户设置完成后)触发调度:

val timeList = listOf("08:00", "10:11", "11:20", "11:21")
scheduleNotifications(applicationContext, timeList)

注意事项

  • 若需要每日重复推送,建议每天重新调度当日的任务(WorkManager的PeriodicWorkRequest最小周期为15分钟,不适合精准到分钟的每日定时)。
  • WorkManager会自动处理设备重启、Doze模式等场景,确保任务在合适时机执行。
  • 如需取消已调度任务,可使用WorkManager.getInstance(context).cancelWorkById(workRequest.id)或cancelAllWorkByTag()方法(可给WorkRequest设置tag)。

内容的提问来源于stack exchange,提问作者quannm18

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:11:07