flutter_local_notifications
package allows to show different types of notifications like plain notifications, notification with picture and big text, schedule notifications etc
Check Flutter installation to setup Flutter
Use flutter create
command to create a Flutter project (here local_notification_app) :
flutter create local_notification_app
Add flutter_local_notifications
and other packages to pubspec.yaml
dependencies:
flutter_local_notifications: 1.4.4+1
http: ^0.12.0
path_provider:
rxdart:
flutter:
sdk: flutter
Run following command to add dependency
flutter pub get
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
// for getApplicationDocumentsDirectory()
import 'package:path_provider/path_provider.dart';
// for BehaviorSubject
import 'package:rxdart/subjects.dart';
flutterLocalNotificationsPlugin.initialize()
method is to be called in main()
function
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final BehaviorSubject<String> selectNotificationSubject =
BehaviorSubject<String>();
Future<void> main() async {
// To initialize in the `main` function
WidgetsFlutterBinding.ensureInitialized();
// To find out if the app was launched via notification, the following call can be used and then something like
// changing the default route of the app can be done
var notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
print("launch details : ${notificationAppLaunchDetails}");
var initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false
);
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: (String payload) async {
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
selectNotificationSubject.add(payload);
});
runApp(
MaterialApp(
home: HomePage(),
),
);
}
Following worked for both android and ios
flutterLocalNotificationsPlugin.show()
method is used to show a notification
Future<void> _showNotification() async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'plain channel id', 'plain channel name', 'plain channel description',
importance: Importance.Max, priority: Priority.High, ticker: 'ticker');
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.show(
0, 'plain title', 'plain body', platformChannelSpecifics,
payload: 'plain notification payload');
}
Future<void> _scheduleNotification() async {
var scheduledNotificationDateTime =
DateTime.now().add(Duration(seconds: 5));
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'schedule channel id',
'schedule channel name',
'schedule channel description',
icon: 'secondary_icon',
);
var platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.schedule( 1, 'scheduled_notification title',
'scheduled_notification body', scheduledNotificationDateTime,
platformChannelSpecifics, androidAllowWhileIdle: true,
payload: 'scheduled notification payload');
}
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:rxdart/subjects.dart';
//import 'package:flutter/cupertino.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final BehaviorSubject<String> selectNotificationSubject =
BehaviorSubject<String>();
final BehaviorSubject<ReceivedNotification> didReceiveLocalNotificationSubject =
BehaviorSubject<ReceivedNotification>();
class ReceivedNotification {
final int id;
final String title;
final String body;
final String payload;
ReceivedNotification( {@required this.id, @required this.title,
@required this.body, @required this.payload});
}
Future<void> main() async {
// To initialize in the `main` function
WidgetsFlutterBinding.ensureInitialized();
// To find out if the app was launched via notification, the following call can be used and then default route of the
// app can be changed or something similar
var notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
print("launch details : ${notificationAppLaunchDetails}");
var initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false
);
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: (String payload) async {
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
selectNotificationSubject.add(payload);
});
runApp(
MaterialApp(
home: HomePage(),
),
);
}
class PaddedRaisedButton extends StatelessWidget {
final String buttonText;
final VoidCallback onPressed;
const PaddedRaisedButton(
{@required this.buttonText, @required this.onPressed});
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 8.0),
child: RaisedButton(child: Text(buttonText), onPressed: onPressed),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
selectNotificationSubject.stream.listen((String payload) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen(payload)),
);
});
}
@override
void dispose() {
selectNotificationSubject.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Notifications example app'),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 8.0),
child: Text(
'Tap on a notification when it appears to trigger navigation'),
),
PaddedRaisedButton(
buttonText: 'Show plain notification with payload',
onPressed: () async {
await _showNotification();
},
),
PaddedRaisedButton(
buttonText: 'Schedule notification to appear in 5 seconds',
onPressed: () async {
await _scheduleNotification();
},
),
PaddedRaisedButton(
buttonText: 'Show big picture notification [Android]',
onPressed: () async {
await _showBigPictureNotification();
},
),
PaddedRaisedButton(
buttonText: 'Show ongoing notification [Android]',
onPressed: () async {
await _showOngoingNotification();
},
),
PaddedRaisedButton(
buttonText: 'Check pending notifications',
onPressed: () async {
await _checkPendingNotificationRequests();
},
),
PaddedRaisedButton(
buttonText: 'Cancel all notifications',
onPressed: () async {
await _cancelAllNotifications();
},
),
],
),
),
),
),
),
);
}
Future<void> _showNotification() async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'plain channel id', 'plain channel name', 'plain channel description',
importance: Importance.Max, priority: Priority.High, ticker: 'ticker');
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.show(
0, 'plain title', 'plain body', platformChannelSpecifics,
payload: 'plain notification payload');
}
Future<void> _scheduleNotification() async {
var scheduledNotificationDateTime =
DateTime.now().add(Duration(seconds: 5));
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'schedule channel id',
'schedule channel name',
'schedule channel description',
icon: 'secondary_icon',
);
var platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.schedule( 1, 'scheduled_notification title',
'scheduled_notification body', scheduledNotificationDateTime,
platformChannelSpecifics, androidAllowWhileIdle: true,
payload: 'scheduled notification payload');
}
Future<String> _downloadAndSaveImage(String url, String fileName) async {
var directory = await getApplicationDocumentsDirectory();
var filePath = '${directory.path}/$fileName';
var response = await http.get(url);
var file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
return filePath;
}
Future<void> _showBigPictureNotification() async {
var largeIconPath = await _downloadAndSaveImage(
'http://via.placeholder.com/128x128/00FF00/000000', 'largeIcon');
var bigPicturePath = await _downloadAndSaveImage(
'http://via.placeholder.com/400x800', 'bigPicture');
var bigPictureStyleInformation = BigPictureStyleInformation(
FilePathAndroidBitmap(bigPicturePath),
largeIcon: FilePathAndroidBitmap(largeIconPath),
contentTitle: 'overridden <b>big</b> content title',
htmlFormatContentTitle: true,
summaryText: 'summary <i>text</i>',
htmlFormatSummaryText: true);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'big_picture channel id',
'big_picture channel name',
'big_picture channel description',
styleInformation: bigPictureStyleInformation);
var platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.show(
2, 'big_picture_minimized title', 'big_picture_minimized body', platformChannelSpecifics);
}
Future<void> _showOngoingNotification() async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'ongoing channel id', 'ongoing channel name', 'ongoing channel description',
importance: Importance.Max,
priority: Priority.High,
ongoing: true,
autoCancel: false);
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.show(4, 'ongoing_notification title',
'ongoing_notification body', platformChannelSpecifics);
}
Future<void> _checkPendingNotificationRequests() async {
var pendingNotificationRequests =
await flutterLocalNotificationsPlugin.pendingNotificationRequests();
for (var pendingNotificationRequest in pendingNotificationRequests) {
debugPrint(
'pending notification: [id: ${pendingNotificationRequest.id}, title: ${pendingNotificationRequest.title}, body: ${pendingNotificationRequest.body}, payload: ${pendingNotificationRequest.payload}]');
}
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: Text(
'${pendingNotificationRequests.length} pending notification requests'),
actions: [
FlatButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Future<void> _cancelAllNotifications() async {
await flutterLocalNotificationsPlugin.cancelAll();
}
}
class SecondScreen extends StatefulWidget {
SecondScreen(this.payload);
final String payload;
@override
State<StatefulWidget> createState() => SecondScreenState();
}
class SecondScreenState extends State<SecondScreen> {
String _payload;
@override
void initState() {
super.initState();
_payload = widget.payload;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen with payload: ${(_payload ?? '')}'),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
Ensure a supported device is connected or emulator/simulator is started
Go to project directory
Use flutter run
command to run
flutter run
It builds and runs app on an available android/ios device