Unit Tests / test (pull_request) Successful in 15s
Capacitor appName and Android string resources (plus docs) now show Hesychia so the mobile shell matches the product rebrand when this wrap lands.
132 lines
3.2 KiB
Markdown
132 lines
3.2 KiB
Markdown
# 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`) |
|