概述
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系統的項目中。