1 /* 2 * Copyright (C) 2014 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 17 package com.example.android.support.wearable.notifications; 18 19 import android.app.Notification; 20 import android.app.PendingIntent; 21 import android.app.RemoteInput; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.graphics.BitmapFactory; 25 import android.graphics.Color; 26 import android.graphics.Typeface; 27 import android.net.Uri; 28 import android.text.SpannableStringBuilder; 29 import android.text.style.ForegroundColorSpan; 30 import android.text.style.RelativeSizeSpan; 31 import android.text.style.StrikethroughSpan; 32 import android.text.style.StyleSpan; 33 import android.text.style.SubscriptSpan; 34 import android.text.style.SuperscriptSpan; 35 import android.text.style.TypefaceSpan; 36 import android.text.style.UnderlineSpan; 37 import android.util.TypedValue; 38 import android.view.Gravity; 39 40 /** 41 * Collection of notification builder presets. 42 */ 43 public class NotificationPresets { 44 public static final NotificationPreset[] PRESETS = new NotificationPreset[] { 45 new BasicPreset(), 46 new StylizedTextPreset(), 47 new DisplayIntentPreset(), 48 new MultiSizeDisplayIntentPreset(), 49 new AnimatedDisplayIntentPreset(), 50 new ContentIconPreset() 51 }; 52 53 private static Notification.Builder buildBasicNotification(Context context) { 54 return new Notification.Builder(context) 55 .setContentTitle(context.getString(R.string.example_content_title)) 56 .setContentText(context.getString(R.string.example_content_text)) 57 // Set a content intent to return to this sample 58 .setContentIntent(PendingIntent.getActivity(context, 0, 59 new Intent(context, MainActivity.class), 0)) 60 .setSmallIcon(R.mipmap.ic_launcher); 61 } 62 63 private static class BasicPreset extends NotificationPreset { 64 public BasicPreset() { 65 super(R.string.basic_example); 66 } 67 68 @Override 69 public Notification buildNotification(Context context) { 70 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, 71 new Intent(context, MainActivity.class), 0); 72 73 Notification page2 = buildBasicNotification(context) 74 .extend(new Notification.WearableExtender() 75 .setHintShowBackgroundOnly(true) 76 .setBackground(BitmapFactory.decodeResource(context.getResources(), 77 R.drawable.example_big_picture))) 78 .build(); 79 80 Notification page3 = buildBasicNotification(context) 81 .setContentTitle(context.getString(R.string.third_page)) 82 .setContentText(null) 83 .extend(new Notification.WearableExtender() 84 .setContentAction(0 /* action A */)) 85 .build(); 86 87 SpannableStringBuilder choice2 = new SpannableStringBuilder( 88 "This choice is best"); 89 choice2.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 5, 11, 0); 90 91 return buildBasicNotification(context) 92 .extend(new Notification.WearableExtender() 93 .addAction(new Notification.Action(R.mipmap.ic_launcher, 94 context.getString(R.string.action_a), pendingIntent)) 95 .addAction(new Notification.Action.Builder(R.mipmap.ic_launcher, 96 context.getString(R.string.reply), pendingIntent) 97 .addRemoteInput(new RemoteInput.Builder(MainActivity.KEY_REPLY) 98 .setChoices(new CharSequence[] { 99 context.getString(R.string.choice_1), 100 choice2 }) 101 .build()) 102 .build()) 103 .addPage(page2) 104 .addPage(page3)) 105 .build(); 106 } 107 } 108 109 private static class StylizedTextPreset extends NotificationPreset { 110 public StylizedTextPreset() { 111 super(R.string.stylized_text_example); 112 } 113 114 @Override 115 public Notification buildNotification(Context context) { 116 Notification.Builder builder = buildBasicNotification(context); 117 118 Notification.BigTextStyle style = new Notification.BigTextStyle(); 119 120 SpannableStringBuilder title = new SpannableStringBuilder(); 121 appendStyled(title, "Stylized", new StyleSpan(Typeface.BOLD_ITALIC)); 122 title.append(" title"); 123 SpannableStringBuilder text = new SpannableStringBuilder("Stylized text: "); 124 appendStyled(text, "C", new ForegroundColorSpan(Color.RED)); 125 appendStyled(text, "O", new ForegroundColorSpan(Color.GREEN)); 126 appendStyled(text, "L", new ForegroundColorSpan(Color.BLUE)); 127 appendStyled(text, "O", new ForegroundColorSpan(Color.YELLOW)); 128 appendStyled(text, "R", new ForegroundColorSpan(Color.MAGENTA)); 129 appendStyled(text, "S", new ForegroundColorSpan(Color.CYAN)); 130 text.append("; "); 131 appendStyled(text, "1.25x size", new RelativeSizeSpan(1.25f)); 132 text.append("; "); 133 appendStyled(text, "0.75x size", new RelativeSizeSpan(0.75f)); 134 text.append("; "); 135 appendStyled(text, "underline", new UnderlineSpan()); 136 text.append("; "); 137 appendStyled(text, "strikethrough", new StrikethroughSpan()); 138 text.append("; "); 139 appendStyled(text, "bold", new StyleSpan(Typeface.BOLD)); 140 text.append("; "); 141 appendStyled(text, "italic", new StyleSpan(Typeface.ITALIC)); 142 text.append("; "); 143 appendStyled(text, "sans-serif-thin", new TypefaceSpan("sans-serif-thin")); 144 text.append("; "); 145 appendStyled(text, "monospace", new TypefaceSpan("monospace")); 146 text.append("; "); 147 appendStyled(text, "sub", new SubscriptSpan()); 148 text.append("script"); 149 appendStyled(text, "super", new SuperscriptSpan()); 150 151 style.setBigContentTitle(title); 152 style.bigText(text); 153 154 builder.setStyle(style); 155 return builder.build(); 156 } 157 158 private void appendStyled(SpannableStringBuilder builder, String str, Object... spans) { 159 builder.append(str); 160 for (Object span : spans) { 161 builder.setSpan(span, builder.length() - str.length(), builder.length(), 0); 162 } 163 } 164 } 165 166 private static class DisplayIntentPreset extends NotificationPreset { 167 public DisplayIntentPreset() { 168 super(R.string.display_intent_example); 169 } 170 171 @Override 172 public Notification buildNotification(Context context) { 173 Intent displayIntent = new Intent(context, BasicNotificationDisplayActivity.class); 174 displayIntent.putExtra(BasicNotificationDisplayActivity.EXTRA_TITLE, 175 context.getString(nameResId)); 176 PendingIntent displayPendingIntent = PendingIntent.getActivity(context, 177 0, displayIntent, PendingIntent.FLAG_UPDATE_CURRENT); 178 return buildBasicNotification(context) 179 .extend(new Notification.WearableExtender() 180 .setDisplayIntent(displayPendingIntent)) 181 .build(); 182 } 183 } 184 185 private static class MultiSizeDisplayIntentPreset extends NotificationPreset { 186 public MultiSizeDisplayIntentPreset() { 187 super(R.string.multisize_display_intent_example); 188 } 189 190 @Override 191 public Notification buildNotification(Context context) { 192 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, 193 new Intent(context, MainActivity.class), 0); 194 Intent displayIntent = new Intent(context, BasicNotificationDisplayActivity.class) 195 .putExtra(BasicNotificationDisplayActivity.EXTRA_TITLE, 196 context.getString(R.string.xsmall_sized_display)); 197 return buildBasicNotification(context) 198 .extend(new Notification.WearableExtender() 199 .setDisplayIntent(PendingIntent.getActivity(context, 0, displayIntent, 200 PendingIntent.FLAG_UPDATE_CURRENT)) 201 .addPage(createPageForSizePreset(context, 202 Notification.WearableExtender.SIZE_SMALL, 203 R.string.small_sized_display, 0)) 204 .addPage(createPageForSizePreset(context, 205 Notification.WearableExtender.SIZE_MEDIUM, 206 R.string.medium_sized_display, 1)) 207 .addPage(createPageForSizePreset(context, 208 Notification.WearableExtender.SIZE_LARGE, 209 R.string.large_sized_display, 2)) 210 .addPage(createPageForSizePreset(context, 211 Notification.WearableExtender.SIZE_FULL_SCREEN, 212 R.string.full_screen_display, 3)) 213 .addPage(createPageForCustomHeight(context, 256, 214 R.string.dp256_height_display)) 215 .addPage(createPageForCustomHeight(context, 512, 216 R.string.dp512_height_display)) 217 .addAction(new Notification.Action(R.mipmap.ic_launcher, 218 context.getString(R.string.action_a), pendingIntent)) 219 .addAction(new Notification.Action(R.mipmap.ic_launcher, 220 context.getString(R.string.action_b), pendingIntent)) 221 .addAction(new Notification.Action(R.mipmap.ic_launcher, 222 context.getString(R.string.action_c), pendingIntent)) 223 .addAction(new Notification.Action(R.mipmap.ic_launcher, 224 context.getString(R.string.action_d), pendingIntent)) 225 .setCustomSizePreset(Notification.WearableExtender.SIZE_XSMALL)) 226 .build(); 227 } 228 229 private Notification createPageForCustomHeight(Context context, int heightDisplayDp, 230 int pageNameResId) { 231 int contentHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 232 heightDisplayDp, context.getResources().getDisplayMetrics()); 233 Intent displayIntent = new Intent(context, BasicNotificationDisplayActivity.class) 234 .setData(Uri.fromParts("example", "height/" + heightDisplayDp, null)) 235 .putExtra(BasicNotificationDisplayActivity.EXTRA_TITLE, 236 context.getString(pageNameResId)); 237 return buildBasicNotification(context) 238 .extend(new Notification.WearableExtender() 239 .setDisplayIntent(PendingIntent.getActivity(context, 0, displayIntent, 240 PendingIntent.FLAG_UPDATE_CURRENT)) 241 .setCustomContentHeight(contentHeight)) 242 .build(); 243 } 244 245 private Notification createPageForSizePreset(Context context, int sizePreset, 246 int pageNameResId, int contentAction) { 247 Intent displayIntent = new Intent(context, BasicNotificationDisplayActivity.class) 248 .setData(Uri.fromParts("example", "size/" + sizePreset, null)) 249 .putExtra(BasicNotificationDisplayActivity.EXTRA_TITLE, 250 context.getString(pageNameResId)); 251 return buildBasicNotification(context) 252 .extend(new Notification.WearableExtender() 253 .setDisplayIntent(PendingIntent.getActivity(context, 0, displayIntent, 254 PendingIntent.FLAG_UPDATE_CURRENT)) 255 .setCustomSizePreset(sizePreset) 256 .setContentAction(contentAction)) 257 .build(); 258 } 259 } 260 261 private static class AnimatedDisplayIntentPreset extends NotificationPreset { 262 public AnimatedDisplayIntentPreset() { 263 super(R.string.animated_display_intent_example); 264 } 265 266 @Override 267 public Notification buildNotification(Context context) { 268 Intent displayIntent = new Intent(context, AnimatedNotificationDisplayActivity.class); 269 displayIntent.putExtra(BasicNotificationDisplayActivity.EXTRA_TITLE, 270 context.getString(nameResId)); 271 PendingIntent displayPendingIntent = PendingIntent.getActivity(context, 272 0, displayIntent, 0); 273 return buildBasicNotification(context) 274 .extend(new Notification.WearableExtender() 275 .setDisplayIntent(displayPendingIntent)) 276 .build(); 277 } 278 } 279 280 private static class ContentIconPreset extends NotificationPreset { 281 public ContentIconPreset() { 282 super(R.string.content_icon_example); 283 } 284 285 @Override 286 public Notification buildNotification(Context context) { 287 Notification page2 = buildBasicNotification(context) 288 .extend(new Notification.WearableExtender() 289 .setContentIcon(R.drawable.content_icon_small) 290 .setContentIconGravity(Gravity.START)) 291 .build(); 292 293 Notification page3 = buildBasicNotification(context) 294 .extend(new Notification.WearableExtender() 295 .setContentIcon(R.drawable.content_icon_large)) 296 .build(); 297 298 Notification page4 = buildBasicNotification(context) 299 .extend(new Notification.WearableExtender() 300 .setContentIcon(R.drawable.content_icon_large) 301 .setContentIconGravity(Gravity.START)) 302 .build(); 303 304 return buildBasicNotification(context) 305 .extend(new Notification.WearableExtender() 306 .setHintHideIcon(true) 307 .setContentIcon(R.drawable.content_icon_small) 308 .addPage(page2) 309 .addPage(page3) 310 .addPage(page4)) 311 .build(); 312 } 313 } 314 } 315