v2.6.0-beta2
Pre-release
Pre-release
Immutable
release. Only release title and notes can be modified.
Security
This release addresses a security advisory covering several intent-handling vulnerabilities. Users are strongly encouraged to upgrade. Thanks to Noel Gomillion & Pranati Majhi at Texas A&M for working with us on this.
- External configuration loading (via
owntracks://URLs and config files) is now disabled by default and must be explicitly enabled in Settings → Advanced - A confirmation dialog is shown when enabling external configuration, warning that any config URL can fully reconfigure the app
- The
allowIntentControlintent receiver now requires a shared secret (intentAuthKey) in every intent, preventing unauthorised apps from triggering location publishes or changing monitoring mode BackgroundServiceis no longer exported; only explicit intents from within the app are accepted. TheSEND_LOCATION_USERandCHANGE_MONITORINGactions have moved to a new exportedExternalIntentReceiver. N.B. automations sending these (e.g. Tasker) must now target a broadcast receiver rather than a service, and must set the package toorg.owntracks.android— an action-only broadcast is silently dropped by Android's background execution limitsEXITandSEND_EVENT_CIRCULARintent actions have been removedOngoingNotificationservice intents are now explicit- Security-related preferences (
allowConfigurationByURIAndConfigFile,allowIntentControl,intentAuthKey) cannot be changed via imported config files or URLs - Certificate fingerprint verification migrated from SHA-1 to SHA-256
New features
- New Remote Control preferences screen showing the intent auth key (with a copy-to-clipboard button) for use with automation apps such as Tasker
- Config import screen now shows a structured diff of what is changing, with human-readable preference names, highlighting new values alongside the current values — unchanged settings are summarised rather than listed in full
- Waypoints in an imported config are listed individually in the import review screen
- Preference setting (Android 16 and later only) to allow user to enable GNSS location source for Significant Monitoring mode (#2155)
- New opt-in, config-import-only
maxImplausibleSpeedKmhpreference: drops a published location fix if it implies travel faster than the configured maximum ground speed relative to the last published fix, to filter out occasional wildly-inaccurate network-provider locations (#2034)
Bug fixes
- DEBUG and VERBOSE log messages are no longer emitted to the system Logcat in release builds, preventing potential PII (e.g. coordinates) leakage via
TimberInMemoryLogTree(CWE-532) - HTTP mode no longer treats an unparsable or empty response body as a send failure. A
200 OKresponse is sufficient to confirm a message was delivered successfully; response body parse errors are logged as warnings and ignored (#2242) - Fix geofences silently failing to register with Google Play Services on devices with significant uptime, due to a
Long.MAX_VALUEoverflow when computing the expiration time (#2245, thanks @Cooad) - Waypoint editing had a race when loading the existing waypoint from Room, causing UI overwrites and other inconsistent behaviour. Fixed by only enabling the UI once the waypoint is loaded (#2130)
- Set the en locale'd strings.xml to be the same as the generic fallback. Hopefully this fixes weirdness on devices with an en-US fallback locale (#2112).
- Waypoint region state no longer flips back and forth ("bouncing") when a location fix lands near the boundary. GMS builds now rely solely on the native Play Services geofencing API, which already has its own hysteresis, instead of racing it against the app's own per-fix distance check; OSS builds (which have no native geofencing to fall back on) now require a region transition candidate to persist for 2 minutes before it's committed
- Remote "reportLocation" requests are no longer silently dropped by the new (opt-in) implausible-speed filter
discardNetworkLocationThresholdSecondshad its check the wrong way round, discarding a high-accuracy gps/fused fix that arrived shortly after a network one, rather than the other way about. It now behaves as documented. Only affects users who had set this preference; it is disabled by default (#2289)- MQTT mode could get permanently stuck after a network change, queueing messages indefinitely until the app was force-stopped and reopened. A connect attempt that failed while the new network was still settling (typically a DNS failure moments after WiFi associated) left the endpoint in an error state that no later network event would retry, and a background service restart could silently kill the outgoing message loop for the remaining lifetime of the process (#2294, thanks @tobru)
- A periodic check now verifies that the MQTT connection is genuinely alive, and reconnects if it isn't. Previously every reconnect was triggered by an event — a connectivity change, a dropped connection, a failed publish — so a connection that had died silently (common when a mobile network drops, since the socket stays readable until something is written to it) was reported as connected indefinitely and never repaired (#2294)
- The gap between MQTT reconnection attempts is now capped at 10 minutes. It previously doubled without limit up to WorkManager's five-hour maximum, which a run of failures reached in well under a day — after which a broker that had become reachable again might not be noticed for hours. Reconnection is also no longer abandoned outright when the endpoint is not yet configured (#2294)
- A scheduled MQTT reconnection attempt no longer disconnects an already-healthy connection when a faster path (typically the network becoming available again) restores it first. Previously the scheduled attempt ran regardless, occasionally turning a connection that never needed fixing into a brief real outage if the unnecessary reconnect happened to hit a transient failure of its own (#2294)
- MQTT client-certificate connections no longer route through a PKCS12
KeyStore, working around theInvalidKeyExceptionsome devices' vendored BouncyCastle threw loading one (#1225) at the source rather than by installing a full replacement crypto provider app-wide. Also shrinks the app: that provider's-keeprules alone accounted for over a quarter of the app's classes