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

如何在AlarmReceiver接收闹钟时调用Room的upsertNotification操作数据库?

实现AlarmReceiver接收闹钟时向Room数据库插入数据

要在AlarmReceiver中调用Room的upsertNotification方法,需要解决两个核心问题:获取Room的DAO实例和在后台线程执行挂起函数,以下是具体实现方案:

方案一:直接使用协程(快速实现)

借助Hilt注入DAO,并通过协程在IO线程执行数据库操作:

1. 修改AlarmReceiver代码

给AlarmReceiver添加Hilt注解,注入NotificationDao,并在协程中执行插入操作:

@AndroidEntryPoint
class AlarmReceiver : BroadcastReceiver() {
    @Inject
    lateinit var notificationDao: NotificationDao

    override fun onReceive(context: Context?, intent: Intent?) {
        val message = intent?.getStringExtra("EXTRA_MESSAGE") ?: return
        val notificationType = NotificationType.fromValue(intent.getIntExtra("NOTIFICATION_TYPE", 0))

        // 构造要插入的Notification对象(注意使用intent传递的通知类型)
        val notification = Notification(
            id = null,
            date = LocalDate.now(),
            time = LocalTime.now(),
            title = "Test Title Premium",
            description = message,
            unread = true,
            notificationType = notificationType.value
        )

        // 在IO线程执行数据库挂起函数
        CoroutineScope(Dispatchers.IO).launch {
            notificationDao.upsertNotification(notification)
        }

        // 原有通知展示逻辑
        context?.let { DayReminderNotificationService(it) }?.showNotification(message)
    }
}

关键注意事项

  • 确保你的Application类已添加@HiltAndroidApp注解,否则Hilt无法正常注入依赖。
  • 协程方式适合短耗时操作,但如果onReceive执行完成后进程被系统回收,可能导致数据库操作中断。

方案二:使用WorkManager(可靠保障)

如果需要确保数据库操作一定完成,推荐使用WorkManager,即使进程被杀,系统也会重新调度任务:

1. 创建NotificationInsertWorker

@HiltWorker
class NotificationInsertWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted params: WorkerParameters,
    private val notificationDao: NotificationDao
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        // 从输入数据中获取参数
        val message = inputData.getString("EXTRA_MESSAGE") ?: return Result.failure()
        val notificationTypeValue = inputData.getInt("NOTIFICATION_TYPE", 0)
        val notificationType = NotificationType.fromValue(notificationTypeValue)

        // 构造Notification对象
        val notification = Notification(
            id = null,
            date = LocalDate.now(),
            time = LocalTime.now(),
            title = "Test Title Premium",
            description = message,
            unread = true,
            notificationType = notificationType.value
        )

        // 执行数据库操作
        return try {
            notificationDao.upsertNotification(notification)
            Result.success()
        } catch (e: Exception) {
            // 失败后可重试
            Result.retry()
        }
    }
}

2. 修改AlarmReceiver调度WorkManager任务

@AndroidEntryPoint
class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val message = intent?.getStringExtra("EXTRA_MESSAGE") ?: return
        val notificationTypeValue = intent.getIntExtra("NOTIFICATION_TYPE", 0)

        // 构造WorkRequest并传递参数
        val workRequest = OneTimeWorkRequestBuilder<NotificationInsertWorker>()
            .setInputData(
                Data.Builder()
                    .putString("EXTRA_MESSAGE", message)
                    .putInt("NOTIFICATION_TYPE", notificationTypeValue)
                    .build()
            )
            .build()

        // 调度任务
        WorkManager.getInstance(context!!).enqueue(workRequest)

        // 原有通知展示逻辑
        context.let { DayReminderNotificationService(it) }.showNotification(message)
    }
}

关键注意事项

  • 需添加WorkManager与Hilt的依赖(根据你的Gradle版本调整)。
  • WorkManager会自动处理后台任务的生命周期,确保操作最终完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:36:03