1 package com.xtremelabs.robolectric.shadows; 2 3 import android.app.AlarmManager; 4 import android.app.PendingIntent; 5 import android.content.Intent; 6 import com.xtremelabs.robolectric.internal.Implementation; 7 import com.xtremelabs.robolectric.internal.Implements; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 import static com.xtremelabs.robolectric.Robolectric.shadowOf; 13 14 /** 15 * Shadows the {@code android.app.AlarmManager} class. 16 */ 17 @SuppressWarnings({"UnusedDeclaration"}) 18 @Implements(AlarmManager.class) 19 public class ShadowAlarmManager { 20 21 private List<ScheduledAlarm> scheduledAlarms = new ArrayList<ScheduledAlarm>(); 22 23 @Implementation 24 public void set(int type, long triggerAtTime, PendingIntent operation) { 25 internalSet(type, triggerAtTime, 0L, operation); 26 } 27 28 @Implementation 29 public void setRepeating (int type, long triggerAtTime, long interval, PendingIntent operation){ 30 internalSet(type, triggerAtTime, interval, operation); 31 } 32 33 private void internalSet(int type, long triggerAtTime, long interval, PendingIntent operation) { 34 Intent intent = shadowOf(operation).getSavedIntent(); 35 for (ScheduledAlarm scheduledAlarm : scheduledAlarms) { 36 Intent scheduledIntent = shadowOf(scheduledAlarm.operation).getSavedIntent(); 37 if (scheduledIntent.filterEquals(intent)) { 38 scheduledAlarms.remove(scheduledAlarm); 39 break; 40 } 41 } 42 scheduledAlarms.add(new ScheduledAlarm(type, triggerAtTime, interval, operation)); 43 } 44 45 /** 46 * Non-Android accessor consumes and returns the next scheduled alarm on the 47 * AlarmManager's stack. 48 * 49 * @return the next scheduled alarm, wrapped in a 50 * {@link ShadowAlarmManager.ScheduledAlarm} object 51 */ 52 public ScheduledAlarm getNextScheduledAlarm() { 53 if (scheduledAlarms.isEmpty()) { 54 return null; 55 } else { 56 return scheduledAlarms.remove(0); 57 } 58 } 59 60 /** 61 * Non-Android accessor returns the most recent scheduled alarm without 62 * consuming it. 63 * 64 * @return the most recently scheduled alarm, wrapped in a 65 * {@link ShadowAlarmManager.ScheduledAlarm} object 66 */ 67 public ScheduledAlarm peekNextScheduledAlarm() { 68 if (scheduledAlarms.isEmpty()) { 69 return null; 70 } else { 71 return scheduledAlarms.get(0); 72 } 73 } 74 75 public List<ScheduledAlarm> getScheduledAlarms() { 76 return scheduledAlarms; 77 } 78 79 @Implementation 80 public void cancel(PendingIntent pendingIntent) { 81 final Intent intentTypeToRemove = shadowOf(pendingIntent).getSavedIntent(); 82 for (ScheduledAlarm scheduledAlarm : new ArrayList<ScheduledAlarm>(scheduledAlarms)) { 83 final Intent alarmIntent = shadowOf(scheduledAlarm.operation).getSavedIntent(); 84 if (intentTypeToRemove.filterEquals(alarmIntent)) { 85 scheduledAlarms.remove(scheduledAlarm); 86 } 87 } 88 } 89 90 /** 91 * Container object to hold an PendingIntent, together with the alarm 92 * parameters used in a call to {@code AlarmManager} 93 */ 94 public class ScheduledAlarm { 95 public int type; 96 public long triggerAtTime; 97 public long interval; 98 public PendingIntent operation; 99 100 public ScheduledAlarm(int type, long triggerAtTime, PendingIntent operation) { 101 this(type, triggerAtTime, 0, operation); 102 } 103 104 public ScheduledAlarm(int type, long triggerAtTime, long interval, PendingIntent operation) { 105 this.type = type; 106 this.triggerAtTime = triggerAtTime; 107 this.operation = operation; 108 this.interval = interval; 109 } 110 } 111 } 112