# Hesychia — Android Native Capacitor project for `com.aimloperations.chat`. Web UI comes from the CRA `build/` output in the parent `llm-fe/` package (synced with `npx cap sync`). Broader Capacitor notes (env files, icons, QA): [`../ANDROID.md`](../ANDROID.md). ## Prerequisites - Node.js **20** - JDK **17+** - [Android Studio](https://developer.android.com/studio) with SDK Platform **35** - `ANDROID_HOME` set, or open this folder once in Android Studio (writes `local.properties`) ## Build the web bundle and sync From the **npm root** (`llm-fe/`, one level up): ```bash cd .. npm ci npm run build:mobile # .env.mobile → react-scripts build → cap sync android ``` Open this project in Android Studio: ```bash npm run android:open # or: npx cap open android ``` Re-sync after changing web code (with an existing `build/`): ```bash npm run android:sync ``` Backend URLs are baked in at web-build time via `../.env.mobile` (prod by default). ## Run on a device / emulator ### Android Studio 1. Sync Gradle when prompted. 2. Pick an emulator or USB device (enable USB debugging). 3. Run **app**. ### CLI (debug APK) ```bash ./gradlew assembleDebug adb install -r app/build/outputs/apk/debug/app-debug.apk ``` ## Version before a store release Edit `app/build.gradle` → `defaultConfig`: | Field | Rule | |-------|------| | `versionName` | User-visible string; keep in sync with `../package.json` `version` | | `versionCode` | Integer; **must increase** for every Play upload | ## Sign a release build **Do not commit keystores or passwords.** 1. Create an upload keystore (once), outside the repo: ```bash keytool -genkey -v -keystore ~/Documents/secrets/aiml-chat-upload.jks \ -keyalg RSA -keysize 2048 -validity 10000 \ -alias aiml-chat-upload ``` 2. Create `keystore.properties` in **this** directory (`android/`, gitignored): ```properties storeFile=/absolute/path/to/aiml-chat-upload.jks storePassword=REPLACE_ME keyAlias=aiml-chat-upload keyPassword=REPLACE_ME ``` 3. Build a signed App Bundle: ```bash ./gradlew bundleRelease ``` Output: ```text app/build/outputs/bundle/release/app-release.aab ``` Signed APK (if needed): ```bash ./gradlew assembleRelease # → app/build/outputs/apk/release/app-release.apk ``` Without `keystore.properties`, release builds are unsigned; debug builds do not need it. ## Deploy to Google Play 1. [Play Console](https://play.google.com/console) → app **Hesychia** (`com.aimloperations.chat`). 2. Complete store listing: privacy policy URL, data-safety form, screenshots. 3. **Testing → Internal testing** → create release → upload `app-release.aab`. 4. Add testers, roll out internal track, verify on devices. 5. Promote to closed / open / production only after internal QA passes. Each new upload needs a higher `versionCode`. ## Useful Gradle tasks | Task | Purpose | |------|---------| | `./gradlew assembleDebug` | Debug APK | | `./gradlew assembleRelease` | Release APK (signed if props present) | | `./gradlew bundleRelease` | Play Store `.aab` | | `./gradlew clean` | Clean build outputs | ## App identity | | | |--|--| | Application ID | `com.aimloperations.chat` | | Display name | Hesychia | | Min / target SDK | 23 / 35 (see `variables.gradle`) |