蓝牙开发业务实践
# 目录介绍
- 01.整体概述
- 1.1 项目背景说明
- 1.2 遇到问题记录
- 1.3 基础概念介绍
- 1.4 开发设计目标
- 02.蓝牙基础概念
- 2.1 蓝牙作用说明
- 2.2 蓝牙必备点
- 2.3 配对和连接区别
- 2.4 连接技术分类
- 2.5 官方实践步骤
- 03.蓝牙实践思路
- 3.1 简单开发步骤
- 3.2 一些核心类说明
- 3.3 扫描开始和停止
- 3.4 查找蓝牙设备
- 3.5 匹配蓝牙配对
- 3.6 配对后连接蓝牙
- 3.7 蓝牙数据传递
- 3.8 设置扫描规则
- 3.9 获取蓝牙信息
- 04.蓝牙实践技术点
- 4.1 蓝牙优化点
- 4.3 蓝牙功耗优化
- 4.4
- 05.方案设计
- 5.1 整体架构图
- 5.2 UML设计图
- 5.3 关键流程图
- 5.4 接口设计图
- 5.5 模块间依赖关系
- 5.6 组件化通信
- 06.稳定性实践说明
- 6.1 性能设计
- 6.2 稳定性设计
- 6.3 灰度设计
- 6.4 降级设计
- 6.5 异常设计
- 6.6 兼容性设计
- 6.7 蓝牙实践坑
- 07.项目优化点说明
# 01.整体概述
# 1.1 项目背景说明
# 1.2 遇到问题记录
# 1.3 基础概念介绍
- 蓝牙开发基础知识
- 为了让蓝牙设备可以在彼此之间传输数据,必须先通过配对过程形成通道。其中一台设备需要将自身设置为可接收传入的连接请求,另一台设备则通过服务发现过程并找到可检测的设备。
- 随后在检测到的设备接受配对请求后,设备之间完成绑定操作,并在此期间交换安全密钥。二者会缓存这些密钥,以供日后使用。
- 完成配对和绑定过程后,两台设备会交换信息。当会话完成时,发起配对请求的设备会将其链接到可检测设备的通道。
- 蓝牙现在还分经典蓝牙、低功耗蓝牙和双模蓝牙。
- 经典蓝牙:
- 低功耗蓝牙:
- 双模蓝牙:
# 1.4 开发设计目标
# 02.蓝牙基础概念
# 2.1 蓝牙作用说明
- Android 平台包含蓝牙网络堆栈支持,此支持能让设备以无线方式与其他蓝牙设备交换数据。Android 应用可通过 Bluetooth API 执行以下操作:
- 扫描其他蓝牙设备
- 查询本地蓝牙适配器的配对蓝牙设备
- 建立 RFCOMM 通道
- 通过服务发现连接到其他设备
- 与其他设备进行双向数据传输
- 管理多个连接
- 蓝牙基础介绍
- 为了让支持蓝牙的设备能够在彼此之间传输数据,它们必须先通过配对过程形成通信通道。
- 在可检测到的设备接受配对请求后,这两台设备会完成绑定过程,并在此期间交换安全密钥。二者会缓存这些密钥,以供日后使用。完成配对和绑定过程后,两台设备会交换信息。
- 当会话完成时,发起配对请求的设备会发布已将其链接到可检测设备的通道。但是,这两台设备仍保持绑定状态,因此在未来的会话期间,只要二者在彼此的范围内且均未移除绑定,便可自动重新连接。
# 2.2 蓝牙必备点
- 使用蓝牙进行通信的四大必需任务:
- 设置蓝牙、查找局部区域内的配对设备或可用设备、连接设备,以及在设备之间传输数据。
- 蓝牙权限
- 如要在应用中使用蓝牙功能,您必须声明两个权限。第一个是 BLUETOOTH。您需要此权限才能执行任何蓝牙通信,例如请求连接、接受连接和传输数据等。
- 第二个必须声明的权限是 ACCESS_FINE_LOCATION。您的应用需要此权限,因为蓝牙扫描可用于收集用户的位置信息。此类信息可能来自用户自己的设备,以及在商店和交通设施等位置使用的蓝牙信标。
# 2.3 配对和连接区别
- 被配对与被连接之间存在区别:
- 被配对是指两台设备知晓彼此的存在,具有可用于身份验证的共享链路密钥,并且能够与彼此建立加密连接。
- 被连接是指设备当前共享一个 RFCOMM 通道,并且能够向彼此传输数据。要求规定,只有先对设备进行配对,然后才能建立 RFCOMM 连接。在使用 Bluetooth API 发起加密连接时,系统会自动执行配对。
# 2.4 连接技术分类
- 什么是蓝牙连接技术
- 是自动将每台设备准备为一个服务器,从而使每台设备开放一个服务器套接字并侦听连接。在此情况下,任一设备都可发起与另一台设备的连接,并成为客户端。或者,其中一台设备可显式托管连接并按需开放一个服务器套接字,而另一台设备则发起连接。
- 作为服务器连接和作为客户端连接如何理解?
- 待完善
# 2.5 官方实践步骤
- 第一步:设置蓝牙
- 验证设备支持蓝牙,确保在此情况下启用该功能。然后代码获取蓝牙bluetoothAdapter,然后可以通过该对象判断蓝牙是否启用
- 第二步:查找设备
- 利用 BluetoothAdapter,您可以通过设备发现或查询配对设备的列表来查找远程蓝牙设备。
- 查询已配对设备,调用 getBondedDevices()。您可以查询所有已配对设备,并获取每台设备的名称和 MAC 地址。
- 发现设备。调用 startDiscovery(),异步检索,会对发现的每台设备进行页面扫描,以检索其蓝牙名称。
- 第三步:连接设备
- 在两台设备之间创建连接,必须同时实现服务器端和客户端机制,因为其中一台设备必须开放服务器套接字,而另一台设备必须使用服务器设备的 MAC 地址发起连接。
- 通过调用bluetoothDevice.connectGatt,连接到此设备托管的GATT服务器,该方法返回对象可以来执行GATT客户端操作。
- 第四步:管理连接后数据传递
- 成功连接多台设备后,每台设备都会有已连接的 BluetoothSocket。然后使用 BluetoothSocket 传输数据。
# 03.蓝牙实践思路
# 3.1 简单开发步骤
- 总体流程:
- 发现蓝牙->配对蓝牙->连接蓝牙->数据交互
- 第一步:设置蓝牙
- 首先需要动态申请蓝牙和定位权限,否则无法获取到蓝牙列表数据。然后检查设备是否支持蓝牙,并不是所有的Android 设备都支持蓝牙,所以在使用之前,检测当前设备是否支持蓝牙。
- 开启蓝牙,先检测蓝牙是否打开。没有打开则提示用户打开,或者直接打开。
- 第二步:查找设备
- 设置可被发现,蓝牙打开后,要将自身设置为可以被周边蓝牙搜索到,以便可以进行下一步操作。蓝牙默认可被周边设备在120秒内搜索到,最长设置不过300秒。
- 收集周边蓝牙设备,通过注册广播监听,对发现的蓝牙设备添加到集合中。
- 第三步:连接设备
- 获取设备详情,获取蓝牙列表之后,点击对应的蓝牙,进入蓝牙详情。一个BluetoothDevice对象代表着一个周边蓝牙设备,通过该对象,可以获取该蓝牙设备的名称,绑定状态,Mac地址,uuid等。
- 未配对蓝牙设备通过mDevice.createBond();进行配对。
- 第四步:管理连接后数据传递
- 配对成功后,通过BluetoothDevice的createRfcommSocketToServiceRecord()方法和蓝牙设备连接,连接成功会返回BluetoothSocket对象,进而获得输入输出流,进行数据交互。
# 3.2 一些核心类说明
# 3.3 扫描开始和停止
- 开始扫描api说明
- bluetoothAdapter.startLeScan,这个方法是启动蓝牙LE设备的扫描,查找发布给定服务的设备。不过这个方法显示过时
- bluetoothLeScanner.startScan,这个方法在21以上使用,开启蓝牙扫描,主要增加了屏幕灭和亮蓝牙扫描停止和恢复功能
- 停止扫描api说明
- bluetoothAdapter.stopLeScan,这个方法是关闭蓝牙LE设备的扫描,不过这个方法显示过时
- bluetoothLeScanner.stopScan,这个方法在21以上使用,停止正在进行的蓝牙LE扫描
- 开始扫描中的状态
- 开始扫描后,可以定义状态接口(有开始扫描,扫描中,扫描完成等)
- 监听蓝牙开启和关闭
- 可以通过注册广播来监听,当action为BluetoothAdapter.ACTION_STATE_CHANGED时,获取蓝牙状态即可判断判断开启和关闭
# 3.4 查找蓝牙设备
- 首先搞明白一个概念
- 蓝牙在扫描中,是一条条查找到设备的。蓝牙扫描完毕,可以获取所有识别的蓝牙设备。
- 如何获取扫描的蓝牙设备
- 如果是使用bluetoothAdapter.startLeScan扫描设备,通过LeScanCallback.onLeScan回调扫描发现的蓝牙。发现一个蓝牙设备则会回调一次。
- 如果是使用bluetoothLeScanner.startScan扫描设备,通过ScanCallback.onScanResult和ScanCallback.onBatchScanResults获取发现的蓝牙设备。
- 如何停止蓝牙扫描设备
- 调用bluetoothAdapter.stopLeScan停止扫描。
- 如果过滤一些设备呢
- 作为线上蓝牙库,当然希望只是扫描特定智能设备的一些蓝牙,该怎么处理?可以添加过滤隐私,这个就是蓝牙设备的uuid。
- 如果是bluetoothAdapter.startLeScan扫描设备,则是startLeScan(serviceUuids, callback),传递uuid数组即可。
- 如果是bluetoothLeScanner.startScan扫描设备,则是startScan(listOf(scanFilter), scanSettings, scanCallBack),传递scanFilter(包装版的uuid)
# 3.5 匹配蓝牙配对
- 如何判断设备是否配对
- 先获取所有已经配对的设备,然后遍历查询。就可以知道目标设备是否有配对。
- 如何设置蓝牙配对
- 第一种:在低于Android API 19时,配对的方法是隐藏的方法,所以只有通过反射方法实现。反射BluetoothDevice类中的createBond方法。
- 第二种:官方API,但是只支持Android API 19以上的设备。直接调用bluetoothDevice.createBond()去配对。
- 如何查询已经配对的设备
- 直接调用bluetoothAdapter.getBondedDevices()方法即可获取已经配对的设备。
- 如何解除已经配对的设备
- 第一种:配对的方法是隐藏的方法,所以只有通过反射方法实现。反射BluetoothDevice类中的removeBond方法。
# 3.6 配对后连接蓝牙
- 如何判断蓝牙是否连接
- 第一种方法:通过BluetoothAdapter.getProfileConnectionState(), 这个方法需要传入一个设备类型,不同设备类型可能不同。
- 第二种方法:BluetoothAdapter类中有一个函数getConnectionState(),然后拿到状态是否是:STATE_CONNECTED,如果是则表示已经连接。
- 如何设置连接蓝牙
- 调用bluetoothDevice.connectGatt方法即可表示连接蓝牙。
- 如何取消蓝牙连接
- 调用bluetoothGatt.disconnect()方法即可取消蓝牙连接。
- 如何获取已经连接的蓝牙设备
- 待定
# 3.7 蓝牙数据传递
- 主要是指蓝牙连接之后,然后使用socket进行数据传递
- 调用bluetoothDevice.createRfcommSocketToServiceRecord获取socket对象。然后再通过socket进行通信数据传递!
- 什么叫做蓝牙串口通信
# 3.8 设置扫描规则
# 3.9 获取蓝牙信息
# 04.蓝牙实践技术点
# 4.1 蓝牙优化点
- 从蓝牙连接,配对,传输效率三个点去做优化操作。
# 4.3 蓝牙功耗优化
# 06.稳定性实践说明
# 6.1 性能设计
# 6.2 稳定性设计
# 6.3 灰度设计
# 6.4 降级设计
# 6.5 异常设计
- 蓝牙在扫描过程中回调了失败该如何处理?
- 如果是使用bluetoothAdapter.startLeScan扫描设备,则没有处理回调失败的逻辑
- 如果是使用bluetoothLeScanner.startScan扫描设备,通过ScanCallback.onScanFailed回调失败的原因,这个时候可以给开发回调失败然后终止扫描。
# 6.6 兼容性设计
# 6.7 蓝牙实践坑
# 参考链接
Android 蓝牙聊天
- https://juejin.cn/post/6844903458689007629
Android:蓝牙实现一对一聊天
- https://juejin.cn/post/6844903862516580359
https://juejin.cn/post/6844903862516580359
一线大厂中的大型App全套性能优化实战方案
- https://github.com/liuyangbajin/Performance
tts
- https://github.com/gotev/android-speech
蓝牙
- https://github.com/kongzue/BTLinker
- https://github.com/Jasonchenlijian/FastBle
Wi-Fi
- https://github.com/kongzue/WifiLinker
- https://github.com/kongqw/AndroidWiFiManager
- https://github.com/leavesCZY/WifiFileTransfer
系统分享
- https://www.jianshu.com/p/28f25dcf81cd
上次更新: 2026/06/10, 11:13:41