Skip to content

VeloSpot v1.0.27

Latest

Choose a tag to compare

@github-actions github-actions released this 03 Aug 23:03
d6bcd21

VeloSpot v1.0.27

Added

  • Pause & resume a ride β€” for commuters who hop on a train or ferry mid-way β€” ride recording can now be paused and later resumed, so a daily bike-to-work commute that includes, say, a 30 km train leg (or a ferry crossing) is captured as one ride without the in-between counting. While paused, incoming GPS fixes are discarded so the pause adds no distance and no time, and the elapsed timer freezes and continues exactly where it left off; the first fix after resuming opens a new track segment, so the skipped stretch is stored as a real gap rather than a straight line drawn across it. The gap survives everywhere the track does: it is persisted (and crash-recovered) via a new TrackPoint.segmentStart flag, exported as a separate <trkseg> in the GPX file (the portable, Strava/Garmin-friendly way to store an interruption), and drawn as multiple polyline segments on the map (live and for saved rides) via a pure, JVM-testable List<TrackPoint>.splitIntoSegments(). Pause/resume is reachable from every recording surface: the live map overlay, the ongoing notification, the home-screen widget, the quick-settings tile, and the navigation screen (the recording pauses while the route guidance keeps running). Covered by RideTrackerTest, GpxWriterTest and TrackSegmentsTest. Localised across all eight supported languages.

Changed

  • Drop the F-Droid product flavor β€” VeloSpot is now a single Google Play build β€” the distribution flavor dimension (fdroid / googlePlay) is removed. The app builds one unbundled variant that uses Google Play Services' FusedLocationProviderClient for location (the previous LocationManager-based F-Droid LocationRepositoryImpl / LocationModule are gone). The flavor-specific src/googlePlay/… sources moved into src/main/…, play-services-location is now a plain implementation dependency, and all tooling that was pinned to a flavor was retargeted to the plain variant: Kover (koverXmlReportDebug), the CycloneDX SBOM (releaseRuntimeClasspath), and the CI/lint workflows (assembleDebug, testDebugUnitTest, lintDebug). The F-Droid-only reproducibility vcsInfo { include = false } block was dropped (the AGP dependency-metadata block is still kept out of the APK). Docs (README, CONTRIBUTING, RELEASING, ATTRIBUTIONS, SCREENSHOTS) updated accordingly.
  • Automated Google Play release β€” signed AAB + fastlane upload from CI β€” release.yml now builds a signed App Bundle (bundleRelease) alongside the sideload APK and, on a vX.Y.Z tag, uploads the AAB plus the store listing and per-version "What's New" changelogs (fastlane/metadata/android) to Google Play via fastlane supply (new Gemfile, fastlane/Appfile, fastlane/Fastfile). The upload runs only when the PLAY_SERVICE_ACCOUNT_JSON secret is set and defaults to the production track with draft status (the release is staged in the Play Console for a final manual "Publish"); a manual Run workflow lets you pick the track (internal/alpha/beta/production) and status. The GitHub Release now attaches the AAB and the universal APK (VeloSpot-vX.Y.Z.apk) instead of two flavor APKs.
  • Bike paths are now preferred over gravel tracks (trekking.brf, shortest.brf, PROFILES_VERSION 11 β†’ 12) β€” a rider reported that the trekking profile (the default for ordinary riders on a normal bike) picked a gravel track (Schotterweg) even though a dedicated cycleway (Fahrradweg) ran only a few metres away. Both profiles now detect gravel / loose unpaved surfaces (surface=gravel|pebblestone|rock|unpaved|ground|dirt|earth|mud|sand) and add a surcharge to such tracks, so a proper bike path β€” or a paved way β€” clearly wins, while the gravel track stays usable when there is no reasonable alternative. The shortest profile previously ignored the surface entirely (every way cost the same), so it crossed gravel whenever it was marginally shorter; it now applies the same surcharge. The fastbike profile already priced unpaved tracks well above a cycleway and is left unchanged. PROFILES_VERSION is bumped so the updated profiles replace the stale copies in internal storage on existing installs. Covered by a new BRouterGravelAvoidanceTest (which evaluates the real BRouter cost factor and asserts trekking, shortest and fastbike all price a gravel track well above a cycleway), plus the existing BRouterProfileIntegrityTest and BRouterProfileRoutabilityTest.

Fixed

  • Crash when the address search returned duplicate hits β€” searching for a place could crash the app with IllegalArgumentException: Key "…" was already used from the results LazyColumn. The list key was displayName + latitude, which is not unique: Nominatim can return several hits that share the same display name and latitude (e.g. a place plus its administrative boundary), so two rows collided. The results list is ephemeral and never reordered, so AddressSearchBar now keys the LazyColumn by the item index (via itemsIndexed), which is guaranteed unique, and draws the row divider using index < results.lastIndex.

πŸ“₯ Artifacts

File Description
VeloSpot-v1.0.27.apk Universal APK, ready to sideload
app-release.aab Android App Bundle (uploaded to Google Play)
VeloSpot-v1.0.27-sbom.cdx.json / .xml CycloneDX SBOM – full dependency + license inventory

πŸ” Supply-chain verification

All release artifacts ship with signed build provenance attestations.
Verify any downloaded file with the GitHub CLI:

gh attestation verify VeloSpot-v1.0.27.apk --repo drzeeb/VeloSpot

Installation (sideload)

  1. Download the APK below.
  2. On your Android device: Settings β†’ Apps β†’ Install unknown apps β†’ allow your browser or file manager.
  3. Open the APK and tap Install.