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