NordicSemiconductor/Android-BLE-Library 监听连接状态变化

文章目录

    监听的目的

    • 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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式