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
17package android.app;
18
19import android.content.Context;
20import android.content.Intent;
21import android.os.Build;
22import android.os.RemoteException;
23import 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 */
56public 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