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 
buildBasicNotification(Context context)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 {
BasicPreset()64         public BasicPreset() {
65             super(R.string.basic_example);
66         }
67 
68         @Override
buildNotification(Context context)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 {
StylizedTextPreset()110         public StylizedTextPreset() {
111             super(R.string.stylized_text_example);
112         }
113 
114         @Override
buildNotification(Context context)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 
appendStyled(SpannableStringBuilder builder, String str, Object... spans)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 {
DisplayIntentPreset()167         public DisplayIntentPreset() {
168             super(R.string.display_intent_example);
169         }
170 
171         @Override
buildNotification(Context context)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 {
MultiSizeDisplayIntentPreset()186         public MultiSizeDisplayIntentPreset() {
187             super(R.string.multisize_display_intent_example);
188         }
189 
190         @Override
buildNotification(Context context)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 
createPageForCustomHeight(Context context, int heightDisplayDp, int pageNameResId)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 
createPageForSizePreset(Context context, int sizePreset, int pageNameResId, int contentAction)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 {
AnimatedDisplayIntentPreset()262         public AnimatedDisplayIntentPreset() {
263             super(R.string.animated_display_intent_example);
264         }
265 
266         @Override
buildNotification(Context context)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 {
ContentIconPreset()281         public ContentIconPreset() {
282             super(R.string.content_icon_example);
283         }
284 
285         @Override
buildNotification(Context context)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