• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 package com.android.deskclock.alarms;
17 
18 import android.app.AlarmManager;
19 import android.app.Notification;
20 import android.app.NotificationManager;
21 import android.app.PendingIntent;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.res.Resources;
25 
26 import com.android.deskclock.AlarmClockFragment;
27 import com.android.deskclock.AlarmUtils;
28 import com.android.deskclock.DeskClock;
29 import com.android.deskclock.LogUtils;
30 import com.android.deskclock.R;
31 import com.android.deskclock.provider.Alarm;
32 import com.android.deskclock.provider.AlarmInstance;
33 
34 public final class AlarmNotifications {
35 
registerNextAlarmWithAlarmManager(Context context, AlarmInstance instance)36     public static void registerNextAlarmWithAlarmManager(Context context, AlarmInstance instance)  {
37         // Sets a surrogate alarm with alarm manager that provides the AlarmClockInfo for the
38         // alarm that is going to fire next. The operation is constructed such that it is ignored
39         // by AlarmStateManager.
40 
41         AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
42 
43         int flags = instance == null ? PendingIntent.FLAG_NO_CREATE : 0;
44         PendingIntent operation = PendingIntent.getBroadcast(context, 0 /* requestCode */,
45                 AlarmStateManager.createIndicatorIntent(context), flags);
46 
47         if (instance != null) {
48             long alarmTime = instance.getAlarmTime().getTimeInMillis();
49 
50             // Create an intent that can be used to show or edit details of the next alarm.
51             PendingIntent viewIntent = PendingIntent.getActivity(context, instance.hashCode(),
52                     createViewAlarmIntent(context, instance), PendingIntent.FLAG_UPDATE_CURRENT);
53 
54             AlarmManager.AlarmClockInfo info =
55                     new AlarmManager.AlarmClockInfo(alarmTime, viewIntent);
56             alarmManager.setAlarmClock(info, operation);
57         } else if (operation != null) {
58             alarmManager.cancel(operation);
59         }
60     }
61 
showLowPriorityNotification(Context context, AlarmInstance instance)62     public static void showLowPriorityNotification(Context context, AlarmInstance instance) {
63         LogUtils.v("Displaying low priority notification for alarm instance: " + instance.mId);
64         NotificationManager nm = (NotificationManager)
65                 context.getSystemService(Context.NOTIFICATION_SERVICE);
66 
67         Resources resources = context.getResources();
68         Notification.Builder notification = new Notification.Builder(context)
69                 .setContentTitle(resources.getString(R.string.alarm_alert_predismiss_title))
70                 .setContentText(AlarmUtils.getAlarmText(context, instance))
71                 .setSmallIcon(R.drawable.stat_notify_alarm)
72                 .setOngoing(false)
73                 .setAutoCancel(false)
74                 .setPriority(Notification.PRIORITY_DEFAULT)
75                 .setCategory(Notification.CATEGORY_ALARM);
76 
77         // Setup up hide notification
78         Intent hideIntent = AlarmStateManager.createStateChangeIntent(context, "DELETE_TAG",
79                 instance, AlarmInstance.HIDE_NOTIFICATION_STATE);
80         notification.setDeleteIntent(PendingIntent.getBroadcast(context, instance.hashCode(),
81                 hideIntent, PendingIntent.FLAG_UPDATE_CURRENT));
82 
83         // Setup up dismiss action
84         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context, "DISMISS_TAG",
85                 instance, AlarmInstance.DISMISSED_STATE);
86         notification.addAction(R.drawable.ic_alarm_off_black,
87                 resources.getString(R.string.alarm_alert_dismiss_now_text),
88                 PendingIntent.getBroadcast(context, instance.hashCode(),
89                         dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
90 
91         // Setup content action if instance is owned by alarm
92         Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
93         notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
94                 viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
95 
96         nm.cancel(instance.hashCode());
97         nm.notify(instance.hashCode(), notification.build());
98     }
99 
showHighPriorityNotification(Context context, AlarmInstance instance)100     public static void showHighPriorityNotification(Context context, AlarmInstance instance) {
101         LogUtils.v("Displaying high priority notification for alarm instance: " + instance.mId);
102         NotificationManager nm = (NotificationManager)
103                 context.getSystemService(Context.NOTIFICATION_SERVICE);
104 
105         Resources resources = context.getResources();
106         Notification.Builder notification = new Notification.Builder(context)
107                 .setContentTitle(resources.getString(R.string.alarm_alert_predismiss_title))
108                 .setContentText(AlarmUtils.getAlarmText(context, instance))
109                 .setSmallIcon(R.drawable.stat_notify_alarm)
110                 .setOngoing(true)
111                 .setAutoCancel(false)
112                 .setPriority(Notification.PRIORITY_HIGH)
113                 .setCategory(Notification.CATEGORY_ALARM);
114 
115         // Setup up dismiss action
116         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context, "DISMISS_TAG",
117                 instance, AlarmInstance.DISMISSED_STATE);
118         notification.addAction(R.drawable.ic_alarm_off_black,
119                 resources.getString(R.string.alarm_alert_dismiss_now_text),
120                 PendingIntent.getBroadcast(context, instance.hashCode(),
121                         dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
122 
123         // Setup content action if instance is owned by alarm
124         Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
125         notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
126                 viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
127 
128         nm.cancel(instance.hashCode());
129         nm.notify(instance.hashCode(), notification.build());
130     }
131 
showSnoozeNotification(Context context, AlarmInstance instance)132     public static void showSnoozeNotification(Context context, AlarmInstance instance) {
133         LogUtils.v("Displaying snoozed notification for alarm instance: " + instance.mId);
134         NotificationManager nm = (NotificationManager)
135                 context.getSystemService(Context.NOTIFICATION_SERVICE);
136 
137         Resources resources = context.getResources();
138         Notification.Builder notification = new Notification.Builder(context)
139                 .setContentTitle(instance.getLabelOrDefault(context))
140                 .setContentText(resources.getString(R.string.alarm_alert_snooze_until,
141                         AlarmUtils.getFormattedTime(context, instance.getAlarmTime())))
142                 .setSmallIcon(R.drawable.stat_notify_alarm)
143                 .setOngoing(true)
144                 .setAutoCancel(false)
145                 .setPriority(Notification.PRIORITY_MAX)
146                 .setCategory(Notification.CATEGORY_ALARM);
147 
148         // Setup up dismiss action
149         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context, "DISMISS_TAG",
150                 instance, AlarmInstance.DISMISSED_STATE);
151         notification.addAction(R.drawable.ic_alarm_off_black,
152                 resources.getString(R.string.alarm_alert_dismiss_text),
153                 PendingIntent.getBroadcast(context, instance.hashCode(),
154                         dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
155 
156         // Setup content action if instance is owned by alarm
157         Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
158         notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
159                 viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
160         nm.cancel(instance.hashCode());
161         nm.notify(instance.hashCode(), notification.build());
162     }
163 
showMissedNotification(Context context, AlarmInstance instance)164     public static void showMissedNotification(Context context, AlarmInstance instance) {
165         LogUtils.v("Displaying missed notification for alarm instance: " + instance.mId);
166         NotificationManager nm = (NotificationManager)
167                 context.getSystemService(Context.NOTIFICATION_SERVICE);
168 
169         String label = instance.mLabel;
170         String alarmTime = AlarmUtils.getFormattedTime(context, instance.getAlarmTime());
171         String contextText = instance.mLabel.isEmpty() ? alarmTime :
172                 context.getString(R.string.alarm_missed_text, alarmTime, label);
173         Notification.Builder notification = new Notification.Builder(context)
174                 .setContentTitle(context.getString(R.string.alarm_missed_title))
175                 .setContentText(contextText)
176                 .setSmallIcon(R.drawable.stat_notify_alarm)
177                 .setPriority(Notification.PRIORITY_HIGH)
178                 .setCategory(Notification.CATEGORY_ALARM);
179 
180         // Setup dismiss intent
181         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context, "DISMISS_TAG",
182                 instance, AlarmInstance.DISMISSED_STATE);
183         notification.setDeleteIntent(PendingIntent.getBroadcast(context, instance.hashCode(),
184                 dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
185 
186         // Setup content intent
187         Intent showAndDismiss = AlarmInstance.createIntent(context, AlarmStateManager.class,
188                 instance.mId);
189         showAndDismiss.setAction(AlarmStateManager.SHOW_AND_DISMISS_ALARM_ACTION);
190         notification.setContentIntent(PendingIntent.getBroadcast(context, instance.hashCode(),
191                 showAndDismiss, PendingIntent.FLAG_UPDATE_CURRENT));
192 
193         nm.cancel(instance.hashCode());
194         nm.notify(instance.hashCode(), notification.build());
195     }
196 
showAlarmNotification(Context context, AlarmInstance instance)197     public static void showAlarmNotification(Context context, AlarmInstance instance) {
198         LogUtils.v("Displaying alarm notification for alarm instance: " + instance.mId);
199         NotificationManager nm = (NotificationManager)
200                 context.getSystemService(Context.NOTIFICATION_SERVICE);
201 
202         // Close dialogs and window shade, so this will display
203         context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
204 
205         Resources resources = context.getResources();
206         Notification.Builder notification = new Notification.Builder(context)
207                 .setContentTitle(instance.getLabelOrDefault(context))
208                 .setContentText(AlarmUtils.getFormattedTime(context, instance.getAlarmTime()))
209                 .setSmallIcon(R.drawable.stat_notify_alarm)
210                 .setOngoing(true)
211                 .setAutoCancel(false)
212                 .setDefaults(Notification.DEFAULT_LIGHTS)
213                 .setWhen(0)
214                 .setCategory(Notification.CATEGORY_ALARM);
215 
216         // Setup Snooze Action
217         Intent snoozeIntent = AlarmStateManager.createStateChangeIntent(context, "SNOOZE_TAG",
218                 instance, AlarmInstance.SNOOZE_STATE);
219         PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(context, instance.hashCode(),
220                 snoozeIntent,
221                 PendingIntent.FLAG_UPDATE_CURRENT);
222         notification.addAction(R.drawable.ic_snooze_black,
223                 resources.getString(R.string.alarm_alert_snooze_text), snoozePendingIntent);
224 
225         // Setup Dismiss Action
226         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context, "DISMISS_TAG",
227                 instance, AlarmInstance.DISMISSED_STATE);
228         PendingIntent dismissPendingIntent = PendingIntent.getBroadcast(context,
229                 instance.hashCode(), dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT);
230         notification.addAction(R.drawable.ic_alarm_off_black,
231                 resources.getString(R.string.alarm_alert_dismiss_text),
232                 dismissPendingIntent);
233 
234         // Setup Content Action
235         Intent contentIntent = AlarmInstance.createIntent(context, AlarmActivity.class,
236                 instance.mId);
237         notification.setContentIntent(PendingIntent.getActivity(context,
238                 instance.hashCode(), contentIntent, PendingIntent.FLAG_UPDATE_CURRENT));
239 
240         // Setup fullscreen intent
241         Intent fullScreenIntent = AlarmInstance.createIntent(context, AlarmActivity.class,
242                 instance.mId);
243         // set action, so we can be different then content pending intent
244         fullScreenIntent.setAction("fullscreen_activity");
245         fullScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
246                 Intent.FLAG_ACTIVITY_NO_USER_ACTION);
247         notification.setFullScreenIntent(PendingIntent.getActivity(context,
248                 instance.hashCode(), fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT), true);
249         notification.setPriority(Notification.PRIORITY_MAX);
250 
251         nm.cancel(instance.hashCode());
252         nm.notify(instance.hashCode(), notification.build());
253     }
254 
clearNotification(Context context, AlarmInstance instance)255     public static void clearNotification(Context context, AlarmInstance instance) {
256         LogUtils.v("Clearing notifications for alarm instance: " + instance.mId);
257         NotificationManager nm = (NotificationManager)
258                 context.getSystemService(Context.NOTIFICATION_SERVICE);
259         nm.cancel(instance.hashCode());
260     }
261 
createViewAlarmIntent(Context context, AlarmInstance instance)262     private static Intent createViewAlarmIntent(Context context, AlarmInstance instance) {
263         long alarmId = instance.mAlarmId == null ? Alarm.INVALID_ID : instance.mAlarmId;
264         Intent viewAlarmIntent = Alarm.createIntent(context, DeskClock.class, alarmId);
265         viewAlarmIntent.putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.ALARM_TAB_INDEX);
266         viewAlarmIntent.putExtra(AlarmClockFragment.SCROLL_TO_ALARM_INTENT_EXTRA, alarmId);
267         viewAlarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
268         return viewAlarmIntent;
269     }
270 }
271