Android中工作日与周末差异化本地通知实现求助
实现Android工作日/周末差异化本地通知方案
基于你已实现的每日Alarm Manager通知逻辑,提供两种可行的差异化调度方案,结合时间选择器的选定时间完成需求。
核心工具:日期判断方法
先封装一个工具类,用于判断当前日期是否为工作日(周一至周五):
object DateUtils { // 判断是否为工作日(周一到周五) fun isWeekday(calendar: Calendar): Boolean { val dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) return dayOfWeek in Calendar.MONDAY..Calendar.FRIDAY } }
方案一:基于现有每日闹钟,触发时判断差异化通知
这种方案改动最小,直接复用你已有的每日重复闹钟逻辑,仅在通知触发时根据日期类型切换内容。
1. 修改广播接收器逻辑
在你已有的AlarmReceiver中添加日期判断,发送对应通知:
class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val currentCal = Calendar.getInstance() val isWeekday = DateUtils.isWeekday(currentCal) // 根据日期类型构建通知内容 val (title, content) = if (isWeekday) { "工作日提醒" to "该处理工作任务啦!" } else { "周末提醒" to "放松一下,享受休闲时光~" } // 调用你已实现的通知发送方法 sendNotification(context, title, content) } // 你已有的通知发送逻辑(可直接复用) private fun sendNotification(context: Context, title: String, content: String) { val notificationManager = NotificationManagerCompat.from(context) val notification = NotificationCompat.Builder(context, "your_channel_id") .setSmallIcon(R.drawable.ic_notification) .setContentTitle(title) .setContentText(content) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .build() notificationManager.notify(1, notification) } }
方案二:分别设置工作日/周末独立闹钟
如果需要精准控制仅在工作日或周末触发(避免每日都触发闹钟),可采用这种方案,设置两个独立的闹钟任务,每次触发后自动调度下一次的触发时间。
1. 计算下一次触发时间的工具方法
添加两个方法,分别计算下一个工作日/周末的选定时间:
// 获取下一个工作日的触发时间(基于用户选定的时分) fun getNextWeekdayTriggerTime(selectedHour: Int, selectedMinute: Int): Long { val cal = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, selectedHour) set(Calendar.MINUTE, selectedMinute) set(Calendar.SECOND, 0) set(Calendar.MILLISECOND, 0) } // 如果当前时间已过今日选定时间,或今日是周末,就往后推到下一个工作日 if (cal.timeInMillis <= System.currentTimeMillis() || !DateUtils.isWeekday(cal)) { do { cal.add(Calendar.DAY_OF_MONTH, 1) } while (!DateUtils.isWeekday(cal)) } return cal.timeInMillis } // 获取下一个周末的触发时间(基于用户选定的时分) fun getNextWeekendTriggerTime(selectedHour: Int, selectedMinute: Int): Long { val cal = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, selectedHour) set(Calendar.MINUTE, selectedMinute) set(Calendar.SECOND, 0) set(Calendar.MILLISECOND, 0) } // 如果当前时间已过今日选定时间,或今日是工作日,就往后推到下一个周末 if (cal.timeInMillis <= System.currentTimeMillis() || DateUtils.isWeekday(cal)) { do { cal.add(Calendar.DAY_OF_MONTH, 1) } while (DateUtils.isWeekday(cal)) } return cal.timeInMillis }
2. 保存用户选定的时间
在时间选择器确认按钮点击时,将用户选择的时分保存到SharedPreferences,便于后续调度:
// 时间选择器确认逻辑 val sharedPref = context.getSharedPreferences("AlarmPrefs", Context.MODE_PRIVATE) with(sharedPref.edit()) { putInt("SELECTED_HOUR", timePicker.hour) putInt("SELECTED_MINUTE", timePicker.minute) apply() }
3. 设置初始闹钟
在设置闹钟的代码中,分别创建工作日和周末的闹钟任务:
val sharedPref = context.getSharedPreferences("AlarmPrefs", Context.MODE_PRIVATE) val selectedHour = sharedPref.getInt("SELECTED_HOUR", 8) val selectedMinute = sharedPref.getInt("SELECTED_MINUTE", 0) val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager // 设置工作日闹钟 val weekdayIntent = Intent(context, AlarmReceiver::class.java).apply { putExtra("NOTIFICATION_TYPE", "WEEKDAY") } val weekdayPendingIntent = PendingIntent.getBroadcast( context, 1001, // 唯一请求码,避免与周末闹钟冲突 weekdayIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) val weekdayTriggerTime = getNextWeekdayTriggerTime(selectedHour, selectedMinute) alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, weekdayTriggerTime, weekdayPendingIntent ) // 设置周末闹钟 val weekendIntent = Intent(context, AlarmReceiver::class.java).apply { putExtra("NOTIFICATION_TYPE", "WEEKEND") } val weekendPendingIntent = PendingIntent.getBroadcast( context, 1002, // 唯一请求码 weekendIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) val weekendTriggerTime = getNextWeekendTriggerTime(selectedHour, selectedMinute) alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, weekendTriggerTime, weekendPendingIntent )
4. 修改广播接收器,完成循环调度
在AlarmReceiver中,发送对应通知后,自动设置下一次的闹钟:
class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val sharedPref = context.getSharedPreferences("AlarmPrefs", Context.MODE_PRIVATE) val selectedHour = sharedPref.getInt("SELECTED_HOUR", 8) val selectedMinute = sharedPref.getInt("SELECTED_MINUTE", 0) // 获取通知类型,发送对应内容 val (title, content) = when(intent.getStringExtra("NOTIFICATION_TYPE")) { "WEEKDAY" -> "工作日提醒" to "该处理工作任务啦!" "WEEKEND" -> "周末提醒" to "放松一下,享受休闲时光~" else -> "默认提醒" to "时间到了!" } sendNotification(context, title, content) // 调度下一次闹钟 val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager when(intent.getStringExtra("NOTIFICATION_TYPE")) { "WEEKDAY" -> { val nextTime = getNextWeekdayTriggerTime(selectedHour, selectedMinute) val nextIntent = Intent(context, AlarmReceiver::class.java).apply { putExtra("NOTIFICATION_TYPE", "WEEKDAY") } val nextPendingIntent = PendingIntent.getBroadcast( context, 1001, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextTime, nextPendingIntent) } "WEEKEND" -> { val nextTime = getNextWeekendTriggerTime(selectedHour, selectedMinute) val nextIntent = Intent(context, AlarmReceiver::class.java).apply { putExtra("NOTIFICATION_TYPE", "WEEKEND") } val nextPendingIntent = PendingIntent.getBroadcast( context, 1002, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextTime, nextPendingIntent) } } } // 复用你的通知发送方法 private fun sendNotification(context: Context, title: String, content: String) { // 你的通知逻辑 } }
注意事项
- 权限处理:Android 12及以上需要
SCHEDULE_EXACT_ALARM权限,需在Manifest中添加:
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
并在运行时请求权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager if (!alarmManager.canScheduleExactAlarms()) { startActivity(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)) } }
- PendingIntent请求码:确保工作日和周末的闹钟请求码唯一,避免互相覆盖。
内容的提问来源于stack exchange,提问作者Arpit Jain
相关产品推荐
相关产品推荐

