cloudroam
2025-04-15 3466799c94227c5ebba9fb201621e745058867ee
app/src/main/java/com/example/firstapp/service/ReminderWorker.kt
@@ -40,9 +40,15 @@
    override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
        android.util.Log.d("ReminderWorker", "doWork 开始执行")
        try {
            // 强制发送一条测试通知(确认Worker是否执行)
            // sendTestNotification()
            android.util.Log.d("ReminderWorker", "发送测试通知确认Worker已执行")
            // 获取当前时间
            val currentTime = System.currentTimeMillis()
            val scheduledTime = inputData.getLong("scheduled_time", 0)
            // 如果有设定的预定时间且当前时间与预定时间相差超过30分钟,则跳过执行
            if (scheduledTime > 0 && Math.abs(currentTime - scheduledTime) > 30 * 60 * 1000) {
                android.util.Log.d("ReminderWorker", "当前时间与预定时间相差过大,跳过执行")
                return@withContext Result.success()
            }
            
            // 获取所有提醒设置
            val reminderList = reminderRepository.getAllReminders().first()
@@ -158,8 +164,12 @@
            val channel = NotificationChannel(
                CHANNEL_ID,
                "提醒通知",
                NotificationManager.IMPORTANCE_DEFAULT
            )
                NotificationManager.IMPORTANCE_HIGH // 提高重要性级别
            ).apply {
                enableLights(true) // 开启指示灯
                enableVibration(true) // 开启震动
                description = "重要提醒通知" // 设置描述
            }
            notificationManager.createNotificationChannel(channel)
        }
@@ -168,7 +178,9 @@
            .setSmallIcon(R.drawable.ic_reminder) // 使用自定义图标
            .setContentTitle(title)
            .setContentText(content)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setPriority(NotificationCompat.PRIORITY_HIGH) // 提高通知优先级
            .setCategory(NotificationCompat.CATEGORY_REMINDER) // 设置为提醒类别
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) // 在锁屏上显示完整通知
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .build()
@@ -233,10 +245,11 @@
    companion object {
        private const val CHANNEL_ID = "reminder_channel"
        private const val MISSED_PREF_KEY = "last_checked_reminder_time"
        
        // 定时任务执行频率 - 可选不同配置
        val REPEAT_INTERVAL = 15L  // 设置为每15分钟运行一次
        val REPEAT_INTERVAL_TIME_UNIT = TimeUnit.MINUTES
        // 定时任务执行频率(不再使用)
        val REPEAT_INTERVAL = 24L  // 设置为每24小时运行一次
        val REPEAT_INTERVAL_TIME_UNIT = TimeUnit.HOURS
        
        // 创建在指定时间运行的定时任务
        fun setupScheduledWorker(context: Context, hour: Int, minute: Int) {
@@ -255,11 +268,22 @@
            // 计算初始延迟
            val initialDelay = calendar.timeInMillis - now.timeInMillis
            
            // 先取消所有现有的提醒任务
            WorkManager.getInstance(context).cancelAllWorkByTag("reminder_worker")
            // 创建周期性工作请求(每天同一时间)
            val dailyWorkRequest = PeriodicWorkRequestBuilder<ReminderWorker>(
                24, TimeUnit.HOURS
            )
                .setInitialDelay(initialDelay, TimeUnit.MILLISECONDS)
                .setConstraints(
                    Constraints.Builder()
                        .setRequiredNetworkType(NetworkType.CONNECTED)
                        .build()
                )
                // 设置灵活时间窗口为0,确保尽量准时执行
                .setInputData(Data.Builder().putLong("scheduled_time", calendar.timeInMillis).build())
                .addTag("reminder_worker")
                .build()
                
            // 使用 REPLACE 策略确保新配置生效
@@ -268,6 +292,84 @@
                ExistingPeriodicWorkPolicy.REPLACE,
                dailyWorkRequest
            )
            android.util.Log.d("ReminderWorker", "设置定时提醒: ${hour}:${minute}, 初始延迟: ${initialDelay/1000/60}分钟")
            // 记录预定的下次执行时间
            val prefs = context.getSharedPreferences("reminder_prefs", Context.MODE_PRIVATE)
            prefs.edit().putLong("next_reminder_time_${hour}_${minute}", calendar.timeInMillis).apply()
        }
        // 应用启动时检查是否有错过的提醒
        fun checkMissedReminders(context: Context) {
            val prefs = context.getSharedPreferences("reminder_prefs", Context.MODE_PRIVATE)
            val lastCheckedTime = prefs.getLong(MISSED_PREF_KEY, 0)
            val currentTime = System.currentTimeMillis()
            // 如果上次检查时间是0,说明是首次运行应用
            if (lastCheckedTime == 0L) {
                prefs.edit().putLong(MISSED_PREF_KEY, currentTime).apply()
                return
            }
            // 检查是否错过了提醒时间点
            val lastCheckedCalendar = Calendar.getInstance().apply { timeInMillis = lastCheckedTime }
            val currentCalendar = Calendar.getInstance().apply { timeInMillis = currentTime }
            // 如果不是同一天,或者超过了设定的提醒时间点
            val missedReminder = checkIfMissedReminderTime(lastCheckedCalendar, currentCalendar)
            if (missedReminder) {
                android.util.Log.d("ReminderWorker", "检测到错过的提醒,立即执行一次")
                // 立即安排一次性任务执行提醒检查
                val oneTimeRequest = OneTimeWorkRequestBuilder<ReminderWorker>()
                    .setConstraints(
                        Constraints.Builder()
                            .setRequiredNetworkType(NetworkType.CONNECTED)
                            .build()
                    )
                    .build()
                WorkManager.getInstance(context).enqueue(oneTimeRequest)
            }
            // 更新最后检查时间
            prefs.edit().putLong(MISSED_PREF_KEY, currentTime).apply()
        }
        // 检查是否错过了提醒时间点
        private fun checkIfMissedReminderTime(lastChecked: Calendar, current: Calendar): Boolean {
            // 如果日期不同,说明至少过了一天
            if (lastChecked.get(Calendar.DAY_OF_YEAR) != current.get(Calendar.DAY_OF_YEAR) ||
                lastChecked.get(Calendar.YEAR) != current.get(Calendar.YEAR)) {
                // 检查当前时间是否超过了9:00或13:50
                val currentHour = current.get(Calendar.HOUR_OF_DAY)
                val currentMinute = current.get(Calendar.MINUTE)
                return (currentHour > 9 || (currentHour == 9 && currentMinute >= 0)) ||
                       (currentHour > 13 || (currentHour == 13 && currentMinute >= 50))
            }
            // 如果同一天,检查是否在上次检查后经过了9:00或13:50时间点
            val lastHour = lastChecked.get(Calendar.HOUR_OF_DAY)
            val lastMinute = lastChecked.get(Calendar.MINUTE)
            val currentHour = current.get(Calendar.HOUR_OF_DAY)
            val currentMinute = current.get(Calendar.MINUTE)
            // 检查是否错过了9:00
            if ((lastHour < 9 || (lastHour == 9 && lastMinute == 0)) &&
                (currentHour > 9 || (currentHour == 9 && currentMinute > 0))) {
                return true
            }
            // 检查是否错过了13:50
            if ((lastHour < 13 || (lastHour == 13 && lastMinute < 50)) &&
                (currentHour > 13 || (currentHour == 13 && currentMinute >= 50))) {
                return true
            }
            return false
        }
    }