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

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) {
        // 你的通知逻辑
    }
}

注意事项

  1. 权限处理: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))
    }
}
  1. PendingIntent请求码:确保工作日和周末的闹钟请求码唯一,避免互相覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:10:58