Smart Notification Listener is an Android library that allows applications to listen to system notifications and expose them as a reactive StateFlow. The library is designed for modern Android applications using Jetpack Compose and follows clean architecture principles.
The goal of this library is to provide a reusable, lifecycle-safe, and Compose-friendly way to observe system notifications, while keeping permission handling and UI responsibilities fully in the application layer.
- Listens to system notifications using NotificationListenerService
- Exposes notifications as Kotlin StateFlow
- Designed for Jetpack Compose
- Safe handling of duplicate notification IDs
- Clean separation between library logic and permission handling
- Includes a complete sample application
- Lightweight and production-ready
Click to watch demo
Screen_recording_20251230_161158.mp4
Add JitPack repository to your settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}Add dependency to your app module build.gradle.kts:
implementation("com.github.pascaladitia:smart-notification-listener:1.0.1")This library requires Android Notification Listener Access. This permission is not a runtime permission and cannot be requested using a dialog.
The user must enable it manually from system settings.
Typical path:
Settings → Notifications → Notification access → Your App → Allow
Notes:
- The app must be opened at least once before the setting appears
- Some OEM devices may place this setting in a different menu
- The permission may be revoked by the system at any time
Notifications are exposed as a StateFlow and can be collected in a lifecycle-aware manner.
Example with Jetpack Compose:
val notifications by SmartNotificationListener
.notifications
.collectAsStateWithLifecycle()Example using LazyColumn:
LazyColumn {
items(
items = notifications,
key = { it.packageName + "-" + it.id + "-" + it.postedAt }
) { notification ->
Text(
text = notification.appName + ": " + notification.title
)
}
}Important:
- Android does not guarantee notification IDs are unique
- Always use a stable and unique key when displaying lists
Permission handling is intentionally not included in the library.
Recommended flow:
- Check whether notification listener permission is granted
- If not granted, show an explanation screen
- Redirect the user to system settings
- Re-check permission when the app resumes
This approach ensures better UX, Play Store compliance, and library reusability.
smart-notification-listener/
├── core Notification repository and internal state
├── service NotificationListenerService implementation
├── model Notification data models
├── utils Public API access
└── sample-app Jetpack Compose sample application
- The library registers a NotificationListenerService
- Incoming notifications are received by the service
- Notification data is mapped into a NotifMeta model
- Data is stored in an internal repository
- Updates are emitted via StateFlow
- UI layers collect and react to updates
- Notification listener permission must be enabled manually
- Some applications emit notifications with duplicate IDs
- OEM devices may restrict background services
- Notifications may be removed by the system at any time
- Minimum SDK: 24
- Recommended Android version: 8.0 and above
- Kotlin: 1.9 or newer
- Jetpack Compose: Latest stable
- Material 3 supported
- Notification grouping by application
- Conversation and message extraction
- Application-level filtering
- Persistent storage support
- Maven Central publication
MIT License
Copyright (c) 2025 Pascal
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files to deal in the Software without restriction.
The software is provided "as is", without warranty of any kind.
Pascal
GitHub: https://github.com/pascaladitia