Standard Gradle/Android project. See ARCHITECTURE.md for architecture and
RELEASE.md for the full build/release process.
- JDK 17+ (JDK 21 works).
- Android SDK via
ANDROID_HOME(set here to~/Android/Sdk) orsdk.dirinlocal.properties. ./gradlewwrapper;adbat/usr/bin/adb; the emulator binary is at$ANDROID_HOME/emulator/emulator(not on PATH).
- Distribution flavors:
play,fdroid,website,huawei.playandfdroidare the Firebase-enabled variants (firebaseEnabledVariantsinapp/build.gradle.kts): both include Firebase Cloud Messaging for push, but exclude firebase core/analytics/measurement.huaweiuses HMS push;websiteuses no-op push wiring.
- Build types:
debug,release,releaseWithDebugMenu,qa,automaticQa. - CI (
.github/workflows/build_and_test.yml) builds theqatype across all flavors plus atestjob.
./gradlew :app:assemblePlayDebug # build APK only (no device needed)
./gradlew :app:installPlayDebug # build + install to a running device/emulatorHuawei builds need the flag, e.g. ./gradlew assembleHuaweiDebug -Phuawei.
Available AVDs ($ANDROID_HOME/emulator/emulator -list-avds) include
Pixel_6_API_33. Start one detached, then install:
"$ANDROID_HOME/emulator/emulator" -avd Pixel_6_API_33 &
adb wait-for-device # then poll sys.boot_completed
./gradlew :app:installPlayDebugAfter install, confirm the package id (it is suffixed per flavor/build type):
adb shell pm list packages | grep loki, then launch it.
app/src/main/res/values*/strings.xml and NonTranslatableStringConstants.kt
are generated from Crowdin — do not hand-edit them. Text changes are made in
Crowdin and synced in by the session-foundation/session-shared-scripts
pipeline. See ARCHITECTURE.md §13 (Localization and Translations) for the full
flow, the approved-only export gate, and the ordering to ship a text change.
master= production;dev= integration branch; PRs targetdev.- Crowdin translation PRs land on branch
feature/update-crowdin-translations→dev.