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