To use notifications in our app, we can use the awesome_notifications package. This package provides a simple and easy way to create and manage notifications in our app.
Add the awesome_notifications using the following command:
flutter pub add awesome_notifications:^0.10.1After adding the dependency, we need to modify the android/app/build.gradle file to include the following lines:
android {
...
compileSdkVersion 34 // change the compileSdkVersion to 34
...
defaultConfig {
...
minSdkVersion 23 // change the minSdkVersion to 23
targetSdkVersion 33 // change the targetSdkVersion to 33
}
}To use notifications in our app, we need to configure the permissions in the AndroidManifest.xml file. Open the android/app/src/main/AndroidManifest.xml file and add the following lines:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Add these two lines -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
<application
android:label="notification_demo"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
...Create a new file called notification_service.dart in the lib/services folder.
We will create a NotificationService class that will handle the initialization and display of notifications.
Below is the code for initializing the notification service.
class NotificationService {
static Future<void> initializeNotification() async {
// Initialize Awesome Notifications
await AwesomeNotifications().initialize(
null,
[
NotificationChannel(
channelGroupKey: 'basic_channel_group',
channelKey: 'basic_channel',
channelName: 'Basic notifications',
channelDescription: 'Notification channel for basic tests',
defaultColor: const Color(0xFF9D50DD),
ledColor: Colors.white,
importance: NotificationImportance.Max,
channelShowBadge: true,
playSound: true,
criticalAlerts: true,
)
],
channelGroups: [
NotificationChannelGroup(
channelGroupKey: 'basic_channel_group',
channelGroupName: 'Basic notifications group',
)
],
debug: true,
);
// Request notification permissions
await AwesomeNotifications().isNotificationAllowed().then(
(isAllowed) {
if (!isAllowed) {
AwesomeNotifications().requestPermissionToSendNotifications();
}
},
);
// Set notification listeners
await AwesomeNotifications().setListeners(
onActionReceivedMethod: _onActionReceivedMethod,
onNotificationCreatedMethod: _onNotificationCreateMethod,
onNotificationDisplayedMethod: _onNotificationDisplayedMethod,
onDismissActionReceivedMethod: _onDismissActionReceivedMethod,
);
}
// Listeners
static Future<void> _onNotificationCreateMethod(
ReceivedNotification receivedNotification,
) async {
debugPrint('Notification created: ${receivedNotification.title}');
}
static Future<void> _onNotificationDisplayedMethod(
ReceivedNotification receivedNotification,
) async {
debugPrint('Notification displayed: ${receivedNotification.title}');
}
static Future<void> _onDismissActionReceivedMethod(
ReceivedNotification receivedNotification,
) async {
debugPrint('Notification dismissed: ${receivedNotification.title}');
}
static Future<void> _onActionReceivedMethod(
ReceivedNotification receivedNotification,
) async {
debugPrint('Notification action received: ${receivedNotification.title}');
}
}To create a notification, we will create a method called createNotification in the NotificationService class.
static Future<void> createNotification({
required final int id,
required final String title,
required final String body,
final String? summary,
final Map<String, String>? payload,
final ActionType actionType = ActionType.Default,
final NotificationLayout notificationLayout = NotificationLayout.Default,
final NotificationCategory? category,
final String? bigPicture,
final List<NotificationActionButton>? actionButtons,
final bool scheduled = false,
final Duration? interval,
}) async {
assert(!scheduled || (scheduled && interval != null));
await AwesomeNotifications().createNotification(
content: NotificationContent(
id: id,
channelKey: 'basic_channel',
title: title,
body: body,
actionType: actionType,
notificationLayout: notificationLayout,
summary: summary,
category: category,
payload: payload,
bigPicture: bigPicture,
),
actionButtons: actionButtons,
schedule: scheduled
? NotificationInterval(
interval: interval,
timeZone:
await AwesomeNotifications().getLocalTimeZoneIdentifier(),
preciseAlarm: true,
)
: null,
);
}Create a new file called home_screen.dart in the lib/screens folder.
We will create a simple UI which consists of buttons to create notifications.
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:flutter/material.dart';
import 'package:notification_demo/services/notification_service.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.symmetric(horizontal: 20),
children: [
// Placeholder for the notification buttons
],
),
);
}
}These are the buttons we will create to test the notifications.
To create a default notification, we will create a button that will call the createNotification method in the NotificationService class.
OutlinedButton(
onPressed: () async {
await NotificationService.createNotification(
id: 1,
title: 'Default Notification',
body: 'This is the body of the notification',
summary: 'Small summary',
);
},
child: const Text('Default Notification'),
)To create a notification with a summary, we will create a button that will call the createNotification method in the NotificationService class and change the notificationLayout to NotificationLayout.Inbox.
OutlinedButton(
onPressed: () async {
await NotificationService.createNotification(
id: 2,
title: 'Notification with Summary',
body: 'This is the body of the notification',
summary: 'Small summary',
notificationLayout: NotificationLayout.Inbox,
);
},
child: const Text('Notification with Summary'),
)To create a progress bar notification, we will create a button that will call the createNotification method in the NotificationService class and change the notificationLayout to NotificationLayout.ProgressBar.
OutlinedButton(
onPressed: () async {
await NotificationService.createNotification(
id: 3,
title: 'Progress Bar Notification',
body: 'This is the body of the notification',
summary: 'Small summary',
notificationLayout: NotificationLayout.ProgressBar,
);
},
child: const Text('Progress Bar Notification'),
)To create a message notification, we will create a button that will call the createNotification method in the NotificationService class and change the notificationLayout to NotificationLayout.Messaging.
OutlinedButton(
onPressed: () async {
await NotificationService.createNotification(
id: 4,
title: 'Message Notification',
body: 'This is the body of the notification',
summary: 'Small summary',
notificationLayout: NotificationLayout.Messaging,
);
},
child: const Text('Message Notification'),
)To create a big image notification, we will create a button that will call the createNotification method in the NotificationService class and change the notificationLayout to NotificationLayout.BigPicture.
OutlinedButton(
onPressed: () async {
await NotificationService.createNotification(
id: 5,
title: 'Big Image Notification',
body: 'This is the body of the notification',
summary: 'Small summary',
notificationLayout: NotificationLayout.BigPicture,
bigPicture: 'https://picsum.photos/300/200',
);
},
child: const Text('Big Image Notification'),
)To create a notification with action buttons, we will create a button that will call the createNotification method in the NotificationService class and add action buttons to the notification.
OutlinedButton(
onPressed: () async {
await NotificationService.createNotification(
id: 5,
title: 'Action Button Notification',
body: 'This is the body of the notification',
payload: {'navigate': 'true'},
actionButtons: [
NotificationActionButton(
key: 'action_button',
label: 'Click me',
actionType: ActionType.Default,
)
],
);
},
child: const Text('Action Button Notification'),
)We need to handle the action button in the _onActionReceivedMethod method in the NotificationService class. Change the method to the following:
static Future<void> _onActionReceivedMethod(
ReceivedNotification receivedNotification,
) async {
debugPrint('Notification action received');
final payload = receivedNotification.payload;
if (payload == null) return;
if (payload['navigate'] == 'true') {
debugPrint(MyApp.navigatorKey.currentContext.toString());
Navigator.push(
MyApp.navigatorKey.currentContext!,
MaterialPageRoute(
builder: (_) => const SecondScreen(),
),
);
}
}We also need to add the second_screen.dart file to handle the navigation. Create a new file called second_screen.dart in the lib/screens folder.
import 'package:flutter/material.dart';
class SecondScreen extends StatelessWidget {
const SecondScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Second Screen'),
centerTitle: true,
),
body: Center(
child: Column(
children: [
const Text('This is the second screen from the notification!'),
const SizedBox(height: 20),
OutlinedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Go to Home'),
),
],
),
),
);
}
}To create a scheduled notification, we will create a button that will call the createNotification method in the NotificationService class and set the scheduled parameter to true and the interval parameter to the desired interval.
OutlinedButton(
onPressed: () async {
await NotificationService.createNotification(
id: 5,
title: 'Scheduled Notification',
body: 'This is the body of the notification',
scheduled: true,
interval: Duration(seconds: 5), //if doesn't appear in 5 second please wait a little longer :)
);
},
child: const Text('Scheduled Notification'),
)Finally, we need to modify the main.dart file to initialize the notification service and run the app.
import 'package:flutter/material.dart';
import 'package:notification_app/screens/home_screen.dart';
import 'package:notification_app/screens/second_screen.dart';
import 'package:notification_app/services/notification_service.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await NotificationService.initializeNotification();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Notification Demo',
routes: {
'home': (context) => const HomeScreen(),
'second': (context) => const SecondScreen(),
},
initialRoute: 'home',
navigatorKey: navigatorKey,
);
}
}Here are the result of the notifications we created:







