1.工具类
public class AlarmManagerUtils {
private Context context;
private AlarmManager am;
private PendingIntent pendingIntent;
private Calendar calendar;
private AlarmManagerUtils(Context aContext) {
this.context = aContext;
}
private static AlarmManagerUtils instance = null;
public static AlarmManagerUtils getInstance(Context aContext) {
if (instance == null) {
synchronized (AlarmManagerUtils.class) {
if (instance == null) {
instance = new AlarmManagerUtils(aContext);
}
}
}
return instance;
}
public void createGetUpAlarmManager(int requestCode) {
am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlertService.class);
//不同的任务requesCode需要定义成不同的,否则,后面的会把前面的任务给覆盖掉
pendingIntent = PendingIntent.getService(context, requestCode, intent, 0);
}
@SuppressLint("NewApi")
public void getUpAlarmManagerStartWork(int hour, int minute, int second) {
calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上
am.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pendingIntent);
}
}
public void cancelAllAlarm() {
if (null != am && null != pendingIntent) {
try {
am.cancel(pendingIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
需要说明的部分:
pendingIntent = PendingIntent.getService(context, requestCode, intent, 0);
这里,requestCode需要保证唯一性,如果requestCode相同,那么新的定时会替换掉旧的,所以,如果想要同时实现定义多个定时器,那么这里requestCode一定要使用不同的值。因此,createGetUpAlarmManager 方法增加了requestCode的形参
2.定义服务,用于处理当定时完成时的处理逻辑(比如说,信息发布系统中的场景是,给那些目前还不到播放时间的节目,按照播放时间定义定时任务,例如当前9点,节目列表中有10点开始播和11点开始播的节目,那么我就需要增加10点和11点的定时任务,那么到了播放时间,就通知主线程开始新的播放)
public class AlertService extends Service {
public AlertService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//这里可以定时完成时的处理逻辑,我的处理是对外发送LiveDataBus通知。
//如果说需要针对不同的定时执行不同的逻辑,则可以在定义pendingintent
//时,在其中put便于处理逻辑的参数即可实现
LiveDataBus.getInstance()
.with(EventBus.ITS_TIME_TO_PLAY_THE_NEXT_PROGRAM, Object.class)
.postValue(new Object());
return super.onStartCommand(intent, flags, startId);
}
}
service需要在配置文件中声明
AlarmManagerUtils.getInstance(this).cancelAllAlarm();
<service
android:name=".service.AlertService"
android:enabled="true"
android:exported="true"></service>
3.具体调用
(1)创建定时
AlarmManagerUtils alarmManagerUtils = AlarmManagerUtils.getInstance(this);
alarmManagerUtils.createGetUpAlarmManager(i);
//该方法传入具体的定时的”时分秒”,比如这里定义12点整的定时 alarmManagerUtils.getUpAlarmManagerStartWork(12,0,0);
(2)取消所有定时器:
AlarmManagerUtils.getInstance(this).cancelAllAlarm();
(3)增加对EventBus的处理(这一步是与我前面的业务相关,如果前面AlertService 中不是使用LiveDataBus通知的,则这一步也可以是其他的处理或者省略)
LiveDataBus.getInstance()
.with(EventBus.ITS_TIME_TO_PLAY_THE_NEXT_PROGRAM, Object.class)
.observe(this, event -> {
LogUtil.d("定时到了,开始播下一个节目");
playNextProgram();
});