if you want to implement local notification in Flutter this is the best way to add local notification in Flutter in 2024.

We are using this plugin awesome_notifications: ^0.9.3+1
Key Features:
- Create custom notifications: Use Awesome Notifications to easily create and customize local and push notifications for your Flutter app.
- Engage your users: Keep your users engaged with your app by sending notifications with images, sounds, emoticons, buttons, and many different layouts.
- Real-time events: Receive real-time events on the Flutter level code for notifications that are created, displayed, dismissed, or tapped by the user.
- Highly customizable: With a range of customizable options, including translations, you can tailor notifications to fit your specific needs.
- Scheduled notifications: Schedule notifications repeatedly or at specific times with second precision to keep your users up-to-date.
- Trusted performance: Receive notifications with confidence and trust in any application lifecycle.
- Easy to use: With an easy-to-use interface, you can start creating custom notifications in minutes.
Android notification examples:

iOS notification examples:

Notification Types Available
Here are some of the notification types available with Awesome Notifications:
- Basic notification
- Big picture notification
- Media notification
- Big text notification
- Inbox notification
- Messaging notification
- Messaging group notification
- Notifications with action buttons
- Grouped notifications
- Progress bar notifications (only for Android)
All notification types can be created locally or via remote push services, with all the features and customizations available.
🛑 ATTENTION – PLUGIN UNDER DEVELOPMENT

Now I am going to start local notification in flutter
🔥Setup
Add dependency in Flutter
awesome_notifications: ^0.9.3+1
permission_handler: ^10.3.0
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
permission_handler: ^10.3.0
awesome_notifications: ^0.9.3+1
dev_dependencies:
flutter_test:
sdk: flutter
🗃️Android/app/build.gradle
Change these line
minSdkVersion 21
targetSdkVersion 34
Like this
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "com.example.call"
compileSdk flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
compileSdkVersion 34
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.call"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {}
🗃️Android/app/AndroidManifest.xml
add these lines
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Like this
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:label="call"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility?hl=en and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
🗃️Android/app/src/res/drawable
add an icon file

🗃️NotificationController.dart
Init notification
class NotificationController extends GetxController {
@override
void onInit() async {
// TODO: implement onInit
super.onInit();
AwesomeNotifications().initialize(
'resource://drawable/icon',
[
NotificationChannel(
channelGroupKey: "high_importance_channel",
channelKey: 'high_importance_channel',
channelName: 'Basic notifications',
channelDescription: 'Notification channel for basic notifications',
defaultColor: Color(0xFF9D50DD),
ledColor: Colors.white,
importance: NotificationImportance.Max,
onlyAlertOnce: true,
playSound: true,
enableVibration: true,
criticalAlerts: true,
),
],
);
await AwesomeNotifications().setListeners(
onActionReceivedMethod: onActionReceivedMethod,
onNotificationDisplayedMethod: (receivedNotification) async {
print('Notification Displayed: ${receivedNotification}');
},
);
}
Make a function for when any action click on notification
static Future<void> onActionReceivedMethod(
ReceivedAction receivedAction) async {
print('Action Received: ${receivedAction}');
print('Button Pressed: ${receivedAction.buttonKeyPressed}');
}
Now make a function to show notification
void showNotification() async {
AwesomeNotifications().createNotification(
actionButtons: [
NotificationActionButton(
key: "reject",
label: "Reject",
),
NotificationActionButton(
key: "accept",
label: "accept",
),
],
content: NotificationContent(
id: 10,
channelKey: 'high_importance_channel',
title: 'Notification Title',
body: 'Notification Body',
badge: 3,
color: Colors.green,
displayOnForeground: true,
displayOnBackground: true,
notificationLayout: NotificationLayout.Default,
wakeUpScreen: true,
showWhen: true,
),
);
}
Full NotificationController code
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class NotificationController extends GetxController {
@override
void onInit() async {
// TODO: implement onInit
super.onInit();
AwesomeNotifications().initialize(
'resource://drawable/icon',
[
NotificationChannel(
channelGroupKey: "high_importance_channel",
channelKey: 'high_importance_channel',
channelName: 'Basic notifications',
channelDescription: 'Notification channel for basic notifications',
defaultColor: Color(0xFF9D50DD),
ledColor: Colors.white,
importance: NotificationImportance.Max,
onlyAlertOnce: true,
playSound: true,
enableVibration: true,
criticalAlerts: true,
),
],
);
await AwesomeNotifications().setListeners(
onActionReceivedMethod: onActionReceivedMethod,
onNotificationDisplayedMethod: (receivedNotification) async {
print('Notification Displayed: ${receivedNotification}');
},
);
}
static Future<void> onActionReceivedMethod(
ReceivedAction receivedAction) async {
print('Action Received: ${receivedAction}');
print('Button Pressed: ${receivedAction.buttonKeyPressed}');
}
void showNotification() async {
AwesomeNotifications().createNotification(
actionButtons: [
NotificationActionButton(
key: "reject",
label: "Reject",
),
NotificationActionButton(
key: "accept",
label: "accept",
),
],
content: NotificationContent(
id: 10,
channelKey: 'high_importance_channel',
title: 'Notification Title',
body: 'Notification Body',
badge: 3,
color: Colors.green,
displayOnForeground: true,
displayOnBackground: true,
notificationLayout: NotificationLayout.Default,
wakeUpScreen: true,
showWhen: true,
),
);
}
}
Now make a button and call shownotification on press
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'NotificationContr.dart';
class NotificationPage extends StatelessWidget {
const NotificationPage({super.key});
@override
Widget build(BuildContext context) {
final NotificationController notificationController =
Get.put(NotificationController());
return Scaffold(
body: SafeArea(
child: Column(
children: [
Row(),
SizedBox(height: 200),
ElevatedButton.icon(
onPressed: () async {
if (await Permission.notification.request().isGranted) {
// Permission Granted
notificationController.showNotification();
} else {
// Permission Denied
print('Notification permission denied');
}
},
icon: Icon(Icons.notifications),
label: Text("Notification"),
)
],
),
),
);
}
}
Tags:
flutter local notification,flutter local notification background,flutter local notification schedule,Flutter Notifications,Flutter Notification Plugin,Flutter App Tutorial,Flutter for Beginners,Flutter UI,flutter local notifications,flutter local notifications background,flutter local notifications not working,flutter local notifications schedule,flutter push notification,flutter push notification local,flutter tutorials,ios,local notification,local notification flutter,local notifications in flutter,notification tutorial,notifications,push notifications,timer notification flutter,user notification,android,flutter,flutter local notifications scheduled,