监听的目的
- Android App 界面显示当前的蓝牙连接状态:断开/连接中/已连接
- 在断开时,自动重连
如何监听连接状态 (已废弃)
在 NordicSemiconductor/Android-BLE-Library 官方文档中没有找到相关的说明。
只能在 github 中搜索 no.nordicsemi.android.ble.BleManager 的 kotlin 代码。
确实找到不少参考项目。
例如:
https://github.com/fbiego/ESP32_BLE_OTA_Android/blob/d10f6546f4371dd811767b5b4958c2aa891697ec/app/src/main/java/com/fbiego/ota/ble/LEManager.kt
在实现 BleManager 时传入了状态回调
/**
* Implements BLEManager
*/
class LEManager(context: Context) : BleManager<LeManagerCallbacks>(context) {
BleManagerCallbacks 的实现中,包含了各种状态回调:
/**
* Implements the BLEManager callback methods
*/
open class LeManagerCallbacks : BleManagerCallbacks {
/**
* Called when the Android device started connecting to given device.
* The [.onDeviceConnected] will be called when the device is connected,
* or [.onError] in case of error.
* @param device the device that got connected
*/
override fun onDeviceConnecting(device: BluetoothDevice) {
Timber.d("onDeviceConnecting {address=${device.address},name=${device.name}}")
}
/**
* Called when the device has been connected. This does not mean that the application may start communication.
* A service discovery will be handled automatically after this call. Service discovery
* may ends up with calling [.onServicesDiscovered] or
* [.onDeviceNotSupported] if required services have not been found.
* @param device the device that got connected
*/
override fun onDeviceConnected(device: BluetoothDevice) {
Timber.d("onDeviceConnected {address=${device.address},name=${device.name}}")
}
/**
* Called when user initialized disconnection.
* @param device the device that gets disconnecting
*/
override fun onDeviceDisconnecting(device: BluetoothDevice) {
Timber.d("onDeviceDisconnecting {address=${device.address},name=${device.name}}")
}
/**
* Called when the device has disconnected (when the callback returned
* [BluetoothGattCallback.onConnectionStateChange] with state DISCONNECTED),
* but ONLY if the [BleManager.shouldAutoConnect] method returned false for this device when it was connecting.
* Otherwise the [.onLinklossOccur] method will be called instead.
* @param device the device that got disconnected
*/
override fun onDeviceDisconnected(device: BluetoothDevice) {
Timber.d("onDeviceDisconnected {address=${device.address},name=${device.name}}")
}
还是需要看一下源码,具体有哪些回调, 以方便处理更多的状况。
但是,在 Android Studio 中复制了上述代码之后,会看到 BleManagerGattCallback 的实现已废弃。
如何监听连接状态
https://github.com/NordicSemiconductor/Android-BLE-Library/blob/main/MIGRATION.md
2.0 之后
Move your callback implementation from BleManagerGattCallback to request callbacks.
BleManager is no longer a generic class.
所以也就无法传递 BleManagerGattCallback 的实现。
取而代之的是
Use BlaManager#setConnectionObserver(...) to get connection state updates.
Use BleManager#setBondingObserver(...) to get bonding events.
但是,这些方法都不够简洁,直到我发现了宝藏类 ObservableBleManager 。。。
ObservableBleManager
An extension for easier integration with LiveData is available after adding:
implementation 'no.nordicsemi.android:ble-livedata:2.6.1'
This extension adds ObservableBleManager with state and bondingState properties, which notify about connection and bond state using androidx.lifecycle.LiveData.
https://github.com/NordicSemiconductor/Android-BLE-Library/blob/main/ble-livedata/src/main/java/no/nordicsemi/android/ble/livedata/ObservableBleManager.java
public abstract class ObservableBleManager extends BleManager {
public final LiveData<ConnectionState> state;
public final LiveData<BondState> bondingState;
public ObservableBleManager(@NonNull final Context context) {
this(context, new Handler(Looper.getMainLooper()));
}
public ObservableBleManager(@NonNull final Context context, @NonNull final Handler handler) {
super(context, handler);
state = new ConnectionStateLiveData();
bondingState = new BondingStateLiveData();
setConnectionObserver((ConnectionObserver) state);
setBondingObserver((BondingObserver) bondingState);
}
}
很好,很强大!
只需要监听 ObservableBleManager 的 state 属性就可以了。
有哪些状态值
public class ConnectionState {
public enum State {
CONNECTING,
INITIALIZING,
READY,
DISCONNECTING,
DISCONNECTED
}
}
监听状态变化
viewModel.someDeviceManager.state.observe(
viewLifecycleOwner, Observer {
it?.let { value ->
when (value.state) {
ConnectionState.State.DISCONNECTED -> {
binding.topBar.connectIcon.setImageResource(R.drawable.disconnected)
binding.topBar.connectText.text = "蓝牙已断开"
}
ConnectionState.State.READY -> {
binding.topBar.connectIcon.setImageResource(R.drawable.connected)
binding.topBar.connectText.text = "蓝牙已连接"
}
else -> {
// TODO
}
}
}
}
)
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式