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

API 26升级后AlarmManager在Android 6.0+后台无法正常工作

解决API 26+下AlarmManager后台失效的问题

我太懂你这种升级API后踩坑的感受了——把项目升到API 26之后,AlarmManager在Android 6.0+设备后台完全失效,还试过WakefulBroadcastReceiver没用,这确实让人头大,毕竟你需要的是每15分钟稳定触发的重复闹钟。

为什么原来的方法失效了?

  • API 26+的后台执行限制:Android从API 26开始收紧了后台应用的权限,普通的AlarmManager.setRepeating()在应用进入后台后会被系统延迟甚至直接忽略,尤其是Doze模式和App Standby机制会抑制非必要的后台操作。
  • WakefulBroadcastReceiver已废弃:这个组件在API 26中被官方标记为废弃,取而代之的是更适配新后台规则的WorkManager或结合前台服务的精确闹钟方案。

解决方案一:高精度重复闹钟(适合需严格15分钟间隔的场景)

如果你的业务要求闹钟必须精准触发,不能有较大延迟,推荐使用AlarmManager.setExactAndAllowWhileIdle(),并通过单次闹钟+重复设置的方式实现周期触发(因为API 23+后重复闹钟的精确性无法保证)。

1. 创建广播接收器处理闹钟触发逻辑

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 这里写闹钟触发后要执行的逻辑
        // 注意:不要在这里做耗时操作,否则会触发ANR

        // 立即设置下一次15分钟后的闹钟
        scheduleNextAlarm(context);
    }

    private void scheduleNextAlarm(Context context) {
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                context,
                0, // 请求码,可根据需要修改
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );

        // 计算15分钟后的触发时间
        long nextTriggerTime = System.currentTimeMillis() + 15 * 60 * 1000;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // API 23+使用精确且允许Doze模式下触发的方法
            alarmManager.setExactAndAllowWhileIdle(
                    AlarmManager.RTC_WAKEUP, // 唤醒设备触发
                    nextTriggerTime,
                    pendingIntent
            );
        } else {
            // 低版本使用setExact保证精确性
            alarmManager.setExact(
                    AlarmManager.RTC_WAKEUP,
                    nextTriggerTime,
                    pendingIntent
            );
        }
    }
}

2. 初始化第一次闹钟

在你的Activity或启动类中调用以下代码,设置第一个15分钟后的闹钟:

private void initPeriodicAlarm() {
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );

    long firstTriggerTime = System.currentTimeMillis() + 15 * 60 * 1000;

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

3. 注意事项

如果你的闹钟触发后需要执行耗时操作,绝对不能在BroadcastReceiver中处理,必须启动一个前台服务(API 26+后台服务启动会被限制),前台服务需要显示一个通知告知用户。

解决方案二:WorkManager(适合允许一定延迟的场景)

如果你的业务可以接受15分钟左右的误差(系统可能在10-15分钟之间触发),WorkManager是更省心的选择,它会自动适配系统的后台限制,无需手动处理Doze模式等问题。

1. 创建Worker类

public class PeriodicTaskWorker extends Worker {
    public PeriodicTaskWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        // 这里写闹钟触发后要执行的逻辑
        return Result.success(); // 任务执行成功
    }
}

2. 启动周期性任务

在合适的地方(比如Application的onCreate或Activity的onCreate)调用以下代码:

// 创建周期性工作请求,最小间隔为15分钟,允许5分钟的弹性时间
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(
        PeriodicTaskWorker.class,
        15, TimeUnit.MINUTES,
        5, TimeUnit.MINUTES
).build();

// 将任务加入WorkManager队列
WorkManager.getInstance(getApplicationContext()).enqueue(periodicWork);

总结

  • 若需要高精度的15分钟重复触发:选择AlarmManager.setExactAndAllowWhileIdle()+广播接收器+前台服务(如需耗时操作)的方案。
  • 若允许一定延迟:直接用WorkManager,它会帮你处理所有后台适配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:11:05