MVI Media SDK Community Challenge

EchoJournal

Material Design 3 audio journaling app with mood tagging.

EchoJournal Mockup

The Overview

EchoJournal was constructed as part of the Pl Mobile Dev Campus community challenge. It does more than simple audio recording by allowing users to construct a rich, filterable timeline composed of their voice logs, tagged with metadata indicating varying moods and topics, potentially backed by AI transcription.

The Challenge

Managing media recording state across the Android lifecycle is tricky. If the app is sent to the background or if standard hardware configuration changes occur, the underlying `MediaRecorder` pipeline can leak resources, corrupt the output buffer, or misalign the UI's real-time audio-level visualizers.

Also, developing an MVP that is tightly cohesive yet open for immediate "Multi-Module Integration" refactoring meant balancing quick iteration speed against hard architectural boundaries.

Architecture & Technical Decisions

I structured EchoJournal initially as a pure Single-Module MVP backed entirely by an MVI (Model-View-Intent) architecture. The UI sends strictly typed Intents downward, ensuring the complex state machine governing `PREPARING`, `RECORDING`, `PAUSED`, or `IDLE` never drifts out of sync with the Compose UI view layer.

Handling Media Layers

  • Safely Managing The SDK: Implemented tight coroutine scopes bound by Lifecycle-Aware components. The `MediaPlayer` and `MediaRecorder` instances are carefully released avoiding memory starvation.
  • Reactive Journaling: The history grouping mechanism is entirely reactively bound via Room and Flow. Users filter by 'Topic' or 'Mood' strings natively. Changes in DB records instantly invalidate and update Jetpack Compose constraints seamlessly inline.
  • Flexible Structure: Designed packages (`domain`, `data`, `presentation`) so that promoting AI translation features into isolated Gradle feature modules doesn't require rewriting business logic.

Impact & Results

  • Stable Audio State built, preventing core Android media leaks when pivoting through system configuration changes.
  • Instant Data Invalidation enabled via Room and Flow, dynamically updating complex nested historical views without manual UI re-composition loops.
  • Extensible Core ready to seamlessly slot in AI transcription or dedicated cloud sync feature modules with zero architectural rewrite.

The Tech Stack

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