Skip to content

v0.1.1 (debug build)

Pre-release
Pre-release

Choose a tag to compare

@sultanmaliki sultanmaliki released this 21 Sep 03:20
· 17 commits to main since this release

Second sideloadable build (debug-signed APK; enable "install from unknown sources"). Everything below is a change since v0.1. Verified on one Xiaomi/HyperOS device (Android 16) plus 41 JVM unit tests and clean lint. Gestures, the file-picker screens and HyperOS Island display were not machine-testable (MIUI blocks injected input) and still need hands-on checking.

Fixes: playback and queue

  • Media playback works. Root cause of "unable to play any media": the playback service granted empty command sets to the UI, so every play/load command was silently denied. Commands are now granted explicitly. Also fixed: the controller being released right after connecting, and a launch crash caused by a missing notification-button icon.
  • Real playlist queue. The player now owns the whole queue, so next / previous / auto-advance to the next track work. Previously only one item was ever loaded, so the notification had no Next button and tracks never advanced.
  • Notification controls: Previous, Play/Pause, Next, and a Pause/Resume timer button. The timer button label now stays in sync when you toggle the timer from the screen (it used to go stale).
  • Survives UI recreation (dark mode, font size, language change): the UI re-syncs from the player instead of showing "no media" over playing audio.
  • Unplayable files are skipped. A deleted/moved/unreadable file shows "Can't play this file" and moves on instead of leaving a black screen.
  • Tapping play/pause after a track ends restarts it (was a no-op).

Gym-use improvements

  • Screen stays on while the app is open.
  • Audio focus (calls and other apps pause playback), pauses when headphones are unplugged, and a wake lock so local playback doesn't stutter with the screen off (new WAKE_LOCK permission).
  • Timer survives the app being killed (HyperOS kills background apps aggressively). A running timer is resumed with the time that passed; if it was saved more than 12 hours ago it is restored paused instead.

Bug fixes found by testing

  • Timer digits used the phone's locale, so Arabic-locale phones would show Arabic-Indic digits. Now always 00:00:00 Latin digits.
  • Negative values formatted as garbage; negative countdown targets are clamped to zero.
  • Playlist saving is now atomic (a crash mid-save could have wiped all playlists); a corrupt playlist file is kept as playlists.json.corrupt instead of being overwritten.
  • Picking files from a provider that refuses persistent access no longer crashes the app.
  • Deleting a playlist releases file permissions no other playlist uses (Android caps how many an app can hold).
  • Huge embedded cover art could crash the app with out-of-memory; it is now decoded at a bounded size.
  • Lint errors fixed (wrong error constant for unsupported custom commands, missing opt-in markers).

Performance

  • Timer text updates once per displayed second and is drawn without recomposing the whole screen (was 10 recompositions/second).
  • Equalizer animates only while media is playing, and animates without per-frame layout.
  • Ambient background colour is sampled from a 128px frame instead of a full-size video frame (a 4K frame is ~33 MB).
  • Drag-to-scrub seeks are throttled to ~10/second (the last position is always applied).
  • The gesture handler no longer restarts on unrelated state changes (which cancelled in-flight gestures and forgot a pending double-tap).
  • Measured on device: p50 11 ms, p99 15 ms frame time during video + timer.

Security

  • The media service is exported so system UI and Bluetooth can reach it, but it previously accepted any app as a controller. It now only accepts this app, the system media notification, and system-trusted controllers.
  • The debug launch hooks (debug_media_uris, debug_timer_start) only work in debuggable builds, so other apps cannot inject media through the exported activity.
  • allowBackup disabled so playlist data isn't included in device backups.

Tests and tooling

  • 41 JVM unit tests (timer engine, snapshot/restore, tick scheduling, scrub throttling, playlist storage, image sample sizing); lint clean; clean debug and release builds. Logs are in test-logs/.

Known limitations

  • Debug-signed: fine for your own phone, not for Play Store. Updates install over v0.1 only if signed with the same debug key (same build machine); otherwise uninstall first.
  • A countdown that finishes while the app is in the background is only noticed when you return (no background alarm yet).
  • The equalizer is a decorative animation, not audio-reactive (that would need the microphone permission).
  • Android limits persisted file permissions per app; the app doesn't warn you when you approach the limit.
  • Not verified: gesture behaviour after these changes, the file-picker screens, headphone-unplug pause, and whether HyperOS shows the notification in the Island.

Full diff: v0.1...v0.1.1