|
1 | | -# Melodee Android Auto Player |
| 1 | +<div align="center"> |
| 2 | + <img src="graphics/logo.png" alt="Melodee logo" height="120" /> |
2 | 3 |
|
3 | | -A native Android music player application that allows users to stream music from Melodee servers. The application is built using modern Android development practices with Jetpack Compose and supports Android Auto integration for in-car entertainment. |
| 4 | + # Melodee Android Auto Player |
| 5 | + Native Android + Android Auto client for the Melodee self-hosted music server, built with Jetpack Compose and Media3. |
4 | 6 |
|
5 | | -This app is very heavily vibe coded. |
| 7 | + [](https://github.com/melodee-project/melodee-player/actions/workflows/android.yml) |
| 8 | + [](LICENSE) |
| 9 | +  |
| 10 | +  |
6 | 11 |
|
7 | | -## Recent Improvements (v1.8.0) |
| 12 | + Features | Quick Start | Android Auto | Architecture | Testing | Documentation | Contributing |
| 13 | +</div> |
8 | 14 |
|
9 | | -### 🚀 Performance Enhancements |
10 | | -- **60% Memory Reduction**: Optimized ViewModel memory management for better performance on all devices |
11 | | -- **Improved State Management**: Enhanced error handling with type-safe UiState patterns |
| 15 | +## Overview |
12 | 16 |
|
13 | | -### 🔒 Security Improvements |
14 | | -- **Encrypted Token Storage**: Authentication tokens now encrypted using AES256-GCM |
15 | | -- **Secure Settings**: New SecureSettingsManager for sensitive data protection |
16 | | - |
17 | | -### 💾 Persistence Layer |
18 | | -- **Room Database**: Local database for recent songs, queue state, and search history |
19 | | -- **State Preservation**: App state now survives restarts and process death |
20 | | -- **Smart Caching**: Intelligent data retention with auto-pruning |
21 | | - |
22 | | -**See [docs/REVIEW-SUMMARY.md](docs/REVIEW-SUMMARY.md) for complete details.** |
| 17 | +Melodee Player is a Kotlin/Compose app (version 1.7.1, minSdk 21 / targetSdk 35) that streams music from a Melodee server to phones and Android Auto. It ships with a background MediaBrowserService for car interfaces, a Compose UI for handheld use, and a Media3-based playback stack with caching and scrobbling. |
23 | 18 |
|
24 | 19 | ## Features |
25 | 20 |
|
26 | | -- 🚗 **Android Auto Integration** - Full support with voice commands and car-optimized UI |
27 | | -- 🎵 **Modern UI** - Built with Jetpack Compose and Material Design 3 |
28 | | -- 🏗️ **Clean Architecture** - MVVM pattern with Clean Architecture principles |
29 | | -- 🌐 **Efficient Networking** - Retrofit with OkHttp for reliable API communication |
30 | | -- 🎧 **Media3 Playback** - Advanced media playback with ExoPlayer |
31 | | -- 📱 **Playlist Management** - Browse and manage playlists with infinite scrolling |
32 | | -- 🔍 **Search Functionality** - Search for songs and playlists |
33 | | -- 🔐 **User Authentication** - Secure login with configurable server endpoints |
34 | | -- 🔄 **Pull-to-Refresh** - Refresh content with intuitive gestures |
35 | | -- 🎮 **Playback Controls** - Persistent now playing bar with full media controls |
36 | | - |
37 | | -## Project Structure |
38 | | - |
39 | | -``` |
40 | | -src/ |
41 | | -├── build.gradle.kts # Root project configuration (Kotlin DSL) |
42 | | -├── settings.gradle.kts # Project settings (Kotlin DSL) |
43 | | -├── app/ |
44 | | -│ ├── build.gradle.kts # App module configuration (Kotlin DSL) |
45 | | -│ └── src/main/java/com/melodee/autoplayer/ |
46 | | -│ ├── data/ # Data layer (API, repositories) |
47 | | -│ ├── domain/ # Domain layer (models, use cases) |
48 | | -│ ├── presentation/ # Presentation layer (ViewModels, UI) |
49 | | -│ ├── service/ # Background services (media, scrobbling) |
50 | | -│ ├── ui/ # UI components and themes |
51 | | -│ ├── util/ # Utility classes |
52 | | -│ └── MelodeeApplication.kt # Application class |
53 | | -├── gradlew # Gradle wrapper (Unix) |
54 | | -├── gradlew.bat # Gradle wrapper (Windows) |
55 | | -└── gradle/ # Gradle wrapper configuration |
56 | | -``` |
57 | | - |
58 | | -## Architecture |
59 | | - |
60 | | -The application follows **Clean Architecture** with **MVVM** pattern: |
61 | | - |
62 | | -### 📊 **Data Layer** |
63 | | -- API interfaces and implementations |
64 | | -- Repository pattern for data access |
65 | | -- Network models and DTOs |
66 | | -- Local caching strategies |
67 | | - |
68 | | -### 🎯 **Domain Layer** |
69 | | -- Business logic and use cases |
70 | | -- Domain models and entities |
71 | | -- Repository interfaces |
72 | | -- Business rules validation |
| 21 | +- Android Auto ready: MediaBrowserServiceCompat + MediaSession with browse/search, metadata, steering wheel controls, and voice-triggered playback. |
| 22 | +- Rich browse/search: playlists, songs, artists, and albums with pagination, infinite scroll, artist/album drill-ins, and server-side favorites. |
| 23 | +- Playback service: Media3/ExoPlayer with queue control, shuffle/repeat, prefetching, notification controls, and streaming cache. |
| 24 | +- Resilient networking: login and token refresh against a Melodee API, request deduplication, retry/backoff, normalized server URLs, and scrobble reporting. |
| 25 | +- Compose UI: Material 3 theming (light/dark/dynamic), now playing screen + mini player, playlist view, and artist/album galleries with Coil-powered artwork. |
| 26 | +- Performance and diagnostics: macrobenchmarks, unit/UI tests, optional performance monitor hooks, and detailed logging for Android Auto interactions. |
73 | 27 |
|
74 | | -### 🖼️ **Presentation Layer** |
75 | | -- Jetpack Compose UI components |
76 | | -- ViewModels with state management |
77 | | -- Navigation with Navigation Compose |
78 | | -- UI state handling |
| 28 | +## Quick Start |
79 | 29 |
|
80 | | -### 🔧 **Service Layer** |
81 | | -- Media playback service |
82 | | -- Android Auto integration |
83 | | -- Background processing |
84 | | -- Scrobbling and analytics |
85 | | - |
86 | | -## Setup |
87 | | - |
88 | | -### Prerequisites |
89 | | -- **Android Studio** Hedgehog (2023.1.1) or later |
90 | | -- **JDK 17** or higher |
91 | | -- **Android SDK** with API level 35 |
92 | | -- **Git** for version control |
93 | | - |
94 | | -### Installation |
95 | | -1. **Clone the repository** |
| 30 | +1. **Requirements** |
| 31 | + - Android Studio Hedgehog (2023.1.1)+, JDK 17, Android SDK Platform 35 |
| 32 | + - Device or emulator on API 21+ (Android Auto features require a device or emulator with Android Auto) |
| 33 | + - A running Melodee API server (use your deployment or the bundled `api-server/`—see its README for setup) |
| 34 | +2. **Clone and open** |
96 | 35 | ```bash |
97 | | - git clone <repository-url> |
98 | | - cd melodee-player |
| 36 | + git clone https://github.com/melodee-project/melodee-player.git |
| 37 | + cd melodee-player/src |
99 | 38 | ``` |
100 | | - |
101 | | -2. **Open in Android Studio** |
102 | | - - Open Android Studio |
103 | | - - Select "Open an existing project" |
104 | | - - Navigate to the cloned directory and select the `src` folder |
105 | | - |
106 | | -3. **Configure API endpoint** |
107 | | - - Launch the application |
108 | | - - Enter your Melodee server URL in the login screen |
109 | | - - Provide your credentials |
110 | | - |
111 | | -4. **Build and run** |
| 39 | + Open the `src` directory in Android Studio or keep using the CLI. |
| 40 | +3. **Build and run** |
112 | 41 | ```bash |
113 | | - cd src |
114 | | - ./gradlew build |
115 | | - ./gradlew installDebug |
| 42 | + ./gradlew build # compile and run unit tests |
| 43 | + ./gradlew installDebug # deploy to a connected device/emulator |
116 | 44 | ``` |
| 45 | +4. **Configure the backend** |
| 46 | + - Launch the app, enter your Melodee server base URL (e.g., `https://your-host/`), and sign in with your account. |
| 47 | + - The app stores auth tokens locally and will refresh them automatically during playback or search. |
| 48 | +5. **Use it** |
| 49 | + - Browse playlists/artists/albums, search, start playback, and manage the queue (shuffle/repeat, add/remove, skip/seek). |
| 50 | + - Connect to Android Auto to browse, search, and control playback hands-free. |
| 51 | + |
| 52 | +## Android Auto |
| 53 | + |
| 54 | +- Browse playlists and the current queue from Android Auto using the MediaBrowser tree. |
| 55 | +- Voice search and playback via Google Assistant; results are cached for quick follow-up commands. |
| 56 | +- Full metadata (art, artist, album) and notification controls; steering wheel buttons map to previous/next/play-pause. |
| 57 | +- Queue mutations (add/clear) stay in sync with the handheld UI. |
| 58 | + |
| 59 | +## Architecture & Stack |
| 60 | + |
| 61 | +### Project layout |
| 62 | +- `src/app` — Compose Android app (app module) |
| 63 | +- `src/benchmark` — Macrobenchmark suite for startup/navigation/scroll performance |
| 64 | +- `docs/` — Architecture, reviews, Android Auto specs, performance notes |
| 65 | +- `api-server/` — Melodee backend source for local testing (see `api-server/README.md`) |
| 66 | +- `graphics/` — Branding assets for docs/UI |
| 67 | +- `prompts/` — Prompt artifacts used during development |
| 68 | + |
| 69 | +### Tech stack |
| 70 | +- UI: Jetpack Compose, Material 3, Navigation Compose |
| 71 | +- Playback: Media3/ExoPlayer, MediaBrowserServiceCompat, MediaSessionCompat, Media cache/prefetch |
| 72 | +- Networking: Retrofit + OkHttp (logging, retry/backoff, caching), Gson, request deduplication, token refresh handling |
| 73 | +- Data/auth: SharedPreferences-based SettingsManager (encrypted SecureSettingsManager available for migration), URL normalization, scrobble API integration |
| 74 | +- Concurrency: Kotlin Coroutines + Flow |
| 75 | +- Images: Coil (+ GIF support) |
| 76 | +- Testing: JUnit, MockK, Truth, Robolectric, Compose UI tests, AndroidX Test, Macrobenchmark, JaCoCo coverage |
| 77 | + |
| 78 | +## Testing |
| 79 | + |
| 80 | +From `src/`: |
117 | 81 |
|
118 | | -## Requirements |
119 | | - |
120 | | -### Development Environment |
121 | | -- **Android Studio**: Hedgehog (2023.1.1) or later |
122 | | -- **JDK**: 17 or higher |
123 | | -- **Android SDK**: API 21-35 |
124 | | -- **Kotlin**: 1.9.20 |
125 | | -- **Gradle**: 8.12 |
126 | | -- **Android Gradle Plugin**: 8.10.0 |
127 | | - |
128 | | -### Device Requirements |
129 | | -- **Minimum SDK**: API 21 (Android 5.0) |
130 | | -- **Target SDK**: API 35 (Android 15) |
131 | | -- **Architecture**: ARM64, ARM, x86_64 |
132 | | - |
133 | | -## Dependencies |
134 | | - |
135 | | -### Core Android |
136 | | -- **AndroidX Core KTX**: 1.15.0 |
137 | | -- **AppCompat**: 1.7.0 |
138 | | -- **Material Design**: 1.12.0 |
139 | | - |
140 | | -### Jetpack Compose |
141 | | -- **Compose BOM**: 2024.12.01 |
142 | | -- **Activity Compose**: 1.9.3 |
143 | | -- **Navigation Compose**: 2.8.5 |
144 | | -- **Material 3**: Latest |
145 | | -- **Compiler**: 1.5.4 |
146 | | - |
147 | | -### Architecture & Lifecycle |
148 | | -- **Lifecycle Runtime**: 2.8.7 |
149 | | -- **ViewModel**: 2.8.7 |
150 | | -- **ViewModel Compose**: 2.8.7 |
151 | | -- **Runtime Compose**: 2.8.7 |
152 | | - |
153 | | -### Media & Playback |
154 | | -- **Media3 ExoPlayer**: 1.2.0 |
155 | | -- **Media3 UI**: 1.2.0 |
156 | | -- **Media3 Session**: 1.2.0 |
157 | | -- **AndroidX Media**: 1.7.0 (Android Auto support) |
158 | | - |
159 | | -### Networking |
160 | | -- **Retrofit**: 2.11.0 |
161 | | -- **Gson Converter**: 2.11.0 |
162 | | -- **OkHttp**: 4.12.0 |
163 | | -- **Logging Interceptor**: 4.12.0 |
164 | | - |
165 | | -### Image Loading |
166 | | -- **Coil**: 2.7.0 |
167 | | -- **Coil Compose**: 2.7.0 |
168 | | -- **Coil GIF**: 2.7.0 |
169 | | - |
170 | | -### Concurrency |
171 | | -- **Kotlin Coroutines**: 1.9.0 |
172 | | - |
173 | | -### Testing |
174 | | -- **JUnit**: 4.13.2 |
175 | | -- **AndroidX Test**: 1.2.1 |
176 | | -- **Espresso**: 3.6.1 |
177 | | -- **Compose Testing**: Latest |
178 | | - |
179 | | -## Build System |
180 | | - |
181 | | -This project uses **Kotlin DSL** for Gradle build scripts, providing: |
182 | | -- Type-safe build configuration |
183 | | -- Better IDE support and autocomplete |
184 | | -- Compile-time error checking |
185 | | -- Consistent syntax with Kotlin codebase |
186 | | - |
187 | | -### Build Commands |
188 | 82 | ```bash |
189 | | -# Clean build |
190 | | -./gradlew clean |
| 83 | +# Unit tests |
| 84 | +./gradlew testDebugUnitTest |
191 | 85 |
|
192 | | -# Debug build |
193 | | -./gradlew assembleDebug |
| 86 | +# Instrumented/UI tests (requires emulator/device) |
| 87 | +./gradlew connectedDebugAndroidTest |
194 | 88 |
|
195 | | -# Release build |
196 | | -./gradlew assembleRelease |
| 89 | +# Macrobenchmarks (requires emulator/device) |
| 90 | +./gradlew :benchmark:connectedCheck |
197 | 91 |
|
198 | | -# Run tests |
199 | | -./gradlew test |
200 | | - |
201 | | -# Install on device |
202 | | -./gradlew installDebug |
| 92 | +# Coverage report |
| 93 | +./gradlew jacocoTestReport |
203 | 94 | ``` |
204 | 95 |
|
205 | | -## Usage |
206 | | - |
207 | | -### Getting Started |
208 | | -1. **Launch** the application |
209 | | -2. **Configure** your Melodee server URL |
210 | | -3. **Login** with your credentials |
211 | | -4. **Browse** available playlists and songs |
212 | | -5. **Select** content to start playback |
213 | | -6. **Control** playback using the now playing bar |
214 | | - |
215 | | -### Android Auto |
216 | | -1. **Connect** your device to Android Auto |
217 | | -2. **Launch** the Melodee app from the car interface |
218 | | -3. **Use voice commands** for hands-free control |
219 | | -4. **Browse** playlists using car-safe UI |
220 | | -5. **Control playback** with steering wheel controls |
221 | | - |
222 | | -### Voice Commands (Android Auto) |
223 | | -- "Play [song/artist/playlist name]" |
224 | | -- "Pause music" |
225 | | -- "Skip to next song" |
226 | | -- "Go back to previous song" |
227 | | -- "Shuffle my music" |
228 | | - |
229 | | -## Android Auto Integration |
| 96 | +CI runs `./gradlew build` and `./gradlew testDebugUnitTest` via GitHub Actions (`android.yml`). |
230 | 97 |
|
231 | | -### Features |
232 | | -- 🎵 **Media Playback Controls** - Play, pause, skip, previous |
233 | | -- 🗣️ **Voice Commands** - Full voice control integration |
234 | | -- 📊 **Metadata Display** - Song title, artist, album art |
235 | | -- 📋 **Playlist Browsing** - Car-optimized playlist navigation |
236 | | -- 🔍 **Search Functionality** - Voice and text search |
237 | | -- 🎛️ **Steering Wheel Controls** - Hardware button support |
| 98 | +## Documentation |
238 | 99 |
|
239 | | -### Technical Implementation |
240 | | -- Media3 MediaSession for playback control |
241 | | -- MediaBrowserService for content browsing |
242 | | -- Custom MediaSessionCallback for Android Auto commands |
243 | | -- Optimized UI for automotive displays |
| 100 | +- Android Auto implementation notes: `docs/README.md` |
| 101 | +- Code and performance reviews: `docs/REVIEW-SUMMARY.md`, `docs/performance_review.md`, `docs/PERFORMANCE_ANALYSIS.md` |
| 102 | +- Implementation and migration details: `docs/implementation-summary.md`, `docs/MIGRATION-SUMMARY.md` |
244 | 103 |
|
245 | 104 | ## Contributing |
246 | 105 |
|
247 | | -### Development Workflow |
248 | | -1. **Fork** the repository |
249 | | -2. **Create** a feature branch (`git checkout -b feature/amazing-feature`) |
250 | | -3. **Commit** your changes (`git commit -m 'Add amazing feature'`) |
251 | | -4. **Push** to the branch (`git push origin feature/amazing-feature`) |
252 | | -5. **Open** a Pull Request |
253 | | - |
254 | | -### Code Style |
255 | | -- Follow [Kotlin coding conventions](https://kotlinlang.org/docs/coding-conventions.html) |
256 | | -- Use [ktlint](https://ktlint.github.io/) for code formatting |
257 | | -- Write meaningful commit messages |
258 | | -- Include tests for new features |
259 | | - |
260 | | -### Pull Request Guidelines |
261 | | -- Ensure all tests pass |
262 | | -- Update documentation if needed |
263 | | -- Follow the existing code style |
264 | | -- Include screenshots for UI changes |
| 106 | +1. Fork and create a feature branch (`git checkout -b feature/my-change`). |
| 107 | +2. Make changes, add tests when possible, and run the test suite. |
| 108 | +3. Open a PR describing the change and any user-facing impact (screenshots for UI tweaks help). |
265 | 109 |
|
266 | 110 | ## License |
267 | 111 |
|
268 | | -This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details. |
269 | | - |
270 | | -## Support |
271 | | - |
272 | | -For support and questions: |
273 | | -- Create an issue in the repository |
274 | | -- Check existing documentation |
275 | | -- Review the code comments for implementation details |
| 112 | +Distributed under the MIT License. See `LICENSE` for details. |
0 commit comments