From acb5be78c07b8499d0a38515b05a4982207c1c9a Mon Sep 17 00:00:00 2001
From: zhujie <leon.zhu@cloudroam.com.cn>
Date: 星期五, 18 四月 2025 15:24:16 +0800
Subject: [PATCH] Merge branch 'master' of http://47.96.225.205:8888/r/FirstApp2
---
app/src/main/java/com/example/firstapp/service/ReminderWorker.kt | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 154 insertions(+), 22 deletions(-)
diff --git a/app/src/main/java/com/example/firstapp/service/ReminderWorker.kt b/app/src/main/java/com/example/firstapp/service/ReminderWorker.kt
index 07b811a..ef0d07f 100644
--- a/app/src/main/java/com/example/firstapp/service/ReminderWorker.kt
+++ b/app/src/main/java/com/example/firstapp/service/ReminderWorker.kt
@@ -7,6 +7,7 @@
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
+import androidx.work.*
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.example.firstapp.MainActivity
@@ -21,6 +22,7 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
+import java.util.Calendar
import java.util.concurrent.TimeUnit
/**
@@ -38,23 +40,29 @@
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
android.util.Log.d("ReminderWorker", "doWork 开始执行")
try {
+ // 获取当前时间
+ 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()
android.util.Log.d("ReminderWorker", "获取到 ${reminderList.size} 条提醒设置")
- if (reminderList.isEmpty()) {
- // 测试用:如果没有数据,也发送一条测试通知
- sendTestNotification()
- android.util.Log.d("ReminderWorker", "数据为空,发送了测试通知")
- }
-
- for (reminder in reminderList) {
- try {
- android.util.Log.d("ReminderWorker", "处理提醒: ${reminder.categoryName}")
- checkCategoryContent(reminder.categoryId, reminder.categoryName, reminder.notificationMethod)
- } catch (e: Exception) {
- e.printStackTrace()
- android.util.Log.e("ReminderWorker", "处理提醒失败: ${e.message}")
+ if (reminderList.isNotEmpty()) {
+ for (reminder in reminderList) {
+ try {
+ android.util.Log.d("ReminderWorker", "处理提醒: ${reminder.categoryName}")
+ checkCategoryContent(reminder.categoryId, reminder.categoryName, reminder.notificationMethod)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ android.util.Log.e("ReminderWorker", "处理提醒失败: ${e.message}")
+ }
}
}
@@ -156,8 +164,12 @@
val channel = NotificationChannel(
CHANNEL_ID,
"提醒通知",
- NotificationManager.IMPORTANCE_DEFAULT
- )
+ NotificationManager.IMPORTANCE_HIGH // 提高重要性级别
+ ).apply {
+ enableLights(true) // 开启指示灯
+ enableVibration(true) // 开启震动
+ description = "重要提醒通知" // 设置描述
+ }
notificationManager.createNotificationChannel(channel)
}
@@ -166,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()
@@ -231,13 +245,131 @@
companion object {
private const val CHANNEL_ID = "reminder_channel"
+ private const val MISSED_PREF_KEY = "last_checked_reminder_time"
- // 定时任务执行频率 - 设置为每天运行一次
- val REPEAT_INTERVAL = 24L // 每24小时运行一次
+ // 定时任务执行频率(不再使用)
+ val REPEAT_INTERVAL = 24L // 设置为每24小时运行一次
val REPEAT_INTERVAL_TIME_UNIT = TimeUnit.HOURS
-
- // 测试用的频率配置,已注释掉
- // val REPEAT_INTERVAL = 2L
- // val REPEAT_INTERVAL_TIME_UNIT = TimeUnit.MINUTES
+
+ // 创建在指定时间运行的定时任务
+ fun setupScheduledWorker(context: Context, hour: Int, minute: Int) {
+ val calendar = Calendar.getInstance()
+ val now = Calendar.getInstance()
+
+ calendar.set(Calendar.HOUR_OF_DAY, hour)
+ calendar.set(Calendar.MINUTE, minute)
+ calendar.set(Calendar.SECOND, 0)
+
+ // 如果设定时间已经过了,则设置为明天这个时间
+ if (calendar.timeInMillis < now.timeInMillis) {
+ calendar.add(Calendar.DAY_OF_MONTH, 1)
+ }
+
+ // 计算初始延迟
+ 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 策略确保新配置生效
+ WorkManager.getInstance(context).enqueueUniquePeriodicWork(
+ "daily_reminder_${hour}_${minute}",
+ 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
+ }
}
}
\ No newline at end of file
--
Gitblit v1.9.3