Skip to content

feat(bluetooth): reconnect automatically when the scale link drops - #1566

Closed
kashif-khan wants to merge 1 commit into
oliexdev:masterfrom
kashif-khan:feat/auto-reconnect-dropped-link
Closed

kashif-khan wants to merge 1 commit into
oliexdev:masterfrom
kashif-khan:feat/auto-reconnect-dropped-link

Conversation

@kashif-khan

Copy link
Copy Markdown
Contributor

Problem

When a Bluetooth scale ends the connection by itself, openScale stays disconnected until the user taps the connect icon again. That is the usual case for scales that power off after a weigh-in: the connection is lost about 18 s after the scale's last packet (CONNECTION_TIMEOUT), and the next weigh-in is not picked up. Vendor apps keep listening instead.

Change

With the existing auto-connect setting on, BleConnector now starts a new connection to the same scale after an unexpected drop. The new attempt scans for the saved address until the scale advertises again (the adapter has no scan timeout), so a scale that went to sleep is picked up as soon as it wakes.

  • Backoff: repeated quick drops back off 2 s, 4 s, 8 s … up to 30 s (ReconnectPolicy). A connection that stayed up for 20 s or more starts the sequence over.
  • Only real drops: BluetoothEvent.Disconnected gets a requested flag. GattScaleAdapter sets it when the app or a device handler asked for the disconnect (requestDisconnect(), which 39 handlers call after a finished weigh-in). Those never trigger a reconnect, so handlers that disconnect on purpose behave as before. SPP reports its normal end of session as requested, so SPP scales are not reconnected.
  • Stopping it: the connect/disconnect icon's disconnect, or turning the setting off while a reconnect is pending, cancels it. A connection the user starts by hand also resets the backoff.
  • The English label of the setting now reads "Auto-connect on startup and after drops" (other languages are left to Weblate).

What was verified

On a Samsung Galaxy S24 Ultra (SM-S928W, Android 16) with a Urikar Aero I Pro (a GATT scale, using a handler that is not part of this PR). Each weigh-in ends with the scale switching itself off, then:

Disconnected from D0:4D:…  Reason: CONNECTION_TIMEOUT        (requested=false)
Link to Aero I dropped unexpectedly. Reconnecting in 2000 ms.
Found D0:4D:… → stop scan + connect                         (scale woke up again)
Event: Connected to Aero I

The scale was picked up again, without tapping connect, on every drop in my test sessions (five times in the first session, with the backoff going 2 s, 2 s, 4 s, then back to 2 s after a connection that lasted over 20 s), and each weigh-in after a reconnect was saved.

./gradlew :app:testDebugUnitTest passes (936 tests, including 4 new for ReconnectPolicy).

Not verified

  • Pressing disconnect, and turning the setting off while a reconnect is pending, are covered by the code path but were not exercised on the device.
  • Only that one scale and the GATT adapter were tried. The requested flag keeps handler-initiated disconnects out of the reconnect path, but I did not exercise other handlers.
  • The reconnect lives as long as the connection manager, so it works while the app is open. There is no foreground service, so nothing is kept alive in the background.
  • While waiting for the scale the top-bar icon shows "connecting" and tapping it only shows a message; turning the setting off ends the wait. I left the icon behaviour alone.

A GATT scale that hangs up on its own (it went to sleep, or dropped the link after a few
seconds) left openScale disconnected until the user tapped connect again. Vendor apps keep
listening for the next weigh-in instead.

When the existing auto-connect setting is on, BleConnector now starts a new connection to the
same scale after an unexpected drop. The attempt scans until the scale advertises again, so a
sleeping scale is picked up as soon as it wakes. Repeated quick drops back off from 2 s up to
30 s (ReconnectPolicy); a connection that stayed up for 20 s starts over.

Disconnects that the app or a device handler asked for never trigger it: GattScaleAdapter now
reports them through BluetoothEvent.Disconnected.requested, so the 39 handlers that disconnect
after a finished weigh-in behave as before. SPP sessions report their normal end as requested
and are not reconnected. Pressing disconnect, or turning the setting off, cancels a pending
reconnect.

The setting's English label now says it also covers drops.
@oliexdev

Copy link
Copy Markdown
Owner

Thanks for your PR, but I'd rather not add this.

  • Most people weigh in once a day and open the app for it, and "auto-connect on startup" already
    covers that. Reconnecting only helps while the app process stays alive between weigh-ins.
  • In the case it targets, several people weighing in one after another, the reconnect saves the next
    weigh-in to whoever is still selected unless smart assignment is on. Today the tap to connect is
    also the moment the right user gets picked.
  • It changes the behaviour of every GATT handler that leaves the disconnect to the scale (about 30)
    and keeps scanning without a time limit after each weigh-in, also in the background.

Closing it for now.

@oliexdev oliexdev closed this Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants