Kable使用指南:Android BLE開發的現代化解決方案

概述

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特定配置}}}
}

最佳實踐建議

  1. 生命周期管理
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相關操作}
}
  1. 錯誤處理與重連機制
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("連接失敗,已達最大重試次數")}
}
  1. 資源清理
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()方法清理資源
}

常見問題與解決方案

  1. 權限被拒絕處理
fun handlePermissionDenied(context: Context) {val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {data = Uri.fromParts("package", context.packageName, null)}context.startActivity(intent)
}
  1. 藍牙適配器檢查
fun checkBluetoothAvailability(context: Context): Boolean {val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManagerval bluetoothAdapter = bluetoothManager.adapterreturn bluetoothAdapter != null && bluetoothAdapter.isEnabled
}

總結

Kable庫為Android BLE開發提供了現代化、協程友好的解決方案。通過本文的介紹,您應該能夠:

  1. 理解Kable的基本用法和核心功能
  2. 掌握在Android高版本中處理BLE權限的正確方法
  3. 實現健壯的BLE連接和通信機制
  4. 遵循最佳實踐來管理BLE資源

隨著Android系統的不斷更新,建議開發者始終使用Kable的最新版本,并密切關注Android官方文檔中關于BLE權限和API的變更,以確保應用的長期兼容性和穩定性。

Kable的簡潔API和強大的功能使其成為Android BLE開發的首選庫之一,特別是在需要支持高版本Android系統的項目中。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98748.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98748.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98748.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android圖案解鎖繪制

使用到的庫是Pattern Locker,根據示例進行了修改,把默認樣式和自定義樣式進行了合并調整。 設置密碼 布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xm…

Kotlin 協程之 Flow 的理解使用及源碼解析

前言 在前面的文章中&#xff0c;我們已經討論了 Channel 的概念和基本使用以及 Channel 的高階應用。這篇我們來看日常開發中更常用的Flow。 “冷流” 和 “熱流” 的本質 先來梳理一下所謂的 “冷流” 和 “熱流”。 核心概念 我們已經知道 Channel 是 “熱流”&#xff…

簡述ajax、node.js、webpack、git

本系列可作為前端學習系列的筆記&#xff0c;HTML、CSS和JavaScript系列文章 已經收錄在前端專欄&#xff0c;有需要的寶寶們可以點擊前端專欄查看&#xff01; 點贊關注不迷路&#xff01;您的點贊、關注和收藏是對小編最大的支持和鼓勵&#xff01; 系列文章目錄 簡述ajax、…

經營幫會員經營:全方位助力企業高效發展,解鎖商業新可能

在商業競爭愈發激烈的當下&#xff0c;企業若想脫穎而出&#xff0c;高效的經營管理體系至關重要。經營幫的會員經營板塊&#xff0c;憑借豐富且實用的功能&#xff0c;為企業打造了一站式的經營助力平臺&#xff0c;從多維度賦能企業&#xff0c;讓發展之路更順暢。會員經營與…

Vue 封裝Input組件 雙向通信

子組件<template><div class"box"><div class"box-left"><input blur"handleBlur" v-model"localInput" class"box-left-input"> </div><div class"box-right"><p style…

伽馬(gamma)變換記錄

此只記錄伽馬變換原理及其應用結果&#xff08;文章所有內容基于數字圖像處理-岡薩雷斯&#xff09;&#xff0c;和直接用MATLAB代碼生成伽馬變換代碼。一、原理伽馬變換的公式很簡答 就是一個有規律的冪運算 公式如下&#xff1a;一般在圖像中進行應用是 C1 y為不同值時r的輸…

電路學習(六)三極管

三極管是一種電流驅動元器件&#xff08;MOS管為電壓驅動&#xff09;&#xff0c;在電路中可以充當開關&#xff0c;放大電流等作用。本文章參考了尚硅谷的視頻資料。1. 什么是三極管&#xff1f;三極管又被稱為晶體三極管&#xff08;Bipolar Junction Transistor&#xff0c…

配置docker常見問題

輸入sudo yum install -y yum-utils device-mapper-persistent-data lvm2出現Cannot find a valid baseurl for repo: base/7/x86_64一、檢查網絡輸入ping www.baidu.com出現PING www.a.shifen.com (220.181.111.1) 56(84) bytes of data. 64 bytes from 220.181.111.1 (220.18…

Python 實戰:票據圖像自動矯正技術拆解與落地教程

在日常辦公自動化&#xff08;OA&#xff09;或財務數字化場景中&#xff0c;拍攝的票據常因角度問題出現傾斜、變形&#xff0c;不僅影響視覺呈現&#xff0c;更會導致 OCR 文字識別準確率大幅下降。本文將從技術原理到代碼實現&#xff0c;手把手教你用 Python 打造票據圖像自…

vue3+TS項目配置unocss

配置unocss &#xff08;1&#xff09;安裝依賴 npm i unocss unocss/preset-uno unocss/preset-attributify -D npm install unocss/transformer-directives&#xff08;2&#xff09;根目錄新建uno.config.ts文件 import { defineConfig } from "unocss"; impor…

嵌入式硬件工程師的每日提問

一、LDO與DC-DC的對比1&#xff09;同&#xff1a;兩者都是將不穩定的直流輸入電壓轉換為穩定的直流輸出電壓。2&#xff09;異&#xff1a;LDO&#xff1a;線性調節&#xff0c;通過內部功率晶體管&#xff0c;工作在線性區&#xff0c;穩定輸出電壓。類比&#xff1a;將湍急的…

從零到一使用Linux+Nginx+MySQL+PHP搭建的Web網站服務器架構環境——LNMP(下)

從零到一使用LinuxNginxMySQLPHP搭建的Web網站服務器架構環境——LNMP&#xff08;上&#xff09;https://coffeemilk.blog.csdn.net/article/details/151350565 一、Nginx與PHP-FPM整合原理 1.1、PHP-FPM配置文件 Nginx與PHP-FPM整合原理序號說明1 PHP-FPM是一個第三方的Fast…

論文閱讀-Correlate and Excite

文章目錄1 背景2 創新點3 方法3.1 總體結構3.2 代價體計算3.3 引導式代價體激勵&#xff08;GCE&#xff09;3.4 TopK視差回歸4 效果參考資料1 背景 在IGEV中構建幾何編碼體CGC_GCG?時用到了本文將要描述的CoEx&#xff0c;IGEV中沒有說明為什么要這樣做&#xff0c;本文就是…

探索大語言模型(LLM):Open-WebUI的安裝

前言 Open-WebUI 是一款專為大模型設計的開源可視化交互工具&#xff0c;它通過類 ChatGPT 的直觀界面&#xff0c;讓用戶無需代碼即可管理、調試和調用本地或云端的大語言模型&#xff08;LLMs&#xff09;&#xff0c;成為私有化部署的便捷工具&#xff0c;本文將介紹如何部…

企業遠程訪問方案選擇:何時選內網穿透,何時需要反向代理?

企業遠程訪問需求日益增長&#xff0c;無論是遠程辦公、分支互聯還是服務發布&#xff0c;選擇合適的網絡方案都至關重要。內網穿透和反向代理是兩種常見的技術手段&#xff0c;但它們的設計目標和適用場景截然不同。本文將客觀分析兩者的特點&#xff0c;幫助企業做出更合理的…

ARM指令集(Instruction Set)細節

ARM指令集(Instruction Set)細節 本文旨在深入探討 ARM 指令集(Instruction Set)的細節。這是一個非常廣泛的主題&#xff0c;我會將其分解為關鍵概念、不同版本的區別以及核心特性&#xff0c;并提供一些示例。 ARM 指令集的核心在于 RISC&#xff08;精簡指令集計算機&#x…

Vue基礎知識-Vue集成 Element UI全量引入與按需引入

一、方式一&#xff1a;全量引入 Element UI全量引入即一次性加載 Element UI 所有組件和樣式&#xff0c;優點是配置簡單&#xff0c;適合快速開發&#xff1b;缺點是打包體積較大&#xff0c;生產環境可能存在冗余。1. 安裝 Element UI全量引入只需安裝 Element UI 核心依賴&…

leetcode26(字母異位詞分組)

給你一個字符串數組&#xff0c;請你將 字母異位詞 組合在一起。可以按任意順序返回結果列表。示例 1:輸入: strs ["eat", "tea", "tan", "ate", "nat", "bat"]輸出: [["bat"],["nat","…

光平面標定 (Laser Plane Calibration) 的原理和流程

光平面標定 (Laser Plane Calibration) 是線激光3D相機系統中最為關鍵且精巧的一步,它直接決定了最終的測量精度。 核心目標 光平面標定的目標是:精確地求出激光器發射出的那個扇形激光平面,在相機坐標系下的數學方程。 這個方程通常表示為一般式: Ax + By + Cz + D = 0…

項目1——單片機程序審查,控制系統項目評估總結報告

執行摘要 本報告對基于STM32F103RET6的老虎機控制系統進行了全面的技術評估。通過深入分析代碼結構、系統架構、安全機制和潛在風險&#xff0c;為項目的進一步開發和部署提供專業建議。 核心發現 ? 系統架構: 設計合理&#xff0c;模塊化程度高?? 安全性: 存在輸入驗證和并…