Connection State Machine
A finite state machine that manages Bluetooth Low Energy (BLE) connections and operations.
This class implements the State Machine pattern to handle the complex lifecycle of BLE connections, ensuring that operations are performed in the correct sequence and providing clear state transitions that can be observed via connectionStateFlow.
State Transitions
The state machine follows this primary flow:
[Disconnected] --> [Connecting] --> [Connected] --> [DiscoveringServices] --> [Ready]
^ |
| |
+--------------------------------------------------------------------------+
(on disconnect)Disconnected: Initial state, or after a connection is closed/lost.
Connecting: Connection attempt is in progress via connect.
Connected: Physical connection established; automatically triggers service discovery.
DiscoveringServices: GATT service discovery is in progress (implicit during Connected -> Ready).
Ready: Services discovered successfully; the device is ready for read/write/notify operations.
Error: An error occurred; contains an error message. May trigger auto-reconnect if enabled.
Features
Automatic Reconnection: When autoReconnect is enabled, the state machine will automatically attempt to reconnect after a disconnection or error, with a configurable delay.
Operation Timeouts: All BLE operations (MTU requests, PHY updates, read/write) have configurable timeouts to prevent indefinite waiting.
Bond Management: Optional integration with BondManager for handling device pairing.
Reactive State Observation: Connection state changes are exposed via connectionStateFlow, allowing UI and other components to reactively observe state changes.
Thread Safety
BLE callbacks are dispatched on the Android Bluetooth thread. This class uses coroutines with Dispatchers.IO for timeout handling and reconnection scheduling.
Usage Example
val stateMachine = ConnectionStateMachine(
context = applicationContext,
device = bluetoothDevice,
autoReconnect = true
)
// Observe connection state
lifecycleScope.launch {
stateMachine.connectionStateFlow.collect { state ->
when (state) {
is ConnectionState.Ready -> { /* Device ready for operations */}
is ConnectionState.Error -> { /* Handle error */}
else -> { /* Handle other states */}
}
}
}
// Initiate connection
stateMachine.connect()Parameters
The Android context used for GATT connection.
The BluetoothDevice to connect to.
Optional BondManager for handling device bonding/pairing.
If true, automatically attempts reconnection on disconnection or error. Defaults to true.
Base delay in milliseconds for exponential backoff reconnection. The actual delay increases exponentially with each attempt. Defaults to DEFAULT_RECONNECT_DELAY_MS (1000ms).
Maximum delay in milliseconds between reconnection attempts. The exponential backoff will be capped at this value. Defaults to DEFAULT_MAX_RECONNECT_DELAY_MS (30000ms).
Maximum number of reconnection attempts before giving up. When this limit is reached, the state transitions to ConnectionState.Error. Defaults to DEFAULT_MAX_RECONNECT_ATTEMPTS (10).
Timeout in milliseconds for BLE operations (MTU, PHY, read, write). Defaults to DEFAULT_OPERATION_TIMEOUT_MS (10000ms).
See also
Constructors
Types
Properties
The underlying BluetoothGatt instance for this connection.
A StateFlow that emits the current ConnectionState of this state machine.
Functions
Disables notifications for a GATT characteristic.
Gracefully disconnects from the Bluetooth device.
Gets the list of cached GATT services for this device.
Checks whether services are cached for this device.
Requests an MTU (Maximum Transmission Unit) change with timeout handling.
Resets the reconnect attempt counter to zero.