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

安卓每日7点本地通知异常:设置后凌晨12点触发求排查

问题分析与解决方案

看起来你遇到的问题核心是时区设置错误加上Calendar的24小时制与12小时制设置冲突,导致AlarmManager计算的触发时间和预期完全不符。

错误点拆解

  • 你硬把Calendar的时区设为GMT,但设备实际使用的是本地时区,这会导致你设置的6:59被解析为GMT时间,转换到本地时区后就变成了凌晨12点左右(具体偏差由你所在时区与GMT的差值决定)。
  • 同时设置Calendar.HOUR_OF_DAY(24小时制)和Calendar.AM_PM是冗余且冲突的:HOUR_OF_DAY优先级更高,AM_PM的设置会被直接忽略,这行代码完全没必要加。

修正后的代码

把MainActivity里的dailyVerseNotification方法改成下面这样:

private void dailyVerseNotification() {
    Calendar time = Calendar.getInstance();
    // 移除硬编码的GMT时区,使用设备默认的本地时区
    time.set(Calendar.HOUR_OF_DAY, 7); // 直接设置为早上7点(24小时制)
    time.set(Calendar.MINUTE, 0);
    time.set(Calendar.SECOND, 0);

    // 如果当前时间已经过了今天7点,就把时间顺延到明天7点,避免触发一次通知
    if (time.getTimeInMillis() < System.currentTimeMillis()) {
        time.add(Calendar.DAY_OF_MONTH, 1);
    }

    Intent intent = new Intent(getApplicationContext(), NotificationReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, 
        // Android 12及以上必须指定IMMUTABLE/MUTABLE,按需选择
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    assert alarmManager != null;

    // 针对不同Android版本适配精准触发逻辑
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);
    } else {
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
    }
    // 注意:Android 6.0之后setRepeating的精准度会被系统调整,如需精准每日触发,建议在NotificationReceiver中重新设置下一次闹钟
}

额外注意事项

  • 权限要求:Android 12(API 31)及以上需要在Manifest中添加SCHEDULE_EXACT_ALARM权限,部分场景还需动态申请:
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
  • Doze模式适配:如果需要设备休眠时也能精准触发,setExactAndAllowWhileIdle是更可靠的选择,但它不支持重复闹钟,需要在NotificationReceiver收到广播后,重新设置第二天的闹钟。
  • PendingIntent标记:Android 12及以上强制要求PendingIntent指定FLAG_IMMUTABLE或FLAG_MUTABLE,不需要修改Intent内容的话,用FLAG_IMMUTABLE更安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:37:36