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

Android AlarmManager每日重复闹钟异常:打开应用触发通知问题求助

解决Android AlarmManager打开应用就触发通知的问题

兄弟,我太懂你踩的这个坑了!你现在的问题核心是每次启动App调用setAlarm时,直接把首次触发时间设成了当天9点,但如果当前时间已经过了9点,AlarmManager会立刻触发一次来“补”这次闹钟,然后才开始每天重复;另外如果每次启动都重复设置闹钟,也可能导致重复触发通知。

下面给你一步步解决的方案:

1. 计算正确的首次触发时间

首先要判断当前时间是否已经过了当天9点:

  • 如果还没到,首次触发时间就是今天9点
  • 如果已经过了,首次触发时间就是明天9点
    这样就不会在启动App时立刻触发了。

给你一个计算这个时间的工具方法:

private Calendar getNext9AmTime() {
    Calendar calendar = Calendar.getInstance();
    // 设置时间为今天9点
    calendar.set(Calendar.HOUR_OF_DAY, 9);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    // 如果当前时间已经过了9点,就把日期加1天
    if (System.currentTimeMillis() > calendar.getTimeInMillis()) {
        calendar.add(Calendar.DAY_OF_YEAR, 1);
    }
    return calendar;
}

2. 修改你的setAlarm方法

在设置闹钟时,用上面计算出来的时间作为首次触发时间,而不是直接硬设当天9点。同时注意使用合适的AlarmManager方法,以及避免重复设置闹钟:

private void setAlarm() {
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, AlarmReceiver.class);
    // 这里要注意用唯一的requestCode,避免和其他PendingIntent冲突
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );

    // 获取下一次9点的时间
    Calendar nextTriggerTime = getNext9AmTime();

    // 设置重复闹钟:API 19之后setRepeating会变成不精确重复,如果需要精确可以考虑WorkManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setExactAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                nextTriggerTime.getTimeInMillis(),
                pendingIntent
        );
        // 因为setExactAndAllowWhileIdle不支持重复,所以需要在AlarmReceiver里重新设置下一次闹钟
        // 或者如果接受不精确重复,用下面的setInexactRepeating
    } else {
        alarmManager.setRepeating(
                AlarmManager.RTC_WAKEUP,
                nextTriggerTime.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY,
                pendingIntent
        );
    }
}

3. 避免重复设置闹钟(可选但推荐)

每次启动App都调用setAlarm会导致重复注册闹钟,可能触发多次通知。可以在设置前先检查这个闹钟是否已经存在:

private boolean isAlarmAlreadySet() {
    Intent intent = new Intent(this, AlarmReceiver.class);
    return PendingIntent.getBroadcast(
            this,
            0,
            intent,
            PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE
    ) != null;
}

然后在onCreate里调用时判断:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (!isAlarmAlreadySet()) {
        setAlarm();
    }
}

补充:关于API 19之后的精确重复闹钟

从Android 4.4(API 19)开始,setRepeating会变成不精确重复,系统会把多个闹钟合并触发来节省电量。如果你的需求是必须精确到9点触发,建议在AlarmReceiver的onReceive方法里处理完通知后,再重新设置下一次的闹钟(也就是用setExactAndAllowWhileIdle,每次触发后再设置第二天的9点)。

比如在AlarmReceiver里:

@Override
public void onReceive(Context context, Intent intent) {
    // 显示你的通知逻辑
    showNotification(context);

    // 设置下一次9点的闹钟
    Calendar nextTriggerTime = getNext9AmTime(); // 这里可以把这个工具方法放到Receiver里或者一个公共类中
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent nextIntent = new Intent(context, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            context,
            0,
            nextIntent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setExactAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                nextTriggerTime.getTimeInMillis(),
                pendingIntent
        );
    } else {
        alarmManager.setExact(
                AlarmManager.RTC_WAKEUP,
                nextTriggerTime.getTimeInMillis(),
                pendingIntent
        );
    }
}

这样就能保证每天9点精确触发,而且不会在启动App时立刻弹出通知啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:22:51