Android Setup
This page consolidates the Android build notes that were previously spread across repo notes.
App locations
- Mobile POS app:
apps/mobile - POS terminal app:
apps/pos-terminal
Common commands
Run these from the monorepo root:
yarn mobile:start
yarn mobile:android
yarn mobile:apk
yarn mobile:aab
yarn terminal:start
yarn terminal:android
Run Mobile and Terminal on two Android devices
When two Android devices are connected at the same time, target each command at
the intended device with ANDROID_SERIAL.
List the connected device serials first:
adb devices
Example:
List of devices attached
R58M123456A device
ZY22ABCDE9 device
Run Mobile POS on one device and POS Terminal on the other from separate terminals:
ANDROID_SERIAL=R58M123456A yarn mobile:android
ANDROID_SERIAL=ZY22ABCDE9 yarn terminal:android
If React Native still targets the wrong device, pass the device id directly to the workspace script:
yarn workspace @bsr/mobile android --deviceId R58M123456A
yarn workspace @bsr/pos-terminal android --deviceId ZY22ABCDE9
For normal install/run work, ANDROID_SERIAL is enough. If both apps need Metro
running at the same time, avoid using the same Metro port for both apps. Keep
one app on the default 8081, run the other on a separate port such as 8082,
and reverse ports per device:
adb -s R58M123456A reverse tcp:8081 tcp:8081
adb -s ZY22ABCDE9 reverse tcp:8082 tcp:8082
Run these from inside the mobile app when direct Gradle access is needed:
cd apps/mobile/android
./gradlew clean assembleRelease
./gradlew clean bundleRelease
Run these from inside the mobile app to install a release APK that has already been built:
cd apps/mobile
yarn install:app
Required local tooling
- Node.js version compatible with
>=22.11.0 - Yarn Classic
1.22.x - Java with
JAVA_HOMEpointing to a valid JDK - Android SDK installed and reachable from Gradle
- Android build-tools and platform SDK required by the project
- Android NDK version expected by Gradle
adbavailable inPATH
Release signing inputs
Both Android apps read release signing values from Gradle properties:
MYAPP_UPLOAD_STORE_FILEMYAPP_UPLOAD_STORE_PASSWORDMYAPP_UPLOAD_KEY_ALIASMYAPP_UPLOAD_KEY_PASSWORD
Verify where these values come from on each machine:
~/.gradle/gradle.properties- project
gradle.properties - CI/CD secret injection
APK install signature mismatch
If yarn install:app fails with:
INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package th.co.boonsiri.pos signatures do not match newer version
the device already has th.co.boonsiri.pos installed with a different signing
key. Android will not update an installed app with an APK signed by another
key.
For local testing, uninstall the existing app first, then install again:
cd apps/mobile
yarn clear:app
yarn install:app
This removes the app data on that device or emulator. If app data must be kept, build the APK with the same signing key as the version already installed.
React Native core upgrade notes
When upgrading React Native core, use React Native Upgrade Helper as the baseline template diff, for example:
https://react-native-community.github.io/upgrade-helper/?from=0.84.1&to=0.85.2
Do not copy template files over this repo blindly. The mobile app has
repo-specific native configuration that must be preserved, including monorepo
paths in android/app/build.gradle, explicit Node/Hermes paths,
react-native-vector-icons font linking, Firebase Google Services, release
signing, app versioning, and the Reanimated/Worklets Gradle task workaround.