AlarmManager

来源:互联网 发布:美国离线导航软件 编辑:程序博客网 时间:2024/05/17 02:26
Java代码  收藏代码
  1. alarmManager.set(AlarmManager.RTC_WAKEUP, (5*1000), sender);  

 

本意是设定五秒后启动闹钟 但是每次都是我设置完闹钟之后立马就启动了。

后来我发现问题出在第二个参数上 我对他的理解是错误的


我之前以为它是“延迟”时间,而实际它是“启动”时间。

要理解这个参数还要看type这个参数

 

Java代码  收藏代码
  1. public static final int ELAPSED_REALTIME  
  2.         //当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠时间,可以通过调用SystemClock.elapsedRealtime()获得。系统值是3    (0x00000003)。  
  3.   
  4.         public static final int ELAPSED_REALTIME_WAKEUP  
  5.         //能唤醒系统,用法同ELAPSED_REALTIME,系统值是2 (0x00000002) 。  
  6.   
  7.         public static final int RTC  
  8.         //当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是绝对时间,所用时间是UTC时间,可以通过调用 System.currentTimeMillis()获得。系统值是1 (0x00000001) 。  
  9.   
  10.         public static final int RTC_WAKEUP  
  11.         //能唤醒系统,用法同RTC类型,系统值为 0 (0x00000000) 。  

 

它大致分为两种类型 一种是相对时间 一种是绝对时间

所以,根据使用的类型不同 triggerAtTime设置也有所不同

如果使用ELAPSED_REALTIME_WAKEUP类型 应该调用SystemClock.elapsedRealtime()获取相对时间在加上你设定的延迟时间

Java代码  收藏代码
  1. alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+5000, sender);  

 

如果使用RTC_WAKEUP类型 应该调用System.currentTimeMillis()获取从1970.1.1号以来的时间在加上你设定的延迟时间

Java代码  收藏代码
  1. alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+5000, sender);  

setRepeating方法有4个参数,这些参数的含义如下:

type:表示警报类型,一般可以取的值是AlarmManager.RTC和AlarmManager.RTC_WAKEUP。如果将type参数值设为AlarmManager.RTC,表示是一个正常的定时器,如果将type参数值设为AlarmManager.RTC_WAKEUP,除了有定时器的功能外,还会发出警报声(例如,响铃、震动)。

triggerAtTime:第1次运行时要等待的时间,也就是执行延迟时间,单位是毫秒。

interval:表示执行的时间间隔,单位是毫秒。

operation:一个PendingIntent对象,表示到时间后要执行的操作。PendingIntent与Intent类似,可以封装Activity、BroadcastReceiver和Service。但与Intent不同的是,PendingIntent可以脱离应用程序而存在。


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 = (AlarmManagerctxt.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);

   }

}




0 0
原创粉丝点击