Skip to content

About

A simple, high-quality Android audio recorder. Records uncompressed WAV at the highest practical quality.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Voice Memo

Voice Memo icon

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.

Record screen Recordings list Playback player

Features

  • 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 UNPROCESSED audio source when the device supports it (no automatic gain control or noise suppression), falling back to MIC.
  • 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.

Background recording

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.

Never losing a recording

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.

Audio quality

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.

Where files are stored

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.

Project structure

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

Requirements

  • 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.

Building

From Android Studio

  1. Open the project root folder in Android Studio.
  2. Let Gradle sync.
  3. Run the app configuration on a device or emulator.

From the command line

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 signing

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.

Permissions

  • RECORD_AUDIO is requested at runtime before the first recording.
  • POST_NOTIFICATIONS is requested alongside it on Android 13+, for the ongoing recording notification. Optional: recording works without it.
  • FOREGROUND_SERVICE and FOREGROUND_SERVICE_MICROPHONE let capture continue while the app is not in the foreground.
  • WAKE_LOCK keeps the CPU awake so recording continues with the screen off.

App icon

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.

License

MIT

About

A simple, high-quality Android audio recorder. Records uncompressed WAV at the highest practical quality.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages