Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,27 @@ Per [answer](https://stackoverflow.com/a/50273724) to "What exactly does Android
> dedicate more radio time to listen for connectable advertisements for the remote device, i.e. the connection will be
> established faster.

> [!IMPORTANT]
> `autoConnect` only influences how a connection is _established_ (as described above); it does **not** enable
> automatic **re**connection.
>
> While Android documentation (and the answer quoted above) describe `autoConnect` connections as being automatically
> re-established by the system after a disconnect (until `disconnect()` or `close()` is called), Kable closes the
> underlying [`BluetoothGatt`] as soon as a disconnect occurs, so Android's system-level reconnect behavior never takes
> effect. In other words: Kable never automatically reconnects, regardless of the `autoConnectIf` setting.
>
> To implement automatic reconnection, monitor the [`state`] [`Flow`] and call [`connect`] when [`Disconnected`] state
> is observed, for example:
>
> ```kotlin
> peripheral.state.onEach { state ->
> if (state is State.Disconnected) {
> peripheral.connect()
> delay(2.seconds) // Throttle reconnects so we don't hammer the system if connection immediately drops.
> }
> }.launchIn(scope)
> ```

One possible strategy for a fast initial connection attempt that falls back to lower battery usage connection attempts is:

```kotlin
Expand Down Expand Up @@ -661,6 +682,7 @@ limitations under the License.
[Coroutines with multithread support for Kotlin/Native]: https://github.com/Kotlin/kotlinx.coroutines/issues/462
[SensorTag sample app]: samples/sensortag
[`Advertisement`]: https://juullabs.github.io/kable/kable-core/com.juul.kable/-advertisement/index.html
[`BluetoothGatt`]: https://developer.android.com/reference/android/bluetooth/BluetoothGatt
[`Characteristic`]: https://juullabs.github.io/kable/kable-core/com.juul.kable/-characteristic/index.html
[`Connected`]: https://juullabs.github.io/kable/kable-core/com.juul.kable/-state/-connected/index.html
[`CoroutineScope.peripheral`]: https://juullabs.github.io/kable/kable-core/com.juul.kable/peripheral.html
Expand Down
7 changes: 7 additions & 0 deletions kable-core/src/androidMain/kotlin/PeripheralBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ public actual class PeripheralBuilder internal actual constructor() {
*
* [predicate] is called once per connection attempt, not per call to
* [connect][Peripheral.connect].
*
* This setting only influences how a connection is established; it does **not** enable
* automatic **re**connection. Android's system-level behavior of re-establishing `autoConnect`
* connections after a disconnect does not take effect, because Kable closes the underlying
* [android.bluetooth.BluetoothGatt] as soon as a disconnect occurs. To implement automatic
* reconnection, monitor the [state][Peripheral.state] flow and call
* [connect][Peripheral.connect] when [Disconnected][State.Disconnected] state is observed.
*/
public fun autoConnectIf(predicate: () -> Boolean) {
autoConnectPredicate = predicate
Expand Down
Loading