blob: e458df239b8a8d016d372f87f5befaf059462d8b [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);
47 mManager =
48 (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
49 mContext = getActivity();
50
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
109 .Builder(getActivity(), 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
121 .Builder(getActivity(), 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
136 .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
137 .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) {
150 Intent mIntent = new Intent(getActivity(), KitchenSinkActivity.class);
151 PendingIntent mPendingIntent = PendingIntent.getActivity(getActivity(), 0, mIntent, 0);
Adora Zhangf27f1c92019-01-10 11:25:59 -0800152
Adora Zhang236b90e2019-01-24 20:40:20 -0800153 Notification notification1 = new Notification
154 .Builder(getActivity(), IMPORTANCE_HIGH_ID)
155 .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
182 .Builder(getActivity(), 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
193 Notification notification = new Notification.Builder(getActivity(), IMPORTANCE_LOW_ID)
194 .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
205 Notification notification = new Notification.Builder(getActivity(), IMPORTANCE_MIN_ID)
206 .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
218 .Builder(getActivity(), 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) {
229 int id = mCurrentNotificationId++;
230
231 view.findViewById(R.id.category_message_button).setOnClickListener(v -> {
232
233 PendingIntent replyIntent = createServiceIntent(id, "reply");
234 PendingIntent markAsReadIntent = createServiceIntent(id, "read");
235
236 Person personJohn = new Person.Builder()
237 .setName("John Doe")
238 .build();
239 Person personJane = new Person.Builder()
240 .setName("Jane Roe")
241 .build();
242 MessagingStyle messagingStyle =
243 new MessagingStyle(personJohn)
244 .setConversationTitle("Heads-up: New Message")
245 .addMessage(
246 new MessagingStyle.Message(
247 "The meaning of life, or the answer to the question"
248 + "What is the meaning of life?, pertains to "
249 + "the significance of living or existence in"
250 + " general. Many other related questions "
251 + "include: Why are we here?, What is "
252 + "life all about?, or What is the "
253 + "purpose of existence?",
254 System.currentTimeMillis() - 3600,
255 personJohn))
256 .addMessage(
257 new MessagingStyle.Message(
258 "Importance High; Groups", System.currentTimeMillis(),
259 personJane));
260
261 NotificationCompat.Builder notification = new NotificationCompat
262 .Builder(getActivity(), IMPORTANCE_HIGH_ID)
263 .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
299 .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
300 .setContentTitle("Progress")
301 .setContentText("Doesn't show heads-up; Importance Default; Groups")
302 .setProgress(100, 0, false)
303 .setColor(mContext.getColor(android.R.color.holo_purple))
304 .setContentInfo("0%")
305 .setSmallIcon(R.drawable.car_ic_mode)
306 .build();
307 mManager.notify(id, notification);
308
309 Runnable runnable = new Runnable() {
310 int mProgress = 0;
311
312 @Override
313 public void run() {
314 Notification updateNotification = new Notification
315 .Builder(getActivity(), IMPORTANCE_DEFAULT_ID)
316 .setContentTitle("Progress")
317 .setContentText("Doesn't show heads-up; Importance Default; Groups")
318 .setProgress(100, mProgress, false)
319 .setColor(mContext.getColor(android.R.color.holo_purple))
320 .setContentInfo(mProgress + "%")
321 .setSmallIcon(R.drawable.car_ic_mode)
322 .build();
323 mManager.notify(id, updateNotification);
324 mProgress += 5;
325 if (mProgress <= 100) {
326 mHandler.postDelayed(this, 1000);
327 }
328 }
329 };
330 mUpdateRunnables.put(id, runnable);
331 mHandler.post(runnable);
332 });
333 }
334
335 private void initNavigationButton(View view) {
336 view.findViewById(R.id.navigation_button).setOnClickListener(v -> {
337 int id = mCurrentNotificationId++;
338
339 Notification notification = new Notification
340 .Builder(getActivity(), IMPORTANCE_HIGH_ID)
341 .setContentTitle("Navigation")
342 .setContentText("Turn right in 900 ft")
343 .setColor(mContext.getColor(android.R.color.holo_green_dark))
344 .setColorized(true)
345 .setSubText("900 ft")
346 .setSmallIcon(R.drawable.car_ic_mode)
347 .build();
348 mManager.notify(id, notification);
349
350 Runnable rightTurnRunnable = new Runnable() {
351 int mDistance = 800;
352
353 @Override
354 public void run() {
355 Notification updateNotification = new Notification
356 .Builder(getActivity(), IMPORTANCE_HIGH_NO_SOUND_ID)
357 .setContentTitle("Navigation")
358 .setContentText("Turn right in " + mDistance + " ft")
359 .setColor(mContext.getColor(android.R.color.holo_green_dark))
360 .setColorized(true)
361 .setSubText(mDistance + " ft")
362 .setSmallIcon(R.drawable.car_ic_mode)
363 .build();
364 mManager.notify(id, updateNotification);
365 mDistance -= 100;
366 if (mDistance >= 0) {
367 mHandler.postDelayed(this, 1000);
368 }
369 }
370 };
371
372 Runnable exitRunnable = new Runnable() {
373 int mDistance = 9;
374
375 @Override
376 public void run() {
377 Notification updateNotification = new Notification
378 .Builder(getActivity(), IMPORTANCE_HIGH_NO_SOUND_ID)
379 .setContentTitle("Navigation")
380 .setContentText("Exit in " + mDistance + " miles")
381 .setColor(mContext.getColor(android.R.color.holo_green_dark))
382 .setColorized(true)
383 .setSubText(mDistance + " miles")
384 .setSmallIcon(R.drawable.car_ic_mode)
385 .build();
386 mManager.notify(id, updateNotification);
387 mDistance -= 1;
388 if (mDistance >= 0) {
389 mHandler.postDelayed(this, 1000);
390 }
391 }
392 };
393
394 mUpdateRunnables.put(id, rightTurnRunnable);
395 mUpdateRunnables.put(id, exitRunnable);
396 mHandler.postDelayed(rightTurnRunnable, 1000);
397 mHandler.postDelayed(exitRunnable, 10000);
398 });
399 }
Adora Zhang6ce05892018-03-02 18:29:41 -0800400}