AlarmManager的使用以及该注意的一些坑

不积跬步,无以至千里

   说起我为什么要写这篇文章?就是因为我入坑了,所以我写下这篇来提醒有可能也入坑的人(废了2天时间啊)!

   先说下AlarmManager的使用吧(我这里使用的AlarmManager的repeating方法),再说说入坑的事。

   首先我先把最终要用的方法贴到这里,再让你们看下接下来的其中方法中参数等的由来。

一、设置闹钟

alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, AlarmManager.INTERVAL_DAY, uploadIntent);

1、先获取到AlarmManager对象

AlarmManager alarmManager = (AlarmManager) context.getSystemService(
        Context.ALARM_SERVICE);
2、获取到PendingIntent的意图对象,即方法中的最后一个参数(你打算用这个intent去干什么,开启服务还是发送广播,打开Activity等等)

Intent intent2 = new Intent(context, LauncherService.class).setAction(Constants.PENDING_START_ALARM_ACTION+"");
PendingIntent uploadIntent = PendingIntent.getService(context, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
3、获取使用repeating方法时,需要填入的第二个参数,即你第一次触发这个重复闹钟的时间,其中注意的是,因为我下面seRepeating方法第一个参数ELAPSED_REALTIME

,所以我在获取时间的时候是用systemTime = System.elapsedRealtime()其中这个包括了手机系统的睡眠时间,现对于比较准确。AlarmManager的方法时注意中一些参数的上下的一致性。否则会出现定时的错误!

 long firstTime = SystemClock.elapsedRealtime();//boot from begin to now runnig time ,it includes sleep time
  long systemTime = System.currentTimeMillis();
  Calendar calendar = Calendar.getInstance();
  //calendar.setTimeInMillis(systemTime);
  //setting the TimeZone,or else will have the time mistakes(8 hours)
  // calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
  calendar.set(Calendar.HOUR_OF_DAY, Constants.ALARM_HOUR);
  calendar.set(Calendar.MINUTE, Constants.ALARM_MINUTE);
  calendar.set(Calendar.SECOND, Constants.ALARM_SECOND);
  calendar.set(Calendar.MILLISECOND, Constants.ALARM_MILLISECOND);
  //obtain the timevalues
  long alarmTime = calendar.getTimeInMillis();
  if (systemTime > alarmTime) {
      calendar.add(Calendar.DAY_OF_YEAR, 1);//if set the time is smailer than the current time,it will add one day,tomorrow it will ring
      alarmTime = calendar.getTimeInMillis();
  }
  long time = alarmTime - systemTime;
  firstTime += time;

4、设置重复闹钟

alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, AlarmManager.INTERVAL_DAY, uploadIntent);

其中的第一个参数是设置你定时的通过哪种模式ELAPSED还是RTC,第二个是第一次触发闹钟的时间,第三个就是触发闹钟以后多长时间重复一次,第四个就是PendingIntent意图,你打算通过定时去做什么。其中第一个参数有的后边会添加WAKEUP,那个是在系统睡眠的时候也会触发这个闹钟的意思。

第一个参数会如下几种情况的值:

 AlarmManager.ELAPSED_REALTIME表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;
 AlarmManager.ELAPSED_REALTIME_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;
 AlarmManager.RTC表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;
 AlarmManager.RTC_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;
 AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;

二、取消闹钟

相对于设置闹钟的就是取消闹钟

1、也是先获取AlarmManager对象

alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, AlarmManager.INTERVAL_DAY, uploadIntent);
2、获取PendingIntent对象,注意这里的PendingIntent要和你上边的设置闹钟的保持一致其中Service、BroadCast、Activity等,还有它设置的Action

Intent intent2 = new Intent(context, LauncherService.class).setAction(Constants.PENDING_START_ALARM_ACTION+"");
PendingIntent uploadIntent = PendingIntent.getService(context, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
3、取消方法

alarmManager.cancel(uploadIntent);

总结:

其实我本次代码出问题就是在这一块造成的,其实这块获取这个时间这块我是在网上查的,结果就粘贴复制上去的,结果就出了大问题,加上我第一次使用AlarmManager来进行定时操作,结果出现了定时不准的状况,也查看了网上好多种说法,有的说是版本问题会造成定时不准等等,都没有成功。

后来在排查代码时候,我看到了其中注释的代码setTimeZone方法,你这样手动的添加了你现在显示时间的时区了(设置在北京),结果就导致了你这次获取时间的不管你手机上设置的是哪个时区,你获取的第一次闹钟的时间,就是北京时间规定的那个时间,这样就导致了我的定时每当设置上时间,就会直接出发那个闹钟,因为你的时区并不是北京时间,所以这块使我测试出现了大问题,后来找到了,豁然开朗,十分悔恨自己当时直接粘贴复制大意马虎,所以你们当遇见问题时候也要分析好问题出现的关键,不要分析问题出现方向性的失误。

其中还有一点我想提醒的就是,这个方法在Android4.4中当你关机的之前设置Alarm,你重启后不会生效,所以你重启后要重新定时!

另外一点:你们你知道为什么要用AlarmManager实现定时吗?因为平常的Handler.postDelay、Timer等方法当屏幕关闭手机睡眠后不会生效,当长时间定时、有后台等操作来使用AlarmManager。



  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rom_Fisher

赠人玫瑰,手留余香。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值