# Android App Update Flow ## Overview The app checks for updates itself via the **App settings** dialog. When a newer version is available, the user can download and install it directly from within the app. No Play Store is involved. ## Key Files | File | Role | |---|---| | `app/Http/Controllers/AppVersionController.php` | Serves `/app/version` JSON with current `versionCode`, `versionName`, and `apkUrl` | | `storage/app/public/apk/timebank-cc-{version}.apk` | APK served to users | | `scripts/deploy-apk.sh` | Uploads APK to server and patches the version controller | | `AndroidStudioProjects/Timebankcc/app/build.gradle.kts` | Android version numbers | ## How the In-App Update Check Works 1. User opens **App settings → Check for updates** 2. App fetches `https://timebank.cc/app/version` — returns: ```json { "versionCode": 4, "versionName": "1.0.2", "apkUrl": "https://timebank.cc/storage/apk/timebank-cc-1.0.2.apk" } ``` 3. If `serverVersionCode > BuildConfig.VERSION_CODE`, the **Download and install** button appears 4. User taps it — the APK is downloaded to the app's internal cache dir and the system installer is launched 5. Android asks the user to confirm installation (`REQUEST_INSTALL_PACKAGES` permission required) ## Release Process ### Step 1 — Bump version in Android Studio In `app/build.gradle.kts`: ```kotlin versionCode = 5 // increment by 1 each release versionName = "1.0.3" // semantic version shown to users ``` ### Step 2 — Build a signed APK **Build → Generate Signed Bundle / APK → APK → release** Output: `app/release/app-release.apk` ### Step 3 — Copy to local storage folder Rename and place in the local APK folder: ```bash cp ~/AndroidStudioProjects/Timebankcc/app/release/app-release.apk \ storage/app/public/apk/timebank-cc-1.0.3.apk ``` The filename must follow the pattern `timebank-cc-{versionName}.apk`. ### Step 4 — Deploy to server ```bash bash scripts/deploy-apk.sh ``` The script: - Picks the most recently modified `timebank-cc-*.apk` from `storage/app/public/apk/` - Derives `versionName` from the filename - Auto-increments `versionCode` if the version name has changed - SCPs the APK to `/var/www/timebank_cc/storage/app/public/apk/` on the server - Patches `$versionCode` and `$versionName` in `AppVersionController.php` on both the server and locally ## Version Number Rules - `versionCode` — integer, must increase with every release. The app compares this to decide whether an update is available. The deploy script increments it automatically. - `versionName` — human-readable string shown in the App settings dialog (e.g. `1.0.3`). Derive the APK filename from this. ## APK Storage - **Local**: `storage/app/public/apk/` (symlinked to `public/storage/apk/`) - **Remote**: `/var/www/timebank_cc/storage/app/public/apk/` - **Public URL**: `https://timebank.cc/storage/apk/timebank-cc-{versionName}.apk` Old APK files can be kept or deleted — only the filename referenced by `AppVersionController` is served to users. ## Permissions Required (AndroidManifest.xml) ```xml ``` This allows the app to launch the system installer for the downloaded APK. ## Troubleshooting **"Download failed — please try again"** - Check that the APK filename in `AppVersionController.php` exactly matches the file in `storage/app/public/apk/` - Verify the file is publicly accessible: `curl -I https://timebank.cc/storage/apk/timebank-cc-{version}.apk` - APK is saved to `cacheDir` (internal) — no storage permission needed **Update not offered to users** - Confirm `versionCode` on the server is higher than the `versionCode` baked into the installed APK (`BuildConfig.VERSION_CODE`) - Check `/app/version` response: `curl https://timebank.cc/app/version` **Users not seeing the update without checking manually** - By design — the check is manual via App settings. There is no background polling.