A simple, high-quality Android audio recorder. Records uncompressed WAV at the highest practical quality, keeps recording in the background with the screen locked, lists your recordings, and includes a Spotify-style playback player with a draggable seek bar. Dark mode throughout.
- Records raw PCM WAV at 48 kHz, 16-bit, mono.
- Keeps recording in the background: screen locked, another app in front, or the app swiped out of recents.
- Ongoing notification with a live timer and a one-tap stop.
- Crash-proof files: a recording is never lost, whatever happens to the app.
- Uses the
UNPROCESSEDaudio source when the device supports it (no automatic gain control or noise suppression), falling back toMIC. - Files are named by date and time:
yyyy-MM-dd-HH-mm-ss.wav. - Live waveform visualizer driven by real input amplitude while recording.
- Large circular record button: blue when idle, red and pulsing while recording.
- Recordings tab with duration and file size per item.
- Spotify-style player: draggable seek bar, current and total time, play/pause.
- Share any recording through the Android share sheet.
- Delete recordings with a confirmation dialog.
- Dark theme with a blue accent.
Capture runs in RecordingService, a foreground service declared with the
microphone type, not in the UI. Once you tap record:
- Locking the screen, switching apps or swiping the app out of recents does not stop the recording. A partial wake lock keeps the CPU running with the screen off, and the service holds the mic until you stop it.
- An ongoing notification shows the elapsed time and carries a Parar action, so a recording can be stopped without opening the app. Tapping the notification returns to the app.
- Reopening the app reattaches to the recording already in progress — the timer and waveform pick up where they are, because the UI only mirrors the service.
Android 13+ also asks for notification permission. Denying it only hides the notification; recording still works.
Everything captured is on disk within two seconds of being spoken:
- Samples are streamed straight to the WAV file as they are read.
- Every two seconds the WAV header is rewritten with the real sizes and the file
is
fsynced, so the file on disk is always a complete, playable WAV — not a placeholder that only becomes valid when you press stop. - Every exit path finalizes the file: pressing stop, the notification action, the service being destroyed, and the mic being taken away (an incoming call, an audio-server restart) all close and finalize the recording rather than dropping it.
- On launch the app sweeps the recordings directory and repairs any file whose header disagrees with its length, so a recording cut short by a crash, a force-stop or a dead battery still shows its real duration and plays back.
- Recordings are named down to the second and de-duplicated, so two recordings can never overwrite each other.
The file currently being recorded is hidden from the recordings list until it is finalized, so it cannot be deleted or shared mid-capture.
The recorder writes a canonical 44-byte WAV/PCM header and streams 16-bit little-endian samples straight to disk on a background thread. Settings:
| Property | Value |
|---|---|
| Format | WAV (PCM) |
| Sample rate | 48000 Hz |
| Bit depth | 16-bit |
| Channels | Mono |
| Audio source | UNPROCESSED, fallback MIC |
48 kHz / 16-bit is the practical ceiling for AudioRecord on virtually every
device. 24-bit and float capture vary by hardware, so they are intentionally
not used.
Recordings are saved in the app-private external directory:
Android/data/com.example.voicememo/files/recordings/
Sharing is handled through a FileProvider, so other apps receive a valid
content URI rather than a raw file path.
app/src/main/java/com/example/voicememo/
VoiceMemoApp.kt Application; repairs interrupted recordings at startup
MainActivity.kt Tabs (ViewPager2 + TabLayout)
RecordFragment.kt Record screen, button states, live waveform, timer
RecordingsFragment.kt List + Spotify-style playback player
RecordingAdapter.kt RecyclerView adapter for the recordings list
RecordingService.kt Foreground service that owns the mic and the notification
RecordingState.kt Process-wide recording state the UI observes
WavRecorder.kt AudioRecord capture and checkpointing WAV writer
WavFile.kt WAV header writing, patching and repair
WaveformView.kt Custom live amplitude visualizer
Recordings.kt Storage directory and listing helper
- Android Studio (Ladybug or newer recommended).
- JDK 17.
- Android SDK with platform 34 and build-tools.
- Minimum device API 24 (Android 7.0); target API 34.
- Open the project root folder in Android Studio.
- Let Gradle sync.
- Run the
appconfiguration on a device or emulator.
Debug build:
./gradlew assembleDebug
Output: app/build/outputs/apk/debug/app-debug.apk
Release build (signed, see below):
./gradlew assembleRelease
Output: app/build/outputs/apk/release/app-release.apk
Install directly on a connected device:
./gradlew installRelease
On Windows use gradlew.bat instead of ./gradlew.
Release builds are signed with a keystore configured through
keystore.properties at the project root. That file and the keystore itself are
intentionally excluded from version control (see .gitignore).
Create your own keystore:
keytool -genkeypair -v -keystore release.keystore -alias voicememo \
-keyalg RSA -keysize 2048 -validity 10000
Then create keystore.properties at the project root:
storeFile=release.keystore
storePassword=YOUR_STORE_PASSWORD
keyAlias=voicememo
keyPassword=YOUR_KEY_PASSWORD
If keystore.properties is absent, the release build falls back to an unsigned
APK. Keep the keystore and passwords backed up: Play Store updates require the
same signing key.
RECORD_AUDIOis requested at runtime before the first recording.POST_NOTIFICATIONSis requested alongside it on Android 13+, for the ongoing recording notification. Optional: recording works without it.FOREGROUND_SERVICEandFOREGROUND_SERVICE_MICROPHONElet capture continue while the app is not in the foreground.WAKE_LOCKkeeps the CPU awake so recording continues with the screen off.
The launcher icon is a singing bird with a sound wave, provided as density-
specific PNGs under app/src/main/res/mipmap-*. The source artwork is
voice-memo.png in the project root.
MIT



