A complete Android application for capturing and forwarding system notifications to external APIs with queue management and retry mechanisms.
app/- Android application (Kotlin + Jetpack Compose)backend/- Node.js Express server for receiving notificationsREADME.md- This file
- Notification Capture: Listen to all system notifications with filtering capabilities
- API Forwarding: Send notification data to external endpoints via HTTP POST
- Queue Management: Offline notifications are queued and retried automatically
- Encryption: API keys are stored securely using Android's EncryptedSharedPreferences
- Background Processing: Uses WorkManager for reliable background retries
- Foreground Service: Ensures continuous operation
- Filtering: Forward all notifications or filter by specific package names
- Rupiah Detection: Automatically detects Indonesian currency amounts in notifications
- Logs: Real-time logging with up to 100 recent entries
- Boot Restart: Automatically restarts services after device reboot
git clone <repository-url>
cd NotificationListener
./gradlew assembleDebugadb install app/build/outputs/apk/debug/app-debug.apk- Open the app
- Tap "Buka Pengaturan Akses Notifikasi"
- Find "Notification Listener" in the list
- Toggle the switch to ON
- Confirm the permission dialog
- Return to the app and tap "Cek Status Izin" to verify
- Endpoint URL (wajib): Your webhook URL (must start with http:// or https://)
- API Key (opsional): Optional API key sent as X-API-Key header
- Filter Package: Comma-separated list of app package names (e.g.,
id.dana, com.whatsapp) - Forward semua aplikasi: Toggle to forward ALL notifications (ignores filter)
- Fill in required fields
- Tap "Simpan Pengaturan"
- Grant battery optimization exemption when prompted (recommended)
-
Navigate to backend directory:
cd backend npm install -
Configure environment: Edit
.envfile and set your API key:API_KEY=your-secret-api-key
-
Start the backend server:
npm run dev # Development mode npm start # Production mode
-
Configure Android app:
- Set Endpoint URL:
http://your-server:3000/webhook - Set API Key:
your-secret-api-key
- Set Endpoint URL:
See backend/README.md for detailed backend setup instructions.
The HTTP/HTTPS URL where notification data will be sent via POST request.
- Required: Yes
- Format: Must start with
http://orhttps:// - Example:
https://api.example.com/webhook
Optional authentication key sent in the X-API-Key header.
- Required: No
- Storage: Encrypted using Android's security library
- Usage: Added to all requests if provided
Comma-separated list of Android app package names to monitor.
- Required: Only if "Forward semua aplikasi" is OFF
- Format:
package1, package2, package3 - Example:
id.dana, com.whatsapp, com.gojek.app - Case Sensitive: Exact match required
When enabled, forwards notifications from ALL apps regardless of filter list.
- ON: All notifications are sent (filter is ignored)
- OFF: Only notifications from apps in filter list are sent
{
"deviceId": "550e8400-e29b-41d4-a716-446655440000",
"packageName": "id.dana",
"appName": "DANA",
"postedAt": "2025-08-30T10:00:24+07:00",
"title": "DANA",
"text": "Anda menerima Rp 100.000",
"subText": "",
"bigText": "",
"channelId": "payments",
"notificationId": 12345,
"amountDetected": "100000",
"extras": {
"android.title": "DANA",
"android.text": "Anda menerima Rp 100.000"
}
}{
"test": true,
"message": "Test notification from Notification Listener",
"timestamp": "2025-08-30T10:00:24Z"
}curl -X POST "https://api.example.com/webhook" \
-H "Content-Type: application/json" \
-d '{
"deviceId": "550e8400-e29b-41d4-a716-446655440000",
"packageName": "id.dana",
"appName": "DANA",
"postedAt": "2025-08-30T10:00:24+07:00",
"title": "DANA",
"text": "Anda menerima Rp 100.000",
"amountDetected": "100000"
}'curl -X POST "https://api.example.com/webhook" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key" \
-d '{
"test": true,
"message": "Test notification",
"timestamp": "2025-08-30T10:00:24Z"
}'- Language: Kotlin
- UI: Jetpack Compose + Material3
- DI: Hilt
- Database: Room
- Network: Retrofit + OkHttp
- Background: WorkManager
- Storage: DataStore + EncryptedSharedPreferences
- Build: Gradle Kotlin DSL
com.hiddencyber.notificationlistener/
├── data/
│ ├── database/ # Room entities, DAOs, database
│ ├── model/ # API models and data classes
│ ├── network/ # Retrofit API service
│ ├── preferences/ # DataStore repository
│ ├── repository/ # Main data repository
│ └── security/ # Encrypted storage
├── di/ # Hilt dependency injection modules
├── receiver/ # Broadcast receivers
├── service/ # Services (Notification Listener, Foreground)
├── ui/ # Compose UI screens and components
├── utils/ # Utility functions
└── worker/ # WorkManager workers
- Verify notification access permission is granted
- Check if target apps are in filter list (if not forwarding all)
- Look at logs for permission or filtering messages
- Verify endpoint URL is correct and accessible
- Check network connectivity
- Review API key configuration
- Check logs for HTTP error codes
- Disable battery optimization for the app
- Check if notification permission was revoked
- Restart the app to reinitialize services
- Ensure device has network connectivity
- Check WorkManager constraints in device settings
- Verify pending notifications in logs
./gradlew assembleDebug # Debug build
./gradlew assembleRelease # Release build./gradlew test # Unit tests
./gradlew connectedAndroidTest # Instrumentation tests- Android API 24+ (Android 7.0)
- Target SDK 36
- Kotlin 2.0+
- Jetpack Compose
This project is for demonstration purposes. Ensure compliance with local privacy laws when capturing notification data.