EchoJournal
Material Design 3 audio journaling app with mood tagging.
The Overview
EchoJournal was built for the Pl Mobile Dev Campus community challenge. It records voice logs and lets the user browse them as a filterable timeline tagged by mood and topic, with room to plug in AI transcription later.
The Challenge
Media recording state is tricky to manage across the Android lifecycle. If the app moves to the background or the device rotates, the MediaRecorder pipeline can leak resources, corrupt the output buffer, or push the audio-level visualizer out of sync with the actual recording.
The other tension was building a single-module MVP that could later be split into feature modules without rewriting it. That meant moving fast on shipping, but still drawing hard architectural lines from day one.
Architecture & Technical Decisions
EchoJournal started as a single-module MVP on an MVI (Model-View-Intent) architecture. The UI dispatches typed Intents downward, so the state machine governing PREPARING, RECORDING, PAUSED, and IDLE stays in lockstep with the Compose view layer.
Handling media layers
The MediaPlayer and MediaRecorder instances are bound to lifecycle-aware coroutine scopes and released on cleanup, which is what stops the leaks. The history grouping is reactively bound via Room and Flow: users filter by topic or mood, and any database change invalidates the relevant Compose state directly.
The package layout (domain, data, presentation) was designed so that adding AI transcription as a separate Gradle feature module later won't mean rewriting business logic.
Impact & Results
- Stable audio state across configuration changes, with no
MediaRecorderleaks. - Reactive timeline updates via Room + Flow, with no manual UI invalidation.
- Package layout that lets AI transcription or cloud sync drop in as new feature modules without an architectural rewrite.