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

更新日期: 2023-08-20 阅读次数: 843 字数: 671 分类: Android

监听的目的

  • 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 聊聊, 查看更多联系方式