如何在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
相关产品推荐
相关产品推荐

