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

如何使用AlarmManager在午夜后重启控制器适配周维度REST API?

可行,具体实现步骤如下

1. 实现广播接收器(处理午夜重启逻辑)

创建一个BroadcastReceiver,用来接收AlarmManager触发的广播,在onReceive方法中执行控制器的重启操作:

public class MidnightRestartReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 获取控制器实例并执行重启逻辑
        YourController controller = YourController.getInstance();
        controller.restart();
    }
}

2. 在Manifest中注册广播接收器

确保接收器能被系统唤醒,同时添加必要权限:

<!-- 午夜重启接收器 -->
<receiver
    android:name=".MidnightRestartReceiver"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="com.yourpackage.ACTION_RESTART_CONTROLLER" />
    </intent-filter>
</receiver>

<!-- 开机重启权限(用于设备重启后重新设置闹钟) -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Android 12+ 精确闹钟权限 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

3. 配置AlarmManager,设置每日午夜触发

编写方法计算下一次午夜时间,并设置重复闹钟,确保跨版本兼容(尤其是Android 6+的Doze模式和Android 12+的权限限制):

private void setupMidnightAlarm(Context context) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, MidnightRestartReceiver.class);
    intent.setAction("com.yourpackage.ACTION_RESTART_CONTROLLER");
    
    // PendingIntent需设置FLAG_IMMUTABLE适配Android 12+
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            context,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );

    // 计算下一次午夜的时间戳
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    // 如果当前已过午夜,直接设置为次日午夜
    if (calendar.getTimeInMillis() <= System.currentTimeMillis()) {
        calendar.add(Calendar.DAY_OF_MONTH, 1);
    }

    // 根据系统版本选择闹钟设置方式
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        // Android 12+ 需要先检查精确闹钟权限
        if (alarmManager.canScheduleExactAlarms()) {
            alarmManager.setExactAndAllowWhileIdle(
                    AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(),
                    pendingIntent
            );
        } else {
            // 引导用户前往设置页授权
            Intent permissionIntent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
            permissionIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(permissionIntent);
        }
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // Android 6+ 使用精确闹钟并允许Doze模式下触发
        alarmManager.setExactAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(),
                pendingIntent
        );
    } else {
        // 低版本直接设置重复闹钟
        alarmManager.setRepeating(
                AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY,
                pendingIntent
        );
    }
}

4. 处理设备重启后的闹钟恢复

设备重启后AlarmManager的闹钟会失效,需要监听开机广播重新设置闹钟:

public class BootCompletedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            setupMidnightAlarm(context);
        }
    }
}

在Manifest中注册该接收器:

<receiver
    android:name=".BootCompletedReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

5. 实现控制器的重启方法

在你的控制器类中添加restart方法,重新执行初始化逻辑(包括你无法修改的那段星期几判断代码):

public class YourController {
    private static YourController instance;
    private PlaylistService playlistService;
    private String id;

    private YourController() {
        // 初始化逻辑
    }

    public static YourController getInstance() {
        if (instance == null) {
            instance = new YourController();
        }
        return instance;
    }

    public void restart() {
        // 重新执行初始化流程,让目标代码再次执行
        initPlaylistLogic();
    }

    private void initPlaylistLogic() {
        // 你无法修改位置的代码在这里
        Calendar calendar = Calendar.getInstance();
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        Observable<List<String>> playlistObservable = playlistService.getPlaylist(id, day);
        // 后续的订阅、业务逻辑...
    }
}

6. 启动闹钟

在应用启动时(比如Application的onCreate方法或控制器首次初始化时)调用setupMidnightAlarm方法,初始化闹钟:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        setupMidnightAlarm(this);
    }

    // 这里可以直接把之前的setupMidnightAlarm方法移到这里,或者通过工具类调用
}

通过以上步骤,每天午夜AlarmManager会触发广播,重启你的控制器,让那段获取星期几的代码重新执行,从而保证逻辑基于最新的日期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:02:50