# Dewemoji APK Companion Runbook This is the single guide for APK build, release, direct distribution, and versioning. ## 1) Scope The Android companion uses: - local bundled UI (`dewemoji-capacitor/src` -> `dewemoji-capacitor/www`) - native floating bubble launcher (copy/search workflow) - direct APK update via hosted `version.json` The bubble is not an IME and does not perform direct cross-app insertion. ## 2) Prerequisites 1. Node.js `20+` 2. JDK `17` 3. Android SDK / Android Studio 4. `adb` 5. optional signing toolchain (`apksigner`) Install deps once: ```bash cd /Users/dwindown/Developments/dewemoji npm --prefix dewemoji-capacitor install ``` ## 3) Source and build model Do not edit `dewemoji-capacitor/www/*` directly. - edit source in `dewemoji-capacitor/src/*` - generate runtime assets via: ```bash npm --prefix dewemoji-capacitor run build ``` ## 4) Debug build and device install ```bash cd /Users/dwindown/Developments/dewemoji npm --prefix dewemoji-capacitor run build cd dewemoji-capacitor npx cap sync android cd android ./gradlew assembleDebug adb install -r app/build/outputs/apk/debug/app-debug.apk ``` ## 5) Release build From repo root: ```bash ./scripts/apk/build-release.sh ``` Script behavior: 1. read `versionCode` and `versionName` from `android/app/build.gradle` 2. rebuild web assets 3. run `cap sync android` 4. build release APK 5. sign if signing env vars are present 6. output artifact under `dewemoji-capacitor/dist/apk/` Output naming: - `dewemoji-v{versionName}-{versionCode}.apk` ## 6) Signing env (optional but recommended) ```bash export ANDROID_KEYSTORE_PATH="/absolute/path/release.jks" export ANDROID_KEYSTORE_PASSWORD="..." export ANDROID_KEY_ALIAS="..." export ANDROID_KEY_PASSWORD="..." ``` ## 7) Direct release to Cloudflare R2 Required env: ```bash export R2_ACCOUNT_ID="..." export R2_ACCESS_KEY_ID="..." export R2_SECRET_ACCESS_KEY="..." export R2_BUCKET="dewemoji-downloads" export R2_PUBLIC_BASE_URL="https://downloads.dewemoji.com" ``` Canonical update URLs used by app updater: - `https://dewemoji.com/downloads/version.json` - `https://dewemoji.com/downloads/dewemoji-latest.apk` Publish: ```bash ./scripts/apk/publish-r2.sh \ --apk dewemoji-capacitor/dist/apk/dewemoji-v1.1.2-112.apk \ --version-name 1.1.2 \ --version-code 112 \ --min-supported-version-code 100 \ --notes "Bug fixes and update UX improvements" \ --force false ``` Verify: ```bash ./scripts/apk/verify-release.sh --base-url https://dewemoji.com/downloads ``` ## 8) Versioning rules 1. `versionCode` must increase on every release. 2. `versionName` is user-facing label; ordering uses `versionCode`. 3. upload APK first, then publish/update `version.json`. 4. never compare update order using `versionName`. Expected `version.json` fields: - `versionName` (string) - `versionCode` (number) - `apkUrl` (string) - `notes` (optional) - `force` (optional bool) ## 9) Rollback 1. keep old versioned APK objects immutable 2. repoint latest artifact (`dewemoji-latest.apk`) to known good version 3. republish matching `version.json` 4. rerun verify script ## 10) High-value troubleshooting ### `cap sync android` failures ```bash npm --prefix dewemoji-capacitor install cd dewemoji-capacitor npx cap sync android ``` ### Bubble not appearing 1. confirm overlay permission 2. confirm notification permission (Android 13+) 3. remove OEM battery restrictions ### APK still shows old UI Rebuild assets, sync, and reinstall debug APK. ## 11) Key files - `dewemoji-capacitor/src/index.html` - `dewemoji-capacitor/src/app.css` - `dewemoji-capacitor/src/app.js` - `dewemoji-capacitor/android/app/build.gradle` - `dewemoji-capacitor/android/app/src/main/java/com/dewemoji/app/MainActivity.java` - `dewemoji-capacitor/android/app/src/main/java/com/dewemoji/app/OverlayBubbleService.java` - `dewemoji-capacitor/android/app/src/main/java/com/dewemoji/app/plugins/DewemojiOverlayPlugin.java` - `scripts/apk/build-release.sh` - `scripts/apk/publish-r2.sh` - `scripts/apk/verify-release.sh`