Flutter Notification Listener

February 13, 2026 · View on GitHub

Flutter Notification Listener

A powerful Flutter plugin for listening to all incoming notifications on Android

Pub Version Pub Points GitHub Stars License

Features · Installation · Quick Start · API Reference · Contributing


✨ Features

🔔 Real-time Listening

Capture all system notifications as they arrive, from any app installed on the device.

🎯 Simple API

Clean and intuitive API design. Access notification fields with ease.

⚡ Background Execution

Run Dart code in the background. Auto-start service after device reboot.

🎮 Interactive

Tap notifications, trigger actions, and even auto-reply to messages directly from Flutter.

Compatibility

Android VersionAPI LevelStatus
Android 14API 34✅ Fully Supported
Android 13API 33✅ Fully Supported
Android 12API 31-32✅ Fully Supported
Android 11 and belowAPI ≤ 30✅ Fully Supported

📦 Installation

Add the dependency to your pubspec.yaml:

dependencies:
  flutter_notification_listener: ^1.4.0

Then run:

flutter pub get

🚀 Quick Start

Step 1: Configure Android Manifest

Add the notification listener service inside the <application> tag:

<service 
    android:name="im.zoe.labs.flutter_notification_listener.NotificationsHandlerService"
    android:label="Flutter Notifications Handler"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
    android:exported="true"
    android:foregroundServiceType="specialUse">
    <property 
        android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
        android:value="notification_listener"/>
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

Add required permissions:

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>

Note: For Android 13+, request the POST_NOTIFICATIONS permission at runtime before starting the foreground service.

Step 2: Initialize the Plugin

import 'package:flutter_notification_listener/flutter_notification_listener.dart';

void onData(NotificationEvent event) {
  print('${event.packageName}: ${event.title} - ${event.text}');
}

Future<void> initPlatformState() async {
  NotificationsListener.initialize();
  NotificationsListener.receivePort?.listen((evt) => onData(evt));
}

Step 3: Start the Service

Future<void> startListening() async {
  final hasPermission = await NotificationsListener.hasPermission ?? false;
  
  if (!hasPermission) {
    NotificationsListener.openPermissionSettings();
    return;
  }

  final isRunning = await NotificationsListener.isRunning ?? false;
  
  if (!isRunning) {
    await NotificationsListener.startService(
      foreground: true,
      title: "Listening for notifications",
    );
  }
}

📖 See the example app for a complete implementation.


📖 Usage Guide

Auto-start After Reboot

Register a broadcast receiver to automatically restart the service after device reboot:

<receiver 
    android:name="im.zoe.labs.flutter_notification_listener.RebootBroadcastReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

Add the boot permission:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Background Processing

For reliable background execution, use a static callback function:

@pragma('vm:entry-point')
static void _callback(NotificationEvent evt) {
  // Persist data immediately
  db.save(evt);
  
  // Forward to UI thread if needed
  final send = IsolateNameServer.lookupPortByName("_listener_");
  send?.send(evt);
}

Future<void> initPlatformState() async {
  NotificationsListener.initialize(callbackHandle: _callback);
}

Important: The @pragma('vm:entry-point') annotation is required for Flutter 3.x to prevent the function from being stripped in release builds.

Interactive Notifications

Tap a notification:

void onData(NotificationEvent event) {
  if (event.canTap) {
    event.tap();
  }
}

Auto-reply to messages:

void onData(NotificationEvent event) {
  for (final action in event.actions ?? []) {
    if (action.semantic == 1) { // SEMANTIC_ACTION_REPLY
      final inputs = <String, dynamic>{};
      for (final input in action.inputs ?? []) {
        inputs[input.resultKey ?? ''] = "Auto-reply from Flutter";
      }
      action.postInputs(inputs);
    }
  }
}

Customize Service Notification

await NotificationsListener.startService(
  foreground: true,
  title: "My App",
  description: "Listening for notifications...",
);

📚 API Reference

NotificationEvent

PropertyTypeDescription
uniqueIdStringUnique identifier generated from key
packageNameStringSource application package name
titleString?Notification title
textString?Notification body text
timestampintPost time (milliseconds since epoch)
channelIdString?Notification channel ID (API 26+)
largeIconUint8List?Large icon as bytes
canTapboolWhether notification has a tap action
actionsList<Action>?Available notification actions
rawMap<String, dynamic>Raw notification data

Methods:

MethodReturnsDescription
tap()Future<bool>Trigger the notification's tap action
getFull()Future<dynamic>Get complete notification data

Action

PropertyTypeDescription
idintAction index
titleString?Action button text
semanticintSemantic type (see below)
inputsList<ActionInput>?Input fields for reply actions

Semantic Types:

ConstantValueDescription
SEMANTIC_ACTION_NONE0No semantic
SEMANTIC_ACTION_REPLY1Quick reply
SEMANTIC_ACTION_MARK_AS_READ2Mark as read
SEMANTIC_ACTION_MARK_AS_UNREAD3Mark as unread
SEMANTIC_ACTION_DELETE4Delete
SEMANTIC_ACTION_ARCHIVE5Archive
SEMANTIC_ACTION_MUTE6Mute
SEMANTIC_ACTION_UNMUTE7Unmute

NotificationsListener

MethodDescription
initialize({callbackHandle})Initialize the plugin
hasPermissionCheck notification access permission
isRunningCheck if service is running
openPermissionSettings()Open system permission settings
startService({...})Start the listener service
stopService()Stop the listener service
promoteToForeground({...})Promote service to foreground
demoteToBackground()Demote service to background

⚠️ Known Issues

  • Service may fail to start after reboot if not running in foreground mode.

💖 Support

If you find this plugin useful, please consider:

  • ⭐ Starring the repository
  • 🐛 Reporting bugs
  • 💡 Suggesting new features
  • 🤝 Contributing code

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Made with ❤️ by Zoe