New app: SPRAWL//RUN

Required

  • The app complies with the inclusion criteria
  • The original app author has been notified (and does not oppose the inclusion) — I am the author.
  • All related fdroiddata and RFP issues have been referenced in this merge request — no RFP issue exists; this is a self-submission.
  • Builds with fdroid build and all pipelines pass — I cannot run fdroid build locally (no buildserver available), so I am relying on the CI pipeline. See "Local verification" below for what I did check.
  • There is an issue tracker and contact info of the author so that we can report bugs and contact the author.
  • The upstream app source code repo contains the app metadata in a Fastlane folder structure — fastlane/metadata/android/en-US/ with title, short and full description, changelogs for versionCode 1 and 2, icon and seven phone screenshots. No Summary/Description is set in fdroiddata.
  • Releases are tagged and auto update is enabled — UpdateCheckMode: Tags, AutoUpdateMode: Version, with UpdateCheckData pointed at pubspec.yaml since a Flutter app keeps its versionCode there rather than in build.gradle.kts.

Suggested

  • External repos are added as git submodules instead of srclibs — using the flutter srclib rather than vendoring the SDK. srclibs: flutter@stable, with the exact version pinned in the app repo's .fvmrc and checked out in prebuild, so the build is deterministic without the app repo carrying a Flutter checkout.
  • Reproducible Builds — not enabled for this first submission, so please sign with the F-Droid key. I understand this is one-way and that I cannot enable it later.
  • Multiple apks for native code — one universal APK, 56 MB. Deliberate: a single artifact and a single versionCode. Glad to split per ABI with VercodeOperation if you would rather.

About the app

SPRAWL//RUN is an offline running tracker built around a ten-mission cyberpunk audio story. MIT licensed. No accounts, no analytics, no ads.

Google Play Services

geolocator_android declares com.google.android.gms:play-services-location. The app module excludes the whole com.google.android.gms group from its configurations (android/app/build.gradle.kts) and sets forceLocationManager: true so the AOSP LocationManager is used directly. geolocator supports this explicitly — its client selection catches NoClassDefFoundError with the comment "This might happen when the GMS package has been excluded by the app developer due to its proprietary license".

Verified on the 0.2.0 release APK: 1918 classes defined in the dex, zero under com/google. The scanner may still flag the declaration in the transitive pub dependency; the exclusion is what makes it moot at build time. android/app/proguard-rules.pro exists only to -dontwarn the references this leaves dangling.

Network

No INTERNET permission. The merged manifest carries two permissions the app does not request directly:

  • ACCESS_NETWORK_STATE, merged in by ExoPlayer via just_audio. Reads connectivity status; grants no network access.
  • io.github.jbinder.sprawlrun.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION, self-defined by share_plus so only this app can receive its own share-result broadcast.

Without INTERNET, nothing here can reach the network regardless.

Backup and restore

share_plus and file_selector back the export/import feature in Settings → Data. Export hands a JSON file to the system share sheet; import reads one back through the SAF document picker. No storage permission is requested in either direction.

Assets

All sound effects and launcher icons are generated from source by scripts in tool/ (tool/gen_sfx.dart, tool/gen_icons.dart). The only third-party binaries in the repo are three SIL Open Font License typefaces in assets/fonts/, with their licence texts alongside them.

Local verification

Since I cannot run fdroid build, I reproduced what the buildserver does as closely as I could:

  • Built with android/key.properties absent, which is its state on the buildserver since it is gitignored. apksigner verify reports DOES NOT VERIFY / missing META-INF/MANIFEST.MF, and the APK contains no signature blocks — so the artifact arrives unsigned, ready for your key.
  • APK versionCode (2) matches pubspec.yaml.
  • aapt2 dump permissions confirms no INTERNET.
  • dexdump confirms zero classes under com/google.
  • flutter analyze clean, 151 tests passing.

The build recipe follows templates/build-flutter.yml (srclib variant) and is modelled on the current entries in metadata/com.sidhant.wallet.yml, which pins the same flutter@3.44.8. ndk: 28.2.13676358 is NDK r28c, already used by other apps here.

Edited by Johannes Binder

Merge request reports

Loading
Loading