An app that counts every phone notification and plays a custom sound every N notifications (default: 100).
- Android 14 (API level 34) or higher
- Notification Access permission
- Foreground Service permission
- Storage Access Framework (for custom sound files)
The app requires the following permissions:
- Notification Access: Required to listen to and count notifications
- POST_NOTIFICATIONS: Required to show the foreground service notification
- FOREGROUND_SERVICE: Required to run the notification listener reliably
- FOREGROUND_SERVICE_SPECIAL_USE: Specific foreground service type for notification listening
- Clone this repository
- Open the project in Android Studio
- Sync Gradle files
- Build and run on an Android 14+ device or emulator
git clone https://github.com/thomasjbarrett82/ExtraLifeNotifications.git
cd ExtraLifeNotifications
./gradlew build-
First Launch:
- The app will request necessary permissions
- Grant notification access when prompted (this will open Android settings)
- Grant notification permission when prompted
-
Configure Settings:
- Set the notification interval (default is 100)
- Optionally select a custom sound file from your device
-
Monitor Notifications:
- The app will run in the background and count all notifications
- Every N notifications, it will play the "extra life" sound
- View the current count on the main screen
-
Status Indicators:
- ✓ Active and Running: All permissions granted, service is monitoring
⚠️ Notification Access Required: Need to grant notification listener access⚠️ Notification Permission Required: Need to grant POST_NOTIFICATIONS permission
ExtraLifeNotifications/
├── app/
│ ├── src/
│ │ └── main/
│ │ ├── java/com/extralifenotifications/
│ │ │ ├── MainActivity.kt # Main UI activity
│ │ │ └── NotificationListenerService.kt # Background service
│ │ ├── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_main.xml # Main UI layout
│ │ │ ├── values/
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── themes.xml
│ │ │ ├── drawable/
│ │ │ │ └── ic_notification.xml # Notification icon
│ │ │ ├── raw/
│ │ │ │ └── milestone_sound.mp3 # Default sound
│ │ │ └── mipmap-*/ # Launcher icons
│ │ └── AndroidManifest.xml
│ ├── build.gradle
│ └── proguard-rules.pro
├── build.gradle
├── settings.gradle
└── gradle.properties
- Handles UI and user interactions
- Manages permissions requests
- Displays notification count and status
- Allows configuration of interval and custom sound
- Uses SharedPreferences for persistent storage
- Extends Android's NotificationListenerService
- Runs as a foreground service for reliability
- Counts incoming notifications (excluding its own)
- Plays milestone sounds at configured intervals
- Automatically reconnects if disconnected
notification_count: Current notification countnotification_interval: Milestone interval (default: 100)custom_sound_uri: URI of custom sound file (if selected)
- Foreground Service: Ensures the notification listener isn't killed by Android's battery optimization
- SharedPreferences: Persists app state across restarts and reboots
- Storage Access Framework: Modern way to access user files with proper permissions
- Material Design 3: Modern, accessible UI components
- Kotlin: Modern, type-safe language with null safety
- ViewBinding: Type-safe view access
- Notification Channels: Required for Android O+
- Runtime Permissions: Proper permission handling for Android 13+
- Uses MediaPlayer for audio playback
- Releases resources properly after playback
- Handles both default (raw resource) and custom (SAF URI) sounds
- Includes error handling for invalid sound files
- Implements
onListenerConnected()andonListenerDisconnected() - Uses
requestRebind()to automatically reconnect (Android N+) - Foreground service notification prevents service termination
- Updates foreground notification with current count
Replace app/src/main/res/raw/milestone_sound.mp3 with your own sound file.
Modify the default value in MainActivity.kt:
val savedInterval = sharedPreferences.getInt(PREF_NOTIFICATION_INTERVAL, 100) // Change 100Edit app/src/main/res/values/colors.xml and themes.xml.
- Ensure notification access is granted in Android Settings
- Check that the app has POST_NOTIFICATIONS permission
- Verify the foreground service notification is visible
- Restart the app after granting permissions
- Check device volume is not muted
- Verify the custom sound file (if selected) is valid
- Try resetting to default sound
- Check Android's Do Not Disturb settings
- The count is saved in SharedPreferences and should persist
- If count resets, check if app data was cleared
- Verify SharedPreferences are not being cleared by other apps or tools
- Update version in
app/build.gradle:
versionCode 2
versionName "1.1"- Generate signed APK:
./gradlew assembleRelease- Find APK at:
app/build/outputs/apk/release/app-release.apk
This project is provided as-is for educational and personal use.
Feel free to submit issues and pull requests.
- Built with Android Studio
- Uses Material Design 3 components
- Kotlin programming language
- Written with AI assistance (Claude and Gemini)
- Default sound from IndyArts