AlarmManager.setRepeating将不再准确

背景:

当我们想让Android应用程序定时为做一件工作时,我们往往会在一个BroadcastReceiver中使用AlarmManager.setRepeating()方法来实现。在API 19(即Kitkat)之后,这一方法将不再准确地保证每次工作都在你设置的时间开始。

解释:

Note: Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to "batch" alarms together across the entire system, minimizing the number of times the device needs to "wake up" and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.

With the new batching policy, delivery ordering guarantees are not as strong as they were previously. If the application sets multiple alarms, it is possible that these alarms‘ actual delivery ordering may not match the order of their requesteddelivery times. If your application has strong ordering requirements there are other APIs that you can use to get the necessary behavior; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).

原来,操作系统为了节能省电,将会调整alarm唤醒的时间。故通过AlarmManager.setRepeating()方法将不再保证你定义的工作能按时开始。

解决办法:

1. 按照官方网站说的,调用API 19之后出现的setWindow()或者setExact()方法。

2. 按照如下方法写scheduleAlarm()方法:

public class PollReceiver extends BroadcastReceiver {
   private static final int PERIOD = 60000; // 1 minutes

   @Override
   public void onReceive(Context ctxt, Intent i) {
       if (i.getAction().equals("great")) {
           scheduleAlarms(ctxt);
             //Do your work
       }
   }

   static void scheduleAlarms(Context ctxt) {
       AlarmManager mgr = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
       Intent i = new Intent(ctxt, PollReceiver.class);
       i.setAction("great");
       PendingIntent pi = PendingIntent.getBroadcast(ctxt, 0, i, 0);.
       mgr.cancel(pi);
       mgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+PERIOD, pi);

   }

}
时间: 2024-11-11 17:08:03

AlarmManager.setRepeating将不再准确的相关文章

使用AlarmManager实现Android应用每天定时执行任务

介绍 android官方文档:AlarmManager 在Android平台,除了使用AlarmManger外,还可以使用Timer或者Handler来实现定时任务,但这两种方式定时并不会太准确:因此如果我们需要实现精准定时任务,使用AlarmManger更为合理. AlarmManager类提供对系统闹钟服务(或称为定时器服务)的访问接口,使用它既可以指定单次执行的定时任务,也可以指定重复运行的任务. 当闹钟指定触发时间到达时,实际上是系统发出为这个闹钟注册的广播,因此我们需要实现一个针对特定

Android随笔之——闹钟制作铺垫之AlarmManager详解

说实话,之前写的两篇博客Android广播机制Broadcast详解.Android时间.日期相关类和方法以及现在要写的,都算是为之后要写的闹钟应用做铺垫,有兴趣的话,大家可以去看看前两篇博客. 一.AlarmManager简介 对于一个闹钟应用的实现,个人觉得最主要的应该要属于AlarmManager了.AlarmManager称为全局定时器,字面意思就是闹钟管理(请原谅我蹩脚的英语),是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent.简单的说就是我

Android实战简易教程-第五十八枪(AlarmManager类用法研究小实例)

一.概念及相关方法 android中实现定时任务一般有两种实现方式,一种是使用Java API中提供的Timer类,一种是使用android的Alarm机制.Timer机制有个短板就是不太适用于那些需要长期在后台运行的任务,我们都知道为了让电池更加耐用,会在长时间不操作手机的情况下,CPU进入休眠状态,这是可能导致Timer中的定时任务无法正确运行.所以我们重点来研究一下Alarm机制. AlarmManager,顾名思义,就是"提醒",是Android中常用的一种系统级别的提示服务,

我的Android进阶之旅------>Android使用AlarmManager全局定时器实现定时更换壁纸

该DEMO将会通过AlarmManager来周期的调用ChangeService,从而让系统实现定时更换壁纸的功能. 更换壁纸的API为android.app.WallpaperManager,它提供了clear()方法来清除壁纸,还提供了如下方法来设置壁纸. setResource(int resid)将壁纸设置为resid资源所代表的图片 setBitmap(Bitmap bitmap)将壁纸设置为bitmap所代表的位图 setStream(InputStream data)将壁纸设置为d

Android提供的系统服务之--AlarmManager(闹钟服务)

Android提供的系统服务之--AlarmManager(闹钟服务) --转载请注明出处:coder-pig 本节引言: 本节主要介绍的是Android系统服务中的---AlarmManager(闹钟服务), 除了开发手机闹钟外,更多的时候是作为一个全局的定时器,通常与Service 结合,在特定时间启动其他的组件!本节就来对这个AlarmManager来进行解析 同时通过小闹钟与自动换壁纸来演示这个AlarmManager的用法,好了,开始本节的 内容吧! 本节正文: 1.概念与相关属性方法

Android之AlarmManager

Android平台中,Alarm Manager Service控制着闹钟和唤醒功能.和其他系统服务一样,提供了一个辅助管理类-AlarmManager,我们只需要使用AlarmManager即可调用Alarm Manager Service. 在AlarmManager提供了如下方法: 1.void cancel(pendingIntent operatioin):取消一个已注册的定时器 2.void set(int type,long triggerAtTime,PendingIntent

Android service进程保护

应用进程保活基本就是围绕两个方面来展开: 1 尽量保证进程不被杀死. 2 进程被杀死后复活.细分如下: 1)Service重启 2)进程守护 3)Receiver触发 4) AlarmManager or JobScheduler循环触发 5)与系统Service捆绑-–可以不考虑,了解即可 下面将围绕这几点展开讨论. 一,基本概念 1.什么才叫应用进程保活 应用进程保活可以理解为应用位于后台永远不能被杀死.这里的可以简略地分为两种情况,第一种是当系统资源紧俏的时候或者基于某种系统自身的后台运行

多功能时钟应用

近几天做了个多功能时钟,分享一下 主界面 对应的代码: MainActivity.java package com.example.clock; import android.app.Activity; import android.os.Bundle; import android.widget.TabHost; public class MainActivity extends Activity { private TabHost tabHost; @Override protected v

论Android应用进程长存的可行性

本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可. 转载或引用前请注明来自AigeStudio 侵权必究 关于爱哥 如何能让我们的应用能够在系统后台持续地运行是一个自Android从娘(ma)胎(bi)里出来时就议论不停的话题,而且这似乎成了一个牛(liu)逼(mang)应用标配的功能.每当有人问起爱哥这个沉重的问题时我都会选择避而不答,原因有二,一是我并不曾深入地研究过相关功能,二是本人作为一个有情怀的开发者是不提倡让应用去占用没必要且吃紧的系统资源.不过最近一个偶然的机会让