概述

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;模块化程度高⚠️ 安全性: 存在输入验证和并…