1、简介
JetPack 出了 Bluetooth的 新库, 包含了对 经典蓝牙和 低功耗蓝牙的支持。
目前最新的版本为 1.0.0-alpha02。
这个库主要是使用了Kotlin 和 协程,封装了对蓝牙的操作,简化开发者对蓝牙的使用。
地址:developer.android.com/jetpack/and...
2、集成
arduino
dependencies {
implementation "androidx.bluetooth:bluetooth:1.0.0-alpha02"
}
申请需要的权限:
xml
<!--建立蓝牙连接和传输权限-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!--扫描蓝牙设备或修改蓝牙设置权限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!--Android 6.0及后续版本扫描蓝牙,需要定位权限(进入GPS设置,可以看到蓝牙定位)-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
Android6.0 以上需要动态定位权限。
包结构:
可以看出大部分由Kotlin进行了重写。
3、扫描
首先开始扫描操作:
kotlin
// 初始化 BluetoothLe
val bluetoothLe = BluetoothLe(context)
// 根据serviceUuid和deviceName 过滤条件进行扫描
val scanFlow = bluetoothLe.scan(listOf(ScanFilter(
serviceDataUuid = UUID.fromString("XXX"),
deviceName = "XXX"
)))
// 扫描到的结果
scanFlow.collect {
Log.d("MainActivity", "scan result: $it ${it.device.name} ${it.rssi}")
}
可以看出通过调用 bluetoothLe.scan
返回了 一个Kotlin协程的 Flow<ScanResult>
对象。
和之前的 BLE API 一样, 支持对设备扫描的条件进行配置, 可以配置 serviceId, deviceName, MAC地址等信息。
然后 通过扫描的 ScanResult
结果可以拿到设备信息, 如支持的服务 serviceUuids
, 信号强度 rssi
等信息
扫描到结果后, 不需要我们手动去关闭扫描。会自动关闭扫描
可以看出新出的这个蓝牙库, 比之前的扫描操作代码少了很多, 也简洁了很多。
4、连接
扫描到设备后, 对设备进行发起连接操作
scss
val bluetoothLe = BluetoothLe(context)
// 连接设备, device是刚才扫描到的设备
bluetoothLe.connectGatt(device) {
// 获取服务
getService(UUID.fromString("XXX"))
// 订阅
getService(UUID.fromString("XXX"))?.getCharacteristic(UUID.fromString("XXX"))?.let {
subscribeToCharacteristic(it).collect {
// 收到数据
Log.d("MainActivity", "subscribe result: $it")
}
}
// 读取数据
getService(UUID.fromString("XXX"))?.getCharacteristic(UUID.fromString("XXX"))?.let {
readCharacteristic(it)
}
// 写入数据
getService(UUID.fromString("XXX"))?.getCharacteristic(UUID.fromString("XXX"))?.let {
writeCharacteristic(it, "XXX".toByteArray())
}
}
调用 BluetoothLe
的 connectGatt
方法,发起连接。在连接的回调中, 可以进行获取服务, 订阅, 读取数据, 写入数据等操作。
可以看出相比之前 在 BluetoothGattCallback回调中进行操作, 简洁了很多。
5、增大MTU
在这个库中, 在连接成功时,自动帮我们增大了MTU为,512 + 3
没有发现提供给开发者增大MTU的API, 也没有返回 GATT 对象的接口, 需要动态改变合适的MTU还是需要使用之前的API, 这个库要支持的话,估计要等官方后续更新完善了。
6、源码探索
6.1 BluetoothLe
BluetoothLe是操作的核心类, 主要提供了扫描和连接的API接口。
可以看到 scan方法调用了ScanImpl 的scan方法, connectGatt方法调用了GattClient的 connect方法。
6.2 ScanImplBase 的scan
底层还是使用 BluetoothLeScanner
进行扫描操作,将过滤条件放进 BluetoothLeScanner
中, 扫描到设备后发送数据, collect处理之后 关闭扫描。
6.3 GattClient的 的connect
本质上还是调用了之前的API,BluetoothDevice 的 connectGatt, 并结合携程 和 flow 包装返回一个 GattClientScope的作用域, 在这个作用域中可以进行 writeCharacteristic、readCharacteristic等操作。
本质是并没有引入新的底层BLE API操作,还是使用了之前的那一套 BLE API操作, 在此基础上,使用了Kotlin, 协程,Flow等 对其进行了封装, 是开发者用起来更加简洁, 关注于业务。