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

Android通知定时功能异常:用户自定义时间不生效求助

Android 自定义通知时间不生效问题修复方案

核心问题分析

  1. 偏好设置不同步:用户修改时间后仅保存了字符串格式的notifA,但未同步更新用于闹钟触发的整数类型noti1,导致读取闹钟时间时仍使用旧值或默认的7点。
  2. 未更新旧闹钟:修改时间后没有取消原有重复闹钟,新旧闹钟冲突导致触发逻辑混乱。
  3. Spinner初始化逻辑冗余:用大量if-else转换时间格式既繁琐又易遗漏,且未在用户修改后实时同步noti1。

具体修复步骤

1. 同步偏好设置,简化Spinner逻辑

修改Spinner选择后的保存逻辑,同时保存字符串格式和整数格式的时间,避免数据不一致:

dropdown.setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(
        parent: AdapterView<*>,
        view: View,
        pos: Int,
        id: Long
    ) {
        val selectedTimeStr = parent.getItemAtPosition(pos) as String
        // 直接从选中字符串提取小时数
        val selectedHour = selectedTimeStr.split(":")[0].toInt()

        apply.setOnClickListener {
            val settingsPref = getSharedPreferences("settings", MODE_PRIVATE).edit()
            // 同时保存两种格式的时间
            settingsPref.putString("notifA", selectedTimeStr)
            settingsPref.putInt("noti1", selectedHour)
            settingsPref.commit()
            
            // 修改完成立即更新闹钟
            updateAlarm(selectedHour)
        }
    }

    override fun onNothingSelected(parent: AdapterView<*>?) {}
})

简化Spinner初始化,不用冗余的if-else:

val dropdown = dialog.findViewById<Spinner>(R.id.spinnyboi)
val items = arrayOf("5:00", "6:00", "7:00", "8:00", "9:00", "10:00", "11:00", "12:00", "13:00")
val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, items)
dropdown?.adapter = adapter

val settingsPref = getSharedPreferences("settings", MODE_PRIVATE)
val timeAA = settingsPref.getString("notifA", "7:00")
// 直接通过数组索引设置选中状态
val selectedPos = items.indexOf(timeAA)
if (selectedPos != -1) {
    dropdown.setSelection(selectedPos)
}

2. 新增闹钟更新/重置函数

创建专门的函数用于取消旧闹钟并设置新的重复闹钟,确保修改时间后立即生效:

private fun updateAlarm(targetHour: Int) {
    // 先取消已存在的闹钟
    val mIntent = Intent(this, MyReceiver::class.java)
    val mPendingIntent = PendingIntent.getBroadcast(
        this, 1, mIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
    )
    val mAlarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
    mAlarmManager.cancel(mPendingIntent)

    // 配置新的闹钟时间
    val calendar: Calendar = Calendar.getInstance().apply {
        timeInMillis = System.currentTimeMillis()
        set(Calendar.HOUR_OF_DAY, targetHour)
        set(Calendar.MINUTE, 0)
        set(Calendar.SECOND, 0) // 增加秒数精度,避免触发误差
        // 如果当前时间已过目标点,自动设置为明天
        if (timeInMillis < System.currentTimeMillis()) {
            add(Calendar.DAY_OF_MONTH, 1)
        }
    }

    // 设置每日重复闹钟,用系统常量替代硬编码的间隔值
    mAlarmManager.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        mPendingIntent
    )
}

3. 优化初始闹钟设置

在App启动或初始化闹钟的位置,读取最新设置并调用更新函数:

val settingsPref = getSharedPreferences("settings", MODE_PRIVATE)
val targetHour = settingsPref.getInt("noti1", 7)
updateAlarm(targetHour)

额外注意事项

  • 确保PendingIntent的requestCode统一(这里是1),否则无法正确取消旧闹钟。
  • Android 19及以上版本,setRepeating会被系统调整为不精确触发,若需要精确重复,可在MyReceiver中每次触发后重新设置下一次闹钟。
  • 检查App是否已申请POST_NOTIFICATIONS权限(Android 12+)及后台运行权限,避免通知被系统拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:16:06