The Android app updates itself from our Gitea releases; feed cards fade in instead of bouncing

- API: GET /app/android/latest reads the latest Gitea release (ANDROID_RELEASES_URL, optional token for a
  private repo) with the APK's SHA-256 from SHA256SUMS; GET /app/android/apk/:name streams that APK.
- App (modules/updater): downloads in the background, checks the SHA-256, and installs through
  PackageInstaller: quietly once when leaving the app (Android 12+), otherwise from the feed banner or
  Settings > App version. F-Droid builds leave it out and drop the install permissions.
- CI: the release notes come from the fastlane changelog; the app shows the part above ---.
- Settings: Create-account and Link Spotify buttons for Last.fm and ListenBrainz.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 12:34:04 -04:00
co-authored by Claude Opus 5.5
parent 804493aee0
commit 5cbde5e7f9
29 changed files with 901 additions and 11 deletions
+26
View File
@@ -70,6 +70,32 @@ that release's files.
**Test builds:** go to **Actions > Android > Run workflow** and pick a branch. The APKs go to the
repo's **Packages** as `musicshare-android`, versioned `<branch>-<commit>`, instead of to a release.
## App updates
The normal APK updates itself from these releases; the F-Droid build doesn't (F-Droid updates it).
1. The app asks our server (`GET /app/android/latest`) when it opens, at most every 6 hours, or when you
tap **Settings > Check for updates**.
2. The server reads the latest release from Gitea and returns its version, the APK's SHA-256 (from
`SHA256SUMS`) and the release notes. Drafts and pre-releases are skipped.
3. If it's newer, the app downloads the APK through our server and checks the SHA-256.
4. The next time you leave the app, it tries a quiet install (once per version). Android 12+ allows that
after the app has installed one update itself. Otherwise the feed shows **Update ready**, and tapping it
opens Android's install screen; the first time, Android asks you to allow musicshare to install apps.
On phones with Google Play, Play Protect may ask to scan each new version ("App scan recommended")
because the app isn't from the Play Store. Choosing **Scan app** lets the update finish.
Set these on the API server (`deploy/production.env`):
```ini
ANDROID_RELEASES_URL=https://gitea.chrisedwards.tech/api/v1/repos/chris/musicshare/releases/latest
# Only while the repo is private: a token with read:repository (User settings > Applications).
ANDROID_RELEASES_TOKEN=
```
The release notes come from `fastlane/metadata/android/en-US/changelogs/<versionCode>.txt`: the workflow
puts that text above a `---` line in the release, and the app shows only that part.
## Building by hand
```bash