Android BLE开发 —— Jetpack Bluetooth

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())
            }
            
        }

调用 BluetoothLeconnectGatt方法,发起连接。在连接的回调中, 可以进行获取服务, 订阅, 读取数据, 写入数据等操作。

可以看出相比之前 在 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等 对其进行了封装, 是开发者用起来更加简洁, 关注于业务。

相关推荐
人生游戏牛马NPC1号42 分钟前
学习 Flutter (三):玩安卓项目实战 - 上
android·学习·flutter
小馬佩德罗2 小时前
Android系统的问题分析笔记 - Android上的调试方式 debuggerd
android·调试
清霜之辰4 小时前
安卓基于 FirebaseAuth 实现 google 登录
android·google·auth·firebase
GitLqr4 小时前
数码洞察 | Apple VS DMA、三星新品、Android 16KB Page Size
android·ios·samsung
alexhilton4 小时前
SnapshotFlow还是collectAsState?对于Jetpack Compose来说哪个更香?
android·kotlin·android jetpack
Erwooow5 小时前
Android 16k jni修改
android
l软件定制开发工作室5 小时前
基于Android的景点旅游信息系统App
android
张可5 小时前
一个KMP/CMP项目的组织结构和集成方式
android·前端·kotlin
林林要一直努力6 小时前
AOSP Settings模块问题初窥
android·学习·bug·android studio
顾林海6 小时前
Android 性能优化:启动优化全解析
android·java·面试·性能优化·zygote