From 3466799c94227c5ebba9fb201621e745058867ee Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期二, 15 四月 2025 13:18:34 +0800
Subject: [PATCH] add: 消息提醒时间设定;会员到期时间调整;

---
 app/src/main/res/layout/activity_reminder_list.xml                               |   36 +++++-
 app/src/main/res/values-v23/themes.xml                                           |   12 +-
 app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt |    2 
 app/src/main/java/com/example/firstapp/activity/ReminderListActivity.kt          |    4 
 app/src/main/java/com/example/firstapp/MainActivity.kt                           |   24 ++++
 app/src/main/java/com/example/firstapp/service/ReminderWorker.kt                 |  120 ++++++++++++++++++++++-
 app/src/main/java/com/example/firstapp/App.kt                                    |   34 ------
 app/src/main/res/layout/fragment_notifications.xml                               |   17 ++
 8 files changed, 189 insertions(+), 60 deletions(-)

diff --git a/app/src/main/java/com/example/firstapp/App.kt b/app/src/main/java/com/example/firstapp/App.kt
index a3992f7..1a0b34c 100644
--- a/app/src/main/java/com/example/firstapp/App.kt
+++ b/app/src/main/java/com/example/firstapp/App.kt
@@ -453,41 +453,15 @@
      * 设置定时提醒Worker
      * 配置为每天运行一次检查是否有新的提醒内容
      */
-    private fun setupReminderWorker() {
+    fun setupReminderWorker() {
         Log.d(TAG, "设置定时提醒Worker")
         
-        // 方式1:使用周期性执行
-        val constraints = Constraints.Builder()
-            .setRequiredNetworkType(NetworkType.CONNECTED)
-            .build()
-        
-        // 创建周期性工作请求
-        val reminderWorkRequest = PeriodicWorkRequestBuilder<ReminderWorker>(
-            ReminderWorker.REPEAT_INTERVAL,
-            ReminderWorker.REPEAT_INTERVAL_TIME_UNIT
-        )
-            .setConstraints(constraints)
-            .addTag("reminder_worker")
-            .build()
-
-        // 使用 REPLACE 策略确保新配置生效
-        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
-            "reminder_work",
-            ExistingPeriodicWorkPolicy.REPLACE,
-            reminderWorkRequest
-        )
-        
-        // 方式2:设置在特定时间执行(例如每天上午9点和下午18点)
+        // 仅在特定时间执行(每天指定时间)
         // 可根据需要设置多个不同时间点的提醒
         ReminderWorker.setupScheduledWorker(this, 9, 0)  // 上午9:00
-        ReminderWorker.setupScheduledWorker(this, 13, 50) // 下午18:00
+        ReminderWorker.setupScheduledWorker(this, 13, 50) // 下午13:50
         
-        // 注意:不再立即执行一次提醒检查,避免重复提醒
-        // 如果需要立即检查,可以设置一个延迟,例如5分钟后执行
-        val delayedWorkRequest = OneTimeWorkRequestBuilder<ReminderWorker>()
-            .setInitialDelay(5, TimeUnit.MINUTES)  // 延迟5分钟执行
-            .build()
-        WorkManager.getInstance(this).enqueue(delayedWorkRequest)
+        // 不再使用周期性轮询和立即执行的方式
     }
 
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/MainActivity.kt b/app/src/main/java/com/example/firstapp/MainActivity.kt
index 13ae51e..9c533a8 100644
--- a/app/src/main/java/com/example/firstapp/MainActivity.kt
+++ b/app/src/main/java/com/example/firstapp/MainActivity.kt
@@ -75,6 +75,9 @@
         // 只保留底部导航的设置
         navView.setupWithNavController(navController)
 
+        // 重置提醒计划并检查是否有错过的提醒
+        resetReminders()
+        
         // 检查权限
         if (ContextCompat.checkSelfPermission(
                 this, Manifest.permission.RECEIVE_SMS
@@ -323,4 +326,25 @@
             Toast.makeText(this, "同步短信失败:${e.message}", Toast.LENGTH_SHORT).show()
         }
     }
+
+    // 重置提醒计划
+    private fun resetReminders() {
+        try {
+            // 取消所有现有的提醒任务
+            androidx.work.WorkManager.getInstance(this).cancelAllWorkByTag("reminder_worker")
+            
+            // 清除旧的提醒偏好设置
+            getSharedPreferences("reminder_prefs", Context.MODE_PRIVATE).edit().clear().apply()
+            
+            // 重新设置提醒任务
+            (application as App).setupReminderWorker()
+            
+            // 检查是否有错过的提醒
+            com.example.firstapp.service.ReminderWorker.checkMissedReminders(this)
+            
+            android.util.Log.d("MainActivity", "已重置提醒计划")
+        } catch (e: Exception) {
+            android.util.Log.e("MainActivity", "重置提醒计划失败: ${e.message}")
+        }
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/activity/ReminderListActivity.kt b/app/src/main/java/com/example/firstapp/activity/ReminderListActivity.kt
index 44a6c76..5d8c26f 100644
--- a/app/src/main/java/com/example/firstapp/activity/ReminderListActivity.kt
+++ b/app/src/main/java/com/example/firstapp/activity/ReminderListActivity.kt
@@ -90,7 +90,7 @@
         }
 
         // 添加已读按钮点击事件
-        binding.clearReadMessagesButton.setOnClickListener {
+        binding.clearReadContainer.setOnClickListener {
             lifecycleScope.launch {
                 // 将所有未读消息标记为已读
                 adapter.currentList.forEach { record ->
@@ -99,7 +99,7 @@
                     }
                 }
                 Toast.makeText(
-                    this@ReminderListActivity, "所有消息已标记为已读", Toast.LENGTH_SHORT
+                    this@ReminderListActivity, "所有消息已标记为删除", Toast.LENGTH_SHORT
                 ).show()
                 checkUnreadMessages()
             }
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 5e9d3fd..ef0d07f 100644
--- a/app/src/main/java/com/example/firstapp/service/ReminderWorker.kt
+++ b/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
         }
     }
 } 
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
index 7362c83..b3fe265 100644
--- a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
+++ b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
@@ -312,7 +312,7 @@
                 val userInfo = response.data
 
                 // 本地保存我的邀请码
-                PreferencesManager.setInviteCode(userInfo.intervialcode);
+                //PreferencesManager.setInviteCode(userInfo.intervialcode);
                 // 设置头像
                 Glide.with(this)
                     .load(userInfo.cover)
diff --git a/app/src/main/res/layout/activity_reminder_list.xml b/app/src/main/res/layout/activity_reminder_list.xml
index 59d3474..699f593 100644
--- a/app/src/main/res/layout/activity_reminder_list.xml
+++ b/app/src/main/res/layout/activity_reminder_list.xml
@@ -13,18 +13,38 @@
         android:elevation="4dp"
         android:padding="8dp">
 
-        <!-- 将已读按钮改为图标 -->
-        <ImageButton
-            android:id="@+id/clearReadMessagesButton"
-            android:layout_width="30dp"
-            android:layout_height="30dp"
+        <!-- 使用 LinearLayout 包裹图标和文字 -->
+        <LinearLayout
+            android:id="@+id/clearReadContainer"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_alignParentEnd="true"
             android:layout_centerVertical="true"
             android:layout_marginEnd="16dp"
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
             android:background="?attr/selectableItemBackgroundBorderless"
-            android:contentDescription="标记所有消息为已读"
-            android:padding="8dp"
-            android:src="@drawable/reminder_delete" />
+            android:clickable="true"
+            android:focusable="true">
+
+            <!-- 调整后的图标按钮 -->
+            <ImageButton
+                android:id="@+id/clearReadMessagesButton"
+                android:layout_width="30dp"
+                android:layout_height="30dp"
+                android:background="@null"
+                android:contentDescription="标记所有消息为已读"
+                android:padding="8dp"
+                android:src="@drawable/reminder_delete" />
+
+            <!-- 添加“全部删除”文字 -->
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="全部删除"
+                android:layout_marginEnd="8dp"
+                android:textColor="@color/black" />
+        </LinearLayout>
     </RelativeLayout>
 
     <androidx.recyclerview.widget.RecyclerView
diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml
index 82ad433..6af008d 100644
--- a/app/src/main/res/layout/fragment_notifications.xml
+++ b/app/src/main/res/layout/fragment_notifications.xml
@@ -120,19 +120,28 @@
                         <TextView
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:text="VIP会员  "
+                            android:text="VIP会员"
                             android:textColor="#B8741A"
-                            android:textSize="18sp"
+                            android:textSize="16sp"
                             android:textStyle="bold"/>
 
                         <!-- 添加间隔 -->
+                        <View
+                            android:layout_width="6dp"
+                            android:layout_height="0dp"/>
 
                         <TextView
                             android:id="@+id/tv_vip_expire"
-                            android:layout_width="wrap_content"
+                            android:layout_width="0dp"
                             android:layout_height="wrap_content"
+                            android:layout_weight="1"
+                            android:singleLine="true"
+                            android:ellipsize="end"
                             android:textColor="#F2F2F2"
-                            android:textSize="14sp"/>
+                            android:textSize="12sp"
+                            android:clickable="true"
+                            android:focusable="true"
+                            android:background="?attr/selectableItemBackground"/>
                     </LinearLayout>
 
                     <!-- 第二行:续费提示(上移调整) -->
diff --git a/app/src/main/res/values-v23/themes.xml b/app/src/main/res/values-v23/themes.xml
index 1553ce1..1b76944 100644
--- a/app/src/main/res/values-v23/themes.xml
+++ b/app/src/main/res/values-v23/themes.xml
@@ -7,10 +7,10 @@
     <!--        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>-->
     <!--    </style>-->
 
-    <style name="Theme.FirstApp" parent="Base.Theme.FirstApp">
-        <!-- Transparent system bars for edge-to-edge. -->
-        <item name="android:navigationBarColor">@android:color/transparent</item>
-        <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
-    </style>
+<!--    <style name="Theme.FirstApp" parent="Base.Theme.FirstApp">-->
+<!--        &lt;!&ndash; Transparent system bars for edge-to-edge. &ndash;&gt;-->
+<!--        <item name="android:navigationBarColor">@android:color/transparent</item>-->
+<!--        <item name="android:statusBarColor">@android:color/transparent</item>-->
+<!--        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>-->
+<!--    </style>-->
 </resources>
\ No newline at end of file

--
Gitblit v1.9.3