Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app;
     18 
     19 import android.content.Context;
     20 import android.content.Intent;
     21 import android.os.Build;
     22 import android.os.RemoteException;
     23 import android.os.WorkSource;
     24 
     25 /**
     26  * This class provides access to the system alarm services.  These allow you
     27  * to schedule your application to be run at some point in the future.  When
     28  * an alarm goes off, the {@link Intent} that had been registered for it
     29  * is broadcast by the system, automatically starting the target application
     30  * if it is not already running.  Registered alarms are retained while the
     31  * device is asleep (and can optionally wake the device up if they go off
     32  * during that time), but will be cleared if it is turned off and rebooted.
     33  *
     34  * <p>The Alarm Manager holds a CPU wake lock as long as the alarm receiver's
     35  * onReceive() method is executing. This guarantees that the phone will not sleep
     36  * until you have finished handling the broadcast. Once onReceive() returns, the
     37  * Alarm Manager releases this wake lock. This means that the phone will in some
     38  * cases sleep as soon as your onReceive() method completes.  If your alarm receiver
     39  * called {@link android.content.Context#startService Context.startService()}, it
     40  * is possible that the phone will sleep before the requested service is launched.
     41  * To prevent this, your BroadcastReceiver and Service will need to implement a
     42  * separate wake lock policy to ensure that the phone continues running until the
     43  * service becomes available.
     44  *
     45  * <p><b>Note: The Alarm Manager is intended for cases where you want to have
     46  * your application code run at a specific time, even if your application is
     47  * not currently running.  For normal timing operations (ticks, timeouts,
     48  * etc) it is easier and much more efficient to use
     49  * {@link android.os.Handler}.</b>
     50  *
     51  * <p>You do not
     52  * instantiate this class directly; instead, retrieve it through
     53  * {@link android.content.Context#getSystemService
     54  * Context.getSystemService(Context.ALARM_SERVICE)}.
     55  */
     56 public class AlarmManager
     57 {
     58     private static final String TAG = "AlarmManager";
     59 
     60     /**
     61      * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}
     62      * (wall clock time in UTC), which will wake up the device when
     63      * it goes off.
     64      */
     65     public static final int RTC_WAKEUP = 0;
     66     /**
     67      * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}
     68      * (wall clock time in UTC).  This alarm does not wake the
     69      * device up; if it goes off while the device is asleep, it will not be
     70      * delivered until the next time the device wakes up.
     71      */
     72     public static final int RTC = 1;
     73     /**
     74      * Alarm time in {@link android.os.SystemClock#elapsedRealtime
     75      * SystemClock.elapsedRealtime()} (time since boot, including sleep),
     76      * which will wake up the device when it goes off.
     77      */
     78     public static final int ELAPSED_REALTIME_WAKEUP = 2;
     79     /**
     80      * Alarm time in {@link android.os.SystemClock#elapsedRealtime
     81      * SystemClock.elapsedRealtime()} (time since boot, including sleep).
     82      * This alarm does not wake the device up; if it goes off while the device
     83      * is asleep, it will not be delivered until the next time the device
     84      * wakes up.
     85      */
     86     public static final int ELAPSED_REALTIME = 3;
     87 
     88     /** @hide */
     89     public static final long WINDOW_EXACT = 0;
     90     /** @hide */
     91     public static final long WINDOW_HEURISTIC = -1;
     92 
     93     private final IAlarmManager mService;
     94     private final boolean mAlwaysExact;
     95 
     96 
     97     /**
     98      * package private on purpose
     99      */
    100     AlarmManager(IAlarmManager service, Context ctx) {
    101         mService = service;
    102 
    103         final int sdkVersion = ctx.getApplicationInfo().targetSdkVersion;
    104         mAlwaysExact = (sdkVersion < Build.VERSION_CODES.KITKAT);
    105     }
    106 
    107     private long legacyExactLength() {
    108         return (mAlwaysExact ? WINDOW_EXACT : WINDOW_HEURISTIC);
    109     }
    110 
    111     /**
    112      * TBW: discussion of fuzzy nature of alarms in KLP+.
    113      *
    114      * <p>Schedule an alarm.  <b>Note: for timing operations (ticks, timeouts,
    115      * etc) it is easier and much more efficient to use
    116      * {@link android.os.Handler}.</b>  If there is already an alarm scheduled
    117      * for the same IntentSender, it will first be canceled.
    118      *
    119      * <p>If the time occurs in the past, the alarm will be triggered
    120      * immediately.  If there is already an alarm for this Intent
    121      * scheduled (with the equality of two intents being defined by
    122      * {@link Intent#filterEquals}), then it will be removed and replaced by
    123      * this one.
    124      *
    125      * <p>
    126      * The alarm is an intent broadcast that goes to a broadcast receiver that
    127      * you registered with {@link android.content.Context#registerReceiver}
    128      * or through the &lt;receiver&gt; tag in an AndroidManifest.xml file.
    129      *
    130      * <p>
    131      * Alarm intents are delivered with a data extra of type int called
    132      * {@link Intent#EXTRA_ALARM_COUNT Intent.EXTRA_ALARM_COUNT} that indicates
    133      * how many past alarm events have been accumulated into this intent
    134      * broadcast.  Recurring alarms that have gone undelivered because the
    135      * phone was asleep may have a count greater than one when delivered.
    136      *
    137      * @param type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC or
    138      *             RTC_WAKEUP.
    139      * @param triggerAtMillis time in milliseconds that the alarm should go
    140      * off, using the appropriate clock (depending on the alarm type).
    141      * @param operation Action to perform when the alarm goes off;
    142      * typically comes from {@link PendingIntent#getBroadcast
    143      * IntentSender.getBroadcast()}.
    144      *
    145      * @see android.os.Handler
    146      * @see #setExact
    147      * @see #setRepeating
    148      * @see #setWindow
    149      * @see #cancel
    150      * @see android.content.Context#sendBroadcast
    151      * @see android.content.Context#registerReceiver
    152      * @see android.content.Intent#filterEquals
    153      * @see #ELAPSED_REALTIME
    154      * @see #ELAPSED_REALTIME_WAKEUP
    155      * @see #RTC
    156      * @see #RTC_WAKEUP
    157      */
    158     public void set(int type, long triggerAtMillis, PendingIntent operation) {
    159         setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation, null);
    160     }
    161 
    162     /**
    163      * Schedule a repeating alarm.  <b>Note: for timing operations (ticks,
    164      * timeouts, etc) it is easier and much more efficient to use
    165      * {@link android.os.Handler}.</b>  If there is already an alarm scheduled
    166      * for the same IntentSender, it will first be canceled.
    167      *
    168      * <p>Like {@link #set}, except you can also
    169      * supply a rate at which the alarm will repeat.  This alarm continues
    170      * repeating until explicitly removed with {@link #cancel}.  If the time
    171      * occurs in the past, the alarm will be triggered immediately, with an
    172      * alarm count depending on how far in the past the trigger time is relative
    173      * to the repeat interval.
    174      *
    175      * <p>If an alarm is delayed (by system sleep, for example, for non
    176      * _WAKEUP alarm types), a skipped repeat will be delivered as soon as
    177      * possible.  After that, future alarms will be delivered according to the
    178      * original schedule; they do not drift over time.  For example, if you have
    179      * set a recurring alarm for the top of every hour but the phone was asleep
    180      * from 7:45 until 8:45, an alarm will be sent as soon as the phone awakens,
    181      * then the next alarm will be sent at 9:00.
    182      *
    183      * <p>If your application wants to allow the delivery times to drift in
    184      * order to guarantee that at least a certain time interval always elapses
    185      * between alarms, then the approach to take is to use one-time alarms,
    186      * scheduling the next one yourself when handling each alarm delivery.
    187      *
    188      * @param type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP}, RTC or
    189      *             RTC_WAKEUP.
    190      * @param triggerAtMillis time in milliseconds that the alarm should first
    191      * go off, using the appropriate clock (depending on the alarm type).
    192      * @param intervalMillis interval in milliseconds between subsequent repeats
    193      * of the alarm.
    194      * @param operation Action to perform when the alarm goes off;
    195      * typically comes from {@link PendingIntent#getBroadcast
    196      * IntentSender.getBroadcast()}.
    197      *
    198      * @see android.os.Handler
    199      * @see #set
    200      * @see #setExact
    201      * @see #setWindow
    202      * @see #cancel
    203      * @see android.content.Context#sendBroadcast
    204      * @see android.content.Context#registerReceiver
    205      * @see android.content.Intent#filterEquals
    206      * @see #ELAPSED_REALTIME
    207      * @see #ELAPSED_REALTIME_WAKEUP
    208      * @see #RTC
    209      * @see #RTC_WAKEUP
    210      */
    211     public void setRepeating(int type, long triggerAtMillis,
    212             long intervalMillis, PendingIntent operation) {
    213         setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation, null);
    214     }
    215 
    216     /**
    217      * Schedule an alarm to be delivered within a given window of time.
    218      *
    219      * TBW: clean up these docs
    220      *
    221      * @param type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC or
    222      *        RTC_WAKEUP.
    223      * @param windowStartMillis The earliest time, in milliseconds, that the alarm should
    224      *        be delivered, expressed in the appropriate clock's units (depending on the alarm
    225      *        type).
    226      * @param windowLengthMillis The length of the requested delivery window,
    227      *        in milliseconds.  The alarm will be delivered no later than this many
    228      *        milliseconds after the windowStartMillis time.  Note that this parameter
    229      *        is a <i>duration,</i> not the timestamp of the end of the window.
    230      * @param operation Action to perform when the alarm goes off;
    231      *        typically comes from {@link PendingIntent#getBroadcast
    232      *        IntentSender.getBroadcast()}.
    233      *
    234      * @see #set
    235      * @see #setExact
    236      * @see #setRepeating
    237      * @see #cancel
    238      * @see android.content.Context#sendBroadcast
    239      * @see android.content.Context#registerReceiver
    240      * @see android.content.Intent#filterEquals
    241      * @see #ELAPSED_REALTIME
    242      * @see #ELAPSED_REALTIME_WAKEUP
    243      * @see #RTC
    244      * @see #RTC_WAKEUP
    245      */
    246     public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
    247             PendingIntent operation) {
    248         setImpl(type, windowStartMillis, windowLengthMillis, 0, operation, null);
    249     }
    250 
    251     /**
    252      * TBW: new 'exact' alarm that must be delivered as nearly as possible
    253      * to the precise time specified.
    254      */
    255     public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
    256         setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation, null);
    257     }
    258 
    259     /** @hide */
    260     public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
    261             PendingIntent operation, WorkSource workSource) {
    262         setImpl(type, triggerAtMillis, windowMillis, intervalMillis, operation, workSource);
    263     }
    264 
    265     private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
    266             PendingIntent operation, WorkSource workSource) {
    267         if (triggerAtMillis < 0) {
    268             /* NOTYET
    269             if (mAlwaysExact) {
    270                 // Fatal error for KLP+ apps to use negative trigger times
    271                 throw new IllegalArgumentException("Invalid alarm trigger time "
    272                         + triggerAtMillis);
    273             }
    274             */
    275             triggerAtMillis = 0;
    276         }
    277 
    278         try {
    279             mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation,
    280                     workSource);
    281         } catch (RemoteException ex) {
    282         }
    283     }
    284 
    285     /**
    286      * @deprecated setInexactRepeating() is deprecated; as of API 19 all
    287      * repeating alarms are inexact.
    288      */
    289     @Deprecated
    290     public static final long INTERVAL_FIFTEEN_MINUTES = 15 * 60 * 1000;
    291 
    292     /**
    293      * @deprecated setInexactRepeating() is deprecated; as of API 19 all
    294      * repeating alarms are inexact.
    295      */
    296     @Deprecated
    297     public static final long INTERVAL_HALF_HOUR = 2*INTERVAL_FIFTEEN_MINUTES;
    298 
    299     /**
    300      * @deprecated setInexactRepeating() is deprecated; as of API 19 all
    301      * repeating alarms are inexact.
    302      */
    303     @Deprecated
    304     public static final long INTERVAL_HOUR = 2*INTERVAL_HALF_HOUR;
    305 
    306     /**
    307      * @deprecated setInexactRepeating() is deprecated; as of API 19 all
    308      * repeating alarms are inexact.
    309      */
    310     @Deprecated
    311     public static final long INTERVAL_HALF_DAY = 12*INTERVAL_HOUR;
    312 
    313     /**
    314      * @deprecated setInexactRepeating() is deprecated; as of API 19 all
    315      * repeating alarms are inexact.
    316      */
    317     @Deprecated
    318     public static final long INTERVAL_DAY = 2*INTERVAL_HALF_DAY;
    319 
    320     /**
    321      * Schedule a repeating alarm that has inexact trigger time requirements;
    322      * for example, an alarm that repeats every hour, but not necessarily at
    323      * the top of every hour.  These alarms are more power-efficient than
    324      * the strict recurrences supplied by {@link #setRepeating}, since the
    325      * system can adjust alarms' phase to cause them to fire simultaneously,
    326      * avoiding waking the device from sleep more than necessary.
    327      *
    328      * <p>Your alarm's first trigger will not be before the requested time,
    329      * but it might not occur for almost a full interval after that time.  In
    330      * addition, while the overall period of the repeating alarm will be as
    331      * requested, the time between any two successive firings of the alarm
    332      * may vary.  If your application demands very low jitter, use
    333      * {@link #setRepeating} instead.
    334      *
    335      * @param type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP}, RTC or
    336      *             RTC_WAKEUP.
    337      * @param triggerAtMillis time in milliseconds that the alarm should first
    338      * go off, using the appropriate clock (depending on the alarm type).  This
    339      * is inexact: the alarm will not fire before this time, but there may be a
    340      * delay of almost an entire alarm interval before the first invocation of
    341      * the alarm.
    342      * @param intervalMillis interval in milliseconds between subsequent repeats
    343      * of the alarm.  If this is one of INTERVAL_FIFTEEN_MINUTES,
    344      * INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY
    345      * then the alarm will be phase-aligned with other alarms to reduce the
    346      * number of wakeups.  Otherwise, the alarm will be set as though the
    347      * application had called {@link #setRepeating}.
    348      * @param operation Action to perform when the alarm goes off;
    349      * typically comes from {@link PendingIntent#getBroadcast
    350      * IntentSender.getBroadcast()}.
    351      *
    352      * @deprecated As of API 19, all repeating alarms are inexact.
    353      *
    354      * @see android.os.Handler
    355      * @see #set
    356      * @see #cancel
    357      * @see android.content.Context#sendBroadcast
    358      * @see android.content.Context#registerReceiver
    359      * @see android.content.Intent#filterEquals
    360      * @see #ELAPSED_REALTIME
    361      * @see #ELAPSED_REALTIME_WAKEUP
    362      * @see #RTC
    363      * @see #RTC_WAKEUP
    364      * @see #INTERVAL_FIFTEEN_MINUTES
    365      * @see #INTERVAL_HALF_HOUR
    366      * @see #INTERVAL_HOUR
    367      * @see #INTERVAL_HALF_DAY
    368      * @see #INTERVAL_DAY
    369      */
    370     @Deprecated
    371     public void setInexactRepeating(int type, long triggerAtMillis,
    372             long intervalMillis, PendingIntent operation) {
    373         setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation, null);
    374     }
    375 
    376     /**
    377      * Remove any alarms with a matching {@link Intent}.
    378      * Any alarm, of any type, whose Intent matches this one (as defined by
    379      * {@link Intent#filterEquals}), will be canceled.
    380      *
    381      * @param operation IntentSender which matches a previously added
    382      * IntentSender.
    383      *
    384      * @see #set
    385      */
    386     public void cancel(PendingIntent operation) {
    387         try {
    388             mService.remove(operation);
    389         } catch (RemoteException ex) {
    390         }
    391     }
    392 
    393     /**
    394      * Set the system wall clock time.
    395      * Requires the permission android.permission.SET_TIME.
    396      *
    397      * @param millis time in milliseconds since the Epoch
    398      */
    399     public void setTime(long millis) {
    400         try {
    401             mService.setTime(millis);
    402         } catch (RemoteException ex) {
    403         }
    404     }
    405 
    406     /**
    407      * Set the system default time zone.
    408      * Requires the permission android.permission.SET_TIME_ZONE.
    409      *
    410      * @param timeZone in the format understood by {@link java.util.TimeZone}
    411      */
    412     public void setTimeZone(String timeZone) {
    413         try {
    414             mService.setTimeZone(timeZone);
    415         } catch (RemoteException ex) {
    416         }
    417     }
    418 }
    419