如何使用Kotlin WorkManager实现事件开始前指定天数发送通知的功能
基于Kotlin WorkManager实现事件提前3天推送提醒的实现方案
核心逻辑:WorkManager天然支持延迟执行、应用退出/设备重启后仍可保留任务的特性,完全匹配定时提醒类需求。以下是完整实现步骤:
1. 导入WorkManager依赖
在模块级build.gradle文件中添加依赖:
dependencies { val work_version = "2.8.1" // Kotlin + 协程版本依赖 implementation("androidx.work:work-runtime-ktx:$work_version") }
2. 自定义通知处理Worker类
继承CoroutineWorker实现通知发送逻辑,适配全版本系统的通知规则:
class EventReminderWorker( context: Context, params: WorkerParameters ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { // 取传入的事件参数 val eventName = inputData.getString("EVENT_NAME") ?: return Result.failure() val eventId = inputData.getLong("EVENT_ID", 0L) // Android 8.0+ 需先创建通知通道 val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( "EVENT_REMINDER_CHANNEL", "事件提醒", NotificationManager.IMPORTANCE_HIGH ).apply { description = "待办事件提前提醒通知" } notificationManager.createNotificationChannel(channel) } // 构建通知,按需配置点击跳转逻辑 val notification = NotificationCompat.Builder(applicationContext, "EVENT_REMINDER_CHANNEL") .setSmallIcon(R.drawable.ic_notification) // 替换为你的应用通知图标 .setContentTitle("待办事项提醒") .setContentText("你有事件「${eventName}」将在3天后开始,请及时处理") .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) // 点击通知跳转到事件详情页,替换为你自己的详情页Activity .setContentIntent( PendingIntent.getActivity( applicationContext, eventId.toInt(), Intent(applicationContext, YourEventDetailActivity::class.java).apply { putExtra("EVENT_ID", eventId) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) ) .build() notificationManager.notify(eventId.toInt(), notification) return Result.success() } }
3. 计算任务延迟触发时间
从日期选择器拿到事件开始时间戳后,计算提前3天的触发延迟:
// eventStartTimestamp为你从日期范围选择器获取的事件开始时间(毫秒级时间戳) val threeDaysMillis = 3 * 24 * 60 * 60 * 1000L val triggerTime = eventStartTimestamp - threeDaysMillis val currentTime = System.currentTimeMillis() // 触发时间已过的情况下可根据业务需求选择直接触发提醒或放弃调度 val delayMillis = if (triggerTime > currentTime) triggerTime - currentTime else 0L
4. 提交提醒任务到WorkManager
使用唯一工作请求避免重复创建提醒,同时支持修改事件时间后更新任务:
// 构造传入Worker的事件参数 val inputData = workDataOf( "EVENT_ID" to eventId, // 事件的唯一ID "EVENT_NAME" to eventName // 其他需要传递的事件参数可自行扩展 ) // 构建一次性延迟任务 val reminderRequest = OneTimeWorkRequestBuilder<EventReminderWorker>() .setInitialDelay(delayMillis, TimeUnit.MILLISECONDS) .setInputData(inputData) // 可选:配置执行失败重试策略 .setBackoffCriteria( BackoffPolicy.LINEAR, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS ) .build() // 入队唯一任务,同一事件ID的任务会自动覆盖,适配修改事件时间的场景 WorkManager.getInstance(context) .enqueueUniqueWork( "reminder_${eventId}", ExistingWorkPolicy.REPLACE, reminderRequest )
可选补充操作
- 事件被删除时取消对应提醒:
WorkManager.getInstance(context).cancelUniqueWork("reminder_${eventId}")
- Android 13及以上版本需要提前动态申请
POST_NOTIFICATIONS权限,否则通知无法正常弹出。 - WorkManager默认持久化存储任务,设备重启、应用被杀死后任务仍会在指定时间触发,无需额外处理持久化逻辑。
内容的提问来源于stack exchange,提问作者Malender Kevin
相关产品推荐
相关产品推荐

