如何使用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
相关产品推荐
相关产品推荐

