Home | History | Annotate | Download | only in alarms
      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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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