blob: f5448d32a542aad95a24a03b768904e96d84a715 [file] [log] [blame]
Adora Zhang6ce05892018-03-02 18:29:41 -08001package com.google.android.car.kitchensink.notification;
2
Adora Zhang6ce05892018-03-02 18:29:41 -08003import android.annotation.Nullable;
4import android.app.Notification;
5import android.app.NotificationChannel;
6import android.app.NotificationManager;
7import android.app.PendingIntent;
Adora Zhang6ce05892018-03-02 18:29:41 -08008import android.content.Context;
9import android.content.Intent;
10import android.os.Bundle;
Adora Zhangf27f1c92019-01-10 11:25:59 -080011import android.os.Handler;
Adora Zhang6ce05892018-03-02 18:29:41 -080012import android.view.LayoutInflater;
13import android.view.View;
14import android.view.ViewGroup;
Adora Zhang6ce05892018-03-02 18:29:41 -080015
Adora Zhang236b90e2019-01-24 20:40:20 -080016import androidx.core.app.NotificationCompat;
17import androidx.core.app.NotificationCompat.Action;
18import androidx.core.app.NotificationCompat.MessagingStyle;
19import androidx.core.app.Person;
20import androidx.core.app.RemoteInput;
Anthony Chend12cd772018-04-16 16:20:44 -070021import androidx.fragment.app.Fragment;
22
Adora Zhang6ce05892018-03-02 18:29:41 -080023import com.google.android.car.kitchensink.KitchenSinkActivity;
24import com.google.android.car.kitchensink.R;
25
Adora Zhangf27f1c92019-01-10 11:25:59 -080026import java.util.HashMap;
27
Adora Zhang6ce05892018-03-02 18:29:41 -080028/**
29 * Test fragment that can send all sorts of notifications.
30 */
31public class NotificationFragment extends Fragment {
Adora Zhangf27f1c92019-01-10 11:25:59 -080032 private static final String IMPORTANCE_HIGH_ID = "importance_high";
Adora Zhang236b90e2019-01-24 20:40:20 -080033 private static final String IMPORTANCE_HIGH_NO_SOUND_ID = "importance_high_no_sound";
Adora Zhangf27f1c92019-01-10 11:25:59 -080034 private static final String IMPORTANCE_DEFAULT_ID = "importance_default";
35 private static final String IMPORTANCE_LOW_ID = "importance_low";
36 private static final String IMPORTANCE_MIN_ID = "importance_min";
37 private static final String IMPORTANCE_NONE_ID = "importance_none";
38 private int mCurrentNotificationId = 0;
39 private NotificationManager mManager;
40 private Context mContext;
41 private Handler mHandler = new Handler();
42 private HashMap<Integer, Runnable> mUpdateRunnables = new HashMap<>();
43
44 @Override
45 public void onCreate(Bundle savedInstanceState) {
46 super.onCreate(savedInstanceState);
Adora Zhangf27f1c92019-01-10 11:25:59 -080047 mContext = getActivity();
Adora Zhang9ecb46e2019-02-11 19:46:02 -080048 mManager =
49 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Adora Zhangf27f1c92019-01-10 11:25:59 -080050
51 mManager.createNotificationChannel(new NotificationChannel(
52 IMPORTANCE_HIGH_ID, "Importance High", NotificationManager.IMPORTANCE_HIGH));
53
Adora Zhang236b90e2019-01-24 20:40:20 -080054 NotificationChannel noSoundChannel = new NotificationChannel(
55 IMPORTANCE_HIGH_NO_SOUND_ID, "No sound", NotificationManager.IMPORTANCE_HIGH);
56 noSoundChannel.setSound(null, null);
57 mManager.createNotificationChannel(noSoundChannel);
58
Adora Zhangf27f1c92019-01-10 11:25:59 -080059 mManager.createNotificationChannel(new NotificationChannel(
60 IMPORTANCE_DEFAULT_ID,
61 "Importance Default",
62 NotificationManager.IMPORTANCE_DEFAULT));
63
64 mManager.createNotificationChannel(new NotificationChannel(
65 IMPORTANCE_LOW_ID, "Importance Low", NotificationManager.IMPORTANCE_LOW));
66
67 mManager.createNotificationChannel(new NotificationChannel(
68 IMPORTANCE_MIN_ID, "Importance Min", NotificationManager.IMPORTANCE_MIN));
69
70 mManager.createNotificationChannel(new NotificationChannel(
71 IMPORTANCE_NONE_ID, "Importance None", NotificationManager.IMPORTANCE_NONE));
72 }
Adora Zhang6ce05892018-03-02 18:29:41 -080073
74 @Override
75 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
76 @Nullable Bundle savedInstanceState) {
77 View view = inflater.inflate(R.layout.notification_fragment, container, false);
Adora Zhang6ce05892018-03-02 18:29:41 -080078
Adora Zhangf27f1c92019-01-10 11:25:59 -080079 initCancelAllButton(view);
Adora Zhang236b90e2019-01-24 20:40:20 -080080
81 initCarCategoriesButton(view);
82
83 initImportanceHighBotton(view);
Adora Zhangf27f1c92019-01-10 11:25:59 -080084 initImportanceDefaultButton(view);
85 initImportanceLowButton(view);
86 initImportanceMinButton(view);
Adora Zhang236b90e2019-01-24 20:40:20 -080087
Adora Zhangf27f1c92019-01-10 11:25:59 -080088 initOngoingButton(view);
89 initMessagingStyleButton(view);
90 initProgressButton(view);
Adora Zhang236b90e2019-01-24 20:40:20 -080091 initNavigationButton(view);
Adora Zhang6ce05892018-03-02 18:29:41 -080092
Adora Zhangf27f1c92019-01-10 11:25:59 -080093 return view;
94 }
Adora Zhang6ce05892018-03-02 18:29:41 -080095
Adora Zhangf27f1c92019-01-10 11:25:59 -080096 private void initCancelAllButton(View view) {
97 view.findViewById(R.id.cancel_all_button).setOnClickListener(v -> {
98 for (Runnable runnable : mUpdateRunnables.values()) {
99 mHandler.removeCallbacks(runnable);
100 }
101 mUpdateRunnables.clear();
102 mManager.cancelAll();
Adora Zhang6ce05892018-03-02 18:29:41 -0800103 });
Adora Zhangf27f1c92019-01-10 11:25:59 -0800104 }
Adora Zhang6ce05892018-03-02 18:29:41 -0800105
Adora Zhangf27f1c92019-01-10 11:25:59 -0800106 private void initCarCategoriesButton(View view) {
107 view.findViewById(R.id.category_car_emergency_button).setOnClickListener(v -> {
108 Notification notification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800109 .Builder(mContext, IMPORTANCE_DEFAULT_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800110 .setContentTitle("Car Emergency")
111 .setContentText("Shows heads-up; Shows on top of the list; Does not group")
Brad Stenning2056efe2018-08-14 11:20:13 -0700112 .setCategory(Notification.CATEGORY_CAR_EMERGENCY)
113 .setSmallIcon(R.drawable.car_ic_mode)
114 .build();
Adora Zhangf27f1c92019-01-10 11:25:59 -0800115 mManager.notify(mCurrentNotificationId++, notification);
Brad Stenning2056efe2018-08-14 11:20:13 -0700116 });
117
Adora Zhangf27f1c92019-01-10 11:25:59 -0800118 view.findViewById(R.id.category_car_warning_button).setOnClickListener(v -> {
Brad Stenning2056efe2018-08-14 11:20:13 -0700119
Adora Zhangf27f1c92019-01-10 11:25:59 -0800120 Notification notification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800121 .Builder(mContext, IMPORTANCE_MIN_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800122 .setContentTitle("Car Warning")
123 .setContentText(
124 "Shows heads-up; Shows on top of the list but below Car Emergency; "
125 + "Does not group")
Brad Stenning2056efe2018-08-14 11:20:13 -0700126 .setCategory(Notification.CATEGORY_CAR_WARNING)
Adora Zhang236b90e2019-01-24 20:40:20 -0800127 .setColor(mContext.getColor(android.R.color.holo_orange_dark))
128 .setColorized(true)
Brad Stenning2056efe2018-08-14 11:20:13 -0700129 .setSmallIcon(R.drawable.car_ic_mode)
130 .build();
Adora Zhangf27f1c92019-01-10 11:25:59 -0800131 mManager.notify(mCurrentNotificationId++, notification);
Brad Stenning2056efe2018-08-14 11:20:13 -0700132 });
133
Adora Zhangf27f1c92019-01-10 11:25:59 -0800134 view.findViewById(R.id.category_car_info_button).setOnClickListener(v -> {
135 Notification notification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800136 .Builder(mContext, IMPORTANCE_DEFAULT_ID)
Adora Zhangf27f1c92019-01-10 11:25:59 -0800137 .setContentTitle("Car information")
Adora Zhang236b90e2019-01-24 20:40:20 -0800138 .setContentText("Doesn't show heads-up; Importance Default; Groups")
Adora Zhangf27f1c92019-01-10 11:25:59 -0800139 .setCategory(Notification.CATEGORY_CAR_INFORMATION)
Adora Zhang236b90e2019-01-24 20:40:20 -0800140 .setColor(mContext.getColor(android.R.color.holo_orange_light))
Adora Zhangf27f1c92019-01-10 11:25:59 -0800141 .setColorized(true)
142 .setSmallIcon(R.drawable.car_ic_mode)
143 .build();
144 mManager.notify(mCurrentNotificationId++, notification);
145 });
146
147 }
148
Adora Zhang236b90e2019-01-24 20:40:20 -0800149 private void initImportanceHighBotton(View view) {
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800150 Intent mIntent = new Intent(mContext, KitchenSinkActivity.class);
151 PendingIntent mPendingIntent = PendingIntent.getActivity(mContext, 0, mIntent, 0);
Adora Zhangf27f1c92019-01-10 11:25:59 -0800152
Adora Zhang236b90e2019-01-24 20:40:20 -0800153 Notification notification1 = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800154 .Builder(mContext, IMPORTANCE_HIGH_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800155 .setContentTitle("Importance High: Shows as a heads-up")
156 .setContentText(
157 "Each click generates a new notification. And some "
158 + "looooooong text. "
159 + "Loooooooooooooooooooooong. "
160 + "Loooooooooooooooooooooooooooooooooooooooooooooooooong.")
161 .setSmallIcon(R.drawable.car_ic_mode)
162 .addAction(
163 new Notification.Action.Builder(
164 null, "Long Action (no-op)", mPendingIntent).build())
165 .addAction(
166 new Notification.Action.Builder(
167 null, "Action (no-op)", mPendingIntent).build())
168 .addAction(
169 new Notification.Action.Builder(
170 null, "Long Action (no-op)", mPendingIntent).build())
171 .setColor(mContext.getColor(android.R.color.holo_red_light))
172 .build();
Adora Zhangf27f1c92019-01-10 11:25:59 -0800173
Adora Zhang236b90e2019-01-24 20:40:20 -0800174 view.findViewById(R.id.importance_high_button).setOnClickListener(
175 v -> mManager.notify(mCurrentNotificationId++, notification1)
176 );
Adora Zhangf27f1c92019-01-10 11:25:59 -0800177 }
178
179 private void initImportanceDefaultButton(View view) {
180 view.findViewById(R.id.importance_default_button).setOnClickListener(v -> {
181 Notification notification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800182 .Builder(mContext, IMPORTANCE_DEFAULT_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800183 .setContentTitle("No heads-up; Importance Default; Groups")
Adora Zhangf27f1c92019-01-10 11:25:59 -0800184 .setSmallIcon(R.drawable.car_ic_mode)
185 .build();
186 mManager.notify(mCurrentNotificationId++, notification);
187 });
188 }
189
190 private void initImportanceLowButton(View view) {
191 view.findViewById(R.id.importance_low_button).setOnClickListener(v -> {
192
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800193 Notification notification = new Notification.Builder(mContext, IMPORTANCE_LOW_ID)
Adora Zhangf27f1c92019-01-10 11:25:59 -0800194 .setContentTitle("Importance Low")
Adora Zhang236b90e2019-01-24 20:40:20 -0800195 .setContentText("No heads-up; Below Importance Default; Groups")
Adora Zhangf27f1c92019-01-10 11:25:59 -0800196 .setSmallIcon(R.drawable.car_ic_mode)
197 .build();
198 mManager.notify(mCurrentNotificationId++, notification);
199 });
200 }
201
202 private void initImportanceMinButton(View view) {
203 view.findViewById(R.id.importance_min_button).setOnClickListener(v -> {
204
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800205 Notification notification = new Notification.Builder(mContext, IMPORTANCE_MIN_ID)
Adora Zhangf27f1c92019-01-10 11:25:59 -0800206 .setContentTitle("Importance Min")
Adora Zhang236b90e2019-01-24 20:40:20 -0800207 .setContentText("No heads-up; Below Importance Low; Groups")
Adora Zhangf27f1c92019-01-10 11:25:59 -0800208 .setSmallIcon(R.drawable.car_ic_mode)
209 .build();
210 mManager.notify(mCurrentNotificationId++, notification);
211 });
212 }
213
214 private void initOngoingButton(View view) {
215 view.findViewById(R.id.ongoing_button).setOnClickListener(v -> {
216
217 Notification notification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800218 .Builder(mContext, IMPORTANCE_DEFAULT_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800219 .setContentTitle("Persistent/Ongoing Notification")
220 .setContentText("Cannot be dismissed; No heads-up; Importance default; Groups")
Adora Zhangf27f1c92019-01-10 11:25:59 -0800221 .setSmallIcon(R.drawable.car_ic_mode)
222 .setOngoing(true)
223 .build();
224 mManager.notify(mCurrentNotificationId++, notification);
225 });
Adora Zhang6ce05892018-03-02 18:29:41 -0800226 }
Adora Zhang236b90e2019-01-24 20:40:20 -0800227
228 private void initMessagingStyleButton(View view) {
Adora Zhang236b90e2019-01-24 20:40:20 -0800229 view.findViewById(R.id.category_message_button).setOnClickListener(v -> {
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800230 int id = mCurrentNotificationId++;
Adora Zhang236b90e2019-01-24 20:40:20 -0800231
232 PendingIntent replyIntent = createServiceIntent(id, "reply");
233 PendingIntent markAsReadIntent = createServiceIntent(id, "read");
234
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800235 Person personJohn = new Person.Builder().setName("John Doe").build();
236 Person personJane = new Person.Builder().setName("Jane Roe").build();
Adora Zhang236b90e2019-01-24 20:40:20 -0800237 MessagingStyle messagingStyle =
238 new MessagingStyle(personJohn)
239 .setConversationTitle("Heads-up: New Message")
240 .addMessage(
241 new MessagingStyle.Message(
242 "The meaning of life, or the answer to the question"
243 + "What is the meaning of life?, pertains to "
244 + "the significance of living or existence in"
245 + " general. Many other related questions "
246 + "include: Why are we here?, What is "
247 + "life all about?, or What is the "
248 + "purpose of existence?",
249 System.currentTimeMillis() - 3600,
250 personJohn))
251 .addMessage(
252 new MessagingStyle.Message(
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800253 "Importance High; Groups; Each click generates a new"
254 + "notification. And some looooooong text. "
255 + "Loooooooooooooooooooooong. "
256 + "Loooooooooooooooooooooooooong."
257 + "Long long long long text.",
258 System.currentTimeMillis(),
Adora Zhang236b90e2019-01-24 20:40:20 -0800259 personJane));
260
261 NotificationCompat.Builder notification = new NotificationCompat
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800262 .Builder(mContext, IMPORTANCE_HIGH_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800263 .setContentTitle("Message from someone")
264 .setContentText("hi")
265 .setShowWhen(true)
266 .setCategory(Notification.CATEGORY_MESSAGE)
267 .setSmallIcon(R.drawable.car_ic_mode)
268 .setStyle(messagingStyle)
269 .setAutoCancel(true)
270 .setColor(mContext.getColor(android.R.color.holo_green_light))
271 .addAction(
272 new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
273 .setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
274 .setShowsUserInterface(false)
275 .build())
276 .addAction(
277 new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
278 .setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
279 .setShowsUserInterface(false)
280 .addRemoteInput(new RemoteInput.Builder("input").build())
281 .build());
282
283 mManager.notify(id, notification.build());
284 });
285 }
286
287 private PendingIntent createServiceIntent(int notificationId, String action) {
288 Intent intent = new Intent(mContext, KitchenSinkActivity.class).setAction(action);
289
290 return PendingIntent.getForegroundService(mContext, notificationId, intent,
291 PendingIntent.FLAG_UPDATE_CURRENT);
292 }
293
294 private void initProgressButton(View view) {
295 view.findViewById(R.id.progress_button).setOnClickListener(v -> {
296 int id = mCurrentNotificationId++;
297
298 Notification notification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800299 .Builder(mContext, IMPORTANCE_DEFAULT_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800300 .setContentTitle("Progress")
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800301 .setOngoing(true)
302 .setContentText(
303 "Doesn't show heads-up; Importance Default; Groups; Ongoing (cannot "
304 + "be dismissed)")
Adora Zhang236b90e2019-01-24 20:40:20 -0800305 .setProgress(100, 0, false)
306 .setColor(mContext.getColor(android.R.color.holo_purple))
307 .setContentInfo("0%")
308 .setSmallIcon(R.drawable.car_ic_mode)
309 .build();
310 mManager.notify(id, notification);
311
312 Runnable runnable = new Runnable() {
313 int mProgress = 0;
314
315 @Override
316 public void run() {
317 Notification updateNotification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800318 .Builder(mContext, IMPORTANCE_DEFAULT_ID)
Adora Zhang236b90e2019-01-24 20:40:20 -0800319 .setContentTitle("Progress")
320 .setContentText("Doesn't show heads-up; Importance Default; Groups")
321 .setProgress(100, mProgress, false)
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800322 .setOngoing(true)
Adora Zhang236b90e2019-01-24 20:40:20 -0800323 .setColor(mContext.getColor(android.R.color.holo_purple))
324 .setContentInfo(mProgress + "%")
325 .setSmallIcon(R.drawable.car_ic_mode)
326 .build();
327 mManager.notify(id, updateNotification);
328 mProgress += 5;
329 if (mProgress <= 100) {
330 mHandler.postDelayed(this, 1000);
331 }
332 }
333 };
334 mUpdateRunnables.put(id, runnable);
335 mHandler.post(runnable);
336 });
337 }
338
339 private void initNavigationButton(View view) {
340 view.findViewById(R.id.navigation_button).setOnClickListener(v -> {
341 int id = mCurrentNotificationId++;
342
343 Notification notification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800344 .Builder(mContext, IMPORTANCE_HIGH_ID)
345 .setCategory(Notification.CATEGORY_NAVIGATION)
Adora Zhang236b90e2019-01-24 20:40:20 -0800346 .setContentTitle("Navigation")
347 .setContentText("Turn right in 900 ft")
348 .setColor(mContext.getColor(android.R.color.holo_green_dark))
349 .setColorized(true)
350 .setSubText("900 ft")
351 .setSmallIcon(R.drawable.car_ic_mode)
352 .build();
353 mManager.notify(id, notification);
354
355 Runnable rightTurnRunnable = new Runnable() {
356 int mDistance = 800;
357
358 @Override
359 public void run() {
360 Notification updateNotification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800361 .Builder(mContext, IMPORTANCE_HIGH_NO_SOUND_ID)
362 .setCategory(Notification.CATEGORY_NAVIGATION)
Adora Zhang236b90e2019-01-24 20:40:20 -0800363 .setContentTitle("Navigation")
364 .setContentText("Turn right in " + mDistance + " ft")
365 .setColor(mContext.getColor(android.R.color.holo_green_dark))
366 .setColorized(true)
367 .setSubText(mDistance + " ft")
368 .setSmallIcon(R.drawable.car_ic_mode)
369 .build();
370 mManager.notify(id, updateNotification);
371 mDistance -= 100;
372 if (mDistance >= 0) {
373 mHandler.postDelayed(this, 1000);
374 }
375 }
376 };
377
378 Runnable exitRunnable = new Runnable() {
379 int mDistance = 9;
380
381 @Override
382 public void run() {
383 Notification updateNotification = new Notification
Adora Zhang9ecb46e2019-02-11 19:46:02 -0800384 .Builder(mContext, IMPORTANCE_HIGH_NO_SOUND_ID)
385 .setCategory(Notification.CATEGORY_NAVIGATION)
Adora Zhang236b90e2019-01-24 20:40:20 -0800386 .setContentTitle("Navigation")
387 .setContentText("Exit in " + mDistance + " miles")
388 .setColor(mContext.getColor(android.R.color.holo_green_dark))
389 .setColorized(true)
390 .setSubText(mDistance + " miles")
391 .setSmallIcon(R.drawable.car_ic_mode)
392 .build();
393 mManager.notify(id, updateNotification);
394 mDistance -= 1;
395 if (mDistance >= 0) {
396 mHandler.postDelayed(this, 1000);
397 }
398 }
399 };
400
401 mUpdateRunnables.put(id, rightTurnRunnable);
402 mUpdateRunnables.put(id, exitRunnable);
403 mHandler.postDelayed(rightTurnRunnable, 1000);
404 mHandler.postDelayed(exitRunnable, 10000);
405 });
406 }
Adora Zhang6ce05892018-03-02 18:29:41 -0800407}