Unit Tests / test (pull_request) Successful in 12s
Document sync, debug/release Gradle builds, signing, and internal-testing upload so the native project folder is self-contained for release work.
AI ML Chat — 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.
Prerequisites
- Node.js 20
- JDK 17+
- Android Studio with SDK Platform 35
ANDROID_HOMEset, or open this folder once in Android Studio (writeslocal.properties)
Build the web bundle and sync
From the npm root (llm-fe/, one level up):
cd ..
npm ci
npm run build:mobile # .env.mobile → react-scripts build → cap sync android
Open this project in Android Studio:
npm run android:open
# or: npx cap open android
Re-sync after changing web code (with an existing build/):
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
- Sync Gradle when prompted.
- Pick an emulator or USB device (enable USB debugging).
- Run app.
CLI (debug APK)
./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.
- Create an upload keystore (once), outside the repo:
keytool -genkey -v -keystore ~/Documents/secrets/aiml-chat-upload.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias aiml-chat-upload
- Create
keystore.propertiesin this directory (android/, gitignored):
storeFile=/absolute/path/to/aiml-chat-upload.jks
storePassword=REPLACE_ME
keyAlias=aiml-chat-upload
keyPassword=REPLACE_ME
- Build a signed App Bundle:
./gradlew bundleRelease
Output:
app/build/outputs/bundle/release/app-release.aab
Signed APK (if needed):
./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
- Play Console → app AI ML Chat (
com.aimloperations.chat). - Complete store listing: privacy policy URL, data-safety form, screenshots.
- Testing → Internal testing → create release → upload
app-release.aab. - Add testers, roll out internal track, verify on devices.
- 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 | AI ML Chat |
| Min / target SDK | 23 / 35 (see variables.gradle) |