Android 使用AlarmManager实现每日定时任务触发

一、需求

最近遇到一个需求,需要每天在某时间点触发执行一个任务,类似闹铃提醒,使用AlarmManager来实现。

二、实现

AlarmManager的基本使用大家可参考后面的文章,写的非常详细,在实现的过程中主要对闹钟的类型及相应的触发时间triggerTime(或者叫starttime)花了点时间研究了下。

1、闹钟的类型

  • AlarmManager.RTC_WAKEUP
    表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,即当前系统时间,状态值为0;

  • AlarmManager.RTC
    表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;

  • AlarmManager.ELAPSED_REALTIME_WAKEUP
    表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间(相对于系统启动开始),状态值为2;

  • AlarmManager.ELAPSED_REALTIME
    表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;

  • AlarmManager.POWER_OFF_WAKEUP
    表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;

2、AlarmManager的常用方法

  • set(int type,long startTime,PendingIntent pi);

该方法用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟执行时间,第三个参数表示闹钟响应动作。

  • setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);

该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。

3、AlarmManager.RTC_WAKEUP 和 AlarmManager.ELAPSED_REALTIME_WAKEUP区别
这个在参考文章2,stackoverflow中的一个提问中解释的比较清晰,大家可以直接看,我这把我自己理解的记录下:

  • AlarmManager.ELAPSED_REALTIME_WAKEUP:使用该类型的闹钟,设置的triggerTime需要使用相对时间,就是从设备开机后到现在的时间,即使设备断网或者用户手动修改时间,不会影响闹钟计时;

  • AlarmManager.RTC_WAKEUP:使用该类型的闹钟,设置的triggerTime需要使用绝对时间,即当前系统时间,因为系统时间会受到网络的影响,断网后时间不准了,且用户可以在系统设置中随意修改时间,这些都会影响闹钟的准确性。

代码举例1:
AlarmService是新建的Service,用来触发执行任务,代码比较简单就不贴了,大家新建service后别忘了在Manifest中注册。

下面代码实现1min后启动service,代码中有两种实现方式,均可以实现1min后提醒。

#MainActivity

private void startAlarm() {
    Log.i(TAG, "startAlarm");
    Intent intent = new Intent(this, AlarmService.class);
    intent.setAction("com.alarm.notice");
    pendingIntent = PendingIntent.getService(this, 0, intent, 0);
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    
    //1min后触发,实现方式1
    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
                + 60 * 1000, pendingIntent);
       
    //1min后触发,实现方式2
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
                + 60 * 1000, pendingIntent);
}

private void cancelAlarm() {
    Log.i(TAG, "cancelAlarm");
    alarmManager.cancel(pendingIntent);
}

代码举例2:每天到13:50点提醒,代码中两种实现方式,具体用哪一个大家根据自己需求来。

private void startAlarmRepeatEveryDay() {
    Log.i(TAG, "startAlarmRepeatEveryDay");
    Intent intent = new Intent(this, AlarmService.class);
    intent.setAction("com.alarm.notice");
    pendingIntent = PendingIntent.getService(this, 0, intent, 0);
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    
    //设置提醒时间
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    //这里时区需要设置一下,不然会有8个小时的时间差
    calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
    //设置每天为13:50点提醒
    calendar.set(Calendar.MINUTE, 50);
    calendar.set(Calendar.HOUR_OF_DAY, 13);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    long firstTime = SystemClock.elapsedRealtime();
    long systemTime = System.currentTimeMillis();
    long selectTime = calendar.getTimeInMillis();
    //当前时间大于设置时间,说明今天提醒时间已经过去了,设置为明天的点来提醒
    if (systemTime > selectTime) {
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        selectTime = calendar.getTimeInMillis();
    }

    long time = selectTime - systemTime;// 计算现在时间到设定时间的时间差
    long triggerTime = firstTime + time;//系统当前的时间+时间差
    //13:50点提醒,实现方式1
    alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP
                               , triggerTime,  AlarmManager.INTERVAL_DAY, pendingIntent);

    //13:50点提醒,实现方式2
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, selectTime,AlarmManager.INTERVAL_DAY, pendingIntent);
}

参考文章:
定时任务,AlarmManager使用
Android AlarmManager - RTC_WAKEUP vs ELAPSED_REALTIME_WAKEUP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值