1 /* 2 Copyright 2016 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.example.android.wearable.wear.wearnotifications.handlers; 17 18 import android.app.IntentService; 19 import android.app.Notification; 20 import android.app.PendingIntent; 21 import android.content.Intent; 22 import android.graphics.BitmapFactory; 23 import android.support.v4.app.NotificationCompat.BigTextStyle; 24 import android.support.v4.app.NotificationManagerCompat; 25 import android.support.v7.app.NotificationCompat; 26 import android.util.Log; 27 28 import com.example.android.wearable.wear.wearnotifications.GlobalNotificationBuilder; 29 import com.example.android.wearable.wear.wearnotifications.MainActivity; 30 import com.example.android.wearable.wear.wearnotifications.R; 31 import com.example.android.wearable.wear.wearnotifications.mock.MockDatabase; 32 33 import java.util.concurrent.TimeUnit; 34 35 /** 36 * Asynchronously handles snooze and dismiss actions for reminder app (and active Notification). 37 * Notification for for reminder app uses BigTextStyle. 38 */ 39 public class BigTextIntentService extends IntentService { 40 41 private static final String TAG = "BigTextService"; 42 43 public static final String ACTION_DISMISS = 44 "com.example.android.wearable.wear.wearnotifications.handlers.action.DISMISS"; 45 public static final String ACTION_SNOOZE = 46 "com.example.android.wearable.wear.wearnotifications.handlers.action.SNOOZE"; 47 48 private static final long SNOOZE_TIME = TimeUnit.SECONDS.toMillis(5); 49 BigTextIntentService()50 public BigTextIntentService() { 51 super("BigTextIntentService"); 52 } 53 54 @Override onHandleIntent(Intent intent)55 protected void onHandleIntent(Intent intent) { 56 Log.d(TAG, "onHandleIntent(): " + intent); 57 58 if (intent != null) { 59 final String action = intent.getAction(); 60 if (ACTION_DISMISS.equals(action)) { 61 handleActionDismiss(); 62 } else if (ACTION_SNOOZE.equals(action)) { 63 handleActionSnooze(); 64 } 65 } 66 } 67 68 /** 69 * Handles action Dismiss in the provided background thread. 70 */ handleActionDismiss()71 private void handleActionDismiss() { 72 Log.d(TAG, "handleActionDismiss()"); 73 74 NotificationManagerCompat notificationManagerCompat = 75 NotificationManagerCompat.from(getApplicationContext()); 76 notificationManagerCompat.cancel(MainActivity.NOTIFICATION_ID); 77 } 78 79 /** 80 * Handles action Snooze in the provided background thread. 81 */ handleActionSnooze()82 private void handleActionSnooze() { 83 Log.d(TAG, "handleActionSnooze()"); 84 85 // You could use NotificationManager.getActiveNotifications() if you are targeting SDK 23 86 // and above, but we are targeting devices with lower SDK API numbers, so we saved the 87 // builder globally and get the notification back to recreate it later. 88 89 NotificationCompat.Builder notificationCompatBuilder = 90 GlobalNotificationBuilder.getNotificationCompatBuilderInstance(); 91 92 // Recreate builder from persistent state if app process is killed 93 if (notificationCompatBuilder == null) { 94 // Note: New builder set globally in the method 95 notificationCompatBuilder = recreateBuilderWithBigTextStyle(); 96 } 97 98 Notification notification; 99 notification = notificationCompatBuilder.build(); 100 101 102 if (notification != null) { 103 NotificationManagerCompat notificationManagerCompat = 104 NotificationManagerCompat.from(getApplicationContext()); 105 106 notificationManagerCompat.cancel(MainActivity.NOTIFICATION_ID); 107 108 try { 109 Thread.sleep(SNOOZE_TIME); 110 } catch (InterruptedException ex) { 111 Thread.currentThread().interrupt(); 112 } 113 notificationManagerCompat.notify(MainActivity.NOTIFICATION_ID, notification); 114 } 115 116 } 117 118 /* 119 * This recreates the notification from the persistent state in case the app process was killed. 120 * It is basically the same code for creating the Notification from MainActivity. 121 */ recreateBuilderWithBigTextStyle()122 private NotificationCompat.Builder recreateBuilderWithBigTextStyle() { 123 124 // Main steps for building a BIG_TEXT_STYLE notification (for more detailed comments on 125 // building this notification, check MainActivity.java):: 126 // 0. Get your data 127 // 1. Build the BIG_TEXT_STYLE 128 // 2. Set up main Intent for notification 129 // 3. Create additional Actions for the Notification 130 // 4. Build and issue the notification 131 132 // 0. Get your data 133 MockDatabase.BigTextStyleReminderAppData bigTextData = MockDatabase.getBigTextStyleData(); 134 135 // 1. Build the BIG_TEXT_STYLE 136 BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle() 137 .bigText(bigTextData.getBigText()) 138 .setBigContentTitle(bigTextData.getBigContentTitle()) 139 .setSummaryText(bigTextData.getSummaryText()); 140 141 142 // 2. Set up main Intent for notification 143 Intent notifyIntent = new Intent(this, BigTextMainActivity.class); 144 notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 145 146 PendingIntent notifyPendingIntent = 147 PendingIntent.getActivity( 148 this, 149 0, 150 notifyIntent, 151 PendingIntent.FLAG_UPDATE_CURRENT 152 ); 153 154 155 // 3. Create additional Actions (Intents) for the Notification 156 157 // Snooze Action 158 Intent snoozeIntent = new Intent(this, BigTextIntentService.class); 159 snoozeIntent.setAction(BigTextIntentService.ACTION_SNOOZE); 160 161 PendingIntent snoozePendingIntent = PendingIntent.getService(this, 0, snoozeIntent, 0); 162 NotificationCompat.Action snoozeAction = 163 new NotificationCompat.Action.Builder( 164 R.drawable.ic_alarm_white_48dp, 165 "Snooze", 166 snoozePendingIntent) 167 .build(); 168 169 170 // Dismiss Action 171 Intent dismissIntent = new Intent(this, BigTextIntentService.class); 172 dismissIntent.setAction(BigTextIntentService.ACTION_DISMISS); 173 174 PendingIntent dismissPendingIntent = PendingIntent.getService(this, 0, dismissIntent, 0); 175 NotificationCompat.Action dismissAction = 176 new NotificationCompat.Action.Builder( 177 R.drawable.ic_cancel_white_48dp, 178 "Dismiss", 179 dismissPendingIntent) 180 .build(); 181 182 // 4. Build and issue the notification 183 NotificationCompat.Builder notificationCompatBuilder = 184 new NotificationCompat.Builder(getApplicationContext()); 185 186 GlobalNotificationBuilder.setNotificationCompatBuilderInstance(notificationCompatBuilder); 187 188 notificationCompatBuilder 189 .setStyle(bigTextStyle) 190 .setContentTitle(bigTextData.getContentTitle()) 191 .setContentText(bigTextData.getContentText()) 192 .setSmallIcon(R.drawable.ic_launcher) 193 .setLargeIcon(BitmapFactory.decodeResource( 194 getResources(), 195 R.drawable.ic_alarm_white_48dp)) 196 .setContentIntent(notifyPendingIntent) 197 .setColor(getResources().getColor(R.color.colorPrimary)) 198 .setCategory(Notification.CATEGORY_REMINDER) 199 .setPriority(Notification.PRIORITY_HIGH) 200 .setVisibility(Notification.VISIBILITY_PUBLIC) 201 .addAction(snoozeAction) 202 .addAction(dismissAction); 203 204 return notificationCompatBuilder; 205 } 206 }