• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.google.android.car.kitchensink.notification;
2 
3 import android.annotation.Nullable;
4 import android.app.Notification;
5 import android.app.NotificationChannel;
6 import android.app.NotificationManager;
7 import android.app.PendingIntent;
8 import android.content.Context;
9 import android.content.Intent;
10 import android.graphics.drawable.Icon;
11 import android.media.session.MediaSession;
12 import android.os.Bundle;
13 import android.os.Handler;
14 import android.view.LayoutInflater;
15 import android.view.View;
16 import android.view.ViewGroup;
17 import android.widget.NumberPicker;
18 
19 import androidx.core.app.NotificationCompat;
20 import androidx.core.app.NotificationCompat.Action;
21 import androidx.core.app.NotificationCompat.MessagingStyle;
22 import androidx.core.app.Person;
23 import androidx.core.app.RemoteInput;
24 import androidx.core.graphics.drawable.IconCompat;
25 import androidx.fragment.app.Fragment;
26 
27 import com.google.android.car.kitchensink.KitchenSinkActivity;
28 import com.google.android.car.kitchensink.R;
29 
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 
34 /**
35  * Test fragment that can send all sorts of notifications.
36  */
37 public class NotificationFragment extends Fragment {
38     private static final String IMPORTANCE_HIGH_ID = "importance_high";
39     private static final String IMPORTANCE_HIGH_NO_SOUND_ID = "importance_high_no_sound";
40     private static final String IMPORTANCE_DEFAULT_ID = "importance_default";
41     private static final String IMPORTANCE_LOW_ID = "importance_low";
42     private static final String IMPORTANCE_MIN_ID = "importance_min";
43     private static final String IMPORTANCE_NONE_ID = "importance_none";
44     private int mCurrentNotificationId;
45     private int mCurrentGroupNotificationCount;
46     private NotificationManager mManager;
47     private Context mContext;
48     private Handler mHandler = new Handler();
49     private int mCount = 0;
50     private HashMap<Integer, Runnable> mUpdateRunnables = new HashMap<>();
51 
52     @Override
onCreate(Bundle savedInstanceState)53     public void onCreate(Bundle savedInstanceState) {
54         super.onCreate(savedInstanceState);
55         mContext = getActivity();
56         mManager =
57                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
58 
59         mManager.createNotificationChannel(new NotificationChannel(
60                 IMPORTANCE_HIGH_ID, "Importance High", NotificationManager.IMPORTANCE_HIGH));
61 
62         NotificationChannel noSoundChannel = new NotificationChannel(
63                 IMPORTANCE_HIGH_NO_SOUND_ID, "No sound", NotificationManager.IMPORTANCE_HIGH);
64         noSoundChannel.setSound(null, null);
65         mManager.createNotificationChannel(noSoundChannel);
66 
67         mManager.createNotificationChannel(new NotificationChannel(
68                 IMPORTANCE_DEFAULT_ID,
69                 "Importance Default",
70                 NotificationManager.IMPORTANCE_DEFAULT));
71 
72         mManager.createNotificationChannel(new NotificationChannel(
73                 IMPORTANCE_LOW_ID, "Importance Low", NotificationManager.IMPORTANCE_LOW));
74 
75         mManager.createNotificationChannel(new NotificationChannel(
76                 IMPORTANCE_MIN_ID, "Importance Min", NotificationManager.IMPORTANCE_MIN));
77 
78         mManager.createNotificationChannel(new NotificationChannel(
79                 IMPORTANCE_NONE_ID, "Importance None", NotificationManager.IMPORTANCE_NONE));
80     }
81 
82     @Override
onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)83     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
84             @Nullable Bundle savedInstanceState) {
85         View view = inflater.inflate(R.layout.notification_fragment, container, false);
86 
87         initCancelAllButton(view);
88 
89         initCarCategoriesButton(view);
90 
91         initImportanceHighBotton(view);
92         initImportanceDefaultButton(view);
93         initImportanceLowButton(view);
94         initImportanceMinButton(view);
95 
96         initOngoingButton(view);
97         initMessagingStyleButtonForDiffPerson(view);
98         initMessagingStyleButtonForSamePerson(view);
99         initMessagingStyleButtonForLongMessageSamePerson(view);
100         initMessagingStyleButtonForMessageSameGroup(view);
101         initMessagingStyleButtonWithMuteAction(view);
102         initTestMessagesButton(view);
103         initProgressButton(view);
104         initNavigationButton(view);
105         initMediaButton(view);
106         initCallButton(view);
107         initCustomGroupSummaryButton(view);
108         initGroupWithoutSummaryButton(view);
109         initCustomizableMessageButton(view);
110 
111         return view;
112     }
113 
createServiceIntent(int notificationId, String action)114     private PendingIntent createServiceIntent(int notificationId, String action) {
115         Intent intent = new Intent(mContext, KitchenSinkActivity.class).setAction(action);
116 
117         return PendingIntent.getForegroundService(mContext, notificationId, intent,
118                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
119     }
120 
initCancelAllButton(View view)121     private void initCancelAllButton(View view) {
122         view.findViewById(R.id.cancel_all_button).setOnClickListener(v -> {
123             for (Runnable runnable : mUpdateRunnables.values()) {
124                 mHandler.removeCallbacks(runnable);
125             }
126             mUpdateRunnables.clear();
127             mManager.cancelAll();
128         });
129     }
130 
initCarCategoriesButton(View view)131     private void initCarCategoriesButton(View view) {
132         view.findViewById(R.id.category_car_emergency_button).setOnClickListener(v -> {
133             Notification notification = new Notification
134                     .Builder(mContext, IMPORTANCE_HIGH_ID)
135                     .setContentTitle("Car Emergency")
136                     .setContentText("Shows heads-up; Shows on top of the list; Does not group")
137                     .setCategory(Notification.CATEGORY_CAR_EMERGENCY)
138                     .setSmallIcon(R.drawable.car_ic_mode)
139                     .build();
140             mManager.notify(mCurrentNotificationId++, notification);
141         });
142 
143         view.findViewById(R.id.category_car_warning_button).setOnClickListener(v -> {
144 
145             Notification notification = new Notification
146                     .Builder(mContext, IMPORTANCE_HIGH_ID)
147                     .setContentTitle("Car Warning")
148                     .setContentText(
149                             "Shows heads-up; Shows on top of the list but below Car Emergency; "
150                                     + "Does not group")
151                     .setCategory(Notification.CATEGORY_CAR_WARNING)
152                     .setColor(mContext.getColor(android.R.color.holo_orange_dark))
153                     .setColorized(true)
154                     .setSmallIcon(R.drawable.car_ic_mode)
155                     .build();
156             mManager.notify(mCurrentNotificationId++, notification);
157         });
158 
159         view.findViewById(R.id.category_car_info_button).setOnClickListener(v -> {
160             Notification notification = new Notification
161                     .Builder(mContext, IMPORTANCE_DEFAULT_ID)
162                     .setContentTitle("Car information")
163                     .setContentText("Doesn't show heads-up; Importance Default; Groups")
164                     .setCategory(Notification.CATEGORY_CAR_INFORMATION)
165                     .setColor(mContext.getColor(android.R.color.holo_orange_light))
166                     .setColorized(true)
167                     .setSmallIcon(R.drawable.car_ic_mode)
168                     .build();
169             mManager.notify(mCurrentNotificationId++, notification);
170         });
171 
172     }
173 
initImportanceHighBotton(View view)174     private void initImportanceHighBotton(View view) {
175         Intent intent = new Intent(mContext, KitchenSinkActivity.class);
176         PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent,
177                 PendingIntent.FLAG_IMMUTABLE);
178 
179         Notification notification1 = new Notification
180                 .Builder(mContext, IMPORTANCE_HIGH_ID)
181                 .setContentTitle("Importance High: Shows as a heads-up")
182                 .setContentText(
183                         "Each click generates a new notification. And some "
184                                 + "looooooong text. "
185                                 + "Loooooooooooooooooooooong. "
186                                 + "Loooooooooooooooooooooooooooooooooooooooooooooooooong.")
187                 .setSmallIcon(R.drawable.car_ic_mode)
188                 .addAction(
189                         new Notification.Action.Builder(
190                                 null, "Long Action (no-op)", pendingIntent).build())
191                 .addAction(
192                         new Notification.Action.Builder(
193                                 null, "Action (no-op)", pendingIntent).build())
194                 .addAction(
195                         new Notification.Action.Builder(
196                                 null, "Long Action (no-op)", pendingIntent).build())
197                 .setColor(mContext.getColor(android.R.color.holo_red_light))
198                 .build();
199 
200         view.findViewById(R.id.importance_high_button).setOnClickListener(
201                 v -> mManager.notify(mCurrentNotificationId++, notification1)
202         );
203     }
204 
initImportanceDefaultButton(View view)205     private void initImportanceDefaultButton(View view) {
206         view.findViewById(R.id.importance_default_button).setOnClickListener(v -> {
207             Notification notification = new Notification
208                     .Builder(mContext, IMPORTANCE_DEFAULT_ID)
209                     .setContentTitle("No heads-up; Importance Default; Groups")
210                     .setSmallIcon(R.drawable.car_ic_mode)
211                     .build();
212             mManager.notify(mCurrentNotificationId++, notification);
213         });
214     }
215 
initImportanceLowButton(View view)216     private void initImportanceLowButton(View view) {
217         view.findViewById(R.id.importance_low_button).setOnClickListener(v -> {
218 
219             Notification notification = new Notification.Builder(mContext, IMPORTANCE_LOW_ID)
220                     .setContentTitle("Importance Low")
221                     .setContentText("No heads-up; Below Importance Default; Groups")
222                     .setSmallIcon(R.drawable.car_ic_mode)
223                     .build();
224             mManager.notify(mCurrentNotificationId++, notification);
225         });
226     }
227 
initImportanceMinButton(View view)228     private void initImportanceMinButton(View view) {
229         view.findViewById(R.id.importance_min_button).setOnClickListener(v -> {
230 
231             Notification notification = new Notification.Builder(mContext, IMPORTANCE_MIN_ID)
232                     .setContentTitle("Importance Min")
233                     .setContentText("No heads-up; Below Importance Low; Groups")
234                     .setSmallIcon(R.drawable.car_ic_mode)
235                     .build();
236             mManager.notify(mCurrentNotificationId++, notification);
237         });
238     }
239 
initOngoingButton(View view)240     private void initOngoingButton(View view) {
241         view.findViewById(R.id.ongoing_button).setOnClickListener(v -> {
242 
243             Notification notification = new Notification
244                     .Builder(mContext, IMPORTANCE_DEFAULT_ID)
245                     .setContentTitle("Persistent/Ongoing Notification")
246                     .setContentText("Cannot be dismissed; No heads-up; Importance default; Groups")
247                     .setSmallIcon(R.drawable.car_ic_mode)
248                     .setOngoing(true)
249                     .build();
250             mManager.notify(mCurrentNotificationId++, notification);
251         });
252     }
253 
initCustomizableMessageButton(View view)254     private void initCustomizableMessageButton(View view) {
255         NumberPicker messagesPicker = view.findViewById(R.id.number_messages);
256         messagesPicker.setMinValue(1);
257         messagesPicker.setMaxValue(25);
258         messagesPicker.setWrapSelectorWheel(true);
259         NumberPicker peoplePicker = view.findViewById(R.id.number_people);
260         peoplePicker.setMinValue(1);
261         peoplePicker.setMaxValue(25);
262         peoplePicker.setWrapSelectorWheel(true);
263 
264         view.findViewById(R.id.customizable_message_button).setOnClickListener(v -> {
265             int id = mCurrentNotificationId++;
266 
267             int numPeople = peoplePicker.getValue();
268             int numMessages = messagesPicker.getValue();
269 
270             PendingIntent replyIntent = createServiceIntent(id, "reply");
271             PendingIntent markAsReadIntent = createServiceIntent(id, "read");
272 
273             List<Person> personList = new ArrayList<>();
274 
275             for (int i = 1; i <= numPeople; i++) {
276                 personList.add(new Person.Builder()
277                         .setName("Person " + i)
278                         .setIcon(IconCompat.createWithResource(v.getContext(),
279                                 i % 2 == 1 ? R.drawable.avatar1 : R.drawable.avatar2))
280                         .build());
281             }
282 
283             MessagingStyle messagingStyle =
284                     new MessagingStyle(personList.get(0))
285                             .setConversationTitle("Customizable Group chat: " + id);
286             if (personList.size() > 1) {
287                 messagingStyle.setGroupConversation(true);
288             }
289 
290             int messageNumber = 1;
291             for (int i = 0; i < numMessages; i++) {
292                 int personNum = i % numPeople;
293                 if (personNum == numPeople - 1) {
294                     messageNumber++;
295                 }
296                 Person person = personList.get(personNum);
297                 String messageText = person.getName() + "'s " + messageNumber + " message";
298                 messagingStyle.addMessage(
299                         new MessagingStyle.Message(
300                                 messageText,
301                                 System.currentTimeMillis(),
302                                 person));
303             }
304 
305             NotificationCompat.Builder notification = new NotificationCompat
306                     .Builder(mContext, IMPORTANCE_HIGH_ID)
307                     .setContentTitle("Customizable Group chat (Title)")
308                     .setContentText("Customizable Group chat (Text)")
309                     .setShowWhen(true)
310                     .setCategory(Notification.CATEGORY_MESSAGE)
311                     .setSmallIcon(R.drawable.car_ic_mode)
312                     .setStyle(messagingStyle)
313                     .setAutoCancel(true)
314                     .setColor(mContext.getColor(android.R.color.holo_green_light))
315                     .addAction(
316                             new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
317                                     .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
318                                     .setShowsUserInterface(false)
319                                     .build())
320                     .addAction(
321                             new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
322                                     .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
323                                     .setShowsUserInterface(false)
324                                     .addRemoteInput(new RemoteInput.Builder("input").build())
325                                     .build());
326 
327             mManager.notify(id, notification.build());
328         });
329     }
330 
initMessagingStyleButtonForDiffPerson(View view)331     private void initMessagingStyleButtonForDiffPerson(View view) {
332         view.findViewById(R.id.category_message_diff_person_button).setOnClickListener(v -> {
333             int id = mCurrentNotificationId++;
334 
335             PendingIntent replyIntent = createServiceIntent(id, "reply");
336             PendingIntent markAsReadIntent = createServiceIntent(id, "read");
337 
338             Person person1 = new Person.Builder()
339                     .setName("Person " + id)
340                     .setIcon(IconCompat.createWithResource(v.getContext(), R.drawable.avatar1))
341                     .build();
342             Person person2 = new Person.Builder()
343                     .setName("Person " + id + 1)
344                     .setIcon(IconCompat.createWithResource(v.getContext(), R.drawable.android_logo))
345                     .build();
346             Person person3 = new Person.Builder()
347                     .setName("Person " + id + 2)
348                     .setIcon(IconCompat.createWithResource(v.getContext(), R.drawable.avatar2))
349                     .build();
350             MessagingStyle messagingStyle =
351                     new MessagingStyle(person3)
352                             .setConversationTitle("Group chat")
353                             .addMessage(
354                                     new MessagingStyle.Message(
355                                             person1.getName() + "'s message",
356                                             System.currentTimeMillis(),
357                                             person1))
358                             .addMessage(
359                                     new MessagingStyle.Message(
360                                             person2.getName() + "'s message",
361                                             System.currentTimeMillis(),
362                                             person2))
363                             .addMessage(
364                                     new MessagingStyle.Message(
365                                             person3.getName() + "'s message; "
366                                                     + "Each click generates a new"
367                                                     + "notification. And some looooooong text. "
368                                                     + "Loooooooooooooooooooooong. "
369                                                     + "Loooooooooooooooooooooooooong."
370                                                     + "Long long long long text.",
371                                             System.currentTimeMillis(),
372                                             person3));
373 
374             NotificationCompat.Builder notification = new NotificationCompat
375                     .Builder(mContext, IMPORTANCE_HIGH_ID)
376                     .setContentTitle("Jane, John, Joe")
377                     .setContentText("Group chat")
378                     .setShowWhen(true)
379                     .setCategory(Notification.CATEGORY_MESSAGE)
380                     .setSmallIcon(R.drawable.car_ic_mode)
381                     .setStyle(messagingStyle)
382                     .setAutoCancel(true)
383                     .setColor(mContext.getColor(android.R.color.holo_green_light))
384                     .addAction(
385                             new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
386                                     .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
387                                     .setShowsUserInterface(false)
388                                     .build())
389                     .addAction(
390                             new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
391                                     .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
392                                     .setShowsUserInterface(false)
393                                     .addRemoteInput(new RemoteInput.Builder("input").build())
394                                     .build());
395 
396             mManager.notify(id, notification.build());
397         });
398     }
399 
initMessagingStyleButtonForMessageSameGroup(View view)400     private void initMessagingStyleButtonForMessageSameGroup(View view) {
401         int numOfPeople = 3;
402         Person user = new Person.Builder()
403                 .setName("User")
404                 .setIcon(IconCompat.createWithResource(view.getContext(), R.drawable.avatar1))
405                 .build();
406 
407         MessagingStyle messagingStyle =
408                 new MessagingStyle(user)
409                         .setConversationTitle("Same group chat")
410                         .setGroupConversation(true);
411 
412         List<Person> personList = new ArrayList<>();
413         for (int i = 1; i <= numOfPeople; i++) {
414             personList.add(new Person.Builder()
415                     .setName("Person " + i)
416                     .setIcon(IconCompat.createWithResource(view.getContext(),
417                             i % 2 == 1 ? R.drawable.avatar1 : R.drawable.avatar2))
418                     .build());
419         }
420 
421         view.findViewById(R.id.category_message_same_group_button).setOnClickListener(v -> {
422             mCurrentGroupNotificationCount++;
423             PendingIntent replyIntent = createServiceIntent(123456, "reply");
424             PendingIntent markAsReadIntent = createServiceIntent(123456, "read");
425             Person person = personList.get(mCurrentGroupNotificationCount % numOfPeople);
426             String messageText =
427                     person.getName() + "'s " + mCurrentGroupNotificationCount + " message";
428             messagingStyle.addMessage(
429                     new MessagingStyle.Message(messageText, System.currentTimeMillis(), person));
430 
431             NotificationCompat.Builder notification = new NotificationCompat
432                     .Builder(mContext, IMPORTANCE_HIGH_ID)
433                     .setContentTitle("Same Group chat (Title)")
434                     .setContentText("Same Group chat (Text)")
435                     .setShowWhen(true)
436                     .setCategory(Notification.CATEGORY_MESSAGE)
437                     .setSmallIcon(R.drawable.car_ic_mode)
438                     .setStyle(messagingStyle)
439                     .setAutoCancel(true)
440                     .addAction(
441                             new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
442                                     .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
443                                     .setShowsUserInterface(false)
444                                     .build())
445                     .addAction(
446                             new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
447                                     .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
448                                     .setShowsUserInterface(false)
449                                     .addRemoteInput(new RemoteInput.Builder("input").build())
450                                     .build());
451 
452             mManager.notify(123456, notification.build());
453         });
454     }
455 
initMessagingStyleButtonForSamePerson(View view)456     private void initMessagingStyleButtonForSamePerson(View view) {
457         view.findViewById(R.id.category_message_same_person_button).setOnClickListener(v -> {
458             int id = mCurrentNotificationId++;
459 
460             PendingIntent replyIntent = createServiceIntent(id, "reply");
461             PendingIntent markAsReadIntent = createServiceIntent(id, "read");
462 
463             Person person = new Person.Builder().setName("John Doe").build();
464             MessagingStyle messagingStyle =
465                     new MessagingStyle(person).setConversationTitle("Hello!");
466             NotificationCompat.Builder builder = new NotificationCompat
467                     .Builder(mContext, IMPORTANCE_HIGH_ID)
468                     .setContentTitle("Message from someone")
469                     .setContentText("hi")
470                     .setShowWhen(true)
471                     .setCategory(Notification.CATEGORY_MESSAGE)
472                     .setSmallIcon(R.drawable.car_ic_mode)
473                     .setAutoCancel(true)
474                     .setColor(mContext.getColor(android.R.color.holo_green_light))
475                     .addAction(
476                             new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
477                                     .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
478                                     .setShowsUserInterface(false)
479                                     .build())
480                     .addAction(
481                             new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
482                                     .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
483                                     .setShowsUserInterface(false)
484                                     .addRemoteInput(new RemoteInput.Builder("input").build())
485                                     .build());
486 
487             NotificationCompat.Builder updateNotification =
488                     builder.setStyle(messagingStyle.addMessage(
489                             new MessagingStyle.Message(
490                                     "Message " + id,
491                                     System.currentTimeMillis(),
492                                     person)));
493             mManager.notify(12345, updateNotification.build());
494         });
495     }
496 
initMessagingStyleButtonForLongMessageSamePerson(View view)497     private void initMessagingStyleButtonForLongMessageSamePerson(View view) {
498         view.findViewById(R.id.category_long_message_same_person_button).setOnClickListener(v -> {
499             int id = mCurrentNotificationId++;
500 
501             PendingIntent replyIntent = createServiceIntent(id, "reply");
502             PendingIntent markAsReadIntent = createServiceIntent(id, "read");
503 
504 
505             Person person = new Person.Builder().setName("John Doe").build();
506             MessagingStyle messagingStyle =
507                     new MessagingStyle(person).setConversationTitle("Hello!");
508             NotificationCompat.Builder builder = new NotificationCompat
509                     .Builder(mContext, IMPORTANCE_HIGH_ID)
510                     .setContentTitle("Message from someone")
511                     .setContentText("hi")
512                     .setShowWhen(true)
513                     .setCategory(Notification.CATEGORY_MESSAGE)
514                     .setSmallIcon(R.drawable.car_ic_mode)
515                     .setAutoCancel(true)
516                     .setColor(mContext.getColor(android.R.color.holo_green_light))
517                     .addAction(
518                             new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
519                                     .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
520                                     .setShowsUserInterface(false)
521                                     .build())
522                     .addAction(
523                             new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
524                                     .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
525                                     .setShowsUserInterface(false)
526                                     .addRemoteInput(new RemoteInput.Builder("input").build())
527                                     .build());
528 
529             String messageText = "";
530             for (int i = 0; i < 100; i++) {
531                 messageText += " test";
532             }
533 
534             NotificationCompat.Builder updateNotification =
535                     builder.setStyle(messagingStyle.addMessage(
536                             new MessagingStyle.Message(
537                                     id + messageText,
538                                     System.currentTimeMillis(),
539                                     person)));
540             mManager.notify(12345, updateNotification.build());
541         });
542     }
543 
544 
initMessagingStyleButtonWithMuteAction(View view)545     private void initMessagingStyleButtonWithMuteAction(View view) {
546         view.findViewById(R.id.category_message_mute_action_button).setOnClickListener(v -> {
547             int id = mCurrentNotificationId++;
548 
549             PendingIntent replyIntent = createServiceIntent(id, "reply");
550             PendingIntent markAsReadIntent = createServiceIntent(id, "read");
551             PendingIntent muteIntent = createServiceIntent(id, "mute");
552 
553             Person person = new Person.Builder().setName("John Doe").build();
554             MessagingStyle messagingStyle =
555                     new MessagingStyle(person).setConversationTitle("Hello, try muting me!");
556             NotificationCompat.Builder builder = new NotificationCompat
557                     .Builder(mContext, IMPORTANCE_HIGH_ID)
558                     .setContentTitle("Message from someone")
559                     .setContentText("Muting notification when "
560                             + "mute pending intent is provided by posting app")
561                     .setShowWhen(true)
562                     .setCategory(Notification.CATEGORY_MESSAGE)
563                     .setSmallIcon(R.drawable.car_ic_mode)
564                     .setAutoCancel(true)
565                     .setColor(mContext.getColor(android.R.color.holo_green_light))
566                     .addAction(
567                             new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
568                                     .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
569                                     .setShowsUserInterface(false)
570                                     .build())
571                     .addAction(
572                             new Action.Builder(R.drawable.ic_check_box, "mute", muteIntent)
573                                     .setSemanticAction(Action.SEMANTIC_ACTION_MUTE)
574                                     .setShowsUserInterface(false)
575                                     .build())
576                     .addAction(
577                             new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
578                                     .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
579                                     .setShowsUserInterface(false)
580                                     .addRemoteInput(new RemoteInput.Builder("input").build())
581                                     .build());
582 
583             builder.setStyle(messagingStyle.addMessage(
584                     new MessagingStyle.Message(
585                             "Message with mute pending intent" + id,
586                             System.currentTimeMillis(),
587                             person)));
588             mManager.notify(id, builder.build());
589         });
590     }
591 
initTestMessagesButton(View view)592     private void initTestMessagesButton(View view) {
593         view.findViewById(R.id.test_message_button).setOnClickListener(v -> {
594             int id = mCurrentNotificationId++;
595 
596             PendingIntent replyIntent = createServiceIntent(id, "reply");
597             PendingIntent markAsReadIntent = createServiceIntent(id, "read");
598 
599             Person person = new Person.Builder().setName("John Doe " + id).build();
600             MessagingStyle messagingStyle =
601                     new MessagingStyle(person).setConversationTitle("Hello!");
602             NotificationCompat.Builder builder = new NotificationCompat
603                     .Builder(mContext, IMPORTANCE_HIGH_ID)
604                     .setContentTitle("Message from someone")
605                     .setContentText("hi")
606                     .setShowWhen(true)
607                     .setCategory(Notification.CATEGORY_MESSAGE)
608                     .setSmallIcon(R.drawable.car_ic_mode)
609                     .setAutoCancel(true)
610                     .setColor(mContext.getColor(android.R.color.holo_green_light))
611                     .addAction(
612                             new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
613                                     .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
614                                     .setShowsUserInterface(false)
615                                     .build())
616                     .addAction(
617                             new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
618                                     .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
619                                     .setShowsUserInterface(false)
620                                     .addRemoteInput(new RemoteInput.Builder("input").build())
621                                     .build());
622 
623             Runnable runnable = new Runnable() {
624                 int mCount = 1;
625 
626                 @Override
627                 public void run() {
628                     NotificationCompat.Builder updateNotification =
629                             builder.setStyle(messagingStyle.addMessage(
630                                     new MessagingStyle.Message(
631                                             "Message " + mCount++,
632                                             System.currentTimeMillis(),
633                                             person)));
634                     mManager.notify(id, updateNotification.build());
635                     if (mCount < 5) {
636                         mHandler.postDelayed(this, 6000);
637                     }
638                 }
639             };
640             mUpdateRunnables.put(id, runnable);
641             mHandler.post(runnable);
642         });
643     }
644 
initProgressButton(View view)645     private void initProgressButton(View view) {
646         view.findViewById(R.id.progress_button).setOnClickListener(v -> {
647             int id = mCurrentNotificationId++;
648 
649             Notification notification = new Notification
650                     .Builder(mContext, IMPORTANCE_DEFAULT_ID)
651                     .setContentTitle("Progress")
652                     .setOngoing(true)
653                     .setContentText(
654                             "Doesn't show heads-up; Importance Default; Groups; Ongoing (cannot "
655                                     + "be dismissed)")
656                     .setProgress(100, 0, false)
657                     .setColor(mContext.getColor(android.R.color.holo_purple))
658                     .setContentInfo("0%")
659                     .setSmallIcon(R.drawable.car_ic_mode)
660                     .build();
661             mManager.notify(id, notification);
662 
663             Runnable runnable = new Runnable() {
664                 int mProgress = 0;
665 
666                 @Override
667                 public void run() {
668                     Notification updateNotification = new Notification
669                             .Builder(mContext, IMPORTANCE_DEFAULT_ID)
670                             .setContentTitle("Progress")
671                             .setContentText("Doesn't show heads-up; Importance Default; Groups")
672                             .setProgress(100, mProgress, false)
673                             .setOngoing(true)
674                             .setColor(mContext.getColor(android.R.color.holo_purple))
675                             .setContentInfo(mProgress + "%")
676                             .setSmallIcon(R.drawable.car_ic_mode)
677                             .build();
678                     mManager.notify(id, updateNotification);
679                     mProgress += 5;
680                     if (mProgress <= 100) {
681                         mHandler.postDelayed(this, 1000);
682                     }
683                 }
684             };
685             mUpdateRunnables.put(id, runnable);
686             mHandler.post(runnable);
687         });
688     }
689 
initNavigationButton(View view)690     private void initNavigationButton(View view) {
691         view.findViewById(R.id.navigation_button).setOnClickListener(v -> {
692 
693             int id1 = mCurrentNotificationId++;
694             Runnable rightTurnRunnable = new Runnable() {
695                 int mDistance = 900;
696 
697                 @Override
698                 public void run() {
699                     Notification updateNotification = new Notification
700                             .Builder(mContext, IMPORTANCE_HIGH_ID)
701                             .setCategory("navigation")
702                             .setContentTitle("Navigation")
703                             .setContentText("Turn right in " + mDistance + " ft")
704                             .setColor(mContext.getColor(android.R.color.holo_green_dark))
705                             .setColorized(true)
706                             .setSubText(mDistance + " ft")
707                             .setSmallIcon(R.drawable.car_ic_mode)
708                             .setOnlyAlertOnce(true)
709                             .build();
710                     mManager.notify(id1, updateNotification);
711                     mDistance -= 100;
712                     if (mDistance >= 0) {
713                         mHandler.postDelayed(this, 1000);
714                     } else {
715                         mManager.cancel(id1);
716                     }
717                 }
718             };
719             mUpdateRunnables.put(id1, rightTurnRunnable);
720             mHandler.postDelayed(rightTurnRunnable, 1000);
721 
722             int id2 = mCurrentNotificationId++;
723             Runnable exitRunnable = new Runnable() {
724                 int mDistance = 20;
725 
726                 @Override
727                 public void run() {
728                     Notification updateNotification = new Notification
729                             .Builder(mContext, IMPORTANCE_HIGH_ID)
730                             .setCategory("navigation")
731                             .setContentTitle("Navigation")
732                             .setContentText("Exit in " + mDistance + " miles")
733                             .setColor(mContext.getColor(android.R.color.holo_green_dark))
734                             .setColorized(true)
735                             .setSubText(mDistance + " miles")
736                             .setSmallIcon(R.drawable.car_ic_mode)
737                             .setOnlyAlertOnce(true)
738                             .build();
739                     mManager.notify(id2, updateNotification);
740                     mDistance -= 1;
741                     if (mDistance >= 0) {
742                         mHandler.postDelayed(this, 500);
743                     }
744                 }
745             };
746             mUpdateRunnables.put(id2, exitRunnable);
747             mHandler.postDelayed(exitRunnable, 10000);
748         });
749     }
750 
initMediaButton(View view)751     private void initMediaButton(View view) {
752         view.findViewById(R.id.media_button).setOnClickListener(v -> {
753             int id = mCurrentNotificationId++;
754 
755             Notification.Builder builder = new Notification
756                     .Builder(mContext, IMPORTANCE_DEFAULT_ID)
757                     .setContentTitle("Lady Adora")
758                     .setContentText("Funny Face")
759                     .setColor(mContext.getColor(android.R.color.holo_orange_dark))
760                     .setColorized(true)
761                     .setSubText("Some album")
762                     .addAction(new Notification.Action(R.drawable.thumb_down, "Thumb down", null))
763                     .addAction(new Notification.Action(R.drawable.skip_prev, "Skip prev", null))
764                     .addAction(new Notification.Action(R.drawable.play_arrow, "Play", null))
765                     .addAction(new Notification.Action(R.drawable.skip_next, "Skip next", null))
766                     .addAction(new Notification.Action(R.drawable.thumb_up, "Thumb up", null))
767                     .setSmallIcon(R.drawable.play_arrow)
768                     .setLargeIcon(Icon.createWithResource(mContext, R.drawable.android_logo));
769 
770             Notification.MediaStyle style = new Notification.MediaStyle();
771             style.setShowActionsInCompactView(1, 2, 3);
772             MediaSession mediaSession = new MediaSession(mContext, "KitchenSink");
773             style.setMediaSession(mediaSession.getSessionToken());
774             builder.setStyle(style);
775             mediaSession.release();
776 
777             mManager.notify(id, builder.build());
778         });
779     }
780 
initCallButton(View view)781     private void initCallButton(View view) {
782         Intent intent = new Intent(mContext, KitchenSinkActivity.class);
783         PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent,
784                 PendingIntent.FLAG_IMMUTABLE);
785 
786         view.findViewById(R.id.category_call_button).setOnClickListener(v -> {
787             Notification notification = new Notification
788                     .Builder(mContext, IMPORTANCE_HIGH_ID)
789                     .setContentTitle("+1 1231231234")
790                     .setContentText("Shows persistent heads-up")
791                     .setCategory(Notification.CATEGORY_CALL)
792                     .setOngoing(true)
793                     .setSmallIcon(R.drawable.car_ic_mode)
794                     .setFullScreenIntent(pendingIntent, true)
795                     .setColor(mContext.getColor(android.R.color.holo_red_light))
796                     .setColorized(true)
797                     .build();
798             mManager.notify(mCurrentNotificationId++, notification);
799         });
800     }
801 
initCustomGroupSummaryButton(View view)802     private void initCustomGroupSummaryButton(View view) {
803         view.findViewById(R.id.custom_group_summary_button).setOnClickListener(v -> {
804             String groupKey = "GROUP_KEY" + mCurrentNotificationId++;
805             int delay = 500;
806 
807             Notification summaryNotification = new Notification
808                     .Builder(mContext, IMPORTANCE_HIGH_ID)
809                     .setContentTitle("6 New mails")
810                     .setContentText("this is some summary")
811                     .setSmallIcon(R.drawable.thumb_up)
812                     .setLargeIcon(Icon.createWithResource(mContext, R.drawable.avatar1))
813                     .setGroup(groupKey)
814                     .setGroupSummary(true)
815                     .setStyle(new Notification.InboxStyle()
816                             .addLine("line 1")
817                             .addLine("line 2")
818                             .addLine("line 3")
819                             .addLine("line 4")
820                             .addLine("line 5")
821                             .setBigContentTitle("You've received 6 messages")
822                             .setSummaryText("From Alice, Bob, Claire, Douglas.."))
823                     .build();
824 
825             mHandler.postDelayed(
826                     () -> mManager.notify(mCurrentNotificationId++, summaryNotification), delay);
827             for (int i = 1; i <= 6; i++) {
828                 Notification notification = new Notification
829                         .Builder(mContext, IMPORTANCE_HIGH_ID)
830                         .setContentTitle("Group child " + i)
831                         .setSmallIcon(R.drawable.car_ic_mode)
832                         .setGroup(groupKey)
833                         .setSortKey(Integer.toString(6 - i))
834                         .build();
835                 mHandler.postDelayed(() -> mManager.notify(mCurrentNotificationId++, notification),
836                         delay += 5000);
837             }
838         });
839     }
840 
initGroupWithoutSummaryButton(View view)841     private void initGroupWithoutSummaryButton(View view) {
842         view.findViewById(R.id.group_without_summary_button).setOnClickListener(v -> {
843             String groupKey = "GROUP_KEY" + mCurrentNotificationId++;
844 
845             for (int i = 1; i <= 6; i++) {
846                 Notification notification = new Notification
847                         .Builder(mContext, IMPORTANCE_DEFAULT_ID)
848                         .setContentTitle("This notification should not group " + i)
849                         .setSmallIcon(R.drawable.car_ic_mode)
850                         .setGroup(groupKey)
851                         .setSortKey(Integer.toString(i))
852                         .build();
853                 mHandler.post(() -> mManager.notify(mCurrentNotificationId++, notification));
854             }
855         });
856     }
857 }
858