Repository navigation
Build from Source
| Tool | Version |
|---|---|
| JDK | 17 |
| Android SDK | platform 36 and build tools |
| Android NDK | 27.1.12297006 |
| Flutter SDK | The build goes through Flutter because the APK carries the Flutter engine that reads the previous version's data once |
| Dart | comes with Flutter |
For the optional offline-speech engine rebuild you also need Rust with the aarch64-linux-android target, cargo-ndk and CMake.
git clone https://github.com/roadstrapp/roadstr-app.git
cd roadstr-app
flutter pub get
flutter gen-l10n # the ARB files are the source of every translation
flutter build apk --release # debug: flutter runOnly the Kotlin side and one ABI:
cd android && ./gradlew :app:assembleRelease -Ptarget-platform=android-arm64The Kotlin launcher is the default. -Pnative_launcher=false builds the old Flutter launcher instead, to compare the two.
A signed release uses android/key.properties (copy android/key.properties.template and fill in the keystore). It is never
committed. Then:
./build_release.shIt builds the four APKs (universal, arm64-v8a, armeabi-v7a, x86_64), checks package, version, certificate, ABIs and 16 KB
page alignment, and writes the SHA-256 sums. It publishes nothing. A release candidate must advance beyond the currently
shipped version code; release tooling and the rollback plan are described in
docs/kotlin-rewrite/RELEASE_TOOLING.md.
Without a keystore Gradle produces an unsigned release rather than disguising a debug-signed one as official.
flutter test # Dart contract tests (resources, build, docs)
cd android && ./gradlew :app:testDebugUnitTest # Kotlin JVM tests (about 1,500 cases)
tools/kotlin_rewrite/audit_android_release.sh --source-only
python3 tools/interop/generate_vectors.py --check # the published road-report test vectors are currentThe Dart tests are contract tests: they pin the generated resources, the build configuration, the manifest permissions, the vendored native binaries and the documents the README links to. A change that drifts from any of them fails.
After editing a translation, regenerate both the Dart classes and the Android resources:
flutter gen-l10n
for g in tools/kotlin_rewrite/generate_android_*_strings.dart; do dart run "$g"; doneSome native libraries are committed so that normal builds stay offline, and each is checked against a SHA-256 before the build
starts (bundledNativeChecksums in android/app/build.gradle.kts):
| Library | Rebuild with |
|---|---|
| eSpeak NG (voice phonemisation), three ABIs | tools/build_espeak_android.sh |
The offline speech engine (libofflinestt_*.so), arm64 only |
third_party/offline-stt-engine/rebuild.sh |
Both rebuild byte for byte from pinned sources.
-
Road-test app (
native-android/): the same Compose shell with its own stores; a separate Gradle project that compiles the shared source directories. Its package (app.roadstr.roadtest) cannot replace the real app. -
In-app browser variant (GeckoView, optional):
native-android/gradlew-geckoview :app:assembleDebug. About 130 MiB bigger (debug build, one ABI), needs Android 8, andnative-android/verify-geckoview-variant.shchecks what must stay true of both builds. It has not been run on a device yet.
See Architecture.
Roadstr is open source under the MIT licence · Source · Releases · Changelog · Issues
Using Roadstr
- Installation
- Getting started
- Navigation
- Maps and offline use
- Search and Explore
- Road reports
- Public transport
- Voice guidance
- Voice search
- Journey and achievements
- Settings reference
Nostr and money
Trust
Build and extend