Skip to main content

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_HOME pointing 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
  • adb available in PATH

Release signing inputs

Both Android apps read release signing values from Gradle properties:

  • MYAPP_UPLOAD_STORE_FILE
  • MYAPP_UPLOAD_STORE_PASSWORD
  • MYAPP_UPLOAD_KEY_ALIAS
  • MYAPP_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.