Simple Music Player: Folder Trees, Flat Views, and UI Polish
Image generated by Google Gemini
When the January activity journal last checked in on simple_music_player — the Jetpack Compose music player that Claude Opus 4.5 built from scratch in two days — it had just received seek-bar fixes and slider styling. Six months and seven releases later, the app has grown up considerably. Most of that growth has been on two fronts: how the app organizes and navigates music folders, and steady polish of the user interface — including a release that landed the same day as this post.
Release Timeline
| Date | Version | Key Work |
|---|---|---|
| 2026-01-24 | MediaStore migration, folder tree navigation, friendly storage names | |
| 2026-01-25 | 1.1–1.2 | About dialog, translations, GitHub Releases workflow |
| 2026-04-12 | 1.4 | Chromecast premature track cutoff and screensaver fixes |
| 2026-06-10 | 1.5 | All Tracks flat view, system back navigation, scroll optimization |
| 2026-07-04 | 1.6 | Song search scoped to the current folder subtree |
| 2026-07-21 | 1.7 | Song-only track titles with tap-for-details dialog |
From Folder Picker to Folder Browser
The original app used the Storage Access Framework: pick a folder through the system dialog, play what’s in it. That worked, but it made browsing a library feel like filling out paperwork. A late-January overhaul replaced it entirely:
- MediaStore instead of SAF — the user grants
READ_MEDIA_AUDIOonce, and the app discovers every folder containing music, complete with album art thumbnails. The SAF folder picker was removed outright. - Hierarchical tree navigation — instead of a flat folder list, the browser now works like a file explorer. Each level shows only its immediate children, with track counts displayed as “X tracks” or “X tracks in subfolders,” and the browse path persists across app restarts.
- Human-friendly names — raw storage paths are translated for display:
emulatedbecomes “Internal Storage,” a hex volume ID like51ED-A7DCbecomes “SD Card,” and numeric multi-user IDs are replaced with actual user profile names viaUserManager. The top bar shows a readable path like “SD Card > Music” instead of the raw volume path. - Pull-to-refresh on both folder and track lists, for when the library changes underneath the app.
Taming Large Libraries
Two later releases tackled the problem of libraries with lots of folders:
All Tracks flat view (v1.5). An iTunes library of purchased singles tends to produce hundreds of folders containing one track each — miserable to navigate as a tree. When a folder subtree contains five or more single-track leaf directories, an “All Tracks (N)” chip now appears that collapses every leaf-folder track into one sorted list showing artist, title, and duration. Tapping a track loads the whole list as a playlist. The folder view remains the default; the flat view is opt-in.
Scoped song search (v1.6). A search icon in the top bar filters by title, artist, or album — but results are bounded to the folder subtree currently being browsed rather than the whole library, so searching inside “Classical” doesn’t surface your podcast archive.
UI Polish
The interface picked up refinements throughout:
- Unplayable format handling — files Android’s MediaPlayer can’t handle (WMA, DRM-protected M4P) show a circle-slash icon in place of the play button, while previous/next still work to skip past them.
- System back button — back now navigates up the folder tree, or from the track list to the folder browser, and only exits the app at the tree root.
- Shuffle indicator — the shuffle icon is bright yellow when active and dark grey when inactive, in both portrait and landscape layouts.
- Scroll jank fix — large scroll jumps (shuffle landing on a distant track) use an instant
scrollToItem, while small sequential hops (previous/next) animate, eliminating multi-pass layout jank on large playlists. - About dialog — added with app info and external links, made scrollable in landscape, with proper back navigation between its sub-dialogs, improved text contrast, and an instrumented test to keep it honest.
The v1.7 release, out today, addresses a long-standing readability niggle: files named in the common “artist - album - song” pattern used to display that entire string in the track list. The filename is now parsed — pure companion functions with JVM unit tests — and only the song title appears in the track list, All Tracks view, search results, and Now Playing. Tapping the Now Playing title opens a dialog with cover art and the full artist/album/song details, which dismisses on tap or after ten seconds.
Distribution and Housekeeping
The app is now distributed as a signed APK through GitHub Releases, with a release workflow, installation documentation, and translations added along the way. The build itself was kept current too: AGP 9.0, Gradle 9.1, and JVM target 17. An April fix resolved Chromecast tracks cutting off prematurely and the screensaver interrupting playback.
A Note on the Co-Authors
One quiet detail in the git history: the commit trailers trace the Claude model lineup across the year. The January folder browser work was co-authored by Claude Opus 4.5, the June flat-view release by Claude Sonnet 4.6 with 1M context, July’s scoped search by Claude Sonnet 5, and today’s track-title release by Claude Fable 5. Same app, same collaboration pattern — four generations of assistant.