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等 对其进行了封装, 是开发者用起来更加简洁, 关注于业务。

相关推荐
诸神黄昏EX1 小时前
Android 分区相关介绍
android
大白要努力!2 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee2 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood2 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-5 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen8 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年15 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿17 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神19 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛19 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee