概述
Kable(com.juul.kable:core)是一个专为Android蓝牙低功耗(BLE)开发设计的Kotlin协程友好库。它通过提供简洁的API和响应式编程模式,极大地简化了BLE设备交互的复杂性。本文将详细介绍Kable的使用方法,并重点讨论其在Android高版本系统中的兼容性问题。
环境配置
添加依赖
在项目的build.gradle.kts文件中添加Kable依赖:
dependencies {implementation("com.juul.kable:core:0.33.0")
}
权限声明
在AndroidManifest.xml中声明必要的BLE权限:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
<!-- Android 12+ 额外权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /><!-- 可选:声明BLE功能 -->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
核心功能使用
设备扫描
Kable提供了简洁的API来扫描附近的BLE设备:
import com.juul.kable.Scanner
import com.juul.kable.Filter
import kotlinx.coroutines.flow.collectclass DeviceScanner {suspend fun scanForDevices(deviceNamePrefix: String) {val scanner = Scanner {filters = listOf(Filter.NamePrefix(deviceNamePrefix))}scanner.advertisements.collect { advertisement ->println("发现设备: ${advertisement.name ?: "未知"}, RSSI: ${advertisement.rssi}")// 处理找到的设备}}
}
设备连接与通信
建立与BLE设备的连接并进行数据交互:
import com.juul.kable.Peripheral
import com.juul.kable.Characteristicclass BleDeviceManager {private var peripheral: Peripheral? = nullsuspend fun connectToDevice(advertisement: Advertisement) {peripheral = Peripheral(advertisement)try {// 建立连接peripheral?.connect()// 发现服务discoverServices()} catch (e: Exception) {println("连接失败: ${e.message}")disconnect()}}private suspend fun discoverServices() {val services = peripheral?.services()services?.forEach { service ->println("发现服务: ${service.uuid}")service.characteristics.forEach { characteristic ->println("特征值: ${characteristic.uuid}")// 根据需求进行读写操作}}}suspend fun readCharacteristic(characteristic: Characteristic): ByteArray? {return peripheral?.read(characteristic)}suspend fun writeCharacteristic(characteristic: Characteristic, data: ByteArray) {peripheral?.write(characteristic, data)}suspend fun enableNotifications(characteristic: Characteristic) {peripheral?.observe(characteristic)?.collect { data ->// 处理接收到的数据println("收到数据: ${data.toHexString()}")}}fun disconnect() {peripheral?.disconnect()peripheral = null}
}
Android高版本兼容性指南
权限处理策略
针对Android 12及更高版本,需要采用新的权限请求策略:
class BlePermissionHelper(private val activity: FragmentActivity
) {private val permissionLauncher = activity.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->if (permissions.all { it.value }) {onPermissionsGranted()} else {onPermissionsDenied()}}fun checkAndRequestPermissions() {val requiredPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {arrayOf(Manifest.permission.BLUETOOTH_SCAN,Manifest.permission.BLUETOOTH_CONNECT)} else {arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)}permissionLauncher.launch(requiredPermissions)}private fun onPermissionsGranted() {// 权限已授予,开始BLE操作}private fun onPermissionsDenied() {// 处理权限被拒绝的情况}
}
Android 12+ 特定配置
fun createAndroid12CompatibleScanner(context: Context): Scanner {return Scanner {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {android {callerPackageName = context.packageNameisLegacy = false// 其他Android 12特定配置}}}
}
最佳实践建议
- 生命周期管理
class LifecycleAwareBleManager(lifecycle: Lifecycle,private val context: Context
) : DefaultLifecycleObserver {init {lifecycle.addObserver(this)}override fun onStart(owner: LifecycleOwner) {if (checkPermissions()) {startBleOperations()}}override fun onStop(owner: LifecycleOwner) {stopBleOperations()}private fun checkPermissions(): Boolean {// 权限检查逻辑return true}private fun startBleOperations() {// 启动BLE相关操作}private fun stopBleOperations() {// 停止BLE相关操作}
}
- 错误处理与重连机制
class RobustBleConnection {private var connectionAttempts = 0private val maxAttempts = 3suspend fun connectWithRetry(peripheral: Peripheral) {while (connectionAttempts < maxAttempts) {try {peripheral.connect()connectionAttempts = 0return} catch (e: Exception) {connectionAttempts++delay(2000) // 等待2秒后重试}}throw Exception("连接失败,已达最大重试次数")}
}
- 资源清理
class SafeBleOperator : AutoCloseable {private val peripherals = mutableListOf<Peripheral>()suspend fun addPeripheral(advertisement: Advertisement) {val peripheral = Peripheral(advertisement)peripheral.connect()peripherals.add(peripheral)}override fun close() {peripherals.forEach { it.disconnect() }peripherals.clear()}
}// 使用示例
fun exampleUsage() {SafeBleOperator().use { operator ->// 执行BLE操作}// 自动调用close()方法清理资源
}
常见问题与解决方案
- 权限被拒绝处理
fun handlePermissionDenied(context: Context) {val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {data = Uri.fromParts("package", context.packageName, null)}context.startActivity(intent)
}
- 蓝牙适配器检查
fun checkBluetoothAvailability(context: Context): Boolean {val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManagerval bluetoothAdapter = bluetoothManager.adapterreturn bluetoothAdapter != null && bluetoothAdapter.isEnabled
}
总结
Kable库为Android BLE开发提供了现代化、协程友好的解决方案。通过本文的介绍,您应该能够:
- 理解Kable的基本用法和核心功能
- 掌握在Android高版本中处理BLE权限的正确方法
- 实现健壮的BLE连接和通信机制
- 遵循最佳实践来管理BLE资源
随着Android系统的不断更新,建议开发者始终使用Kable的最新版本,并密切关注Android官方文档中关于BLE权限和API的变更,以确保应用的长期兼容性和稳定性。
Kable的简洁API和强大的功能使其成为Android BLE开发的首选库之一,特别是在需要支持高版本Android系统的项目中。