· 5 years ago · Jan 29, 2021, 11:38 AM
1import 'dart:async';
2import 'dart:io';
3import 'dart:typed_data';
4import 'dart:ui';
5
6import 'package:flutter/material.dart';
7import 'package:flutter_local_notifications/flutter_local_notifications.dart';
8
9import 'package:device_info/device_info.dart';
10import 'package:flutter/cupertino.dart';
11import 'package:flutter/material.dart';
12import 'package:flutter/services.dart';
13import 'package:http/http.dart' as http;
14import 'package:path_provider/path_provider.dart';
15import 'package:rxdart/subjects.dart';
16import 'package:timezone/data/latest.dart' as tz;
17import 'package:timezone/timezone.dart' as tz;
18
19
20
21
22final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
23FlutterLocalNotificationsPlugin();
24
25/// Streams are created so that app can respond to notification-related events
26/// since the plugin is initialised in the `main` function
27final BehaviorSubject<ReceivedNotification> didReceiveLocalNotificationSubject =
28BehaviorSubject<ReceivedNotification>();
29
30final BehaviorSubject<String> selectNotificationSubject =
31BehaviorSubject<String>();
32
33const MethodChannel platform =
34MethodChannel('dexterx.dev/flutter_local_notifications_example');
35
36class ReceivedNotification {
37 ReceivedNotification({
38 @required this.id,
39 @required this.title,
40 @required this.body,
41 @required this.payload,
42 });
43
44 final int id;
45 final String title;
46 final String body;
47 final String payload;
48}
49
50Future<void> main() async {
51 // needed if you intend to initialize in the `main` function
52 WidgetsFlutterBinding.ensureInitialized();
53
54 await _configureLocalTimeZone();
55
56 final NotificationAppLaunchDetails notificationAppLaunchDetails =
57 await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
58
59 const AndroidInitializationSettings initializationSettingsAndroid =
60 AndroidInitializationSettings('app_icon');
61
62 /// Note: permissions aren't requested here just to demonstrate that can be
63 /// done later
64 final IOSInitializationSettings initializationSettingsIOS =
65 IOSInitializationSettings(
66 requestAlertPermission: false,
67 requestBadgePermission: false,
68 requestSoundPermission: false,
69 onDidReceiveLocalNotification:
70 (int id, String title, String body, String payload) async {
71 didReceiveLocalNotificationSubject.add(ReceivedNotification(
72 id: id, title: title, body: body, payload: payload));
73 });
74 const MacOSInitializationSettings initializationSettingsMacOS =
75 MacOSInitializationSettings(
76 requestAlertPermission: false,
77 requestBadgePermission: false,
78 requestSoundPermission: false);
79 final InitializationSettings initializationSettings = InitializationSettings(
80 android: initializationSettingsAndroid,
81 iOS: initializationSettingsIOS,
82 macOS: initializationSettingsMacOS);
83 await flutterLocalNotificationsPlugin.initialize(initializationSettings,
84 onSelectNotification: (String payload) async {
85 if (payload != null) {
86 debugPrint('notification payload: $payload');
87 }
88 selectNotificationSubject.add(payload);
89 });
90 runApp(
91 MaterialApp(
92 home: HomePage(
93 notificationAppLaunchDetails,
94 ),
95 ),
96 );
97}
98
99Future<void> _configureLocalTimeZone() async {
100 tz.initializeTimeZones();
101 //final String timeZoneName = await platform.invokeMethod('getTimeZoneName');
102 //tz.setLocalLocation(tz.getLocation(timeZoneName));
103}
104
105class PaddedRaisedButton extends StatelessWidget {
106 const PaddedRaisedButton({
107 @required this.buttonText,
108 @required this.onPressed,
109 Key key,
110 }) : super(key: key);
111
112 final String buttonText;
113 final VoidCallback onPressed;
114
115 @override
116 Widget build(BuildContext context) => Padding(
117 padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
118 child: RaisedButton(
119 onPressed: onPressed,
120 child: Text(buttonText),
121 ),
122 );
123}
124
125
126
127
128
129class HomePage extends StatefulWidget {
130 const HomePage(
131 this.notificationAppLaunchDetails, {
132 Key key,
133 }) : super(key: key);
134
135 final NotificationAppLaunchDetails notificationAppLaunchDetails;
136 bool get didNotificationLaunchApp =>
137 notificationAppLaunchDetails?.didNotificationLaunchApp ?? false;
138
139 @override
140 _HomePageState createState() => _HomePageState();
141}
142
143class _HomePageState extends State<HomePage> {
144 @override
145 void initState() {
146 super.initState();
147 _requestPermissions();
148 _configureDidReceiveLocalNotificationSubject();
149 _configureSelectNotificationSubject();
150 }
151
152 void _requestPermissions() {
153 flutterLocalNotificationsPlugin
154 .resolvePlatformSpecificImplementation<
155 IOSFlutterLocalNotificationsPlugin>()
156 ?.requestPermissions(
157 alert: true,
158 badge: true,
159 sound: true,
160 );
161 flutterLocalNotificationsPlugin
162 .resolvePlatformSpecificImplementation<
163 MacOSFlutterLocalNotificationsPlugin>()
164 ?.requestPermissions(
165 alert: true,
166 badge: true,
167 sound: true,
168 );
169 }
170
171 void _configureDidReceiveLocalNotificationSubject() {
172 didReceiveLocalNotificationSubject.stream
173 .listen((ReceivedNotification receivedNotification) async {
174 await showDialog(
175 context: context,
176 builder: (BuildContext context) => CupertinoAlertDialog(
177 title: receivedNotification.title != null
178 ? Text(receivedNotification.title)
179 : null,
180 content: receivedNotification.body != null
181 ? Text(receivedNotification.body)
182 : null,
183 actions: <Widget>[
184 CupertinoDialogAction(
185 isDefaultAction: true,
186 onPressed: () async {
187 Navigator.of(context, rootNavigator: true).pop();
188 await Navigator.push(
189 context,
190 MaterialPageRoute<void>(
191 builder: (BuildContext context) =>
192 SecondScreen(receivedNotification.payload),
193 ),
194 );
195 },
196 child: const Text('Ok'),
197 )
198 ],
199 ),
200 );
201 });
202 }
203
204 void _configureSelectNotificationSubject() {
205 selectNotificationSubject.stream.listen((String payload) async {
206 await Navigator.push(
207 context,
208 MaterialPageRoute<void>(
209 builder: (BuildContext context) => SecondScreen(payload)),
210 );
211 });
212 }
213
214 @override
215 void dispose() {
216 didReceiveLocalNotificationSubject.close();
217 selectNotificationSubject.close();
218 super.dispose();
219 }
220
221 @override
222 Widget build(BuildContext context) => MaterialApp(
223 home: Scaffold(
224 appBar: AppBar(
225 title: const Text('Plugin example app'),
226 ),
227 body: SingleChildScrollView(
228 child: Padding(
229 padding: const EdgeInsets.all(8),
230 child: Center(
231 child: Column(
232 children: <Widget>[
233 const Padding(
234 padding: EdgeInsets.fromLTRB(0, 0, 0, 8),
235 child: Text(
236 'Tap on a notification when it appears to trigger'
237 ' navigation'),
238 ),
239 Padding(
240 padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
241 child: Text.rich(
242 TextSpan(
243 children: <InlineSpan>[
244 const TextSpan(
245 text: 'Did notification launch app? ',
246 style: TextStyle(fontWeight: FontWeight.bold),
247 ),
248 TextSpan(
249 text: '${widget.didNotificationLaunchApp}',
250 )
251 ],
252 ),
253 ),
254 ),
255 if (widget.didNotificationLaunchApp)
256 Padding(
257 padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
258 child: Text.rich(
259 TextSpan(
260 children: <InlineSpan>[
261 const TextSpan(
262 text: 'Launch notification payload: ',
263 style: TextStyle(fontWeight: FontWeight.bold),
264 ),
265 TextSpan(
266 text:
267 widget.notificationAppLaunchDetails.payload,
268 )
269 ],
270 ),
271 ),
272 ),
273 PaddedRaisedButton(
274 buttonText: 'Show plain notification with payload',
275 onPressed: () async {
276 await _showNotification();
277 },
278 ),
279 PaddedRaisedButton(
280 buttonText:
281 'Show plain notification that has no title with '
282 'payload',
283 onPressed: () async {
284 await _showNotificationWithNoTitle();
285 },
286 ),
287 PaddedRaisedButton(
288 buttonText:
289 'Show plain notification that has no body with '
290 'payload',
291 onPressed: () async {
292 await _showNotificationWithNoBody();
293 },
294 ),
295 PaddedRaisedButton(
296 buttonText: 'Show notification with custom sound',
297 onPressed: () async {
298 await _showNotificationCustomSound();
299 },
300 ),
301 PaddedRaisedButton(
302 buttonText:
303 'Schedule notification to appear in 5 seconds based '
304 'on local time zone',
305 onPressed: () async {
306 await _zonedScheduleNotification();
307 },
308 ),
309 PaddedRaisedButton(
310 buttonText: 'Repeat notification every minute',
311 onPressed: () async {
312 await _repeatNotification();
313 },
314 ),
315 PaddedRaisedButton(
316 buttonText:
317 'Schedule daily 10:00:00 am notification in your '
318 'local time zone',
319 onPressed: () async {
320 await _scheduleDailyTenAMNotification();
321 },
322 ),
323 PaddedRaisedButton(
324 buttonText:
325 'Schedule daily 10:00:00 am notification in your '
326 "local time zone using last year's date",
327 onPressed: () async {
328 await _scheduleDailyTenAMLastYearNotification();
329 },
330 ),
331 PaddedRaisedButton(
332 buttonText:
333 'Schedule weekly 10:00:00 am notification in your '
334 'local time zone',
335 onPressed: () async {
336 await _scheduleWeeklyTenAMNotification();
337 },
338 ),
339 PaddedRaisedButton(
340 buttonText:
341 'Schedule weekly Monday 10:00:00 am notification in '
342 'your local time zone',
343 onPressed: () async {
344 await _scheduleWeeklyMondayTenAMNotification();
345 },
346 ),
347 PaddedRaisedButton(
348 buttonText: 'Show notification with no sound',
349 onPressed: () async {
350 await _showNotificationWithNoSound();
351 },
352 ),
353 PaddedRaisedButton(
354 buttonText: 'Check pending notifications',
355 onPressed: () async {
356 await _checkPendingNotificationRequests();
357 },
358 ),
359 PaddedRaisedButton(
360 buttonText: 'Cancel notification',
361 onPressed: () async {
362 await _cancelNotification();
363 },
364 ),
365 PaddedRaisedButton(
366 buttonText: 'Cancel all notifications',
367 onPressed: () async {
368 await _cancelAllNotifications();
369 },
370 ),
371 if (Platform.isAndroid) ...<Widget>[
372 const Text(
373 'Android-specific examples',
374 style: TextStyle(fontWeight: FontWeight.bold),
375 ),
376 PaddedRaisedButton(
377 buttonText:
378 'Show plain notification with payload and update '
379 'channel description',
380 onPressed: () async {
381 await _showNotificationUpdateChannelDescription();
382 },
383 ),
384 PaddedRaisedButton(
385 buttonText:
386 'Show plain notification as public on every '
387 'lockscreen',
388 onPressed: () async {
389 await _showPublicNotification();
390 },
391 ),
392 PaddedRaisedButton(
393 buttonText:
394 'Show notification with custom vibration pattern, '
395 'red LED and red icon',
396 onPressed: () async {
397 await _showNotificationCustomVibrationIconLed();
398 },
399 ),
400 PaddedRaisedButton(
401 buttonText: 'Show notification using Android Uri sound',
402 onPressed: () async {
403 await _showSoundUriNotification();
404 },
405 ),
406 PaddedRaisedButton(
407 buttonText:
408 'Show notification that times out after 3 seconds',
409 onPressed: () async {
410 await _showTimeoutNotification();
411 },
412 ),
413 PaddedRaisedButton(
414 buttonText: 'Show insistent notification',
415 onPressed: () async {
416 await _showInsistentNotification();
417 },
418 ),
419 PaddedRaisedButton(
420 buttonText: 'Show big picture notification',
421 onPressed: () async {
422 await _showBigPictureNotification();
423 },
424 ),
425 PaddedRaisedButton(
426 buttonText:
427 'Show big picture notification, hide large icon '
428 'on expand',
429 onPressed: () async {
430 await _showBigPictureNotificationHiddenLargeIcon();
431 },
432 ),
433 PaddedRaisedButton(
434 buttonText: 'Show media notification',
435 onPressed: () async {
436 await _showNotificationMediaStyle();
437 },
438 ),
439 PaddedRaisedButton(
440 buttonText: 'Show big text notification',
441 onPressed: () async {
442 await _showBigTextNotification();
443 },
444 ),
445 PaddedRaisedButton(
446 buttonText: 'Show inbox notification',
447 onPressed: () async {
448 await _showInboxNotification();
449 },
450 ),
451 PaddedRaisedButton(
452 buttonText: 'Show messaging notification',
453 onPressed: () async {
454 await _showMessagingNotification();
455 },
456 ),
457 PaddedRaisedButton(
458 buttonText: 'Show grouped notifications',
459 onPressed: () async {
460 await _showGroupedNotifications();
461 },
462 ),
463 PaddedRaisedButton(
464 buttonText: 'Show notification with tag',
465 onPressed: () async {
466 await _showNotificationWithTag();
467 },
468 ),
469 PaddedRaisedButton(
470 buttonText: 'Cancel notification with tag',
471 onPressed: () async {
472 await _cancelNotificationWithTag();
473 },
474 ),
475 PaddedRaisedButton(
476 buttonText: 'Show ongoing notification',
477 onPressed: () async {
478 await _showOngoingNotification();
479 },
480 ),
481 PaddedRaisedButton(
482 buttonText:
483 'Show notification with no badge, alert only once',
484 onPressed: () async {
485 await _showNotificationWithNoBadge();
486 },
487 ),
488 PaddedRaisedButton(
489 buttonText:
490 'Show progress notification - updates every second',
491 onPressed: () async {
492 await _showProgressNotification();
493 },
494 ),
495 PaddedRaisedButton(
496 buttonText: 'Show indeterminate progress notification',
497 onPressed: () async {
498 await _showIndeterminateProgressNotification();
499 },
500 ),
501 PaddedRaisedButton(
502 buttonText: 'Show notification without timestamp',
503 onPressed: () async {
504 await _showNotificationWithoutTimestamp();
505 },
506 ),
507 PaddedRaisedButton(
508 buttonText: 'Show notification with custom timestamp',
509 onPressed: () async {
510 await _showNotificationWithCustomTimestamp();
511 },
512 ),
513 PaddedRaisedButton(
514 buttonText: 'Show notification with custom sub-text',
515 onPressed: () async {
516 await _showNotificationWithCustomSubText();
517 },
518 ),
519 PaddedRaisedButton(
520 buttonText: 'Show notification with chronometer',
521 onPressed: () async {
522 await _showNotificationWithChronometer();
523 },
524 ),
525 PaddedRaisedButton(
526 buttonText: 'Show full-screen notification',
527 onPressed: () async {
528 await _showFullScreenNotification();
529 },
530 ),
531 PaddedRaisedButton(
532 buttonText: 'Create grouped notification channels',
533 onPressed: () async {
534 await _createNotificationChannelGroup();
535 },
536 ),
537 PaddedRaisedButton(
538 buttonText: 'Delete notification channel group',
539 onPressed: () async {
540 await _deleteNotificationChannelGroup();
541 },
542 ),
543 PaddedRaisedButton(
544 buttonText: 'Create notification channel',
545 onPressed: () async {
546 await _createNotificationChannel();
547 },
548 ),
549 PaddedRaisedButton(
550 buttonText: 'Delete notification channel',
551 onPressed: () async {
552 await _deleteNotificationChannel();
553 },
554 ),
555 PaddedRaisedButton(
556 buttonText: 'Get active notifications',
557 onPressed: () async {
558 await _getActiveNotifications();
559 },
560 ),
561 ],
562 if (Platform.isIOS || Platform.isMacOS) ...<Widget>[
563 const Text(
564 'iOS and macOS-specific examples',
565 style: TextStyle(fontWeight: FontWeight.bold),
566 ),
567 PaddedRaisedButton(
568 buttonText: 'Show notification with subtitle',
569 onPressed: () async {
570 await _showNotificationWithSubtitle();
571 },
572 ),
573 PaddedRaisedButton(
574 buttonText: 'Show notification with icon badge',
575 onPressed: () async {
576 await _showNotificationWithIconBadge();
577 },
578 ),
579 PaddedRaisedButton(
580 buttonText: 'Show notification with attachment',
581 onPressed: () async {
582 await _showNotificationWithAttachment();
583 },
584 ),
585 PaddedRaisedButton(
586 buttonText: 'Show notifications with thread identifier',
587 onPressed: () async {
588 //await _showNotificationsWithThreadIdentifier();
589 },
590 ),
591 ],
592 ],
593 ),
594 ),
595 ),
596 ),
597 ),
598 );
599
600 Future<void> _showNotification() async {
601 const AndroidNotificationDetails androidPlatformChannelSpecifics =
602 AndroidNotificationDetails(
603 'your channel id', 'your channel name', 'your channel description',
604 importance: Importance.max,
605 priority: Priority.high,
606 ticker: 'ticker');
607 const NotificationDetails platformChannelSpecifics =
608 NotificationDetails(android: androidPlatformChannelSpecifics);
609 await flutterLocalNotificationsPlugin.show(
610 0, 'plain title', 'plain body', platformChannelSpecifics,
611 payload: 'item x');
612 }
613
614 Future<void> _showFullScreenNotification() async {
615 await showDialog(
616 context: context,
617 builder: (_) => AlertDialog(
618 title: const Text('Turn off your screen'),
619 content: const Text(
620 'to see the full-screen intent in 5 seconds, press OK and TURN '
621 'OFF your screen'),
622 actions: <Widget>[
623 FlatButton(
624 onPressed: () {
625 Navigator.pop(context);
626 },
627 child: const Text('Cancel'),
628 ),
629 FlatButton(
630 onPressed: () async {
631 await flutterLocalNotificationsPlugin.zonedSchedule(
632 0,
633 'scheduled title',
634 'scheduled body',
635 tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)),
636 const NotificationDetails(
637 android: AndroidNotificationDetails(
638 'full screen channel id',
639 'full screen channel name',
640 'full screen channel description',
641 priority: Priority.high,
642 importance: Importance.high,
643 fullScreenIntent: true)),
644 androidAllowWhileIdle: true,
645 uiLocalNotificationDateInterpretation:
646 UILocalNotificationDateInterpretation.absoluteTime);
647
648 Navigator.pop(context);
649 },
650 child: const Text('OK'),
651 )
652 ],
653 ),
654 );
655 }
656
657 Future<void> _showNotificationWithNoBody() async {
658 const AndroidNotificationDetails androidPlatformChannelSpecifics =
659 AndroidNotificationDetails(
660 'your channel id', 'your channel name', 'your channel description',
661 importance: Importance.max,
662 priority: Priority.high,
663 ticker: 'ticker');
664 const NotificationDetails platformChannelSpecifics = NotificationDetails(
665 android: androidPlatformChannelSpecifics,
666 );
667 await flutterLocalNotificationsPlugin.show(
668 0, 'plain title', null, platformChannelSpecifics,
669 payload: 'item x');
670 }
671
672 Future<void> _showNotificationWithNoTitle() async {
673 const AndroidNotificationDetails androidPlatformChannelSpecifics =
674 AndroidNotificationDetails(
675 'your channel id', 'your channel name', 'your channel description',
676 importance: Importance.max,
677 priority: Priority.high,
678 ticker: 'ticker');
679 const NotificationDetails platformChannelSpecifics = NotificationDetails(
680 android: androidPlatformChannelSpecifics,
681 );
682 await flutterLocalNotificationsPlugin.show(
683 0, null, 'plain body', platformChannelSpecifics,
684 payload: 'item x');
685 }
686
687 Future<void> _cancelNotification() async {
688 await flutterLocalNotificationsPlugin.cancel(0);
689 }
690
691 Future<void> _cancelNotificationWithTag() async {
692 await flutterLocalNotificationsPlugin.cancel(0);
693 }
694
695 Future<void> _showNotificationCustomSound() async {
696 const AndroidNotificationDetails androidPlatformChannelSpecifics =
697 AndroidNotificationDetails(
698 'your other channel id',
699 'your other channel name',
700 'your other channel description',
701 sound: RawResourceAndroidNotificationSound('slow_spring_board'),
702 );
703 const IOSNotificationDetails iOSPlatformChannelSpecifics =
704 IOSNotificationDetails(sound: 'slow_spring_board.aiff');
705 const MacOSNotificationDetails macOSPlatformChannelSpecifics =
706 MacOSNotificationDetails(sound: 'slow_spring_board.aiff');
707 const NotificationDetails platformChannelSpecifics = NotificationDetails(
708 android: androidPlatformChannelSpecifics,
709 iOS: iOSPlatformChannelSpecifics,
710 macOS: macOSPlatformChannelSpecifics);
711 await flutterLocalNotificationsPlugin.show(
712 0,
713 'custom sound notification title',
714 'custom sound notification body',
715 platformChannelSpecifics);
716 }
717
718 Future<void> _showNotificationCustomVibrationIconLed() async {
719 final Int64List vibrationPattern = Int64List(4);
720 vibrationPattern[0] = 0;
721 vibrationPattern[1] = 1000;
722 vibrationPattern[2] = 5000;
723 vibrationPattern[3] = 2000;
724
725 final AndroidNotificationDetails androidPlatformChannelSpecifics =
726 AndroidNotificationDetails('other custom channel id',
727 'other custom channel name', 'other custom channel description',
728 icon: 'secondary_icon',
729 largeIcon: const DrawableResourceAndroidBitmap('sample_large_icon'),
730 vibrationPattern: vibrationPattern,
731 enableLights: true,
732 color: const Color.fromARGB(255, 255, 0, 0),
733 ledColor: const Color.fromARGB(255, 255, 0, 0),
734 ledOnMs: 1000,
735 ledOffMs: 500);
736
737 final NotificationDetails platformChannelSpecifics =
738 NotificationDetails(android: androidPlatformChannelSpecifics);
739 await flutterLocalNotificationsPlugin.show(
740 0,
741 'title of notification with custom vibration pattern, LED and icon',
742 'body of notification with custom vibration pattern, LED and icon',
743 platformChannelSpecifics);
744 }
745
746 Future<void> _zonedScheduleNotification() async {
747 await flutterLocalNotificationsPlugin.zonedSchedule(
748 0,
749 'scheduled title',
750 'scheduled body',
751 tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)),
752 const NotificationDetails(
753 android: AndroidNotificationDetails('your channel id',
754 'your channel name', 'your channel description')),
755 androidAllowWhileIdle: true,
756 uiLocalNotificationDateInterpretation:
757 UILocalNotificationDateInterpretation.absoluteTime);
758 }
759
760 Future<void> _showNotificationWithNoSound() async {
761 const AndroidNotificationDetails androidPlatformChannelSpecifics =
762 AndroidNotificationDetails('silent channel id', 'silent channel name',
763 'silent channel description',
764 playSound: false,
765 styleInformation: DefaultStyleInformation(true, true));
766 const IOSNotificationDetails iOSPlatformChannelSpecifics =
767 IOSNotificationDetails(presentSound: false);
768 const MacOSNotificationDetails macOSPlatformChannelSpecifics =
769 MacOSNotificationDetails(presentSound: false);
770 const NotificationDetails platformChannelSpecifics = NotificationDetails(
771 android: androidPlatformChannelSpecifics,
772 iOS: iOSPlatformChannelSpecifics,
773 macOS: macOSPlatformChannelSpecifics);
774 await flutterLocalNotificationsPlugin.show(0, '<b>silent</b> title',
775 '<b>silent</b> body', platformChannelSpecifics);
776 }
777
778 Future<void> _showSoundUriNotification() async {
779 /// this calls a method over a platform channel implemented within the
780 /// example app to return the Uri for the default alarm sound and uses
781 /// as the notification sound
782 final String alarmUri = await platform.invokeMethod('getAlarmUri');
783 final UriAndroidNotificationSound uriSound =
784 UriAndroidNotificationSound(alarmUri);
785 final AndroidNotificationDetails androidPlatformChannelSpecifics =
786 AndroidNotificationDetails(
787 'uri channel id', 'uri channel name', 'uri channel description',
788 sound: uriSound,
789 styleInformation: const DefaultStyleInformation(true, true));
790 final NotificationDetails platformChannelSpecifics =
791 NotificationDetails(android: androidPlatformChannelSpecifics);
792 await flutterLocalNotificationsPlugin.show(
793 0, 'uri sound title', 'uri sound body', platformChannelSpecifics);
794 }
795
796 Future<void> _showTimeoutNotification() async {
797 const AndroidNotificationDetails androidPlatformChannelSpecifics =
798 AndroidNotificationDetails('silent channel id', 'silent channel name',
799 'silent channel description',
800 timeoutAfter: 3000,
801 styleInformation: DefaultStyleInformation(true, true));
802 const NotificationDetails platformChannelSpecifics =
803 NotificationDetails(android: androidPlatformChannelSpecifics);
804 await flutterLocalNotificationsPlugin.show(0, 'timeout notification',
805 'Times out after 3 seconds', platformChannelSpecifics);
806 }
807
808 Future<void> _showInsistentNotification() async {
809 // This value is from: https://developer.android.com/reference/android/app/Notification.html#FLAG_INSISTENT
810 const int insistentFlag = 4;
811 final AndroidNotificationDetails androidPlatformChannelSpecifics =
812 AndroidNotificationDetails(
813 'your channel id', 'your channel name', 'your channel description',
814 importance: Importance.max,
815 priority: Priority.high,
816 ticker: 'ticker',
817 additionalFlags: Int32List.fromList(<int>[insistentFlag]));
818 final NotificationDetails platformChannelSpecifics =
819 NotificationDetails(android: androidPlatformChannelSpecifics);
820 await flutterLocalNotificationsPlugin.show(
821 0, 'insistent title', 'insistent body', platformChannelSpecifics,
822 payload: 'item x');
823 }
824
825 Future<String> _downloadAndSaveFile(String url, String fileName) async {
826 final Directory directory = await getApplicationDocumentsDirectory();
827 final String filePath = '${directory.path}/$fileName';
828 final http.Response response = await http.get(url);
829 final File file = File(filePath);
830 await file.writeAsBytes(response.bodyBytes);
831 return filePath;
832 }
833
834 Future<void> _showBigPictureNotification() async {
835 final String largeIconPath = await _downloadAndSaveFile(
836 'https://via.placeholder.com/48x48', 'largeIcon');
837 final String bigPicturePath = await _downloadAndSaveFile(
838 'https://via.placeholder.com/400x800', 'bigPicture');
839 final BigPictureStyleInformation bigPictureStyleInformation =
840 BigPictureStyleInformation(FilePathAndroidBitmap(bigPicturePath),
841 largeIcon: FilePathAndroidBitmap(largeIconPath),
842 contentTitle: 'overridden <b>big</b> content title',
843 htmlFormatContentTitle: true,
844 summaryText: 'summary <i>text</i>',
845 htmlFormatSummaryText: true);
846 final AndroidNotificationDetails androidPlatformChannelSpecifics =
847 AndroidNotificationDetails('big text channel id',
848 'big text channel name', 'big text channel description',
849 styleInformation: bigPictureStyleInformation);
850 final NotificationDetails platformChannelSpecifics =
851 NotificationDetails(android: androidPlatformChannelSpecifics);
852 await flutterLocalNotificationsPlugin.show(
853 0, 'big text title', 'silent body', platformChannelSpecifics);
854 }
855
856 Future<void> _showBigPictureNotificationHiddenLargeIcon() async {
857 final String largeIconPath = await _downloadAndSaveFile(
858 'https://via.placeholder.com/48x48', 'largeIcon');
859 final String bigPicturePath = await _downloadAndSaveFile(
860 'https://via.placeholder.com/400x800', 'bigPicture');
861 final BigPictureStyleInformation bigPictureStyleInformation =
862 BigPictureStyleInformation(FilePathAndroidBitmap(bigPicturePath),
863 hideExpandedLargeIcon: true,
864 contentTitle: 'overridden <b>big</b> content title',
865 htmlFormatContentTitle: true,
866 summaryText: 'summary <i>text</i>',
867 htmlFormatSummaryText: true);
868 final AndroidNotificationDetails androidPlatformChannelSpecifics =
869 AndroidNotificationDetails('big text channel id',
870 'big text channel name', 'big text channel description',
871 largeIcon: FilePathAndroidBitmap(largeIconPath),
872 styleInformation: bigPictureStyleInformation);
873 final NotificationDetails platformChannelSpecifics =
874 NotificationDetails(android: androidPlatformChannelSpecifics);
875 await flutterLocalNotificationsPlugin.show(
876 0, 'big text title', 'silent body', platformChannelSpecifics);
877 }
878
879 Future<void> _showNotificationMediaStyle() async {
880 final String largeIconPath = await _downloadAndSaveFile(
881 'https://via.placeholder.com/128x128/00FF00/000000', 'largeIcon');
882 final AndroidNotificationDetails androidPlatformChannelSpecifics =
883 AndroidNotificationDetails(
884 'media channel id',
885 'media channel name',
886 'media channel description',
887 largeIcon: FilePathAndroidBitmap(largeIconPath),
888 styleInformation: const MediaStyleInformation(),
889 );
890 final NotificationDetails platformChannelSpecifics =
891 NotificationDetails(android: androidPlatformChannelSpecifics);
892 await flutterLocalNotificationsPlugin.show(
893 0, 'notification title', 'notification body', platformChannelSpecifics);
894 }
895
896 Future<void> _showBigTextNotification() async {
897 const BigTextStyleInformation bigTextStyleInformation =
898 BigTextStyleInformation(
899 'Lorem <i>ipsum dolor sit</i> amet, consectetur <b>adipiscing elit</b>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
900 htmlFormatBigText: true,
901 contentTitle: 'overridden <b>big</b> content title',
902 htmlFormatContentTitle: true,
903 summaryText: 'summary <i>text</i>',
904 htmlFormatSummaryText: true,
905 );
906 const AndroidNotificationDetails androidPlatformChannelSpecifics =
907 AndroidNotificationDetails('big text channel id',
908 'big text channel name', 'big text channel description',
909 styleInformation: bigTextStyleInformation);
910 const NotificationDetails platformChannelSpecifics =
911 NotificationDetails(android: androidPlatformChannelSpecifics);
912 await flutterLocalNotificationsPlugin.show(
913 0, 'big text title', 'silent body', platformChannelSpecifics);
914 }
915
916 Future<void> _showInboxNotification() async {
917 final List<String> lines = <String>['line <b>1</b>', 'line <i>2</i>'];
918 final InboxStyleInformation inboxStyleInformation = InboxStyleInformation(
919 lines,
920 htmlFormatLines: true,
921 contentTitle: 'overridden <b>inbox</b> context title',
922 htmlFormatContentTitle: true,
923 summaryText: 'summary <i>text</i>',
924 htmlFormatSummaryText: true);
925 final AndroidNotificationDetails androidPlatformChannelSpecifics =
926 AndroidNotificationDetails('inbox channel id', 'inboxchannel name',
927 'inbox channel description',
928 styleInformation: inboxStyleInformation);
929 final NotificationDetails platformChannelSpecifics =
930 NotificationDetails(android: androidPlatformChannelSpecifics);
931 await flutterLocalNotificationsPlugin.show(
932 0, 'inbox title', 'inbox body', platformChannelSpecifics);
933 }
934
935 Future<void> _showMessagingNotification() async {
936 // use a platform channel to resolve an Android drawable resource to a URI.
937 // This is NOT part of the notifications plugin. Calls made over this
938 /// channel is handled by the app
939 final String imageUri =
940 await platform.invokeMethod('drawableToUri', 'food');
941
942 /// First two person objects will use icons that part of the Android app's
943 /// drawable resources
944 const Person me = Person(
945 name: 'Me',
946 key: '1',
947 uri: 'tel:1234567890',
948 icon: DrawableResourceAndroidIcon('me'),
949 );
950 const Person coworker = Person(
951 name: 'Coworker',
952 key: '2',
953 uri: 'tel:9876543210',
954 icon: FlutterBitmapAssetAndroidIcon('icons/coworker.png'),
955 );
956 // download the icon that would be use for the lunch bot person
957 final String largeIconPath = await _downloadAndSaveFile(
958 'https://via.placeholder.com/48x48', 'largeIcon');
959 // this person object will use an icon that was downloaded
960 final Person lunchBot = Person(
961 name: 'Lunch bot',
962 key: 'bot',
963 bot: true,
964 icon: BitmapFilePathAndroidIcon(largeIconPath),
965 );
966 final List<Message> messages = <Message>[
967 Message('Hi', DateTime.now(), null),
968 Message("What's up?", DateTime.now().add(const Duration(minutes: 5)),
969 coworker),
970 Message('Lunch?', DateTime.now().add(const Duration(minutes: 10)), null,
971 dataMimeType: 'image/png', dataUri: imageUri),
972 Message('What kind of food would you prefer?',
973 DateTime.now().add(const Duration(minutes: 10)), lunchBot),
974 ];
975 final MessagingStyleInformation messagingStyle = MessagingStyleInformation(
976 me,
977 groupConversation: true,
978 conversationTitle: 'Team lunch',
979 htmlFormatContent: true,
980 htmlFormatTitle: true,
981 messages: messages);
982 final AndroidNotificationDetails androidPlatformChannelSpecifics =
983 AndroidNotificationDetails('message channel id', 'message channel name',
984 'message channel description',
985 category: 'msg', styleInformation: messagingStyle);
986 final NotificationDetails platformChannelSpecifics =
987 NotificationDetails(android: androidPlatformChannelSpecifics);
988 await flutterLocalNotificationsPlugin.show(
989 0, 'message title', 'message body', platformChannelSpecifics);
990
991 // wait 10 seconds and add another message to simulate another response
992 await Future<void>.delayed(const Duration(seconds: 10), () async {
993 messages.add(Message(
994 'Thai', DateTime.now().add(const Duration(minutes: 11)), null));
995 await flutterLocalNotificationsPlugin.show(
996 0, 'message title', 'message body', platformChannelSpecifics);
997 });
998 }
999
1000 Future<void> _showGroupedNotifications() async {
1001 const String groupKey = 'com.android.example.WORK_EMAIL';
1002 const String groupChannelId = 'grouped channel id';
1003 const String groupChannelName = 'grouped channel name';
1004 const String groupChannelDescription = 'grouped channel description';
1005 // example based on https://developer.android.com/training/notify-user/group.html
1006 const AndroidNotificationDetails firstNotificationAndroidSpecifics =
1007 AndroidNotificationDetails(
1008 groupChannelId, groupChannelName, groupChannelDescription,
1009 importance: Importance.max,
1010 priority: Priority.high,
1011 groupKey: groupKey);
1012 const NotificationDetails firstNotificationPlatformSpecifics =
1013 NotificationDetails(android: firstNotificationAndroidSpecifics);
1014 await flutterLocalNotificationsPlugin.show(1, 'Alex Faarborg',
1015 'You will not believe...', firstNotificationPlatformSpecifics);
1016 const AndroidNotificationDetails secondNotificationAndroidSpecifics =
1017 AndroidNotificationDetails(
1018 groupChannelId, groupChannelName, groupChannelDescription,
1019 importance: Importance.max,
1020 priority: Priority.high,
1021 groupKey: groupKey);
1022 const NotificationDetails secondNotificationPlatformSpecifics =
1023 NotificationDetails(android: secondNotificationAndroidSpecifics);
1024 await flutterLocalNotificationsPlugin.show(
1025 2,
1026 'Jeff Chang',
1027 'Please join us to celebrate the...',
1028 secondNotificationPlatformSpecifics);
1029
1030 // Create the summary notification to support older devices that pre-date
1031 /// Android 7.0 (API level 24).
1032 ///
1033 /// Recommended to create this regardless as the behaviour may vary as
1034 /// mentioned in https://developer.android.com/training/notify-user/group
1035 const List<String> lines = <String>[
1036 'Alex Faarborg Check this out',
1037 'Jeff Chang Launch Party'
1038 ];
1039 const InboxStyleInformation inboxStyleInformation = InboxStyleInformation(
1040 lines,
1041 contentTitle: '2 messages',
1042 summaryText: 'janedoe@example.com');
1043 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1044 AndroidNotificationDetails(
1045 groupChannelId, groupChannelName, groupChannelDescription,
1046 styleInformation: inboxStyleInformation,
1047 groupKey: groupKey,
1048 setAsGroupSummary: true);
1049 const NotificationDetails platformChannelSpecifics =
1050 NotificationDetails(android: androidPlatformChannelSpecifics);
1051 await flutterLocalNotificationsPlugin.show(
1052 3, 'Attention', 'Two messages', platformChannelSpecifics);
1053 }
1054
1055 Future<void> _showNotificationWithTag() async {
1056 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1057
1058
1059 //AndroidNotificationDetails(
1060 // 'your channel id', 'your channel name', 'your channel description',
1061 // importance: Importance.max, priority: Priority.high, tag: 'tag');
1062
1063 AndroidNotificationDetails("pippo", "pippo", "pippo", importance: Importance.max, priority: Priority.high);
1064
1065
1066
1067 const NotificationDetails platformChannelSpecifics = NotificationDetails(
1068 android: androidPlatformChannelSpecifics,
1069 );
1070 await flutterLocalNotificationsPlugin.show(
1071 0, 'first notification', null, platformChannelSpecifics);
1072 }
1073
1074 Future<void> _checkPendingNotificationRequests() async {
1075 final List<PendingNotificationRequest> pendingNotificationRequests =
1076 await flutterLocalNotificationsPlugin.pendingNotificationRequests();
1077 return showDialog<void>(
1078 context: context,
1079 builder: (BuildContext context) => AlertDialog(
1080 content:
1081 Text('${pendingNotificationRequests.length} pending notification '
1082 'requests'),
1083 actions: <Widget>[
1084 FlatButton(
1085 onPressed: () {
1086 Navigator.of(context).pop();
1087 },
1088 child: const Text('OK'),
1089 ),
1090 ],
1091 ),
1092 );
1093 }
1094
1095 Future<void> _cancelAllNotifications() async {
1096 await flutterLocalNotificationsPlugin.cancelAll();
1097 }
1098
1099 Future<void> _showOngoingNotification() async {
1100 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1101 AndroidNotificationDetails(
1102 'your channel id', 'your channel name', 'your channel description',
1103 importance: Importance.max,
1104 priority: Priority.high,
1105 ongoing: true,
1106 autoCancel: false);
1107 const NotificationDetails platformChannelSpecifics =
1108 NotificationDetails(android: androidPlatformChannelSpecifics);
1109 await flutterLocalNotificationsPlugin.show(0, 'ongoing notification title',
1110 'ongoing notification body', platformChannelSpecifics);
1111 }
1112
1113 Future<void> _repeatNotification() async {
1114 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1115 AndroidNotificationDetails('repeating channel id',
1116 'repeating channel name', 'repeating description');
1117 const NotificationDetails platformChannelSpecifics =
1118 NotificationDetails(android: androidPlatformChannelSpecifics);
1119 await flutterLocalNotificationsPlugin.periodicallyShow(0, 'repeating title',
1120 'repeating body', RepeatInterval.everyMinute, platformChannelSpecifics,
1121 androidAllowWhileIdle: true);
1122 }
1123
1124 Future<void> _scheduleDailyTenAMNotification() async {
1125 await flutterLocalNotificationsPlugin.zonedSchedule(
1126 0,
1127 'daily scheduled notification title',
1128 'daily scheduled notification body',
1129 _nextInstanceOfTenAM(),
1130 const NotificationDetails(
1131 android: AndroidNotificationDetails(
1132 'daily notification channel id',
1133 'daily notification channel name',
1134 'daily notification description'),
1135 ),
1136 androidAllowWhileIdle: true,
1137 uiLocalNotificationDateInterpretation:
1138 UILocalNotificationDateInterpretation.absoluteTime,
1139 matchDateTimeComponents: DateTimeComponents.time);
1140 }
1141
1142 /// To test we don't validate past dates when using `matchDateTimeComponents`
1143 Future<void> _scheduleDailyTenAMLastYearNotification() async {
1144 await flutterLocalNotificationsPlugin.zonedSchedule(
1145 0,
1146 'daily scheduled notification title',
1147 'daily scheduled notification body',
1148 _nextInstanceOfTenAMLastYear(),
1149 const NotificationDetails(
1150 android: AndroidNotificationDetails(
1151 'daily notification channel id',
1152 'daily notification channel name',
1153 'daily notification description'),
1154 ),
1155 androidAllowWhileIdle: true,
1156 uiLocalNotificationDateInterpretation:
1157 UILocalNotificationDateInterpretation.absoluteTime,
1158 matchDateTimeComponents: DateTimeComponents.time);
1159 }
1160
1161 Future<void> _scheduleWeeklyTenAMNotification() async {
1162 await flutterLocalNotificationsPlugin.zonedSchedule(
1163 0,
1164 'weekly scheduled notification title',
1165 'weekly scheduled notification body',
1166 _nextInstanceOfTenAM(),
1167 const NotificationDetails(
1168 android: AndroidNotificationDetails(
1169 'weekly notification channel id',
1170 'weekly notification channel name',
1171 'weekly notificationdescription'),
1172 ),
1173 androidAllowWhileIdle: true,
1174 uiLocalNotificationDateInterpretation:
1175 UILocalNotificationDateInterpretation.absoluteTime,
1176 matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime);
1177 }
1178
1179 Future<void> _scheduleWeeklyMondayTenAMNotification() async {
1180 await flutterLocalNotificationsPlugin.zonedSchedule(
1181 0,
1182 'weekly scheduled notification title',
1183 'weekly scheduled notification body',
1184 _nextInstanceOfMondayTenAM(),
1185 const NotificationDetails(
1186 android: AndroidNotificationDetails(
1187 'weekly notification channel id',
1188 'weekly notification channel name',
1189 'weekly notificationdescription'),
1190 ),
1191 androidAllowWhileIdle: true,
1192 uiLocalNotificationDateInterpretation:
1193 UILocalNotificationDateInterpretation.absoluteTime,
1194 matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime);
1195 }
1196
1197 tz.TZDateTime _nextInstanceOfTenAM() {
1198 final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
1199 tz.TZDateTime scheduledDate =
1200 tz.TZDateTime(tz.local, now.year, now.month, now.day, 10);
1201 if (scheduledDate.isBefore(now)) {
1202 scheduledDate = scheduledDate.add(const Duration(days: 1));
1203 }
1204 return scheduledDate;
1205 }
1206
1207 tz.TZDateTime _nextInstanceOfTenAMLastYear() {
1208 final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
1209 return tz.TZDateTime(tz.local, now.year - 1, now.month, now.day, 10);
1210 }
1211
1212 tz.TZDateTime _nextInstanceOfMondayTenAM() {
1213 tz.TZDateTime scheduledDate = _nextInstanceOfTenAM();
1214 while (scheduledDate.weekday != DateTime.monday) {
1215 scheduledDate = scheduledDate.add(const Duration(days: 1));
1216 }
1217 return scheduledDate;
1218 }
1219
1220 Future<void> _showNotificationWithNoBadge() async {
1221 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1222 AndroidNotificationDetails(
1223 'no badge channel', 'no badge name', 'no badge description',
1224 channelShowBadge: false,
1225 importance: Importance.max,
1226 priority: Priority.high,
1227 onlyAlertOnce: true);
1228 const NotificationDetails platformChannelSpecifics =
1229 NotificationDetails(android: androidPlatformChannelSpecifics);
1230 await flutterLocalNotificationsPlugin.show(
1231 0, 'no badge title', 'no badge body', platformChannelSpecifics,
1232 payload: 'item x');
1233 }
1234
1235 Future<void> _showProgressNotification() async {
1236 const int maxProgress = 5;
1237 for (int i = 0; i <= maxProgress; i++) {
1238 await Future<void>.delayed(const Duration(seconds: 1), () async {
1239 final AndroidNotificationDetails androidPlatformChannelSpecifics =
1240 AndroidNotificationDetails('progress channel', 'progress channel',
1241 'progress channel description',
1242 channelShowBadge: false,
1243 importance: Importance.max,
1244 priority: Priority.high,
1245 onlyAlertOnce: true,
1246 showProgress: true,
1247 maxProgress: maxProgress,
1248 progress: i);
1249 final NotificationDetails platformChannelSpecifics =
1250 NotificationDetails(android: androidPlatformChannelSpecifics);
1251 await flutterLocalNotificationsPlugin.show(
1252 0,
1253 'progress notification title',
1254 'progress notification body',
1255 platformChannelSpecifics,
1256 payload: 'item x');
1257 });
1258 }
1259 }
1260
1261 Future<void> _showIndeterminateProgressNotification() async {
1262 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1263 AndroidNotificationDetails(
1264 'indeterminate progress channel',
1265 'indeterminate progress channel',
1266 'indeterminate progress channel description',
1267 channelShowBadge: false,
1268 importance: Importance.max,
1269 priority: Priority.high,
1270 onlyAlertOnce: true,
1271 showProgress: true,
1272 indeterminate: true);
1273 const NotificationDetails platformChannelSpecifics =
1274 NotificationDetails(android: androidPlatformChannelSpecifics);
1275 await flutterLocalNotificationsPlugin.show(
1276 0,
1277 'indeterminate progress notification title',
1278 'indeterminate progress notification body',
1279 platformChannelSpecifics,
1280 payload: 'item x');
1281 }
1282
1283 Future<void> _showNotificationUpdateChannelDescription() async {
1284 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1285 AndroidNotificationDetails('your channel id', 'your channel name',
1286 'your updated channel description',
1287 importance: Importance.max,
1288 priority: Priority.high,
1289 channelAction: AndroidNotificationChannelAction.update);
1290 const NotificationDetails platformChannelSpecifics =
1291 NotificationDetails(android: androidPlatformChannelSpecifics);
1292 await flutterLocalNotificationsPlugin.show(
1293 0,
1294 'updated notification channel',
1295 'check settings to see updated channel description',
1296 platformChannelSpecifics,
1297 payload: 'item x');
1298 }
1299
1300 Future<void> _showPublicNotification() async {
1301 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1302 AndroidNotificationDetails(
1303 'your channel id', 'your channel name', 'your channel description',
1304 importance: Importance.max,
1305 priority: Priority.high,
1306 ticker: 'ticker',
1307 visibility: NotificationVisibility.public);
1308 const NotificationDetails platformChannelSpecifics =
1309 NotificationDetails(android: androidPlatformChannelSpecifics);
1310 await flutterLocalNotificationsPlugin.show(0, 'public notification title',
1311 'public notification body', platformChannelSpecifics,
1312 payload: 'item x');
1313 }
1314
1315 Future<void> _showNotificationWithSubtitle() async {
1316 const IOSNotificationDetails iOSPlatformChannelSpecifics =
1317 IOSNotificationDetails(subtitle: 'the subtitle');
1318 const MacOSNotificationDetails macOSPlatformChannelSpecifics =
1319 MacOSNotificationDetails(subtitle: 'the subtitle');
1320 const NotificationDetails platformChannelSpecifics = NotificationDetails(
1321 iOS: iOSPlatformChannelSpecifics, macOS: macOSPlatformChannelSpecifics);
1322 await flutterLocalNotificationsPlugin.show(
1323 0,
1324 'title of notification with a subtitle',
1325 'body of notification with a subtitle',
1326 platformChannelSpecifics,
1327 payload: 'item x');
1328 }
1329
1330 Future<void> _showNotificationWithIconBadge() async {
1331 const IOSNotificationDetails iOSPlatformChannelSpecifics =
1332 IOSNotificationDetails(badgeNumber: 1);
1333 const MacOSNotificationDetails macOSPlatformChannelSpecifics =
1334 MacOSNotificationDetails(badgeNumber: 1);
1335 const NotificationDetails platformChannelSpecifics = NotificationDetails(
1336 iOS: iOSPlatformChannelSpecifics, macOS: macOSPlatformChannelSpecifics);
1337 await flutterLocalNotificationsPlugin.show(
1338 0, 'icon badge title', 'icon badge body', platformChannelSpecifics,
1339 payload: 'item x');
1340 }
1341
1342 /*Future<void> _showNotificationsWithThreadIdentifier() async {
1343 NotificationDetails buildNotificationDetailsForThread(
1344 String threadIdentifier,
1345 ) {
1346 //final IOSNotificationDetails iOSPlatformChannelSpecifics = IOSNotificationDetails(threadIdentifier: threadIdentifier);
1347 //final MacOSNotificationDetails macOSPlatformChannelSpecifics = MacOSNotificationDetails(threadIdentifier: threadIdentifier);
1348
1349 final IOSNotificationDetails iOSPlatformChannelSpecifics = IOSNotificationDetails(threadIdentifier: threadIdentifier);
1350
1351
1352 return NotificationDetails(
1353 iOS: iOSPlatformChannelSpecifics,
1354 macOS: macOSPlatformChannelSpecifics);
1355 }
1356
1357 final NotificationDetails thread1PlatformChannelSpecifics =
1358 buildNotificationDetailsForThread('thread1');
1359 final NotificationDetails thread2PlatformChannelSpecifics =
1360 buildNotificationDetailsForThread('thread2');
1361
1362 await flutterLocalNotificationsPlugin.show(
1363 0, 'thread 1', 'first notification', thread1PlatformChannelSpecifics);
1364 await flutterLocalNotificationsPlugin.show(
1365 1, 'thread 1', 'second notification', thread1PlatformChannelSpecifics);
1366 await flutterLocalNotificationsPlugin.show(
1367 2, 'thread 1', 'third notification', thread1PlatformChannelSpecifics);
1368
1369 await flutterLocalNotificationsPlugin.show(
1370 3, 'thread 2', 'first notification', thread2PlatformChannelSpecifics);
1371 await flutterLocalNotificationsPlugin.show(
1372 4, 'thread 2', 'second notification', thread2PlatformChannelSpecifics);
1373 await flutterLocalNotificationsPlugin.show(
1374 5, 'thread 2', 'third notification', thread2PlatformChannelSpecifics);
1375 }*/
1376
1377 Future<void> _showNotificationWithoutTimestamp() async {
1378 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1379 AndroidNotificationDetails(
1380 'your channel id', 'your channel name', 'your channel description',
1381 importance: Importance.max,
1382 priority: Priority.high,
1383 showWhen: false);
1384 const NotificationDetails platformChannelSpecifics =
1385 NotificationDetails(android: androidPlatformChannelSpecifics);
1386 await flutterLocalNotificationsPlugin.show(
1387 0, 'plain title', 'plain body', platformChannelSpecifics,
1388 payload: 'item x');
1389 }
1390
1391 Future<void> _showNotificationWithCustomTimestamp() async {
1392 final AndroidNotificationDetails androidPlatformChannelSpecifics =
1393 AndroidNotificationDetails(
1394 'your channel id',
1395 'your channel name',
1396 'your channel description',
1397 importance: Importance.max,
1398 priority: Priority.high,
1399 when: DateTime.now().millisecondsSinceEpoch - 120 * 1000,
1400 );
1401 final NotificationDetails platformChannelSpecifics =
1402 NotificationDetails(android: androidPlatformChannelSpecifics);
1403 await flutterLocalNotificationsPlugin.show(
1404 0, 'plain title', 'plain body', platformChannelSpecifics,
1405 payload: 'item x');
1406 }
1407
1408 Future<void> _showNotificationWithCustomSubText() async {
1409 const AndroidNotificationDetails androidPlatformChannelSpecifics =
1410 AndroidNotificationDetails(
1411 'your channel id',
1412 'your channel name',
1413 'your channel description',
1414 importance: Importance.max,
1415 priority: Priority.high,
1416 showWhen: false,
1417 subText: 'custom subtext',
1418 );
1419 const NotificationDetails platformChannelSpecifics =
1420 NotificationDetails(android: androidPlatformChannelSpecifics);
1421 await flutterLocalNotificationsPlugin.show(
1422 0, 'plain title', 'plain body', platformChannelSpecifics,
1423 payload: 'item x');
1424 }
1425
1426 Future<void> _showNotificationWithChronometer() async {
1427 final AndroidNotificationDetails androidPlatformChannelSpecifics =
1428 AndroidNotificationDetails(
1429 'your channel id',
1430 'your channel name',
1431 'your channel description',
1432 importance: Importance.max,
1433 priority: Priority.high,
1434 when: DateTime.now().millisecondsSinceEpoch - 120 * 1000,
1435 usesChronometer: true,
1436 );
1437 final NotificationDetails platformChannelSpecifics =
1438 NotificationDetails(android: androidPlatformChannelSpecifics);
1439 await flutterLocalNotificationsPlugin.show(
1440 0, 'plain title', 'plain body', platformChannelSpecifics,
1441 payload: 'item x');
1442 }
1443
1444 Future<void> _showNotificationWithAttachment() async {
1445 final String bigPicturePath = await _downloadAndSaveFile(
1446 'https://via.placeholder.com/600x200', 'bigPicture.jpg');
1447 final IOSNotificationDetails iOSPlatformChannelSpecifics =
1448 IOSNotificationDetails(attachments: <IOSNotificationAttachment>[
1449 IOSNotificationAttachment(bigPicturePath)
1450 ]);
1451 final MacOSNotificationDetails macOSPlatformChannelSpecifics =
1452 MacOSNotificationDetails(attachments: <MacOSNotificationAttachment>[
1453 MacOSNotificationAttachment(bigPicturePath)
1454 ]);
1455 final NotificationDetails notificationDetails = NotificationDetails(
1456 iOS: iOSPlatformChannelSpecifics, macOS: macOSPlatformChannelSpecifics);
1457 await flutterLocalNotificationsPlugin.show(
1458 0,
1459 'notification with attachment title',
1460 'notification with attachment body',
1461 notificationDetails);
1462 }
1463
1464 Future<void> _createNotificationChannelGroup() async {
1465 const String channelGroupId = 'your channel group id';
1466 // create the group first
1467 const AndroidNotificationChannelGroup androidNotificationChannelGroup =
1468 AndroidNotificationChannelGroup(
1469 channelGroupId, 'your channel group name',
1470 description: 'your channel group description');
1471 await flutterLocalNotificationsPlugin
1472 .resolvePlatformSpecificImplementation<
1473 AndroidFlutterLocalNotificationsPlugin>()
1474 .createNotificationChannelGroup(androidNotificationChannelGroup);
1475
1476 // create channels associated with the group
1477 await flutterLocalNotificationsPlugin
1478 .resolvePlatformSpecificImplementation<
1479 AndroidFlutterLocalNotificationsPlugin>()
1480 .createNotificationChannel(const AndroidNotificationChannel(
1481 'grouped channel id 1',
1482 'grouped channel name 1',
1483 'grouped channel description 1',
1484 groupId: channelGroupId));
1485
1486 await flutterLocalNotificationsPlugin
1487 .resolvePlatformSpecificImplementation<
1488 AndroidFlutterLocalNotificationsPlugin>()
1489 .createNotificationChannel(const AndroidNotificationChannel(
1490 'grouped channel id 2',
1491 'grouped channel name 2',
1492 'grouped channel description 2',
1493 groupId: channelGroupId));
1494
1495 await showDialog<void>(
1496 context: context,
1497 builder: (BuildContext context) => AlertDialog(
1498 content: Text('Channel group with name '
1499 '${androidNotificationChannelGroup.name} created'),
1500 actions: <Widget>[
1501 FlatButton(
1502 onPressed: () {
1503 Navigator.of(context).pop();
1504 },
1505 child: const Text('OK'),
1506 ),
1507 ],
1508 ));
1509 }
1510
1511 Future<void> _deleteNotificationChannelGroup() async {
1512 const String channelGroupId = 'your channel group id';
1513 await flutterLocalNotificationsPlugin
1514 .resolvePlatformSpecificImplementation<
1515 AndroidFlutterLocalNotificationsPlugin>()
1516 ?.deleteNotificationChannelGroup(channelGroupId);
1517
1518 await showDialog<void>(
1519 context: context,
1520 builder: (BuildContext context) => AlertDialog(
1521 content: const Text('Channel group with id $channelGroupId deleted'),
1522 actions: <Widget>[
1523 FlatButton(
1524 onPressed: () {
1525 Navigator.of(context).pop();
1526 },
1527 child: const Text('OK'),
1528 ),
1529 ],
1530 ),
1531 );
1532 }
1533
1534 Future<void> _createNotificationChannel() async {
1535 const AndroidNotificationChannel androidNotificationChannel =
1536 AndroidNotificationChannel(
1537 'your channel id 2',
1538 'your channel name 2',
1539 'your channel description 2',
1540 );
1541 await flutterLocalNotificationsPlugin
1542 .resolvePlatformSpecificImplementation<
1543 AndroidFlutterLocalNotificationsPlugin>()
1544 ?.createNotificationChannel(androidNotificationChannel);
1545
1546 await showDialog<void>(
1547 context: context,
1548 builder: (BuildContext context) => AlertDialog(
1549 content:
1550 Text('Channel with name ${androidNotificationChannel.name} '
1551 'created'),
1552 actions: <Widget>[
1553 FlatButton(
1554 onPressed: () {
1555 Navigator.of(context).pop();
1556 },
1557 child: const Text('OK'),
1558 ),
1559 ],
1560 ));
1561 }
1562
1563 Future<void> _deleteNotificationChannel() async {
1564 const String channelId = 'your channel id 2';
1565 await flutterLocalNotificationsPlugin
1566 .resolvePlatformSpecificImplementation<
1567 AndroidFlutterLocalNotificationsPlugin>()
1568 ?.deleteNotificationChannel(channelId);
1569
1570 await showDialog<void>(
1571 context: context,
1572 builder: (BuildContext context) => AlertDialog(
1573 content: const Text('Channel with id $channelId deleted'),
1574 actions: <Widget>[
1575 FlatButton(
1576 onPressed: () {
1577 Navigator.of(context).pop();
1578 },
1579 child: const Text('OK'),
1580 ),
1581 ],
1582 ),
1583 );
1584 }
1585
1586 Future<void> _getActiveNotifications() async {
1587 final Widget activeNotificationsDialogContent =
1588 await _getActiveNotificationsDialogContent();
1589 await showDialog<void>(
1590 context: context,
1591 builder: (BuildContext context) => AlertDialog(
1592 content: activeNotificationsDialogContent,
1593 actions: <Widget>[
1594 FlatButton(
1595 onPressed: () {
1596 Navigator.of(context).pop();
1597 },
1598 child: const Text('OK'),
1599 ),
1600 ],
1601 ),
1602 );
1603 }
1604
1605 Future<Widget> _getActiveNotificationsDialogContent() async {
1606 final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
1607 final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
1608 if (!(androidInfo.version.sdkInt >= 23)) {
1609 return const Text(
1610 '"getActiveNotifications" is available only for Android 6.0 or newer',
1611 );
1612 }
1613
1614 try {
1615 final List<ActiveNotification> activeNotifications =
1616 await flutterLocalNotificationsPlugin
1617 .resolvePlatformSpecificImplementation<
1618 AndroidFlutterLocalNotificationsPlugin>()
1619 ?.getActiveNotifications();
1620
1621 return Column(
1622 crossAxisAlignment: CrossAxisAlignment.start,
1623 mainAxisSize: MainAxisSize.min,
1624 children: <Widget>[
1625 const Text(
1626 'Active Notifications',
1627 style: TextStyle(fontWeight: FontWeight.bold),
1628 ),
1629 const Divider(color: Colors.black),
1630 if (activeNotifications.isEmpty)
1631 const Text('No active notifications'),
1632 if (activeNotifications.isNotEmpty)
1633 for (ActiveNotification activeNotification in activeNotifications)
1634 Column(
1635 crossAxisAlignment: CrossAxisAlignment.start,
1636 children: <Widget>[
1637 Text(
1638 'id: ${activeNotification.id}\n'
1639 'channelId: ${activeNotification.channelId}\n'
1640 'title: ${activeNotification.title}\n'
1641 'body: ${activeNotification.body}',
1642 ),
1643 const Divider(color: Colors.black),
1644 ],
1645 ),
1646 ],
1647 );
1648 } on PlatformException catch (error) {
1649 return Text(
1650 'Error calling "getActiveNotifications"\n'
1651 'code: ${error.code}\n'
1652 'message: ${error.message}',
1653 );
1654 }
1655 }
1656}
1657
1658class SecondScreen extends StatefulWidget {
1659 const SecondScreen(
1660 this.payload, {
1661 Key key,
1662 }) : super(key: key);
1663
1664 final String payload;
1665
1666 @override
1667 State<StatefulWidget> createState() => SecondScreenState();
1668}
1669
1670class SecondScreenState extends State<SecondScreen> {
1671 String _payload;
1672 @override
1673 void initState() {
1674 super.initState();
1675 _payload = widget.payload;
1676 }
1677
1678 @override
1679 Widget build(BuildContext context) => Scaffold(
1680 appBar: AppBar(
1681 title: Text('Second Screen with payload: ${_payload ?? ''}'),
1682 ),
1683 body: Center(
1684 child: RaisedButton(
1685 onPressed: () {
1686 Navigator.pop(context);
1687 },
1688 child: const Text('Go back!'),
1689 ),
1690 ),
1691 );
1692}
1693