BLEManager

Main BLE manager for Electric Unicycles.

This class is responsible for BLE scanning, connection lifecycle management, protocol selection, command transmission, and decoded data delivery.

Threading model:

  • Internal asynchronous work is executed on a background coroutine scope based on Dispatchers.IO + SupervisorJob().

  • Public callbacks exposed by this manager (ConnectionCallback, DataCallback, and ErrorCallback) are not guaranteed to be invoked on the Android main thread.

  • Callers must explicitly switch to Dispatchers.Main, runOnUiThread, or an equivalent UI mechanism before touching Android views.

Rationale:

  • BLE operations, retries, polling, and response timeouts are background work and should not run on the main thread.

  • Keeping callback dispatching explicit avoids hiding threading behavior from the library consumer and keeps the manager usable from non-UI contexts as well.

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
Link copied to clipboard
val rawFrameFlow: SharedFlow<ByteArray>

Flow emitting every raw BLE characteristic notification received from the connected device as a defensive copy of the original byte array.

Functions

Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
fun cleanup()
Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
fun connect(device: EUCDevice)

Connect to a specific device

Link copied to clipboard
fun createCommand(commandType: CommandType, value: Any = Unit): ByteArray
Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
fun disconnect()

Disconnect from current device

Link copied to clipboard

Send a command to the connected device

Link copied to clipboard

Get currently connected device

Link copied to clipboard

Get current connection state

Link copied to clipboard

Initialize the BLE Manager

Link copied to clipboard

Check if Bluetooth is enabled

Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
open override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic)
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
@RequiresApi(value = 33)
open override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray)
Link copied to clipboard
open fun onCharacteristicRead(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int)
open fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray, status: Int)
Link copied to clipboard
open override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int)
Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
open override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int)
Link copied to clipboard
open fun onDescriptorRead(gatt: BluetoothGatt?, descriptor: BluetoothGattDescriptor?, status: Int)
open fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int, value: ByteArray)
Link copied to clipboard
open fun onDescriptorWrite(gatt: BluetoothGatt?, descriptor: BluetoothGattDescriptor?, status: Int)
Link copied to clipboard
open override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int)
Link copied to clipboard
open fun onPhyRead(gatt: BluetoothGatt?, txPhy: Int, rxPhy: Int, status: Int)
Link copied to clipboard
open fun onPhyUpdate(gatt: BluetoothGatt?, txPhy: Int, rxPhy: Int, status: Int)
Link copied to clipboard
open fun onReadRemoteRssi(gatt: BluetoothGatt?, rssi: Int, status: Int)
Link copied to clipboard
open fun onReliableWriteCompleted(gatt: BluetoothGatt?, status: Int)
Link copied to clipboard
Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
open override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int)
Link copied to clipboard

Register a protocol for device detection and data processing

Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
fun sendCommand(commandType: CommandType, value: Any = Unit)
@RequiresPermission(value = "android.permission.BLUETOOTH_CONNECT")
fun sendCommand(command: ByteArray, characteristicUuid: UUID)
Link copied to clipboard
Link copied to clipboard

Callback registration methods.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
fun setMaxRetries(retries: Int)
Link copied to clipboard
fun setScanTimeout(timeout: Long)
Link copied to clipboard
@RequiresApi(value = 23)
@RequiresPermission(value = "android.permission.BLUETOOTH_SCAN")
fun startScan()

Start scanning for EUC devices

Link copied to clipboard
@RequiresPermission(value = "android.permission.BLUETOOTH_SCAN")
fun stopScan()

Stop scanning for devices