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

AlarmManager设置的当日闹钟不触发及延迟问题求助

问题排查与解决方案

嘿,我来帮你搞定这两个问题,咱们逐个拆解:

问题1:当日设置的闹钟无法触发,修改系统日期才生效

你代码里注释掉的「判断当前时间是否晚于目标时间」的逻辑,正是核心问题!当你设置的11:02已经过了当天这个时间点时,calendar.getTimeInMillis()会返回一个过去的时间戳,AlarmManager.setRepeating会直接把第一次触发安排到第二天的11:02,所以当日完全不会触发。

另外还有个容易忽略的细节:你只设置了小时和分钟,但没把秒和毫秒清零。如果当前时间是11:02:05,那你设置的calendar时间会默认保留当前的秒和毫秒,导致目标时间比当前时间还早,同样会被判定为「过去的时间」。

修复方案:

恢复判断逻辑,同时添加秒和毫秒清零的代码:

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// 清零秒和毫秒,确保目标时间是当天的11:02:00整
calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, 02);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);

// 如果当前时间已经过了目标时间,就把闹钟安排到明天
if(Calendar.getInstance().after(calendar)){
    calendar.add(Calendar.DATE, 1);
}

// 先取消之前的旧闹钟,再设置新的
alarmManager.cancel(pendingIntent);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);

问题2:闹钟触发存在10秒延迟

这个延迟主要来自三个原因:

  1. API版本限制:从Android 4.4(API 19)开始,setRepeating会被系统优化为「不精确闹钟」,系统会批量触发这类闹钟来节省电量,所以会有几秒到几十秒的延迟。
  2. Doze模式影响:Android 6.0(API 23)及以上的Doze模式会抑制普通闹钟,只有允许忽略Doze的闹钟才能精确触发。
  3. Reboot逻辑不完善:你当前的rebootDevice方法没有等待命令执行完成,可能导致命令没被正确执行,看起来像是延迟。

修复方案:

1. 改用精确闹钟API

放弃setRepeating,改用setExactAndAllowWhileIdle(API 23+,可绕过Doze),然后在Receiver中每次触发后,手动设置下一天的闹钟。这样能保证每次触发的精确性。

修改MainActivity的设置逻辑:

// 替换原来的setRepeating代码
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    // API 23+ 用setExactAndAllowWhileIdle绕过Doze模式
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    // API 19-22 用setExact保证精确性
    alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
    // 低版本继续用setRepeating
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}

然后在AlarmReceiver的onReceive方法中,添加设置下一天闹钟的逻辑:

@Override
public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, "Triggered", Toast.LENGTH_SHORT).show();
    Log.d("Gajanand", "onReceive: Triggered");
    rebootDevice();
    
    // 设置下一天的闹钟
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent myIntent = new Intent(context, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 11);
    calendar.set(Calendar.MINUTE, 02);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    // 直接加一天,因为当前已经触发了当天的闹钟
    calendar.add(Calendar.DATE, 1);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    } else {
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
    }
}

2. 完善rebootDevice方法

确保命令被正确执行,添加flush和waitFor:

public static void rebootDevice() {
    try {
        Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
        os.writeBytes("reboot\n");
        os.flush(); // 确保命令被写入终端
        os.close();
        process.waitFor(); // 等待命令执行完成
    } catch (Exception e) {
        e.printStackTrace();
    }
}

额外注意事项

  • Root权限:你的重启方法需要设备有Root权限,如果设备未Root,这个方法会抛出异常,重启不会生效。
  • PendingIntent的Flag:使用PendingIntent.FLAG_UPDATE_CURRENT或者FLAG_IMMUTABLE(API 31+)来确保PendingIntent能正确更新,避免出现旧的Intent数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:53:39