Sound Notifier
A simple Android app to find a lost device. Send a push notification via UnifiedPush (using ntfy as the distributor) and the device plays a loud alarm — even if it's on silent, vibrate, or Do Not Disturb.
Everything here is claudeslop (Opus 4.6 initially), you have been warned
How it works
- The ntfy app runs on your device as a UnifiedPush distributor
- Sound Notifier registers with ntfy and gets a unique endpoint URL
- When anyone POSTs to that URL, the device plays an alarm at max volume
- The alarm uses the
STREAM_ALARMaudio channel withUSAGE_ALARMattributes, which bypasses silent/vibrate mode - A notification channel with
setBypassDnd(true)handles Do Not Disturb override
Prerequisites
Setup
- Install the ntfy app on your device
- Install Sound Notifier
- Open Sound Notifier and tap Register
- The app will display an endpoint URL — save this somewhere accessible (another device, your server, etc.)
- If the "Grant DND Access" button is visible, tap it and enable DND access for Sound Notifier (this lets the alarm override Do Not Disturb)
Triggering the alarm
From any device with the endpoint URL:
curl -d "find me" https://ntfy.sh/upYOUR_ENDPOINT_ID
The message content doesn't matter — any POST triggers the alarm.
Stopping the alarm
Open the app — either by tapping the notification or any other way. The alarm stops immediately and the message that triggered it is shown on screen.
The alarm volume and ringer mode are restored to their original values when stopped.
Permissions
| Permission | Type | Why |
|---|---|---|
POST_NOTIFICATIONS |
Runtime (Android 13+) | Show the alarm notification |
ACCESS_NOTIFICATION_POLICY |
Special (user grants in Settings) | Override Do Not Disturb mode |
MODIFY_AUDIO_SETTINGS |
Normal (auto-granted) | Set alarm volume to max |
FOREGROUND_SERVICE |
Normal | Keep alarm playing in background |
FOREGROUND_SERVICE_MEDIA_PLAYBACK |
Normal | Required foreground service type on Android 14+ |
VIBRATE |
Normal | Vibration with the alarm |
Only POST_NOTIFICATIONS requires a runtime prompt. ACCESS_NOTIFICATION_POLICY requires the user to manually enable it in system settings (the app shows a button for this). All others are auto-granted.
Design decisions
- minSdk 26: Simplifies the code since notification channels (required for DND bypass) are always available. Covers Android 8.0+, which is ~95% of active devices.
- Selectable alarm sound: Uses Android's built-in ringtone picker (
ACTION_RINGTONE_PICKER) filtered to alarm sounds. The selection is saved to SharedPreferences. Falls back to the system default alarm if nothing is chosen. - STREAM_ALARM + USAGE_ALARM: The alarm audio stream is independent of the ringer volume on most devices and is not silenced by vibrate/silent mode. Combined with the DND bypass notification channel, this covers all quiet modes.
- Foreground service for playback: Ensures the alarm keeps playing even if the system tries to reclaim resources. Uses
mediaPlaybacktype as required by Android 14+. - Volume restoration: Saves and restores the original alarm volume and ringer mode when the alarm is stopped, so the app doesn't permanently change device settings.
- No server component: The endpoint URL is displayed directly in the app. You POST to it from anywhere — no app server needed.
- PushService (not MessagingReceiver): Uses the modern
PushServicepattern from UnifiedPush connector 3.x, which is more secure (exported="false") than the deprecatedMessagingReceiverbroadcast receiver.
Building
./build.sh
This will download the Android SDK if needed (requires JDK 17-24 and curl/unzip), build the APK, and copy it to sound-notifier-debug.apk.
You can also set ANDROID_HOME if you already have an SDK, or JAVA_HOME to point at a specific JDK. Android Studio's bundled JDK (/opt/android-studio/jbr) is detected automatically.