1 /* 2 * Copyright (C) 2016 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 androidx.core.app; 18 19 import android.app.AlarmManager; 20 import android.app.PendingIntent; 21 import android.os.Build; 22 23 import androidx.annotation.NonNull; 24 25 /** 26 * Compatibility library for {@link AlarmManager} with fallbacks for older platforms. 27 */ 28 public final class AlarmManagerCompat { 29 /** 30 * Schedule an alarm that represents an alarm clock. 31 * 32 * The system may choose to display information about this alarm to the user. 33 * 34 * <p> 35 * This method is like {@link #setExact}, but implies 36 * {@link AlarmManager#RTC_WAKEUP}. 37 * 38 * @param alarmManager AlarmManager instance used to set the alarm 39 * @param triggerTime time at which the underlying alarm is triggered in wall time 40 * milliseconds since the epoch 41 * @param showIntent an intent that can be used to show or edit details of 42 * the alarm clock. 43 * @param operation Action to perform when the alarm goes off; 44 * typically comes from {@link PendingIntent#getBroadcast 45 * IntentSender.getBroadcast()}. 46 * 47 * @see AlarmManager#set 48 * @see AlarmManager#setRepeating 49 * @see AlarmManager#setWindow 50 * @see #setExact 51 * @see AlarmManager#cancel 52 * @see AlarmManager#getNextAlarmClock() 53 * @see android.content.Context#sendBroadcast 54 * @see android.content.Context#registerReceiver 55 * @see android.content.Intent#filterEquals 56 */ 57 public static void setAlarmClock(@NonNull AlarmManager alarmManager, long triggerTime, 58 @NonNull PendingIntent showIntent, @NonNull PendingIntent operation) { 59 if (Build.VERSION.SDK_INT >= 21) { 60 alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(triggerTime, showIntent), 61 operation); 62 } else { 63 AlarmManagerCompat.setExact(alarmManager, AlarmManager.RTC_WAKEUP, triggerTime, 64 operation); 65 } 66 } 67 68 /** 69 * Like {@link AlarmManager#set(int, long, PendingIntent)}, but this alarm will be allowed to 70 * execute even when the system is in low-power idle modes. This type of alarm must <b>only</b> 71 * be used for situations where it is actually required that the alarm go off while in 72 * idle -- a reasonable example would be for a calendar notification that should make a 73 * sound so the user is aware of it. When the alarm is dispatched, the app will also be 74 * added to the system's temporary whitelist for approximately 10 seconds to allow that 75 * application to acquire further wake locks in which to complete its work.</p> 76 * 77 * <p>These alarms can significantly impact the power use 78 * of the device when idle (and thus cause significant battery blame to the app scheduling 79 * them), so they should be used with care. To reduce abuse, there are restrictions on how 80 * frequently these alarms will go off for a particular application. 81 * Under normal system operation, it will not dispatch these 82 * alarms more than about every minute (at which point every such pending alarm is 83 * dispatched); when in low-power idle modes this duration may be significantly longer, 84 * such as 15 minutes.</p> 85 * 86 * <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen 87 * out of order with any other alarms, even those from the same app. This will clearly happen 88 * when the device is idle (since this alarm can go off while idle, when any other alarms 89 * from the app will be held until later), but may also happen even when not idle.</p> 90 * 91 * <p>Regardless of the app's target SDK version, this call always allows batching of the 92 * alarm.</p> 93 * 94 * @param alarmManager AlarmManager instance used to set the alarm 95 * @param type One of {@link AlarmManager#ELAPSED_REALTIME}, 96 * {@link AlarmManager#ELAPSED_REALTIME_WAKEUP}, 97 * {@link AlarmManager#RTC}, or {@link AlarmManager#RTC_WAKEUP}. 98 * @param triggerAtMillis time in milliseconds that the alarm should go 99 * off, using the appropriate clock (depending on the alarm type). 100 * @param operation Action to perform when the alarm goes off; 101 * typically comes from {@link PendingIntent#getBroadcast 102 * IntentSender.getBroadcast()}. 103 * 104 * @see AlarmManager#set(int, long, PendingIntent) 105 * @see #setExactAndAllowWhileIdle 106 * @see AlarmManager#cancel 107 * @see android.content.Context#sendBroadcast 108 * @see android.content.Context#registerReceiver 109 * @see android.content.Intent#filterEquals 110 * @see AlarmManager#ELAPSED_REALTIME 111 * @see AlarmManager#ELAPSED_REALTIME_WAKEUP 112 * @see AlarmManager#RTC 113 * @see AlarmManager#RTC_WAKEUP 114 */ 115 public static void setAndAllowWhileIdle(@NonNull AlarmManager alarmManager, int type, 116 long triggerAtMillis, @NonNull PendingIntent operation) { 117 if (Build.VERSION.SDK_INT >= 23) { 118 alarmManager.setAndAllowWhileIdle(type, triggerAtMillis, operation); 119 } else { 120 alarmManager.set(type, triggerAtMillis, operation); 121 } 122 } 123 124 /** 125 * Schedule an alarm to be delivered precisely at the stated time. 126 * 127 * <p> 128 * This method is like {@link AlarmManager#set(int, long, PendingIntent)}, but does not permit 129 * the OS to adjust the delivery time. The alarm will be delivered as nearly as 130 * possible to the requested trigger time. 131 * 132 * <p> 133 * <b>Note:</b> only alarms for which there is a strong demand for exact-time 134 * delivery (such as an alarm clock ringing at the requested time) should be 135 * scheduled as exact. Applications are strongly discouraged from using exact 136 * alarms unnecessarily as they reduce the OS's ability to minimize battery use. 137 * 138 * @param alarmManager AlarmManager instance used to set the alarm 139 * @param type One of {@link AlarmManager#ELAPSED_REALTIME}, 140 * {@link AlarmManager#ELAPSED_REALTIME_WAKEUP}, 141 * {@link AlarmManager#RTC}, or {@link AlarmManager#RTC_WAKEUP}. 142 * @param triggerAtMillis time in milliseconds that the alarm should go 143 * off, using the appropriate clock (depending on the alarm type). 144 * @param operation Action to perform when the alarm goes off; 145 * typically comes from {@link PendingIntent#getBroadcast 146 * IntentSender.getBroadcast()}. 147 * 148 * @see AlarmManager#set 149 * @see AlarmManager#setRepeating 150 * @see AlarmManager#setWindow 151 * @see AlarmManager#cancel 152 * @see android.content.Context#sendBroadcast 153 * @see android.content.Context#registerReceiver 154 * @see android.content.Intent#filterEquals 155 * @see AlarmManager#ELAPSED_REALTIME 156 * @see AlarmManager#ELAPSED_REALTIME_WAKEUP 157 * @see AlarmManager#RTC 158 * @see AlarmManager#RTC_WAKEUP 159 */ 160 public static void setExact(@NonNull AlarmManager alarmManager, int type, long triggerAtMillis, 161 @NonNull PendingIntent operation) { 162 if (Build.VERSION.SDK_INT >= 19) { 163 alarmManager.setExact(type, triggerAtMillis, operation); 164 } else { 165 alarmManager.set(type, triggerAtMillis, operation); 166 } 167 } 168 169 /** 170 * Like {@link #setExact}, but this alarm will be allowed to execute 171 * even when the system is in low-power idle modes. If you don't need exact scheduling of 172 * the alarm but still need to execute while idle, consider using 173 * {@link #setAndAllowWhileIdle}. This type of alarm must <b>only</b> 174 * be used for situations where it is actually required that the alarm go off while in 175 * idle -- a reasonable example would be for a calendar notification that should make a 176 * sound so the user is aware of it. When the alarm is dispatched, the app will also be 177 * added to the system's temporary whitelist for approximately 10 seconds to allow that 178 * application to acquire further wake locks in which to complete its work.</p> 179 * 180 * <p>These alarms can significantly impact the power use 181 * of the device when idle (and thus cause significant battery blame to the app scheduling 182 * them), so they should be used with care. To reduce abuse, there are restrictions on how 183 * frequently these alarms will go off for a particular application. 184 * Under normal system operation, it will not dispatch these 185 * alarms more than about every minute (at which point every such pending alarm is 186 * dispatched); when in low-power idle modes this duration may be significantly longer, 187 * such as 15 minutes.</p> 188 * 189 * <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen 190 * out of order with any other alarms, even those from the same app. This will clearly happen 191 * when the device is idle (since this alarm can go off while idle, when any other alarms 192 * from the app will be held until later), but may also happen even when not idle. 193 * Note that the OS will allow itself more flexibility for scheduling these alarms than 194 * regular exact alarms, since the application has opted into this behavior. When the 195 * device is idle it may take even more liberties with scheduling in order to optimize 196 * for battery life.</p> 197 * 198 * @param alarmManager AlarmManager instance used to set the alarm 199 * @param type One of {@link AlarmManager#ELAPSED_REALTIME}, 200 * {@link AlarmManager#ELAPSED_REALTIME_WAKEUP}, 201 * {@link AlarmManager#RTC}, or {@link AlarmManager#RTC_WAKEUP}. 202 * @param triggerAtMillis time in milliseconds that the alarm should go 203 * off, using the appropriate clock (depending on the alarm type). 204 * @param operation Action to perform when the alarm goes off; 205 * typically comes from {@link PendingIntent#getBroadcast 206 * IntentSender.getBroadcast()}. 207 * 208 * @see AlarmManager#set 209 * @see AlarmManager#setRepeating 210 * @see AlarmManager#setWindow 211 * @see AlarmManager#cancel 212 * @see android.content.Context#sendBroadcast 213 * @see android.content.Context#registerReceiver 214 * @see android.content.Intent#filterEquals 215 * @see AlarmManager#ELAPSED_REALTIME 216 * @see AlarmManager#ELAPSED_REALTIME_WAKEUP 217 * @see AlarmManager#RTC 218 * @see AlarmManager#RTC_WAKEUP 219 */ 220 public static void setExactAndAllowWhileIdle(@NonNull AlarmManager alarmManager, int type, 221 long triggerAtMillis, @NonNull PendingIntent operation) { 222 if (Build.VERSION.SDK_INT >= 23) { 223 alarmManager.setExactAndAllowWhileIdle(type, triggerAtMillis, operation); 224 } else { 225 AlarmManagerCompat.setExact(alarmManager, type, triggerAtMillis, operation); 226 } 227 } 228 229 private AlarmManagerCompat() { 230 } 231 } 232