MVI Media SDK Community Challenge

EchoJournal

Material Design 3 audio journaling app with mood tagging.

EchoJournal Mockup

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

The Tech Stack

Language Kotlin
Architecture MVI / Repository
UI Framework Jetpack Compose
Media SDK MediaRecorder / MediaPlayer
DI Framework Koin
Persistence Room DB