Roadstr

app.roadstr
by LWB lwb89@cosanostr.com

Decentralised navigation with Nostr road event reporting and Lightning zaps

Roadstr is a free, open-source navigation app for Android built on decentralised technologies. 🗺️ TURN-BY-TURN NAVIGATION Turn-by-turn routing powered by OpenStreetMap and OSRM. Voice guidance in 27 languages. Speed-limit signs, automatic rerouting, and arrival detection. 📡 NOSTR ROAD EVENTS Report traffic jams, police, accidents, speed cameras, road closures, and road hazards. Events are published to the Nostr network so every driver in the area can see them in real time. Confirm or deny reports from other users. ⚡ LIGHTNING ZAPS Tip the app developers and appreciate good road reports directly with Bitcoin Lightning payments via NIP-57 zaps and NWC wallet connect. 🔒 PRIVACY FIRST No account required. No tracking. No analytics SDKs. No first-party servers — Roadstr talks directly to public Nostr relays, OSM/Overpass, your chosen routing provider, and (for weather) Open-Meteo. This is not an offline app: coordinates or coarse areas reach those services as part of normal operation, never with an account or persistent identifier attached, and nothing is collected by Roadstr itself. Road events are published pseudonymously under your Nostr public key, with an exact position and timestamp attached — pseudonymous, not anonymous. Saved places and parking stay on-device unless you explicitly export or sync them. 🔑 NOSTR IDENTITY Log in with your existing Nostr private key (nsec) or via Amber (NIP-55 external signer). Your keypair is stored encrypted on-device. 🌍 OPEN SOURCE Roadstr is fully open source (MIT). Source code: https://github.com/roadstrapp/roadstr-app FEATURES • Turn-by-turn voice navigation (27 languages) • OpenStreetMap tiles with custom tile URL support • Speed-adaptive zoom during navigation • Automatic rerouting when off-route • Real-time road event markers with category TTLs • Favourite places for quick navigation • Search history • GraphHopper, OSRM, and OpenRouteService backends • Walking and driving modes • Place info with Wikipedia integration • NIP-40 event expiration • ZTL / restricted zone awareness via OSM data • Compass with magnetometer and gyroscope • No Google Play Services required (falls back to Android LocationManager)

First release: Jun 28, 2026, 50 total releases.

Most recent release: Nov 11, 2026.

Repo

Appears in 4 app stacks.

8,705 sats / 10 zaps received in the past year.

Sats Received

Underlying data available via MCP: app_zaps, app_releases.

Zap Count

Underlying data available via MCP: app_zaps, app_releases.

Releases

  • Nov 11, 2026 1.3.0
    Roadstr 1.3.0 — full changelog below. Signed with the official release key; APKs are per-ABI (arm64-v8a is right for almost every phone since 2016) plus a universal one. ### Changed - **One road-event format, shared with Roadbeacon.** Reports and votes follow [nips/road-events.md](https://github.com/jooray/roadbeacon/blob/main/nips/road-events.md): six-decimal coordinates, no `alt`, two-tag votes, and an `expiration` of `created_at + max(14 days, lifetime)`. Roadstr's own reports already had that layout, so each report is now written once: the optional second copy in the *jooray/roadstr* layout and its settings are gone, and reports in that deprecated layout are no longer shown. - **New MeshCore frame.** A report is 117 bytes plus its comment (at most 46 bytes are written, so a frame never exceeds the 163
    More…
    bytes a companion link carries; up to 48 are read), a vote is a self-contained 134 bytes. The codec runs the shared conformance vectors in `docs/interoperability/vectors/road-events-v1.json`. The old 110-byte frame is not accepted. - **MeshCore datagrams use the allocated `data_type` `0x0150` "Road Events"** ([meshcore-dev/MeshCore#3750](https://github.com/meshcore-dev/MeshCore/pull/3750)), sent and accepted; the development value `0xFF52` is no longer used. The frame bytes are unchanged. - Own reports and votes can go on the radio directly ("Send my reports by radio"); they no longer depend on the compatible copy. - **Votes now decide how long every report stays on the map**, not only the ones heard over the radio. A "still there" keeps a report alive for its category's lifetime counted from the vote (a police report confirmed at hour five is still shown), a "no longer there" ends it at the time of the vote, only a key's latest vote counts, and a report is hidden while the last five minutes hold more denials than confirmations. Nothing is shown past the report's `expiration`. A report older than its category's lifetime is now kept while relays still serve it, so the votes that arrive afterwards can bring it back. - **Bigger speed limit and route line while navigating.** The number on the speed-limit sign is 40% larger; a three-digit limit (100, 110, 130) is measured with the real font and shrunk just enough to stay inside the red ring, whatever the system font scale. The route line (the coloured line, its halo, the grey part already driven, traffic and alternatives) is 20% wider, and every route update now first checks that the route's map layers still exist. ### Added - **MeshCore Open as the radio link (opt-in).** Instead of taking the radio's only Bluetooth connection, Roadstr can use it through MeshCore Open's local API on the same phone (`ws://127.0.0.1:8787/api/v1`), so the chat app keeps working. The pairing key lives in the Android Keystore; Settings shows its fingerprint to compare with MeshCore Open's dialog. What the radio heard while Roadstr was closed is replayed from where it left off. Bluetooth stays the default, and a saved radio is never switched over. ### Fixed - Votes on reports heard over the radio were always rejected, because the vote was expected to repeat the report's position. - A 30-day report heard over the radio (speed camera, police station, surveillance camera) disappeared after 14 days. - A vote heard on the radio before its report waits up to 15 minutes for it, from the radio or a relay, instead of being lost. - A report sent again by a relay (relay rotation, area replay) no longer wipes its votes. - Downloadable maps: Czechia could be selected but every one of its downloads failed, because Geofabrik publishes the Shortbread extract for the whole country and not for its regions. Of the 222 European areas offered, 89 had no file; the list of areas that really have one is now checked into the app (`tools/offline_packages/probe_geofabrik_shortbread.py`), a region without its own file downloads the area that contains it, and Czechia and Slovakia are listed under Eastern Europe. - Downloadable maps: a city is placed by its area's outline, not its bounding box, so Northern Irish towns no longer point at England's file. - The turn-by-turn card no longer covers the list of downloadable maps while navigating. - The road-test build remembers the MeshCore switches across launches. - Offline packages: updating or deleting a package no longer deletes the files of another package whose name merely starts the same way (`italy` and `italy-north`). - Importing the old app's data: the copied workspace is no longer closed and deleted while the snapshot is still being read, and a failure in that step is reported like every other one. ### Security - **Opening a report no longer contacts the reporter's Lightning server.** The zap total of someone else's report used to be looked up on open, which told whoever runs that server (the reporter chooses it) the driver's IP address and the moment they looked. It is now looked up only for your own reports; for other people's it starts at zero and grows with what you zap. Zapping itself still contacts that server, as it must. The README's Privacy section says so. - MeshCore Open's local API is only ever reached directly on this phone (no system proxy, no redirect), and a message or a payload larger than the protocol allows is refused instead of being handed on. - A remote signer (bunker) can no longer change the date of an event it is asked to sign, and a repeated request for approval opens the browser once, not once per answer. - A self-hosted SearXNG answer with a negative chunk size is treated as broken. - The Gradle distribution used for release builds is checked against a pinned SHA-256. - Machine-local build files that recorded a developer's home directory are no longer tracked. ### SHA-256 ``` a505f7b4dc3625e2ea6e69d968ffe1570e41fb203de34474e053fcc01b68817e app-arm64-v8a-release.apk 062ca8182fa008f57fcee174f3c0e704271a5d24e731ef24de5f45046406f3be app-armeabi-v7a-release.apk 6660e089d820cc1535ec0b69fc0d4144e311323a654953ac2481d9525bb5498c app-release.apk 2bef7ff1907cb2ab0ada15af3ed37bab3fb46ce2fc9de73f1099bed103560080 app-x86_64-release.apk ```
  • Oct 25, 2026 1.2.3
    # Roadstr 1.2.3 New artwork for the Journey badges and a solid, turning coin. ### Changed - All Journey badges have new artwork. - A won coin is now drawn as a short gold cylinder: its body is built from depth slices and its side is reeded, so it keeps its thickness while it turns, down to the moment it is edge-on. This replaces the separate edge image used in 1.2.2.
  • Oct 25, 2026 1.2.2
    # Roadstr 1.2.2 The speed-limit sign works again, the screen no longer defaults to full brightness, and road reports have proper artwork. ### Fixed - **Speed-limit sign stuck on "–".** The limit came only from the public Overpass servers, and they were all unavailable at once (overpass-api.de at capacity, the openstreetmap.fr instance restricted to white-listed users, the others unreachable). A refusal was also read as "this road has no limit", so the app never moved on to another server. The limit is now read first from the Valhalla
    More…
    server at openstreetmap.de, the one used for routing (the posted `maxspeed` of the road under the fix, already in km/h), and Overpass is only a fallback. A refused or failed answer now rotates to the next server. Roads without a posted limit, roads with no limit at all and ways that disagree still show no limit rather than a guess, and service roads and parking aisles are ignored. - The mail.ru Overpass instance is never asked for the speed limit: it would receive your position every 100 m while driving. ### Changed - **Screen brightness defaults to 75%.** It used to be off, which left the screen to the system and let automatic brightness drive it to full in daylight. The slider moves in 5% steps so the default is one of its positions. Whatever you had already chosen is kept. - Road reports are drawn with illustrations instead of emoji: map pins, report details, the category picker and the route panels. The Journey entry in Settings and Profile has new artwork, and a won coin now turns with a real edge instead of flattening into a line. ### Notes - The speed limit is only looked up while a trip is under way. Not yet verified on the road: the lookup was checked against the live servers (Rome 50, London 32 for 20 mph, Florence 30) but not from a phone. - Other features that rely on Overpass (OpenStreetMap speed cameras, ZTL, hazards, place search) still depend on those servers being up.
  • Oct 22, 2026 1.2.1
    # Roadstr 1.2.1 Roadstr 1.2.1 lets you report surveillance cameras and fixes the order of the spoken start and arrival announcements. ## Added - A **Flock Camera** report category (📹; *Telecamere di sorveglianza* in Italian, translated into all 27 languages) for fixed surveillance cameras. It stays on the map for 30 days, like speed cameras and police stations. - Surveillance cameras are published to Nostr relays only. The open *jooray/roadstr* format has no equivalent type, so they are never sent over the MeshCore radio and never approximated as *other*. ## Changed
    More…
    - **Other** is no longer offered when you file a report. Reports that already carry it, from older versions or other apps, are still read and drawn as before; an older Roadstr shows the new category as *Other*. ## Fixed - Starting a trip no longer speaks the first instruction before *Let's go*: a departure that arrives while another phrase has barely begun now takes its place, and the displaced phrase follows right after it. - *You have arrived* is no longer heard twice. The last maneuver, which leads to the destination, now says that you **will** arrive (*In 300 metres you will arrive at your destination*) in all 27 languages, matching the on-screen banner; the arrival itself keeps the past tense. In Italian the arrival now reads *Sei giunto a destinazione* (both bundled voices regenerated). ## Notes - Both voice fixes are covered by unit tests of the speech queue and the phrase tables, but the order of the announcements and the regenerated Italian audio have not yet been heard on a phone. - *Flock Camera* follows the name of a well-known manufacturer; the other 25 translations of the new category have not been reviewed by native speakers.
  • Oct 18, 2026 1.2.0
    # Roadstr 1.2.0 Roadstr 1.2.0 adds Explore, optional Journey achievements, and private offline voice search. ## Highlights - Explore nearby places with resilient geographic-provider fallback, deduplication, distance-aware ranking, and clearer empty/error states. - Enable Journey from Settings to track defensible distance by transport mode, review trips and totals, and unlock 17 achievements. - Enjoy 17 individually illustrated gold reward coins. Unlocked achievements open a detailed animated coin view with 3D rotation and highlights. - Optionally sync Journey history as encrypted NIP-78 events, with per-device shards and integrity-checked manifests.
    More…
    - Search by voice with an embedded, reusable offline STT engine. Recognition stays on-device after the model download and is limited to supported arm64 devices. - Use refined spoken-address matching for Italian numbers, abbreviations, diacritics, phonetic variants, and local street candidates. - See actions consistently follow the selected Nostr-purple or Bitcoin-orange accent, including support, saved-place, and Nostr actions. - Notifications are back in the bottom safe area, Journey sheets avoid the status bar, and screen transitions now use softer slide, scale, and fade motion. - Search controls now distinguish clearing typed text from closing/resetting search. ## Privacy and compatibility - Journey and Journey sync remain disabled by default and must be enabled separately. - Offline voice audio is processed locally; audio is not uploaded. - The embedded offline STT engine is currently available only on eligible arm64 Android devices.
  • Oct 13, 2026 1.1.0
    Public-transport guidance, road-report interoperability with the open jooray/roadstr format, and an experimental MeshCore radio. Added • Turn-by-turn public-transport guidance: walking, boarding, onboard, interchange and final-walk stages, a dedicated HUD, de-duplicated voice cues, manual boarded / alighted / missed-service actions and a restorable session • Nearby stops and departure boards in search; missed connections can be assessed, refreshed and replanned without replacing the active journey until you confirm • Saved transit journeys in their own encrypted format, with a comparison of the original and the updated plan • Entur as a second online provider for Norway • Reading road reports written in the open jooray/roadstr format (Nostr kinds 1315 and 1316): they keep the lifetime that format gives each type, confirmations extend it and denials cut it short, and the details sheet says where a report came from. Roadstr's own reports are unchanged • A codec for the compact 110/134-byte form of those reports that rebuilds the exact signed event (same ID, key and signature) or refuses to encode, with golden test vectors and a public specification
    More…
    • Optional, off by default: also publish each report in that format, signed with your account key or a one-time key • Experimental, off by default: MeshCore LoRa radio support. Pair a radio over Bluetooth, receive and send reports with or without internet, and bridge them to and from the Nostr relays without ever changing a report's author. The Bluetooth permission is only requested when you pair a radio Fixed • The report sheet is no longer drawn underneath the speed and route panel while navigating, so a report can be published again • The speed figure is centred on the speedometer dial in every style • Public transport can be chosen again in the route planner Notes • The MeshCore support has been verified against a simulated radio only and has not yet been tested on real hardware • Anything sent over the radio can be read by anyone in range: position, time and the public key that signed it. It is not anonymous. Roadstr asks for consent before it transmits or bridges anything • Older Roadstr versions show two markers when "Also publish in the compatible format" is on, because they cannot tell the two copies are one report. The option is off by default Full details: CHANGELOG.md and docs/interoperability/MESHCORE_NOSTR.md
  • Oct 11, 2026 1.0.1
    Public transport is back in the Kotlin planner. Added • Real multimodal itineraries from Transitous/MOTIS v6, including walking, bus, tram, metro, rail and ferry legs when data is available • Provider-supplied alternatives with line direction, operators, platforms, intermediate stops and scheduled/realtime times • Delay, cancellation, accessibility and service-alert details without presenting scheduled data as realtime • Expanded itinerary cards and MapLibre boarding/alighting markers Improved
    More…
    • Added a capability-aware transit provider boundary with bounded retries and provider-scoped identifiers • Added visible provider attribution and updated the legacy Flutter request to the current stable MOTIS contract Note: active transit guidance, saved transit journeys, stop/departure search and offline transit routing are planned follow-ups.
  • Oct 10, 2026 1.0.0
    # Changelog All notable Roadstr changes are documented here. Roadstr 1.0.0 is the first stable release of the Kotlin rewrite. ## Unreleased - Settings: the card of optional map elements is now called *Map element overlays* (27 languages), starts closed, and also holds the altitude readout switch; the altitude readout stays off by default. - Added a destination pin on the map and lighter navigation rendering: the vehicle cursor animation is drawn at its 30 fps source cadence instead of waking the UI at a 90/120 Hz refresh rate.
    More…
    - Restored native ZTL/ZAC/limited-traffic warnings from the 0.5.x line: bounded Overpass loading, restricted-route colouring, live inside/nearby notices, official local acronyms where established, dismissal and navigation-progress integration. - Added client-initiated NIP-46 login with a generated `nostrconnect://` offer for Amber and compatible signers, alongside the existing pasted `bunker://` flow. - Kept NIP-46 relay WebSockets warm and multiplexed across signer requests, while closing each logical Nostr subscription and retaining signature, recipient, request-id and one-time-secret validation. - Documented the upstream GTFS/NeTEx/GTFS-RT contribution path that expands Roadstr coverage through Transitous without an APK release. ## [1.0.0] — 2026-10-10 🎉 **The Kotlin rewrite is stable!** 🎉 This release carries the work started during the 0.5.x to Kotlin migration and makes the native Android app the supported Roadstr experience. It keeps the production package name `app.roadstr`, uses the owner's release certificate, and is designed to update an existing 0.5.x installation in place. ### Kotlin app and migration - Replaced the Flutter launcher with a Jetpack Compose and MapLibre Native application while retaining the Flutter reader needed to import data from 0.5.x. - Added fail-closed, transactional migration for Amber identity/profile data, saved places, parking spot, settings, search history, pending reports, wallet/routing configuration and favourites-sync state. - Preserved encrypted storage boundaries, secure-store aliases and recovery presentation; migration never deletes the legacy data. - Added Amber (NIP-55) and bunker (NIP-46) signing flows without importing private keys into Roadstr. - Delivered 27-language native resources, onboarding/disclaimer/recovery UX, themes, settings, voice model ownership and app version/about presentation. ### Navigation and live road experience - Added the native map-first journey: GPS cursor/follow camera, search, place cards, route planner, alternatives, preview and active-trip HUD. - Added OSRM routing, alternatives, direction-aware rerouting, route progress, arrival handling and background navigation. - Kept trips alive through rotation, task removal and screen-off use with a foreground location service, notifications, wakelock and voice guidance. - Added Nominatim, Photon and Overpass search, contextual place details, weather, OSM speed cameras and road-element overlays. - Added Nostr road reports, confirmations, corrections, activity inbox, relay polling, Lightning/NWC integrations and sync flows. ### Saved routes and offline routing - Added versioned saved-route models and encrypted persistence for route plans, destinations, waypoints and metadata. - Added saved-route UI and offline package controls with bounded validation and transactional state updates. - Added a verified offline package pipeline and opt-in on-device Valhalla routing engine, including package/catalogue checks and routing-data-only package selection. ### Offline maps - Added a hierarchical worldwide map catalogue backed by the live [Geofabrik index](https://download.geofabrik.de/index-v1.json), with bundled GeoNames coverage for 34,156 cities and 3,865 administrative areas. - Added provider presets for Geofabrik, VersaTiles, OpenMapTiles and Roadstr JSON, with the custom HTTPS manifest field moved into an explained advanced section for self-hosted catalogues. - Added verified Shortbread MBTiles downloads with size, validator and checksum checks, persistent installation, attribution and local MapLibre rendering through `mbtiles://` sources. - Added soft directional catalogue transitions: forward navigation slides right and backward navigation slides left. - Fixed replacement of stale catalogue caches and Android asset packaging so the live catalogue and bundled geographic data work reliably in release builds. ### External destinations - Added a strict JSON destination contract for Tankful and other trusted callers: `{"label":"…","lat":0.0,"lon":0.0}` via an explicit `ACTION_SEND` intent. - Supports cold-start and single-top delivery, bounded payloads, finite coordinate validation, duplicate/unknown-field rejection, latest-wins handoff and one-time consumption diagnostics without logging destination contents. - Tankful now targets the production package `app.roadstr`; the release launcher accepts the destination and opens route planning. ### Quality and release engineering - Added extensive JVM, Dart contract and device-level checks for migration, storage, routing, navigation, intents and release compatibility. - Added release-source and signed-artifact auditors covering package identity, version agreement, label, ABI outputs, hardening, checksum and release-certificate verification. - Verified the signed update path, onboarding, JSON destination flow, cold/single-top launches and the production app label on a Pixel 10 running Android 17. ### Known follow-ups - Public transport, some additional provider integrations, real bunker/NWC signing exercises and native-speaker translation review remain documented in the risk and feature-parity reports. ## 0.6.0 — Kotlin rewrite milestone The 0.6.0 milestone introduced the production Kotlin launcher, migration bridge and device-tested native navigation. The complete engineering record is preserved in `docs/kotlin-rewrite/`, including the parity matrix, migration plan, risks and release tooling. ## 0.5.x and earlier The Flutter line remains available on the `flutter-maintenance` branch. Its historical tags and release notes are retained in Git for users who need the rollback path.
  • Sep 25, 2026 0.5.11
    # Roadstr 0.5.11 Turn-by-turn directions in the language you chose. ## Fixed - On the new map, the **turn-by-turn instructions were always in Italian**, whatever language the app was set to. Read aloud by a voice in your language, that came out as Italian with a foreign accent. They now follow the app's language.
    More…
    - With the language left on "system default", the **voice started in Italian** instead of the phone's language. It now follows the phone. - GraphHopper directions are now requested in the app's language (they were only ever Italian or English), and a language OpenRouteService does not offer falls back to English instead of failing the route. - Wikipedia place summaries fell back to the Italian edition when there was no article in your language. They now fall back to English. ## Updating Signed with the same release key as every previous version, so it installs over the top of an existing one — no need to uninstall, and nothing is lost. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 24, 2026 0.5.10
    # Roadstr 0.5.10 Police stations as a road report, the altitude readout back on the MapLibre home screen, and a round of battery savings. ## Added - **Police stations** can now be reported as their own road event. They are separate from the existing police report, which is a patrol or checkpoint that is gone within hours: a station is a building, so its marker stays on
    More…
    the map for 30 days, like a speed camera, and it gets no voice warning as you pass. Older versions show it as a generic "Other" marker. ## Fixed - The **altitude readout** had disappeared from the MapLibre map on the home screen since the last redesign, and the setting for it was buried in a collapsed "Road element overlays" group. Both are fixed: it shows again, and the switch is now a row of its own in the Map section. ## Changed ### Battery - Map markers (crosswalks, traffic lights, speed bumps, cameras, reports) are now built only when they can actually be on screen. Before, every marker in range was rebuilt on every camera frame, off-screen ones included, which in a dense city meant hundreds a frame. - The map camera is no longer re-rendered when it has not visibly moved — mostly in slow traffic. At road speed and in turns nothing changes. - The map camera stops animating while the app is in the background, so navigating with the screen off and just the voice no longer keeps the phone busy following a map nobody can see. - The distance in the navigation notification is updated at most once every three seconds instead of twice a second (a new instruction still shows at once), and the compass sensors only run when something can use them. - Map data (traffic lights, crosswalks, speed cameras) is no longer re-downloaded every two minutes while parked, and is fetched less often while driving. Traffic lights and crosswalks are also skipped while the screen is off, since they only feed map markers. ### Navigation - Finds its place on long routes without rescanning the whole route on every GPS fix, does much less work up front when starting a long route with many manoeuvres, and copes better with routes that double back over the same road. ## Updating Signed with the same release key as every previous version, so it installs over the top of an existing one — no need to uninstall, and nothing is lost. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 16, 2026 0.5.9
    # Roadstr 0.5.9 Security hardening from an independent audit: privacy opt-ins, Nostr relay resilience, and honest store/network claims. ## Changed - **Favorites sync is now a real opt-in** ("Sync automatically" in Settings, off by default). It used to auto-publish an encrypted snapshot on every edit and auto-pull one on every launch for anyone simply signed in with
    More…
    Nostr, contradicting the onboarding text's own "optional, enable it from Settings" wording. - **Logging in no longer publishes a profile-visibility event** unless you had actually chosen public visibility beforehand. Publishing the untouched, pseudonymous default on every sign-in tied your key to "uses Roadstr" on public relays for no benefit — its absence already means pseudonymous. - **The store listing no longer claims "GPS data never leaves your device"** or "offline-capable routing" — both were false. Rewritten to match what the app actually does, also fixing a license line that said AGPL instead of GPL. - **The self-hosted GraphHopper "localhost" hint now actually works**: cleartext is permitted for exactly `localhost`, `127.0.0.1` and the Android emulator alias, nothing else, and any other `http://` address is refused with a clear error instead of failing silently. ## Fixed - A relay outage could be retried roughly every 1.25 seconds indefinitely instead of backing off, because the reconnect counters were reset before the WebSocket handshake had actually finished. Now waits for a real handshake before resetting anything. - Confirmation votes and pending-event tracking on the Nostr road-event stream had no per-report or total ceiling, letting a flood of freshly minted Nostr identities grow memory use against one popular report without limit. Both are now capped, and cheap checks run before the costly signature verification on every incoming event, not after. - Voice-model downloads (Kokoro/Piper) only had a per-chunk stall timeout; a server trickling data indefinitely could hold a download open forever. Added a total time limit per file. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 14, 2026 0.5.8
    # Roadstr 0.5.8 An "avoid unpaved roads" option, offline road reports, and fixes for navigation, Bluetooth audio and GPS recovery. ## Added - **"Avoid unpaved roads"** — a new Settings preference that steers driving routes away from OSM-tagged tracks and dirt roads whenever a paved alternative exists. Applied automatically to every route and
    More…
    reroute once turned on, not something to remember to ask for each trip. Always a best-effort steer, never a guarantee — map data on road surfaces is incomplete, so a road's real condition still needs judging on sight. - Road reports created with no signal are now saved and published automatically the moment a relay connection succeeds, instead of being lost — useful on roads where signal is scarce. - Settings can now be opened during active navigation, from a new icon next to the mute button, without stopping the trip. ## Changed - Off-route recalculation no longer demands a U-turn. Deviating on purpose in a grid of perpendicular streets used to leave the app pinning the old route behind the car instead of recalculating; it now finds the short way back to the original route instead. - "Recalculate" after a traffic-jam alert now genuinely routes around the reported jam rather than handing back the same road. - The first-launch disclaimer now says plainly that turn-by-turn routing is OpenStreetMap data interpreted by third-party engines, not vetted by Roadstr — and can no longer be swiped away with the back button/gesture, only by accepting it. ## Fixed - Bluetooth music/podcasts could stay paused after Roadstr finished speaking instead of resuming, caused by the audio player managing the phone's audio session on its own and a stale internal flag that skipped handing focus back. - A GPS stream could silently stop delivering fixes after an Android location-provider fault, leaving "recenter" stuck on "Acquiring GPS…" indefinitely. It is now detected and restarted automatically. - A single very inaccurate GPS fix (e.g. deep among tall buildings) could trigger a needless reroute; a shaky fix is now ignored unless several fixes in a row actually confirm the driver left the route. - A malformed or empty response from a routing server could crash navigation outright — closed the same gap already guarded elsewhere. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 11, 2026 0.5.7
    # Roadstr 0.5.7 Visual redesign: a new home dashboard, refined glass-style panels throughout, and a simplified theme lineup. ## Changed ### A new look - New collapsible home dashboard on the map screen.
    More…
    - Frosted-glass styling applied consistently across the bottom bar, navigation HUD, route panels and search — one shared design language instead of several ad-hoc looks. - Cleaned up the bottom bar: removed a small logo that was crowding the notifications/profile/menu buttons, giving them more room. ### Simplified theming Dropped the "modern" gradient theme variants, keeping the four classic Nostr/Bitcoin themes (light and dark). Anyone who had picked a modern variant falls back to its closest classic counterpart automatically — no manual action needed. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 7, 2026 0.5.5
    # Roadstr 0.5.5 Crosswalk/speed-bump map icons, better search ranking, and a couple of route-planner fixes. ## Added ### Crosswalk and speed-bump icons Pedestrian crossings and speed bumps now show on the map at their exact
    More…
    OSM-mapped position (`highway=crossing`, `traffic_calming=*` — verified against OsmAnd's own rendering style), the same way the existing speed-camera and traffic-light markers already do. ## Fixed ### Search ranking - Results that actually match the query are now sorted purely by distance from you — a franchise's own branches no longer get reshuffled just because one of them happens to be worded slightly differently on the sign. - Typing a city name at the end of a search ("mercatino usato faenza") now prioritises results actually in that city over merely closer ones elsewhere — detected locally, no extra network round-trip. ### Route planner and map interactions - The two-point route planner's "My Location" field now falls back to the current map view when there's no GPS fix yet, instead of refusing to calculate. - Long-press on the map: "report event here" is back at the exact long-pressed point (previously the report action only worked from your current GPS position via its FAB). - Tapping the recentre button with no GPS fix now shows a "location services are off" prompt instead of silently doing nothing. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 6, 2026 0.5.4
    # Roadstr 0.5.4 German voice guidance. ## Added ### German turn-by-turn voice guidance Kokoro-82M, the neural TTS engine behind the other 7 supported languages, has no German voice at all — it was never trained on German audio. German now
    More…
    gets a second, independent on-device engine: Piper (VITS-based, github.com/OHF-Voice/piper1-gpl), using Thorsten-Voice's MIT-licensed "Martin" voice — a long-running, dedicated open-source German TTS project. Same download flow as before (Settings → voice model), same espeak-ng phonemizer already bundled for the other languages. The phoneme sequencing was verified directly against Piper's own source and tested end-to-end against the real model before shipping. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 6, 2026 0.5.3
    # Roadstr 0.5.3 Traffic-light icons on the map, plus fixes for repeated/overlapping voice guidance. ## Added ### Traffic-light icons Controlled intersections now show a traffic-light icon on the map at their exact OSM-mapped position, sourced from Overpass the same way the existing OSM speed-camera
    More…
    markers already are — cached and throttled the same way, visible from a closer zoom level since signals are far denser than speed cameras. ## Fixed ### Voice guidance repeating or cutting itself off Three related bugs in the turn-by-turn voice announcements: - "You have arrived" could play twice in a row when the final turn was close to the destination — the advance mention chained onto the previous turn ("...then you will arrive") landed only seconds before the real arrival announcement. - A turn mentioned in advance as part of the previous instruction ("...then in 300 metres take the ramp") could have its own standalone announcement fire moments later and cut the first one off mid-sentence. - Two different nearby reports of the same hazard/speed-camera category could be announced back to back with the identical sentence. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 5, 2026 0.5.2
    # Roadstr 0.5.2 Hotfix. 0.5.1 made the MapLibre engine the default and fixed the battery/heat reports from 0.5.0 — one of those fixes broke the screen entirely on real devices. ## Fixed ### The map screen lost every control Disabling a rendering mode to cut battery/heat had the opposite of the intended effect:
    More…
    MapLibre's Android renderer fell back to a mode that draws straight through the Android view hierarchy instead of composing through Flutter, which hid every on-screen control — the search bar, every button — behind the map itself. Reverted. The other battery/heat fixes from 0.5.1 (the screen no longer rebuilding on every camera frame, dead reckoning between GPS fixes) are unaffected and stay in place. ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Sep 5, 2026 0.5.1
    # Roadstr 0.5.1 0.5.0 shipped the MapLibre rendering engine as an option. A week of actually driving with it surfaced the rough edges an opt-in toggle doesn't get exposed to at scale — this release fixes them and makes it the default. ## Changed ### MapLibre is now the default map engine
    More…
    The original renderer isn't going anywhere — the "Motore mappa: MapLibre" toggle in Settings switches back to it at any time — but new installs now start on the new engine. ## Fixed ### Cursor smoothness between GPS fixes The camera and cursor only moved when a GPS fix landed, then sat frozen until the next one — visible as a freeze-then-jump at speed, where a fix interval's worth of travel is tens of metres. Both now advance continuously between fixes, using the last known heading and speed to fill the gap. ### Battery drain and device heat Smoothing that gap the naive way came with a real cost: a screen-wide rebuild — every route polyline, ZTL classification, traffic segment — was firing up to 60 times a second while driving, and the map was rendering through an Android compatibility mode it never needed. Both fixed; reports were a Pixel 9 running hot and 10% battery on a 30-minute drive. ### Route calculation feeling slow Showing the route picker waited on a cosmetic detail — roundabout exit counts, used only to word voice instructions like "take the 3rd exit" — with a timeout of up to 6 seconds if the data source was under load. Alternatives now show immediately; that detail fills in afterwards if it's still relevant. ### Kokoro voice Picking the male voice in Settings had no effect on an already-open map screen — it's now the default, and a change takes effect immediately regardless of what's on screen. ## Added - Long-press a point on the map to set it as parking, with a confirmation prompt in all 27 languages ## Verifying this release sha256sum -c SHA256SUMS.txt
  • Aug 28, 2026 0.5.0
    # Roadstr 0.5.0 Two months ago Roadstr drew its first map exactly one way: flat raster tiles, no tilt, no rotation without blur. This release ships a second way to draw it — a full MapLibre-based 3D rendering engine, built from scratch on its own branch and now merged in at feature parity with the original. ## Added ### A MapLibre-based rendering engine, switchable in Settings
    More…
    Real 3D camera tilt and rotation instead of flat raster tiles, native map styling that extends the light and dark themes to the map itself instead of stopping at the UI around it, and a full navigation feature set built to match the existing renderer rather than trail behind it: - Destination search — POI categories, favourites, history — with a place-info panel shown before committing to a route - Multi-stop route planning - Route alternatives, with highway/toll avoidance - Public transport itineraries — bus, tram, metro, rail, coach, ferry - ZTL-aware route colouring - Speed-camera and hazard proximity alerts, hazard reporting with owner-editable speed limits - Turn-by-turn navigation with off-route detection, rerouting, chained voice instructions and full voice guidance It ships as an option, not a replacement: the "Motore mappa: MapLibre" toggle in Settings switches between it and the original renderer at will, and the app keeps loading the original one by default. Nothing changes for anyone who doesn't opt in. Google Play Services was the reason this was shelved the first time it was evaluated — MapLibre's Android SDK touches it in places the app doesn't otherwise need. It turned out not to matter: Roadstr already excludes the Play Services dependency groups outright at the build level, the same exclusion that keeps the de-Googled GPS stack clean, and the new engine never calls MapLibre's own location APIs to begin with. Zero Play Services code in this build, same as every build before it. ## Verifying this release sha256sum -c SHA256SUMS.txt ## Next up Offline maps. Vector data is small enough to carry a region on the device — which is what raster tiles never allowed.
  • Aug 27, 2026 0.4.29
    # Roadstr 0.4.29 Fixed the tag format that broke ZapStore updates. ## Fixed ### Updating from 0.4.27 to 0.4.28 failed on ZapStore Every release so far was tagged `v.X.Y.Z`, with a literal dot after the `v`. The publishing tool strips only the leading `v` when it reads a tag
    More…
    as a version number, which on this format left a stray dot behind: `.0.4.28` instead of `0.4.28`. Confirmed against the tool's own local cache, and against three other apps published by the same account that all use the plain `vX.Y.Z` convention and come out clean — Roadstr was the only one shaped differently. A malformed version string is exactly the kind of thing that breaks update comparison on the client, which is what surfaced as "can't update." Tags go out as `vX.Y.Z` from here on. This was never actually the project's own convention to begin with — `build_release.sh` has printed the correct, dot-free tag command in its own instructions all along; the dot was introduced by hand at release time and never caught until now. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 38, and contain zero Google classes.
  • Aug 27, 2026 0.4.28
    # Roadstr 0.4.28 Dark mode no longer depends on a third party that can revoke access without warning. ## Fixed ### Dark mode's map tiles came from a service that started requiring an API key Dark mode fetched its map tiles from a free, anonymous CARTO endpoint. It
    More…
    started serving an "API KEY REQUIRED" watermark instead of tiles once some unpublished usage threshold was crossed — a dependency that could, and did, break with zero warning, mid-drive, for anyone using dark mode. This is likely the same root cause behind an earlier, unresolved report of dark mode looking inconsistent on a longer drive: a mix of real dark tiles and watermarked ones reads exactly as "inconsistent." Dark mode now recolours the same OpenStreetMap tiles light mode already depends on, rather than trusting a second, separately-failing service to keep rendering a dark basemap for free. The recolouring inverts lightness (white background to black, dark labels to light) and rotates hue by 180° to undo the colour shift a plain inversion leaves behind — a green park would otherwise invert to magenta — followed by a desaturate-and-darken pass so area fills come out muted rather than vivid, closer to the cartography this replaces than a naive colour inversion would give. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 37, and contain zero Google classes.
  • Aug 26, 2026 0.4.27
    ## Roadstr 0.4.27 ### New - Added an optional real-time altitude badge to the map. - Altitude is displayed in metres or feet according to the selected unit system. - GPS altitude readings are smoothed to reduce normal location jitter. - Added altitude display controls to Settings. - Added tests for altitude formatting, imperial units and badge rendering.
  • Aug 21, 2026 0.4.26
    # Roadstr 0.4.26 A mirrored icon, and two new screen controls — all from continued field reports on the previous release. ## Fixed ### Merge maneuver icons were mirrored The merge symbol has two paths: the muted one for the carriageway being
    More…
    joined, the accent one for the ramp the driver is actually on. A "merge left" instruction means that carriageway is to the driver's left — which puts the ramp, the accent path, on the right at the bottom of the icon. The two were swapped, so every merge rendered as its own mirror image: a driver on a right-side ramp merging left onto the main road saw a left-side ramp merging right, and vice versa. Confirmed against a real routing response before touching the code — a live route with an actual `merge, modifier: slight left` step, the common case of a ramp joining from the right — rather than guessing from the screenshot alone. ## Added Two settings, both **off by default**: ### Keep the screen on outside navigation too The existing "keep screen on" setting only ever applied during an active route. Reading the map stopped, or planning a trip, still let the screen sleep mid-glance. A new toggle extends the same behaviour to free-roam use of the app — left off by default, since always-on is a real battery cost outside of driving. ### Minimum screen brightness Requested by an OLED user whose panel dims low enough, under the phone's own auto-brightness, that the map's grey text stops being readable. A slider sets a floor: while the app is open, the screen won't dim past it, whatever the system's own brightness curve would otherwise do. Off by default, since the entire point is that it only matters to some screens and some ambient conditions. Both settle back to their defaults on their own — ending navigation, or closing the app — rather than needing anything to be turned off by hand. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 35, and contain zero Google classes.
  • Aug 21, 2026 0.4.25
    # Roadstr 0.4.25 Fixes from real driving: a crash, a swinging map, voice timing, and a GPS receiver that let go too eagerly. ## Fixed ### GPS dropped on every background switch, even a glance at a notification Leaving the app — for any reason, not just switching away — released the
    More…
    location receiver the instant the app left the foreground, whether or not navigation was running. Coming back always meant reacquiring from nothing, even after three seconds spent reading a notification. The receiver now survives up to 30 seconds of actually being backgrounded before it is let go, and the pending shutdown is cancelled outright on return — so a quick glance away costs nothing, while a phone genuinely left in a pocket still stops updating. ### A crash while panning the map during navigation Investigating turned up something bigger than the specific crash: the app had **no global error handler at all**. Flutter's own build/layout/paint cycle already keeps a bad frame from taking the whole app down, but anything outside it — a gesture callback, a stream listener, an unawaited `Future` — did not have that protection, and an exception there killed the entire process instead of just the one thing that went wrong. A global handler now catches, logs and swallows those instead of letting them propagate. It won't retroactively explain the one crash that was reported, but it means the next unexpected exception, whatever it turns out to be, ends as a log line instead of a closed app. ### The map still swung on turns sharper than 90° An earlier release fixed the equivalent problem at roundabouts — the nearest piece of route geometry isn't always the one the car is actually on. Sharp turns kept swinging anyway, for a second, independent reason: once a large disagreement between the raw GPS bearing and the route's own direction was confirmed by a second fix, the heading **snapped** straight to the route's exact line instead of easing into it. The raw bearing through the turn was already noisy, since it's measured across two fixes taken on either side of the corner — so the snap landed a second discontinuity right on top of the first, which is what read as the map swinging just after the turn completed. The confirmed correction is now eased in at the same rate ordinary route-following uses, removing that second jump. ### Voice guidance timing, two separate bugs - **The final warning arrived too late at speed.** The point-of-action cue — the one spoken right at the turn — capped its lead distance at 120 metres no matter how fast the vehicle was going. At 120 km/h that is 3.6 seconds: enough time to hear "take the exit," not enough to act on it. The distance now keeps scaling past 100 km/h instead of flattening there, reaching 260 metres — about six seconds — by 160 km/h. - **Instructions ran on in dense junctions.** An advance warning for the next turn used to queue behind whatever maneuver announcement was already playing, rather than being dropped. In a run of closely spaced junctions that meant hearing about a turn that was already behind the car by the time its announcement finally played. A newer cue now simply replaces a stale queued one; the point-of-action repeat still always interrupts immediately, since arriving late at a junction is worse than talking over the warning it replaces. ### The hazard-report button changed sides It sat on the left of the screen before navigation started and jumped to the right the moment a trip began — the only control on screen that moved. It now stays on the right in both states. Parking and route planning stay on the left and pre-trip-only, since re-planning or checking a saved spot mid-drive isn't something either is meant to support. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 34, and contain zero Google classes.
  • Aug 19, 2026 0.4.24
    # Roadstr 0.4.24 Directions in every language the app speaks, restricted-zone warnings that mean something, and the map finally holding still. ## Added ### Turn-by-turn instructions in all 27 languages Until this release, exactly two languages had instructions of their own. The builder was a
    More…
    pair of ternaries on `lang == 'it'`, so the other **twenty-five languages the app ships were navigated in English** — not a missing street name, but a driver being given directions in a language they may not read. The wording now lives in a phrase table: 24 keys across 27 languages, with English as the fallback for anything absent. Adding a language is a data change, and a test reads the locale files from disk to make sure none is left behind. ### Instructions name the road — by its number Instructions say which road they lead onto, and prefer the code over the formal name: **"take the SS3bis"**, not "Strada Statale 3 bis Tiberina", which appears nowhere on the road itself. Where a road carries several codes only the first is spoken; reading a list of synonyms at a junction is worse than naming one of them. ### The street you are on Shown under the manoeuvre panel — **for town streets only**. A motorway number is already on every sign and in the panel above; a street name is the thing that is genuinely hard to know from inside a car in an unfamiliar town. The label sizes itself to the name, and stays clear of the speed-limit sign beside it. ## Fixed ### Warnings on streets that were not restricted The zone search collected every `highway=pedestrian` way **with no check on whether cars were actually barred**. Measured around one Italian historic centre, that was 160 of the 274 ways it returned — and in a dense centre there is almost always a pedestrian alley within a few metres of a perfectly drivable street, which is how an ordinary road came to be announced as restricted. Pedestrian ways now need a restriction like every other class, and `zone:traffic` no longer matches `urban`, which is the ordinary built-up-area tag that sets default speed limits. Same query, same place: **274 elements before, 115 after**. ### A warning could stick over the cursor until the app was restarted The comparison was on the street *name*, and restricted ways are frequently unnamed — leaving one meant comparing null with null, which registers as "no change", so it was never cleared. Compared by identity now. Warnings also sit clear of the cursor, and can be **swiped away**: somebody who holds a permit drives their own restricted street every day, and a warning that cannot be got rid of is one they stop reading. ### The map swinging round The route's direction was read from the nearest piece of it **by distance**. At a roundabout the exit arm passes within metres of the entry arm pointing the opposite way, so "nearest" happily returned a bearing that contradicted the direction of travel — which the heading filter then had to argue with, and occasionally lost to. The segment is now chosen by **progress along the route**. Progress advances monotonically, so the entry and exit of the same roundabout are hundreds of metres apart on it even when they are metres apart on the ground. ### Voice guidance - **Chained instructions no longer break mid-sentence.** The follow-up clause kept its capital letter, and the phonemizer reads a capital in the middle of a sentence as the start of a new one — an audible full stop after "then". - **A cue arriving between two others is no longer silently dropped.** The queue held one item, so the middle of three announcements was overwritten and never spoken. - **Nothing is cut off in its first 1.3 seconds.** Half a word is worse than silence, because the driver cannot tell whether it mattered. - **"Bivio" and similar words are pronounced properly.** The phonemes were defensible but gave the voice one syllable too many; corrected at the phoneme level, so the spelling on screen is untouched. ## Notes on things that turned out not to be bugs **Journey times come from the routing engine, not from this app.** Checked against the same 185 km route: OSRM estimates 2.73 h, Valhalla 2.58 h — agreeing within 6% — and the OSM data is correct, with `maxspeed=90` on 204 of the road's 212 segments. The app reports what the router says, pro-rata by remaining distance. Inventing a speed model to beat two mature routers is how you get confidently wrong arrival times. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 33, and contain zero Google classes.
  • Aug 18, 2026 0.4.22
    # Roadstr 0.4.22 A crash fixed at the root, limited-traffic zones answered street by street, and a new look for driving. ## Fixed ### The app could die outright mid-drive Traced from a captured crash rather than guessed at: a `SIGSEGV` inside
    More…
    `espeak_TextToPhonemes`, faulting two bytes short of a page boundary — the signature of a buffer running off the end of its page. The cause was not in this app. The bundled eSpeak NG was 1.52.0, from December 2024, and **twelve memory-safety fixes have landed upstream since** — including stack buffer overflows in number and clause formatting, which is precisely what voice guidance spends its time reading aloud. 1.52.0 is still upstream's latest tagged release, so the library is now pinned past those fixes rather than to a release, which is a deliberate trade: the alternative is shipping a phonemizer that can take the whole app down. The phonemizer also caps single-word length now. Voice guidance is a convenience; navigation is not, and no place name is legitimately sixty characters long. ### Other fixes - **The map no longer swings round after a roundabout or a slip road.** The heading filter deliberately holds a suspect bearing near junctions — that is the protection against 180° flips added in 0.4.19 — but a watchdog read that hold as a stuck camera and forced the whole accumulated correction through in a fixed 550 ms. The watchdog now measures whether the camera is converging, and self-driven rotation is rate-limited so no correction, from any source, can outrun the driver reading it. - **A destination chosen while the GPS is still acquiring is no longer discarded.** It is saved to recent searches, and the route starts on its own when the position arrives. - **Faster cold GPS fixes, still without Google.** The app asks the receiver to refresh its satellite assistance data — downloaded from whatever the device's own `/etc/gps.conf` names, which is the chipset vendor or a privacy-focused ROM's proxy. ## Limited traffic zones Previously the app announced a zone in the vicinity and left it there. Now the warning follows what is actually happening: - **Only the stretches of route on a restricted street turn red.** The rest keeps its colour and the part already driven stays grey — turning the whole line red claimed the entire journey was restricted when it is usually a block or two. - **"You are in a restricted zone" appears only when you are**, from the live GPS position rather than from the route touching a zone somewhere ahead. - **Driving past a restricted street shows a yellow notice naming it**, so a shortcut that looks open is not mistaken for one. - Restricted streets near the route are drawn dotted in red. Crossing a restricted street at a junction is deliberately *not* treated as entering it: turning the route red at every such junction would recreate the constant, ignorable alarm this replaces. ## Look and feel - **Four new themes** — modern light and dark, in Nostr Violet and Bitcoin Orange — built on a symmetric edge gradient that frames a panel without tinting the text. - **The route is drawn as a lit line**: a bright core between two rails of colour, with a soft halo. It works in violet, orange and the restricted-zone red alike. - **Driving panels float above the map** with rounded corners, lit edges and soft shadows. The manoeuvre tile and the map controls are lit surfaces rather than flat swatches. - **Time to arrival is now the headline figure**, with distance beside it. What a driver is deciding depends on how long is left, not on how many kilometres remain. - **Bicycle routes can be planned from the start**, rather than only chosen after a route has already been calculated. - The roundabout exit number is larger, and no longer clipped on roundabouts with many exits. ## Under the hood - Key derivation for favourites moved off the UI thread, where it blocked for over a second on every favourite edit and at every startup. - Network failures are typed, so a momentarily busy shared server is retried with backoff — honouring its own `Retry-After` — while a malformed answer is not. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 31, and contain zero Google classes.
  • Aug 18, 2026 0.4.21
    # Roadstr 0.4.21 Public transport routing arrives, and the map stops startling you at junctions. ## Added ### 🚌 Public transport Plan a journey by **bus, tram, metro, train, coach or ferry**. In the route planner, pick **On foot** and a sub-choice appears underneath it — walk the whole way, or take a
    More…
    scheduled service. Journeys are shown door to door: - the **walk to the stop**, with which stop to head for and the departure time - each **line** in its operator's own published colour, with the direction sign - the **changes**, and the walk at the far end Routing runs against openly published timetables worldwide through a community-run, provider-neutral service — no account, no API key, and no tracking of who asked for what. It is the same kind of shared infrastructure this app already uses for roads and geocoding. Coverage follows the data: where an operator publishes an open timetable, it works; where none exists, the app says so plainly instead of pretending there is no service. ### 🚲 Cycling from the planner Bicycle routes could previously only be selected *after* a route had already been calculated. The planner now offers cycling from the start. ## Fixed ### The map no longer swings round after a roundabout This was the one that mattered. Leaving a roundabout or a slip road, the map would rotate abruptly — exactly when a driver is checking whether they took the right exit. The heading logic deliberately **holds** a suspect bearing near junctions; that is the protection against 180° flips added in 0.4.19, and it works. But a watchdog read that hold as evidence of a stuck camera, and answered by cancelling the smooth easing and forcing the whole accumulated correction through a fixed 550 ms animation. The heading was never wrong — it was right, and delivered all at once. Two changes, so it does not come back by another route: - the watchdog now measures whether the **camera** is converging on the rotation it was asked for, rather than whether the heading has changed — a steady heading is also just what driving in a straight line looks like; - self-driven rotation is **rate-limited**. A real vehicle's yaw rate stays well under the ceiling even in a tight roundabout, so following genuine motion is untouched; what the limit catches is any *correction*, from any source, present or future. ### A destination is no longer lost while the GPS is acquiring Setting a route before the first fix showed "acquiring GPS" and then quietly discarded the destination — it was not even kept in recent searches, so it had to be found again. The destination is now saved immediately and the route starts on its own the moment the position arrives. ### Faster cold GPS fixes, still without Google The app now asks the receiver to refresh its **satellite assistance data**. Without it, the receiver has to read that data off the satellites themselves, which is a fixed half-minute of physics rather than a software delay. This is not a Google dependency: the platform downloads from whatever the device's own `/etc/gps.conf` already names — the chipset vendor's service, or a privacy-focused ROM's own proxy. It matters most on de-Googled devices, where there is no fused provider to paper over the wait. ### Other - The **exit number** on the roundabout symbol is larger, and no longer clipped on roundabouts with many exits. - **Saving or syncing favourites no longer freezes the app.** The password step is deliberately slow by design, and it was running on the same thread as the interface — on every favourite edit and at every startup. - Requests that fail because a shared server is momentarily **busy** now back off and retry, honouring the server's own requested delay, instead of being treated the same as a permanently broken request. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 30, and contain zero Google classes.
  • Aug 11, 2026 0.4.20
    # Roadstr 0.4.20 Pick your own colours, and a new way to walk. ## Added - **Seven colour tints for the vehicle cursor** — violet, indigo, blue, green, yellow, orange, red — chosen from Settings alongside the existing style picker. - **A new "Classic Fiat 500" cursor style.**
    More…
    ## Fixed - **A timing bug in the new walking animation.** Raw GPS speed readings are noisy — a swing of a few tenths of a km/h between two consecutive fixes is routine even at a constant pace. That noise could trigger the animation to start playing before all of its frames had finished loading, producing a visible flicker right when a walk begins. The frame-loading step now properly waits for itself to finish instead of letting a second request for the same sequence skip ahead of it. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 29, and contain zero Google classes.
  • Aug 11, 2026 0.4.19
    # Roadstr 0.4.19 Four field reports from the road, four fixes — each traced to a concrete cause, not guessed at. ## Fixed - **Search history was hidden, not lost.** Anyone with at least one saved favourite — most users, given the app's own favourites feature — never saw their recent searches at all. The "nothing typed yet" panel picked between two lists with an `if`/`else if`, and an empty search box matches *every* saved favourite, so the favourites branch always won.
    More…
    The two are now shown together: they're different things (shortcuts vs. recent searches), not competitors for the same slot. - **The map no longer flips 180° near junctions and roundabout exits.** The heading logic finds the nearest point on the route's own path to double-check its bearing — but "nearest by raw distance" has no idea which way that road actually runs. Right at a roundabout, or where two arms of a junction both sit close together, the nearest point can belong to the wrong arm and report a direction pointing the wrong way, and that single reading used to be trusted immediately. It now has to repeat on the next fix before the map acts on it — a real turn keeps producing the same reading; a bad match by the roundabout ring does not. - **Voice guidance could go completely silent for an entire drive**, then work again on the next one. Setup for the voice model runs once, right as the map, GPS and routing are all also starting up — a plausible moment for something to fail transiently — and until now a failure there had no retry for the rest of that session. It now retries later in the same drive instead of requiring you to start a new one to get your voice back. - **Recalculating after a wrong turn wasn't finding anything useful.** On a long road with nowhere to legally turn around, a reroute request used to assume the car could face any direction at all, including an instant reversal it physically can't perform — producing a route the driver couldn't follow, which triggered another reroute of the same shape, over and over, each with the map spinning as it re-evaluated. Reroutes now account for which way the car is actually facing, so they find a real way back — the next roundabout, the next junction — instead of an impossible one. Verified against Roadstr's own routing server: the same two points 400 m apart resolve to a degenerate two-metre route with no direction given, and to a realistic route via the next junction once the car's heading is taken into account. A safeguard against an absurd detour applies in both directions. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 28, and contain zero Google classes.
  • Aug 10, 2026 0.4.18
    # Roadstr 0.4.18 A crash during navigation, and the roundabout signs that were drawing the wrong junction. Both came from the previous release. Install this one. ## Fixed - **The app could die mid-route.** The map opened a new database watcher on every GPS fix and could not close the old ones fast enough — cancelling is asynchronous, opening is not — so after a few minutes of driving they piled up until the app ran out of memory.
    More…
    There is now one watcher, opened once. - **Roundabout signs showed too many arms.** Where a road meets a roundabout as two separate carriageways, it was counted as two exits: a four-exit junction drew as seven. How far apart those two connection points *look* depends entirely on the size of the roundabout — twelve metres spans 23° on a large ring and 74° on a small one — so the fixed threshold could never work. It is now measured from the roundabout itself. And when the shape still cannot be resolved confidently, a plain roundabout is drawn rather than a wrong one: on the road, a sign showing the wrong junction is worse than a sign showing no detail. - **Distances over a kilometre are spoken as kilometres.** "In 4567 metres" is now "in 4.5 kilometres" — with the decimal separator your language is actually read with, since a speech engine says 4.5 and 4,5 differently. - **One instruction no longer cuts off another.** Every announcement was marked urgent, which stops whatever is playing. Advance warnings now wait their turn; only the final "now" instruction takes over, because by then the junction is seconds away. - **The map no longer occasionally spins 180°.** Standing still, a GPS fix wanders by several metres, and the direction of travel was still being measured from where it had wandered to. Pulling away could point the map any way at all, including backwards. - **More restricted-traffic zones are recognised.** Most are mapped in OpenStreetMap as time-limited restrictions — active only during certain hours — and those tags were not being read at all. Checked against live data: eleven restricted streets in one Italian city centre that the app previously could not see. ## Changed - The secondary instruction panel is 15% narrower and covers less of the map. Text and padding scale with it, so the same instructions still fit on the same number of lines. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 27, and contain zero Google classes.
  • Aug 9, 2026 0.4.17
    # Roadstr 0.4.17 Roundabout signs that match the junction in front of you. ## Added - **Real roundabout shapes.** A routing engine only tells the app which exit to take — "third exit" describes a four-arm junction and a seven-arm one equally well, and until now the sign drew the same generic ring for both. The number of arms is now read from OpenStreetMap and drawn, so the symbol you glance at looks like the junction you are
    More…
    approaching. Where OSM has no usable ring mapped, the sign falls back to the generic one rather than inventing a shape. - **Cursor styles.** City, racing, SUV, electric, bicycle and formula, alongside the existing arrow. - **A redrawn speedometer.** ## Under the hood The roundabout lookup is deliberately bounded, on two counts. It batched every roundabout in every alternative route into a single OpenStreetMap query with no limit. A city route through France or the UK can pass fifty of them, which is a hundred search clauses sent in one request to a free, volunteer-run server — the same infrastructure this app went to some trouble to stop hammering two releases ago. The second reason matters more. Each of those coordinates is a piece of your itinerary, sent in one request before you have even set off. Every other OpenStreetMap lookup in Roadstr discloses only where the car *is*, progressively as you drive — never where it is going. The lookup now asks about at most 24 roundabouts, nearest first, with a test that an 80-roundabout route cannot exceed that. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key, carry versionCode 26, and contain zero Google classes.
  • Aug 8, 2026 0.4.15
    # Roadstr 0.4.15 **No Google code left in the app. None.** Roadstr was built to run on phones with no Google services, and it did. But the APK still carried Google Play Services code — fifteen classes it could never execute on the very devices this app exists for. Nobody put them there on purpose: they arrived as a dependency of the location plugin and stayed, because a shrinker cannot remove code that is still reachable on paper.
    More…
    They are gone. Verified on the release APK, not assumed: ``` com.google.android.gms.* 0 classes com.google.android.play.* 0 classes Google components in manifest none ``` ## What was there, and why it survived so long Roadstr has always read your position through Android's own `LocationManager` — every single call site asks for it explicitly, which is what makes the app work on GrapheneOS, /e/OS and LineageOS without Google apps. The Play Services code was never called. It shipped anyway because `geolocator` decides *at runtime* whether to use Google's fused provider or Android's own, so both remain reachable to the compiler. Excluding the library at the build level simply broke the build: the Google client will not compile without it. ## What changed `geolocator_android` 5.0.3 (MIT) is now vendored in the repository with the proprietary path removed — one file deleted, three lines changed, one dependency dropped. The Dart API is untouched. `third_party/geolocator_android/ROADSTR_FORK.md` records exactly what differs from upstream, so future versions stay easy to merge. Also removed: Google Play Store split-install and deferred-delivery classes, which Flutter links for apps that download parts of themselves from the Play Store. Roadstr does not. ## What does not change **Nothing about how location works.** Same provider, same accuracy, same behaviour on de-Googled phones — there is simply nothing else left beside it now. Location permissions are unchanged. ## Staying that way The Gradle build refuses `com.google.android.gms` and `com.google.android.play` outright, so neither can return quietly through some future dependency. A test fails if the vendored fork, the dependency override, or the exclusions are ever undone. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key and carry versionCode 24. Install the one matching your device (`arm64-v8a` for practically every phone made in the last decade), or `app-release.apk` if you would rather not think about it.
  • Aug 3, 2026 0.4.13
    # Roadstr 0.4.13 The cursor points where you are actually going, and every remote endpoint is now treated as something that might be lying. Outside navigation the arrow used to follow the phone's compass — which, in a cradle at an angle, means it pointed across the carriageway rather than along it. It now follows your direction of travel whenever you are moving, and it stays glued to the road through a curve instead of drifting and snapping back. Underneath that, a long list of places where a relay, a geocoder or a Lightning server could waste the app's memory, its battery, or
    More…
    your data allowance. ## Added - **Your own relay for favourites sync.** Settings → Favourites sync now takes one relay of your own. Favourites are the only thing in Roadstr you cannot re-create — road events expire and the community re-reports them, but home and work are gone if every relay holding them is. None of the three built-in relays declares a retention policy, so none of them owes you your saved places tomorrow; a relay you run or pay for does. Opt-in and empty by default, and deliberately typed in rather than read from your published NIP-65 relay list: that list is public, so publishing an encrypted snapshot to it would hand anyone curious the signed, authoritative list of places to look for your data. The address is checked strictly — `wss://` only, no credentials, no query string — because whatever that field accepts becomes a destination for an encrypted copy of your home address. - **A third relay for favourites sync.** Measured over ten minutes, `relay.damus.io` refused 22 of 30 connections with HTTP 503 while `nos.lol` accepted all 30 — so the old two-relay set was, most of the time, a one-relay set. `purplerelay.com` joins them: 100 % over the same run, and the fastest of the three. ## Fixed - **The cursor no longer sits sideways to the road in free drive.** The heading source is now one rule everywhere: your GPS course while moving, the compass only when you are standing still. The handover has a dead band, so crawling in traffic no longer makes the map change its mind twice a second. - **The cursor stays aligned through curves.** It was being counter-rotated and then corrected by hand every GPS tick, while the map turns every frame — so the correction was always stale, and most stale exactly mid-curve. The arrow now turns with the map itself, in the same frame. - **Free drive follows the road smoothly.** Heading-up mode outside navigation used the same smoothing as navigation instead of jumping to each new fix. - **Starting navigation while already driving** no longer swings the map to the compass bearing before picking up your actual course, and a GPS fix landing mid-transition no longer cuts the route overview short. - **Passphrase-protected favourites restore automatically again.** The auto-restore was reading the sync passphrase from a storage key that Settings migrates away and deletes, so after your first visit to Settings it always came up empty — silently skipping the restore in exactly the reinstall case the feature exists for. - **Deleting your last favourite now reaches the relays.** Pushing an empty list was treated as nothing to do, which left the old snapshot in place for the next reinstall to bring back. - **Two quick favourite edits can no longer land out of order** and resurrect a place you had just deleted. Uploads are queued. - **Sync no longer reports success** when a relay acknowledges a different event than the one that was sent. - **"My reports"** re-checks locally that each report is actually yours, and has its own processing budget, so a busy report's confirmations can no longer truncate the list. ## Changed - **Search sends far less traffic while you type.** Suggestions now come from the provider built for partial words; the strict address geocoder runs once you stop typing, or on submit. It was being asked on every 300 ms pause, and on a half-typed word it answers with nothing — measured across one query being typed out, it returned no results for half of the states while the other provider answered all of them. Results are unchanged: both providers already render addresses in the same shape. - **Reconnects and map-data lookups back off instead of retrying at a fixed rate.** A dropped relay connection was retried every 5 seconds indefinitely — 720 attempts an hour in a tunnel — and the speed-limit, speed-camera and restricted-zone services each retried Overpass every 15 seconds for the whole drive. Both now grow the delay and cap it, with jitter on the relay path so every client that dropped together does not come back together. Better battery life on a bad connection, and the app stops adding load to a service that is already failing. ## Security - **Addresses that look public but resolve inward** are now rejected on Lightning address lookups. `::ffff:127.0.0.1`, `::127.0.0.1` and NAT64 `64:ff9b::/96` all reach the loopback interface, and the private-range check was never looking at the bytes that decide where the packet actually goes. - **A slow peer can no longer hold a request open indefinitely** by sending one byte before each timeout: the response body has a total deadline, not a per-chunk one. - **Place names, addresses and opening hours from search providers are length-capped** before they are displayed or written to your history. Nothing on the other side of those APIs is under our control, and a kilobyte-long "street name" is both a layout problem and a storage one. - **A hostile relay can no longer grow the app's memory** by streaming updates that point at reports which never arrive, or by replaying activity forever. Both are now bounded and aged out. The anti-replay marks that stop an old, validly-signed update from being re-applied are deliberately kept out of that cleanup. - **NIP-44 encryption is now verified against the official v2 test vector**, not only against itself. ## Localisation - The new sync-relay setting is translated into all 27 languages. ## Housekeeping - Version bumped to 0.4.13 (versionCode 22). - The F-Droid metadata pointed at a tag that does not exist: the tags in this repository carry a dot after the `v`, and the build entry said `v0.4.13`. - The test suite went from 151 to 182, covering the motion hysteresis, the retry back-off, the relay-address validator, the inward-resolving addresses above, and the length caps on remote and stored text. ## Verifying this release sha256sum -c SHA256SUMS.txt All four APKs are signed with the official Roadstr release key. Install the one matching your device (`arm64-v8a` for practically every phone made in the last decade), or `app-release.apk` if you would rather not think about it.
  • Jul 26, 2026 0.4.12
    # Roadstr 0.4.12 One new feature and a long list of things that were quietly wrong. **Nearby** answers "where is the closest petrol station / cash machine / pharmacy" in one tap. **"Avoid motorways and tolls"** stops quoting travel times from a different routing engine than the routes it is compared against. **"My reports"** is no longer empty. Editing a speed limit no longer crashes. The restricted-traffic-zone warning is back on screen, the speed-limit sign goes away when it should, and Roadstr now talks to four relays instead of two — without waiting any longer for the answer.
    More…
    ## Added - **Nearby.** Tap the search box without typing anything and a row of one-tap categories appears — fuel, supermarket, cash machine, pharmacy, hospital, police, post office, parking, charging — each answering "what is around me right now" within 5 km of the **current GPS position**, not of wherever the map happens to be scrolled. Results are listed nearest first with the distance beside each one, and tapping one opens it like any other search result: opening hours, details, navigate. Everything comes straight from OpenStreetMap tags, so it works the same in Berlin, Tokyo, Nairobi and São Paulo (all verified live) — and places OSM has no name for are kept rather than dropped, labelled by category: a cash machine in a wall or an unbranded filling station is exactly what a driver is looking for. Category names are translated into all 27 languages. Repeating a category, or coming back to it, is served from a five-minute cache instead of another round trip, and a busy Overpass mirror no longer costs ten seconds of nothing: the second mirror is asked as soon as the first is late, and whichever answers first becomes the preferred one. ## Fixed - **"Avoid motorways and tolls" no longer reports an absurd travel time.** The avoidance route is computed by Valhalla — the only free engine that can exclude motorways and toll roads, since public OSRM rejects the `exclude` parameter outright — but every other route on screen is timed by OSRM, and the two disagree profoundly about secondary roads. Measured live: the motorway-free Ravenna→Florence route is 200 minutes according to Valhalla and 143 according to OSRM for the very same 135.4 km; Caltabellotta→Messina 621 vs 461; Udine→Genoa 639 vs 559. The avoidance option looked like a detour it never made. Roadstr now takes the road Valhalla found and re-times it with the engine that produced the other routes, by routing OSRM through waypoints sampled from that road — one every 5 km, a spacing measured to reproduce the same roads on journeys from 22 km to 1383 km. The check is per leg, so a single stretch OSRM refuses to follow costs the accuracy of that stretch alone instead of the whole re-timing; if less than half the route can be verified, or the request fails, the original figures are kept. Validated on 40 live runs: 29 journeys over 350 km across six continents (96–100 % of each route verified, no failures) plus 11 edge cases. The correction goes both ways — Delhi→Lucknow drops from 893 to 405 minutes, Houston→New Orleans rises from 535 to 627. Known limit: the public Valhalla refuses paths longer than 1500 km, so on those the avoidance switch reports no route (Perth→Adelaide). - **When the recommended route already avoids motorways and tolls**, the avoidance router returns that very same road; it is now recognised and the existing card is badged instead of showing the identical journey twice. - **Ferry routes are timed by the boat's schedule, not by a road router's guess.** OSM draws a ferry as a line with almost no points — Naples→Palermo arrives as a single 305 km straight jump — so sea crossings keep Valhalla's timing (it reads the crossing duration from OSM) while the driving on either side is still re-timed. - **"My reports" is no longer empty.** The profile page asked a single relay, relay.damus.io, which during testing refused a third of the connections outright (503) and answered one probe with no road event at all — so the page said "no reports yet" no matter how much the user had reported, while the map was displaying those very reports fetched from the other relay. Reports are now requested from every relay in parallel and merged, and the history window went from 30 days to a year. Pending speed-limit suggestions had the same defect: the first relay's empty answer hid what the others held. - **Editing the speed limit of an existing report no longer crashes** with the red "_dependents.isEmpty" screen. The dialog's text controller was disposed as soon as the dialog returned, while the dialog was still animating out and still rebuilding its text field — the disposed controller then brought the whole route down. The dialog now owns its controller and disposes it when it is really gone. Covered by a regression test. - **The report sheet scrolls.** A speed-camera report of your own, with a comment, a speed limit and pending suggestions, was taller than the sheet and overflowed into the yellow-and-black striped bar. - **The next-manoeuvre tile is back to half the screen width**, and a quarter shorter than before: the type scales with the box so the same instructions still fit. - **The speed-limit sign no longer sticks around after the route preview.** It is hidden while you are planning (preview, alternatives, planner, search and place panels), a cached limit now expires after 5 minutes instead of surviving forever while parked, and an Overpass query already in flight can no longer refill a cache that was just cleared. - **The restricted-traffic-zone (ZTL/ZAC) banner is back.** Zone data had kept being refreshed on every GPS fix, but the banner that displayed it was dropped when the map screen was split up — so entering a zone showed nothing at all. While navigating it now sits above the speed-limit sign, where it cannot cover the manoeuvre. - **The map no longer waits for a cold GPS lock before it moves.** The seeding from the position the OS already knows had been written for exactly that, then lost in a refactor: the method survived, its only caller did not. Restored. - **Coordinates on the Greenwich meridian no longer break OSM lookups.** A longitude below a millionth of a degree prints as `5e-7`, which Overpass rejects outright; speed limits, speed cameras, restricted zones and nearby searches now all format coordinates properly. - **Speed-limit updates apply newest-first** even when the update reaches the app before the report it belongs to. - **Fewer needless reroutes.** The off-route thresholds had been tuned against a distance calculation that read 28 % short north-south; with the geometry fixed they are retuned (30 m / 55 m) so a lane change no longer triggers a recalculation. - **Distances under 50 m read "0 m" / "0 ft"** instead of a bare "0" on the final approach. - Settings no longer risk a state update after the screen has been closed when saving the favourites-sync passphrase. ## Changed - **Four relays instead of two.** relay.primal.net and nostr.oxtr.dev join nos.lol and relay.damus.io. Each was verified end to end — publish a Roadstr event kind, then read it straight back — which is not a formality: of the candidates tested, two refused the write, one requires a web of trust, one requires AUTH, and three returned nothing at all for Roadstr's road-event kind. Reports are published to all four in parallel, and reports, confirmations, suggestions, profiles, visibility settings and zap receipts are now read from all four and merged, so no single relay outage can hide them (vote counts are merged, never summed, and zap receipts deduped by id, so nothing is double-counted). Redundancy without the wait: every relay is asked **at once**, never one after another, so the cost is the slowest relay rather than the sum of four. Measured against the live network: profile 0.2–0.9 s, my reports 0.4–0.7 s, edit suggestions 0.2–0.3 s, zap balance 1.6–1.7 s, and a Lightning address is cached for ten minutes so opening a second report costs nothing. A relay refusing the connection (damus answers 503 under load) is now caught where it happens instead of escaping as an unhandled error. - **Automatic dark theme is now off by default.** The theme you pick is the theme you get, until you turn sunset switching on yourself. - **Voice speed now defaults to 1.30×.** Kokoro's neutral pace is slower than a navigation voice needs to be — an instruction has to land before the junction. The pre-rendered start/arrival phrases now play at your chosen speed instead of being skipped whenever the speed was not exactly 1.0×, so they stay instant at any setting. ## Localisation - 21 strings — profile visibility, the notifications screen, and speed-limit editing/suggestions — were still English in every other language. They are now translated into all 26 non-English languages Roadstr ships with. - 38 leftover keys from removed features were dropped from all 27 translation files. ## Under the hood - The heading logic — which way the map faces, and the jitter, reversal and road-snap handling behind it — moved out of the GPS tick handler into a class of its own, six levels of nesting down to two, with thirteen tests where there were none. The GPS handler lost sixty lines with it. - The "my reports" relay listener was one hundred lines doing three jobs; it is now four named functions, and splitting it is what exposed the ordering bug above. - Dead code removed: an unused ZTL getter, an unused TTS alias, and the two heading state fields that left with the logic that used them. ## Housekeeping - Version bumped to 0.4.12 (versionCode 21) in `pubspec.yaml`, `README.md` and the F-Droid metadata. - The test suite went from 114 to 151: the same-road detection, the per-leg re-timing and its fallbacks, sea crossings, the heading filter, the nearby search (radius, unnamed places, sorting, de-duplication, cache, mirror failure) and its UI, and the speed-limit editing flow that used to crash.
  • Jul 21, 2026 0.4.11
    ## v0.4.11 (20) ### Notification - **Added notifications** for every zap, report and alert confirmed or discarded by other users. Notifications will not take place during navigation. - **Vocal alert for speed cameras**, when a user posts an alert for a speed camera a new field with speed limits can be filled. This will vocally alert users in close proximity. - **Bugfixes**, resized remaining time and remaining distance in a more properly dimensioned font.
  • Jul 20, 2026 0.4.10
    ## v0.4.10 (19) ### Location - **GPS now works on de-Googled devices (GrapheneOS, /e/OS, LineageOS without Google apps).** The app was binding to the Google Play Services location provider, which doesn't exist on these systems — so the map stayed stuck on a fallback position and never got a fix, no matter how long it searched. It now reads the GNSS hardware directly through the standard Android provider, which works on every device. Bonus: no location request touches Google Play Services on any device anymore — a privacy win for everyone. - **GPS warms up at launch again** (when location permission is already granted), so the first fix is ready when you need it instead of after a long cold start. You can turn this off in Settings.
  • Jul 20, 2026 0.4.9
    ## v0.4.9 (18) ### Routing - **Avoid highways & toll roads** now actually works. The feature was pointed at the wrong server (which returned a web page instead of route data), so every request silently failed. Fixed — the switch now returns a real motorway- and toll-free route, verified end to end. - **Long-distance walking & cycling routes no longer error out.** A transcontinental foot route (e.g. Boston → Miami, ~2,600 km / ~80,000 path points) was rejected as "too many points"; the internal limits are now generous enough for any realistic continental journey. ### Places - **Rich POI details on tap.** Tapping a place now shows the OpenStreetMap facts that matter: category, opening hours (open/closed now), phone, website, cuisine, operator, wheelchair access and address — no extra lookups, straight from the map data. ### Voice guidance
    More…
    - **New voice-volume slider.** Set the guidance volume independently of your media volume — turn it down when it's louder than your music, or up when a quiet podcast would otherwise drown it out. It still ducks other audio while speaking. - **Your own road reports are no longer read back to you.** Submitting a report used to trigger the very hazard announcement you just created, sometimes two or three times. Fixed. ### Location & units - **Faster "locate me."** The map now jumps to your last known position instantly while a precise fix warms up, instead of waiting several seconds on a cold GPS start. - **Imperial unit fixes.** Wind speed and the speed-limit sign now read in mph (they were still showing metric values under imperial units). ### Privacy - **Screenshots re-enabled.** Blocking all screenshots was overkill; the app-switcher thumbnail (which could reveal your location) stays hidden, but you can once again screenshot a route to share it.
  • Jul 18, 2026 0.4.8
    ### roadstrapp.0.4.8.apk ### Added - Added a strict BOLT11 invoice decoder with: - Network validation. - Amount and expiry verification. - Payment hash and description hash extraction. - Rejection of amountless and non-mainnet invoices. - Added bounded HTTP requests with streaming size limits, hard deadlines, and redirects disabled.
    More…
    - Added native OpenStreetMap information for POIs without a Wikipedia page: - Description. - Category. - Opening hours. - Operator and brand. - Cuisine. - Wheelchair accessibility. - Contact details. - Address and validated HTTPS website. - Added a restricted in-app Wikipedia reader. - Added an optional “Center on my position at startup” setting, disabled by default. - Added reproducible Android builds for the bundled eSpeak NG native libraries. - Added SHA-256 verification of bundled native assets before Android builds. - Added automated tests for BOLT11, bounded HTTP, road events, OSM POI details, and Wikipedia URL validation. ### Changed - Wikipedia articles now open inside Roadstr instead of immediately leaving the app. - Wikipedia lookup now verifies geographical and textual relevance before associating an article with a POI. - Minor POIs without Wikipedia remain useful through native OpenStreetMap data. - External web searches and POI websites require an explicit user action. - GPS no longer starts automatically when the app opens. - Startup GPS centering only runs when explicitly enabled and location permission has already been granted. - Speed limits are now displayed only when OpenStreetMap provides an explicit, unambiguous value. - Removed road-class and Italian default speed-limit inference to prevent incorrect limits. - Speed-limit matching now uses road geometry to avoid borrowing a limit from nearby parallel roads. - Optimized bundled eSpeak NG libraries, significantly reducing their size. - Updated and completed translations for all 27 supported languages. - Improved release signing behavior: unsigned builds are no longer silently replaced with debug-signed release artifacts. - Cleaned up static-analysis warnings and simplified several internal code paths. ### Security - Hardened LNURL and Nostr Wallet Connect payments: - Invoice amount must match the requested amount. - Description hash must match the zap request. - Expired invoices are rejected. - NWC response kind, author, tags, signature, and request binding are verified. - Empty payment results are no longer treated as success. - Payment preimages are verified against the invoice payment hash. - Replay paths are rejected. - Hardened the Wikipedia WebView: - Only validated HTTPS Wikipedia article URLs are allowed. - JavaScript is disabled. - Cookies, cache, and local storage are cleared. - WebView permissions are denied. - File access and mixed content are disabled. - SSL errors fail closed. - External redirects and deceptive Wikipedia-like domains are blocked. - Sanitized and length-limited all untrusted OpenStreetMap POI fields. - POI websites are accepted only when using HTTPS without credentials or custom ports. - Made Hive migrations fail closed with atomic backups instead of deleting unreadable data. - Added timestamp, expiration, TTL, coordinate, category, and duplicate-tag validation for road events. - Added anti-spoofing checks between event coordinates and geohash tags. - Added bounded relay caches to prevent unbounded memory growth. - Fixed stale asynchronous relay results through generation-based request invalidation. - Enforced the NIP-44 padding limit instead of producing oversized payloads. - Removed the Android `ACCESS_BACKGROUND_LOCATION` permission. - Prevented the initial fallback map position from being published to Nostr relays. - Removed committed environment secrets and strengthened repository ignore rules. ### Fixed - Fixed incorrect Wikipedia pages being assigned to nearby minor POIs. - Fixed stale asynchronous map and POI responses overwriting newer selections. - Fixed possible data loss during local database migrations. - Fixed expired or future-dated road events remaining visible or being accepted. - Fixed malformed or spoofed Nostr road events reaching the UI. - Fixed transient speed-limit results leaking between roads or navigation sessions. - Fixed release builds falling back to the debug signing key. - Fixed several race conditions in GPS, relay subscriptions, and map updates. - Fixed unbounded network responses and slow-response resource exhaustion. - Fixed multiple dead-code paths and obsolete services/widgets. ### Removed - Removed inferred speed limits based only on road classification. - Removed unused location-service code. - Removed obsolete HUD widget code. - Removed obsolete WebView ProGuard rules. - Removed generated Android build reports from source control. - Removed the background-location permission. ### Validation - `flutter analyze`: no issues found. - `flutter test`: 46 tests passed. - Android debug APK: built successfully. - Android release APK with R8: built successfully. - All 27 localization files contain the complete message set. ## What's Changed ### POI Search and Navigation Flow - Search results now open on the map before route calculation begins. - Selected POIs are automatically framed and displayed with their complete OSM information panel. - Applied the same information-first flow to search submission, history entries, and favorites. - Added a localized **Navigate here** button to the POI information panel. - Tapping **Navigate here** opens the complete route-selection preview. - Route selection is now available for short trips and single-route results. - Car, bicycle, and walking modes remain available. ### Highway and Toll Avoidance - Added an **Avoid highways and toll roads** toggle for driving routes. - The avoidance option adds a dedicated route without replacing standard alternatives. - Implemented a hybrid routing strategy: - Strictly excludes highways and toll roads whenever possible. - Automatically falls back to soft avoidance when strict exclusion cannot produce a route. - Soft avoidance applies: - Minimum highway preference. - Minimum toll-road preference. - A 900-second virtual toll-booth routing penalty. - Routing penalties influence route selection without artificially increasing the displayed ETA. - Added validation of Valhalla's `has_highway` and `has_toll` route summary fields. - The selected avoidance policy is preserved during automatic rerouting. ### Route Preview UI - Fully highway- and toll-free routes are displayed in green. - Routes containing an unavoidable highway or toll section are displayed in amber. - Added explicit route-card labels distinguishing strict avoidance from minimized usage. - Avoidance routes display both duration and distance in the configured metric or imperial units. - Updated route lines, time bubbles, cards, toggle styling, and loading feedback. - Protected toggle changes, mode switching, and concurrent calculations against stale asynchronous results. ### Localization - Added the new avoidance controls and unavoidable-section messaging to all 27 supported languages. - Regenerated all Flutter localization classes. ### Code Quality - Removed the obsolete search-pin panel and its unused state. - Removed unreliable provider-specific OSRM and GraphHopper avoidance parameters. - Replaced parallel UI state with route-level avoidance metadata. - Added bounded Valhalla polyline decoding and maneuver parsing. - Added defensive validation for route geometry, instructions, distance, duration, and provider responses. - Standard route alternatives remain available while the additional avoidance route is calculated.
  • Jul 17, 2026 0.4.7
    ## v0.4.7 (16) This release is a privacy hardening pass focused on the most sensitive data the app touches: your saved favorites (home/work addresses) and your Nostr identity. ### Favorites sync — privacy hardening - **Stopped relays from enumerating Roadstr users.** The sync event used a fixed, human-readable tag (`roadstr-favorites`), so a single relay query could list every npub using the app — a ready-made target list. The tag is now a per-user hash, so that bulk query no longer works. - **Optional sync passphrase.** You can now add a second encryption layer (PBKDF2 + AES-256-GCM) on top of the existing NIP-44 encryption. With it set, even a compromised Nostr key isn't enough to decrypt the favorites snapshot an attacker pulled or archived from relays. Set it once per device under Settings → favorites sync. - **Rollback protection.** Pull now queries all relays in parallel and keeps the newest verified snapshot, with a local high-water mark that rejects anything older — a malicious relay can no longer resurrect deleted favorites or restore a stale address by replaying an old (validly signed) event. - **Metadata minimization.** The snapshot is padded to a fixed size bucket before encryption (so ciphertext length no longer reveals how many favorites you have), and its timestamp is rounded to the hour (no more broadcasting the exact second you edited a favorite). - **Removed `relay.nostr.band` from sync** — it feeds a public search indexer, the worst place to park privacy-sensitive events.
    More…
    ### Location privacy - **Screen capture is now blocked (FLAG_SECURE).** Previously, minimizing the app left a live screenshot of the map — centered on your current location — as the recents/app-switcher thumbnail, visible to anyone who opened the task switcher. This also blocks screenshots and screen-recording of the app. (Trade-off: you can no longer screenshot a route to share it.) - **Coarser location subscriptions.** The road-event area subscription no longer sends a ~5×5 km geohash to the relay on every move; it now sends only the ~40×20 km cell, which matches the exact same events while giving relays a far coarser view of where you are. - **Opaque request identifiers.** Relay subscription IDs no longer carry descriptive prefixes that let a relay fingerprint the app or tell what each request was for. - **Weather requests are rounded** to ~1 km before being sent to the weather provider (the destination is often home; weather doesn't need street-level precision). ### Notes - Nostr private keys (nsec) remain stored only in Android's encrypted secure storage, are never transmitted, never logged, and cannot be revealed, exported, or copied out of the app. - Snapshots synced before this release keep their encrypted contents safe, but their metadata (the old readable tag, exact timestamps) is already public on relays; re-syncing after setting a passphrase is recommended for the strongest protection.
  • Jul 17, 2026 0.4.6
    ## v0.4.6 (15) ### ZTL (limited-traffic zones) - **Fixed a bug that made ZTL detection silently fail since the feature shipped.** The Overpass query used `["name"~"ZTL","i"]` — the quoted `"i"` is a syntax error in Overpass QL (case-insensitive regex needs an unquoted `,i`), so every ZTL fetch failed, on every mirror, from day one. - **Rewrote ZTL detection to match how Italian zones are actually mapped.** Italian ZTLs are tagged per-street (`motor_vehicle=permit`, `access=no/destination`, `highway=pedestrian`), not as named polygons — the old polygon-only query returned nothing even after the syntax fix. Detection is now proximity-based (≤12 m from a restricted way) in addition to the legacy polygon lookup, verified live against Ravenna's centro storico (251 restricted ways) and cross-checked against the ~350 Italian cities that do use the official `boundary=limited_traffic_zone` polygon tag. - **Removed the `overpass.osm.ch` mirror.** It turned out to be a Switzerland-only data extract that returned HTTP 200 with zero results for anywhere else — every dependent feature (ZTL, speed limits, speed cameras, POI search) silently read that as "nothing here." Replaced with two verified worldwide mirrors. - **Verified live against 24 cities worldwide** (12 European historic centres, 12 US cities/car-free towns) to check the new detection actually generalises rather than just fixing Italy. Works well anywhere OSM has restricted-access tagging; known gap where a town's equivalent has never been mapped by the local OSM community (e.g. Tangier Island, VA); intentionally does *not* flag toll-only zones (NYC congestion pricing, London ULEZ) as ZTL, since those don't restrict entry. - **The warning banner now shows the correct local term** instead of the Italian "ZTL" everywhere — "ZTL" in Italy and France (both use the same official term), "ZAC" in Portugal, a generic translated phrase elsewhere. Countries with no single official acronym (Spain, Germany, UK…) no longer get one invented for them. - Fixed the spoken ZTL warning, which previously had translations for only 9 of the app's 27 languages and silently fell back to English for the rest.
    More…
    ### Navigation - **Map no longer flips 180° mid-drive.** A GPS multipath glitch could teleport a fix 20+ m backward with an inverted bearing, slipping past the existing distance-based filter. A direction reversal during active navigation is now trusted only after two consecutive GPS samples agree on it — a real U-turn confirms itself on the next fix, a glitch doesn't. - **Voice no longer repeats the same instruction 3–4 times** on approach to a manoeuvre. The same normalised instruction is now suppressed for 12 seconds at the single choke-point every announcement passes through. - **Navigation cursor sits further down the screen**, trading a bit of "behind you" for more visible road ahead. - Renamed the button on the pin/place-info panels from "Start navigation" (which actually opened a route preview) to "Show route preview" — "Start navigation" now only appears where navigation genuinely starts. ### Security - **A malicious relay could have redirected Lightning zaps to its own wallet.** `fetchLightningAddress` trusted a relay's kind-0 profile event without checking its id hash, signature, or that the pubkey matched the person being zapped — fixed by verifying every profile event the same way road events already were. - **Logging out no longer destroys local data.** It previously called `deleteAll()` on secure storage, wiping the encrypted-settings key along with it — undecryptable on next launch, silently taking favourites, history and routing/NWC config with it. Logout now removes only the 5 Nostr-identity keys. - One-time report/confirmation fetches (profile screen) now verify event signatures and enforce one-vote-per-identity, matching the live subscription's rules — previously trusted unverified relay data and allowed repeat votes. - Amber (NIP-55) event publishing now broadcasts to all configured relays instead of only the primary one, matching nsec-login behaviour. - NIP-44 decryption now enforces the exact padded length the spec prescribes, rejecting malformed payloads other implementations would also refuse. - Consolidated three duplicated event-verification implementations into one shared, tested helper. ### Legal - **Rewritten as a proper worldwide terms-of-use, in all 27 languages**: an explicit assumption-of-risk clause covering accidents, injury, fines and legal consequences in any country; expanded no-warranty language; an indemnification clause; a severability clause. Speed-limit, speed-camera and ZTL data are now explicitly disclosed as community-sourced and not authoritative.
  • Jul 12, 2026 0.4.5
    ## v0.4.5 (14) ### Search & POI - **Search now favors places near you.** Nominatim results are biased toward your GPS position and re-sorted by distance — fixes generic terms like "cinema" or "supermercato" ranking a same-named place on the other side of the world above the one down the street. - New **category/brand search** (Overpass-powered): typing "farmacia," "benzinaio," or a store brand name now searches OSM directly within a radius of your position, sorted by real distance — independent of Nominatim's global relevance ranking. ### Speed cameras - Added an **OSM-sourced speed camera layer** (`highway=speed_camera` / `enforcement=maxspeed`), shown on the map with a distinct muted marker and included in the proximity beep — additive to, never replacing, community-reported Nostr cameras. ### Parking
    More…
    - **Save your parking spot** — a dedicated button for "I'm here now," plus a long-press map option for "actually it was back there" when you've already walked off. Local-only, never touches Nostr, persists until you clear it. ### Favorites: export, encryption, sync - **Export favorites to JSON**, with optional password encryption (PBKDF2 + AES-256-GCM). - **Encrypted cross-device sync via Nostr** — favorites publish as a self-encrypted NIP-44 event (kind 30078); relays only ever see ciphertext, nobody but you can read the contents. NIP-44 was implemented from scratch (the Nostr library in use didn't support it) and covered by round-trip tests. - Onboarding now explains the encrypted/anonymous sync option. ### Arrival precision - Arrival radius on the last leg is now **dynamic based on live GPS accuracy** (10–40 m) instead of a flat 60 m — tight and precise with a good fix, still forgiving in a parking garage or urban canyon. ### Voice - **Male voice option** added for every supported language except French (Kokoro-82M has no French male voice) — pick it in Settings, with a live preview sample. - **6-stage speech speed slider**, also previewable before committing. - Smoother navigation camera: replaced the fixed-duration tween with a continuous exponential-smoothing follow — removes the faint stutter that showed up when a new GPS fix landed mid-animation. - Secondary instruction panel width fixed to exactly half the screen (was growing unbounded with long text); speed-limit sign no longer overlaps the bottom nav panel. ### Cursor - Removed the extra cursor styles (muscle car, SUV, compact, vespa, moto, bike) — down to **arrow*. The others were too tacky. ### Security & privacy - Full security audit: removed a **dead, exported deep-link intent-filter** that any website could have triggered. - Replaced a Russian-hosted Overpass mirror with a Swiss one — no more real-time GPS coordinates going to a VK/mail.ru-operated server. - Fixed a crash from using a stale screen reference after an async gap. - Verified: private keys never leave secure storage, all incoming Nostr events are signature-verified, no tracking/analytics SDKs, encrypted local settings. - **License clarified as GPL-3.0** (copyleft) — README previously and incorrectly said MIT. - Cleaned up ~120 lint warnings and dead code.
  • Jul 11, 2026 0.4.3
    ## v0.4.3 (12) ### Navigation - **Speed limits actually work now.** The root cause: `annotations=maxspeed` is a Mapbox-only extension — vanilla OSRM (including the FOSSGIS server we use) never returned it. Speed limits now come from Overpass, with class-based inference (motorway/trunk/residential/living_street) for the many roads that have no explicit `maxspeed` tag, 3 rotating mirrors for reliability, and support in free-roam driving (not just active navigation). - **Recenter button** now pulls a fresh one-shot GPS fix instead of reusing the last stream sample, so it snaps to your *actual* current position. - **Compass/heading button** is a real toggle in both navigation and free-roam — free-roam heading-up mode now rotates the map with the magnetometer instead of doing nothing. - **Secondary instruction panel** (next-turn preview) enlarged ~100% — bigger icon, bigger text, easier to read at a glance. ### Voice - Turn instructions and hazard/ZTL alerts no longer cut each other off mid-sentence. Maneuvers are priority (interrupt immediately); ambient alerts queue and wait their turn, keeping only the most recent one.
    More…
    - Fixed a race in audio ducking where a stale utterance could release focus meant for a new one, breaking the "duck other media" behavior. ### Security - Nostr events are now cryptographically verified (event hash + BIP-340 signature) before being trusted — a malicious relay could previously fabricate road reports or confirmations under any pubkey. - One vote per identity per event confirmation (was previously unlimited/re-countable). - Local settings (favorites, search history) are now AES-256 encrypted at rest, key held in the Android Keystore. - `debugPrint` is silenced in release builds — no more street names/coordinates/TTS phrases in logcat. - Event comments capped at 500 chars to prevent relay-side payload abuse. ### Onboarding - Welcome page now shows the real app logo and a privacy notice recommending a VPN (Mullvad, Bitcoin-payable) given that road reports propagate over Nostr. - nsec login page now shows the same security disclaimer as the profile screen. - Fixed the Kokoro voice download completion indicator — it was implemented but never actually triggered (listener was waiting on a stream event that never fires); now shows a white check on a green circle when the download finishes. - GrapheneOS guidance now mentions setting location permission to "Allow all the time," not just "while in use."
  • Jul 11, 2026 0.4.4
    ## v0.4.3 (12) ### Navigation - **Speed limits actually work now.** The root cause: `annotations=maxspeed` is a Mapbox-only extension — vanilla OSRM (including the FOSSGIS server we use) never returned it. Speed limits now come from Overpass, with class-based inference (motorway/trunk/residential/living_street) for the many roads that have no explicit `maxspeed` tag, 3 rotating mirrors for reliability, and support in free-roam driving (not just active navigation). - **Recenter button** now pulls a fresh one-shot GPS fix instead of reusing the last stream sample, so it snaps to your *actual* current position. - **Compass/heading button** is a real toggle in both navigation and free-roam — free-roam heading-up mode now rotates the map with the magnetometer instead of doing nothing. - **Secondary instruction panel** (next-turn preview) enlarged ~100% — bigger icon, bigger text, easier to read at a glance. ### Voice - Turn instructions and hazard/ZTL alerts no longer cut each other off mid-sentence. Maneuvers are priority (interrupt immediately); ambient alerts queue and wait their turn, keeping only the most recent one.
    More…
    - Fixed a race in audio ducking where a stale utterance could release focus meant for a new one, breaking the "duck other media" behavior. ### Security - Nostr events are now cryptographically verified (event hash + BIP-340 signature) before being trusted — a malicious relay could previously fabricate road reports or confirmations under any pubkey. - One vote per identity per event confirmation (was previously unlimited/re-countable). - Local settings (favorites, search history) are now AES-256 encrypted at rest, key held in the Android Keystore. - `debugPrint` is silenced in release builds — no more street names/coordinates/TTS phrases in logcat. - Event comments capped at 500 chars to prevent relay-side payload abuse. ### Onboarding - Welcome page now shows the real app logo and a privacy notice recommending a VPN (Mullvad, Bitcoin-payable) given that road reports propagate over Nostr. - nsec login page now shows the same security disclaimer as the profile screen. - Fixed the Kokoro voice download completion indicator — it was implemented but never actually triggered (listener was waiting on a stream event that never fires); now shows a white check on a green circle when the download finishes. - GrapheneOS guidance now mentions setting location permission to "Allow all the time," not just "while in use."
  • Jul 7, 2026 0.4.1
    <h2>🔒 v0.4.1 — Navigation polish &amp; security hardening</h2> <h3>Navigation fixes</h3> <ul> <li><strong>TTS timing</strong> — Voice announcements now adapt to transport mode. Walking uses tighter distances (far 60 m · near 15 m); cycling uses intermediate distances (far 150 m · near 30 m); driving is unchanged. Back-to-back announcements on short steps are suppressed to prevent the "silencing" effect.</li> <li><strong>Walking arrival radius</strong> — Arrival is now confirmed at 15 m instead of 40 m when navigating on foot, so a 300 m route no longer triggers arrival halfway through.</li> <li><strong>Arrival screen removed</strong> — The 👍/👎 feedback dialog is gone. On arrival the destination pin turns green with a ✓ icon and stays visible on the map; a brief banner auto-dismisses after 6 seconds.</li> </ul> <h3>Security hardening</h3> <ul> <li><strong>EncryptedSharedPreferences enabled</strong> — All four <code>FlutterSecureStorage</code> instances now use <code>encryptedSharedPreferences: true</code>, encrypting both keys and values via Android Keystore (not just values).</li> <li><strong>NWC URI moved to SecureStorage</strong> — The <code>nostr+walletconnect://</code> URI (which contains a Lightning wallet private key) was stored in plain Hive. It is now stored in Android Keystore-backed SecureStorage. Automatic migration from Hive on first launch.</li> <li><strong>Routing API keys moved to SecureStorage</strong> — GraphHopper Cloud and OpenRouteService API keys were stored in plain Hive. Migrated to SecureStorage with the same automatic migration path.</li> <li><strong>WebView hardened</strong> — The Wikipedia/search WebView now blocks any navigation to non-HTTPS URLs via <code>onNavigationRequest</code>.</li> <li><strong>ADB backup disabled</strong> — <code>android:allowBackup="false"</code> added to <code>AndroidManifest.xml</code>. Prevents <code>adb backup</code> from extracting app data (including the Hive settings file) from an unlocked device with USB debugging enabled.</li> <li><strong>Release logging</strong> — Replaced a <code>print()</code> call in <code>gps_service.dart</code> (visible in logcat in release builds) with <code>debugPrint()</code> (stripped in release).</li> </ul> <blockquote> <strong>Migration note:</strong> NWC URI and routing API keys are migrated automatically from Hive to SecureStorage the first time each relevant screen is used after the update. No manual action required. </blockquote>
  • Jul 6, 2026 0.4.0
    <h2>First-launch onboarding</h2> <ul> <li>4-page flow on first install: features showcase → Nostr identity → permissions → ready.</li> <li>Nostr login via <strong>Amber NIP-55</strong> (recommended) or <strong>nsec key</strong> (stored in Android Keystore). Profile name and avatar fetched from relay immediately after login.</li> <li>Dedicated <strong>GrapheneOS guidance</strong>: grant Precise location <em>and</em> "Allow always" to keep GPS active in background.</li> <li>Optional <strong>Kokoro AI voice model</strong> download (82 MB) with live progress bar — can be deferred to Settings.</li> <li>Pages freely swipeable. Fully localised in all 27 supported languages.</li> </ul> <h2>ZTL / restricted zone ahead warning</h2>
    More…
    <ul> <li>Checks whether an upcoming turn leads <em>into</em> a restricted zone at the moment the instruction is announced — before the user enters.</li> <li><strong>Orange banner</strong> + spoken voice warning at that point. One warning per step, no repeated alerts.</li> <li>Distinct from the existing <strong>red banner</strong> shown when already inside a ZTL.</li> <li>Warning spoken in the user's language at runtime.</li> </ul> <h2>Missed-turn rerouting</h2> <ul> <li>After advancing to a new step, a <strong>2.5-second guard timer</strong> verifies the user is actually approaching the next waypoint.</li> <li>If distance hasn't improved and speed is above 3 km/h, silent reroute triggers automatically.</li> </ul> <h2>TTS announcement improvements</h2> <ul> <li>Urban steps now receive an <strong>immediate voice announcement</strong> right after a maneuver, replacing the previous premature 220 m trigger.</li> <li>Announcement distances adapt to road type and current speed.</li> </ul> <h2>Cursor styles overhaul</h2> <ul> <li><strong>7 selectable cursors</strong> rendered from SVG assets: Arrow, Muscle Car, SUV, Compact, Vespa, Racing Moto, Bicycle.</li> <li>Settings cursor grid replaced with a <strong>dropdown with live icon preview</strong>.</li> </ul> <h2>Localisation sweep</h2> <ul> <li>Event categories, transport mode chips, time labels, and weather strings now fully localised across all <strong>27 supported languages</strong>.</li> <li><strong>40 new ARB keys</strong> covering all onboarding screen strings.</li> </ul> <h2>Other improvements</h2> <ul> <li>Route preview panel now supports <strong>drag-to-close</strong> gesture with spring-back animation.</li> <li>Secondary nav instruction row shows distance to next maneuver.</li> </ul>
  • Jul 4, 2026 0.3.4
    <h2>v0.3.4 — Nav UX overhaul, roundabout icons, speed alerts</h2> <h3>New features</h3> <ul> <li>Nav banner now full-width edge-to-edge, covering the status bar area, with ~30% larger text</li> <li>Next-step preview row below the main instruction</li> <li>Roundabout exit icon: custom-drawn painter, exits 1–6, CCW arc — no Overpass API needed</li> <li>TTS: ordinal symbols (1°, 2°…) normalised to spoken words before synthesis</li> <li>Adaptive TTS announcement distances based on road type and current speed</li> <li>Speed limit exceeded → red speedometer arc, text and border</li>
    More…
    <li>Speed camera proximity alert: dual-tone beep (350 Hz + 440 Hz) within 250 m</li> <li>Weather row (Open-Meteo, no API key) in Alternatives panel and Pin panel</li> <li>Drag-to-close gesture on Alternatives panel</li> </ul> <h3>Bug fixes</h3> <ul> <li>Search bar restored to floating position (was accidentally pinned to screen top edge)</li> <li>Roundabout painter geometry corrected: arc now sweeps counter-clockwise (right-hand traffic)</li> <li>Alternatives panel horizontal overflow fixed; title/chip spacing improved</li> <li>Avoid motorways / avoid tolls chips now shown only when GraphHopper is selected</li> </ul>
  • Jul 4, 2026 0.3.3
    <h2>Roadstr 0.3.3</h2> <h3>Navigation</h3> <ul> <li><b>Map and cursor follow direction of travel</b> — definitive fix: <code>_toggleHeadingMode</code> is now a real toggle; <code>_recenter</code> re-enables heading mode during active navigation</li> <li><b>Rerouting on U-turn</b> — added bearing-difference check (&gt;150° at &gt;10 km/h) as a second reroute trigger alongside the existing distance check</li> </ul> <h3>Routing</h3> <ul>
    More…
    <li><b>Route alternatives</b> — panel shows multiple options when available (distance &gt;5 km)</li> <li><b>Cycling mode</b> — new "Bike" chip routing through the dedicated OSRM cycling endpoint, preferring cycle paths</li> <li><b>Route preferences</b> — "Avoid highways", "Avoid tolls", "Shortest route" chips (shown only with GraphHopper/ORS, hidden on OSRM)</li> <li><b>Drag-to-close</b> — alternatives panel closes on downward drag or flick; includes slide-in animation on open</li> </ul> <h3>Weather (Open-Meteo, no API key required)</h3> <ul> <li>Temperature, condition and wind speed shown in the alternatives panel and quick-search pin popup</li> <li>Lazy async loading, silent failure when offline</li> </ul> <h3>UI fixes</h3> <ul> <li>Fixed overflow in alternatives panel on narrow screens (&lt;360dp): title and mode chips are now on separate rows with horizontal scroll</li> <li>GPS camera animation: <code>_gpsAnimMs = 600</code> for continuous 60fps movement</li> </ul>
  • Jul 4, 2026 0.3.2
    Minor bugfixes and updated translations.
  • Jul 3, 2026 0.3.1
    Added vocal directions and bugfixes.
  • Jun 28, 2026 0.2.1
    First public release.