• 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                 .setVisibility(Notification.VISIBILITY_PUBLIC)
77                 .setLocalOnly(true);
78 
79         // Setup up hide notification
80         Intent hideIntent = AlarmStateManager.createStateChangeIntent(context,
81                 AlarmStateManager.ALARM_DELETE_TAG, instance,
82                 AlarmInstance.HIDE_NOTIFICATION_STATE);
83         notification.setDeleteIntent(PendingIntent.getBroadcast(context, instance.hashCode(),
84                 hideIntent, PendingIntent.FLAG_UPDATE_CURRENT));
85 
86         // Setup up dismiss action
87         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
88                 AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
89         notification.addAction(R.drawable.ic_alarm_off_black,
90                 resources.getString(R.string.alarm_alert_dismiss_now_text),
91                 PendingIntent.getBroadcast(context, instance.hashCode(),
92                         dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
93 
94         // Setup content action if instance is owned by alarm
95         Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
96         notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
97                 viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
98 
99         nm.cancel(instance.hashCode());
100         nm.notify(instance.hashCode(), notification.build());
101     }
102 
showHighPriorityNotification(Context context, AlarmInstance instance)103     public static void showHighPriorityNotification(Context context, AlarmInstance instance) {
104         LogUtils.v("Displaying high priority notification for alarm instance: " + instance.mId);
105         NotificationManager nm = (NotificationManager)
106                 context.getSystemService(Context.NOTIFICATION_SERVICE);
107 
108         Resources resources = context.getResources();
109         Notification.Builder notification = new Notification.Builder(context)
110                 .setContentTitle(resources.getString(R.string.alarm_alert_predismiss_title))
111                 .setContentText(AlarmUtils.getAlarmText(context, instance))
112                 .setSmallIcon(R.drawable.stat_notify_alarm)
113                 .setOngoing(true)
114                 .setAutoCancel(false)
115                 .setPriority(Notification.PRIORITY_HIGH)
116                 .setCategory(Notification.CATEGORY_ALARM)
117                 .setVisibility(Notification.VISIBILITY_PUBLIC)
118                 .setLocalOnly(true);
119 
120         // Setup up dismiss action
121         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
122                 AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
123         notification.addAction(R.drawable.ic_alarm_off_black,
124                 resources.getString(R.string.alarm_alert_dismiss_now_text),
125                 PendingIntent.getBroadcast(context, instance.hashCode(),
126                         dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
127 
128         // Setup content action if instance is owned by alarm
129         Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
130         notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
131                 viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
132 
133         nm.cancel(instance.hashCode());
134         nm.notify(instance.hashCode(), notification.build());
135     }
136 
showSnoozeNotification(Context context, AlarmInstance instance)137     public static void showSnoozeNotification(Context context, AlarmInstance instance) {
138         LogUtils.v("Displaying snoozed notification for alarm instance: " + instance.mId);
139         NotificationManager nm = (NotificationManager)
140                 context.getSystemService(Context.NOTIFICATION_SERVICE);
141 
142         Resources resources = context.getResources();
143         Notification.Builder notification = new Notification.Builder(context)
144                 .setContentTitle(instance.getLabelOrDefault(context))
145                 .setContentText(resources.getString(R.string.alarm_alert_snooze_until,
146                         AlarmUtils.getFormattedTime(context, instance.getAlarmTime())))
147                 .setSmallIcon(R.drawable.stat_notify_alarm)
148                 .setOngoing(true)
149                 .setAutoCancel(false)
150                 .setPriority(Notification.PRIORITY_MAX)
151                 .setCategory(Notification.CATEGORY_ALARM)
152                 .setVisibility(Notification.VISIBILITY_PUBLIC)
153                 .setLocalOnly(true);
154 
155         // Setup up dismiss action
156         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
157                 AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
158         notification.addAction(R.drawable.ic_alarm_off_black,
159                 resources.getString(R.string.alarm_alert_dismiss_text),
160                 PendingIntent.getBroadcast(context, instance.hashCode(),
161                         dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
162 
163         // Setup content action if instance is owned by alarm
164         Intent viewAlarmIntent = createViewAlarmIntent(context, instance);
165         notification.setContentIntent(PendingIntent.getActivity(context, instance.hashCode(),
166                 viewAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT));
167         nm.cancel(instance.hashCode());
168         nm.notify(instance.hashCode(), notification.build());
169     }
170 
showMissedNotification(Context context, AlarmInstance instance)171     public static void showMissedNotification(Context context, AlarmInstance instance) {
172         LogUtils.v("Displaying missed notification for alarm instance: " + instance.mId);
173         NotificationManager nm = (NotificationManager)
174                 context.getSystemService(Context.NOTIFICATION_SERVICE);
175 
176         String label = instance.mLabel;
177         String alarmTime = AlarmUtils.getFormattedTime(context, instance.getAlarmTime());
178         String contextText = instance.mLabel.isEmpty() ? alarmTime :
179                 context.getString(R.string.alarm_missed_text, alarmTime, label);
180         Notification.Builder notification = new Notification.Builder(context)
181                 .setContentTitle(context.getString(R.string.alarm_missed_title))
182                 .setContentText(contextText)
183                 .setSmallIcon(R.drawable.stat_notify_alarm)
184                 .setPriority(Notification.PRIORITY_HIGH)
185                 .setCategory(Notification.CATEGORY_ALARM)
186                 .setVisibility(Notification.VISIBILITY_PUBLIC)
187                 .setLocalOnly(true);
188 
189         // Setup dismiss intent
190         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
191                 AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
192         notification.setDeleteIntent(PendingIntent.getBroadcast(context, instance.hashCode(),
193                 dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT));
194 
195         // Setup content intent
196         Intent showAndDismiss = AlarmInstance.createIntent(context, AlarmStateManager.class,
197                 instance.mId);
198         showAndDismiss.setAction(AlarmStateManager.SHOW_AND_DISMISS_ALARM_ACTION);
199         notification.setContentIntent(PendingIntent.getBroadcast(context, instance.hashCode(),
200                 showAndDismiss, PendingIntent.FLAG_UPDATE_CURRENT));
201 
202         nm.cancel(instance.hashCode());
203         nm.notify(instance.hashCode(), notification.build());
204     }
205 
showAlarmNotification(Context context, AlarmInstance instance)206     public static void showAlarmNotification(Context context, AlarmInstance instance) {
207         LogUtils.v("Displaying alarm notification for alarm instance: " + instance.mId);
208         NotificationManager nm = (NotificationManager)
209                 context.getSystemService(Context.NOTIFICATION_SERVICE);
210 
211         // Close dialogs and window shade, so this will display
212         context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
213 
214         Resources resources = context.getResources();
215         Notification.Builder notification = new Notification.Builder(context)
216                 .setContentTitle(instance.getLabelOrDefault(context))
217                 .setContentText(AlarmUtils.getFormattedTime(context, instance.getAlarmTime()))
218                 .setSmallIcon(R.drawable.stat_notify_alarm)
219                 .setOngoing(true)
220                 .setAutoCancel(false)
221                 .setDefaults(Notification.DEFAULT_LIGHTS)
222                 .setWhen(0)
223                 .setCategory(Notification.CATEGORY_ALARM)
224                 .setVisibility(Notification.VISIBILITY_PUBLIC)
225                 .setLocalOnly(true);
226 
227         // Setup Snooze Action
228         Intent snoozeIntent = AlarmStateManager.createStateChangeIntent(context,
229                 AlarmStateManager.ALARM_SNOOZE_TAG, instance, AlarmInstance.SNOOZE_STATE);
230         PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(context, instance.hashCode(),
231                 snoozeIntent,
232                 PendingIntent.FLAG_UPDATE_CURRENT);
233         notification.addAction(R.drawable.ic_snooze_black,
234                 resources.getString(R.string.alarm_alert_snooze_text), snoozePendingIntent);
235 
236         // Setup Dismiss Action
237         Intent dismissIntent = AlarmStateManager.createStateChangeIntent(context,
238                 AlarmStateManager.ALARM_DISMISS_TAG, instance, AlarmInstance.DISMISSED_STATE);
239         PendingIntent dismissPendingIntent = PendingIntent.getBroadcast(context,
240                 instance.hashCode(), dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT);
241         notification.addAction(R.drawable.ic_alarm_off_black,
242                 resources.getString(R.string.alarm_alert_dismiss_text),
243                 dismissPendingIntent);
244 
245         // Setup Content Action
246         Intent contentIntent = AlarmInstance.createIntent(context, AlarmActivity.class,
247                 instance.mId);
248         notification.setContentIntent(PendingIntent.getActivity(context,
249                 instance.hashCode(), contentIntent, PendingIntent.FLAG_UPDATE_CURRENT));
250 
251         // Setup fullscreen intent
252         Intent fullScreenIntent = AlarmInstance.createIntent(context, AlarmActivity.class,
253                 instance.mId);
254         // set action, so we can be different then content pending intent
255         fullScreenIntent.setAction("fullscreen_activity");
256         fullScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
257                 Intent.FLAG_ACTIVITY_NO_USER_ACTION);
258         notification.setFullScreenIntent(PendingIntent.getActivity(context,
259                 instance.hashCode(), fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT), true);
260         notification.setPriority(Notification.PRIORITY_MAX);
261 
262         nm.cancel(instance.hashCode());
263         nm.notify(instance.hashCode(), notification.build());
264     }
265 
clearNotification(Context context, AlarmInstance instance)266     public static void clearNotification(Context context, AlarmInstance instance) {
267         LogUtils.v("Clearing notifications for alarm instance: " + instance.mId);
268         NotificationManager nm = (NotificationManager)
269                 context.getSystemService(Context.NOTIFICATION_SERVICE);
270         nm.cancel(instance.hashCode());
271     }
272 
createViewAlarmIntent(Context context, AlarmInstance instance)273     private static Intent createViewAlarmIntent(Context context, AlarmInstance instance) {
274         long alarmId = instance.mAlarmId == null ? Alarm.INVALID_ID : instance.mAlarmId;
275         Intent viewAlarmIntent = Alarm.createIntent(context, DeskClock.class, alarmId);
276         viewAlarmIntent.putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.ALARM_TAB_INDEX);
277         viewAlarmIntent.putExtra(AlarmClockFragment.SCROLL_TO_ALARM_INTENT_EXTRA, alarmId);
278         viewAlarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
279         return viewAlarmIntent;
280     }
281 }
282