Android蓝牙开发
本文于 1058 天之前发表,文中内容可能已经过时。
蓝牙的介绍,建立连接过程,错误码说明
Android蓝牙介绍
系统版本
- Android4.4系统以下使用的是传统蓝牙(经典蓝牙),4.4以上的话使用低功耗蓝牙(也就是经常俗称的ble),蓝牙连接有距离限制,大概几十米左右(根据当前环境的障碍物多少)。
Android建立连接过程
流程
graph TD A(gatt.connectGatt-其中的参数:BluetoothGattCallback回调) --> B[BGCB的onConnectionStateChange回调] B --> C{判断status值} C --> |不等于GATT_SUCCESS| D[断开连接+关闭服务] C --> |等于GATT_SUCCESS| E{判断newState的值} E --> |等于STATE_DISCONNECTED| G[close关闭服务] E --> |等于STATE_CONNECTED| F{判断需要requestMtu} F --> |请求则协商数据交互包大小| J[BGCB的onMtuChanged回调-获取协商结果] J --> H[gatt.discoverServices] F --> |不请求则默认23字节| H H --> I[BGCB的onServicesDiscovered回调] I --> K[发现服务成功则获取对应的特征-mGattService.getCharacteristic] --> L[订阅特征值-gatt.setCharacteristicNotification] L --> N[连接建立-可通信] G --> M[一次连接结束] D --> M 12[BluetoothGattCallback简称BGCB]
介绍低功耗蓝牙
- 低功耗蓝牙体系结构主要分为三个部分:控制器、主机和应用程序。在控制器内既有物理层和链路层,又有直接测试模式和主机控制接口(HCI)层的下半部分。在主机内包含三个协议:逻辑链路控制和适配协议(L2CAP)、属性协议(Attribute Protocol)和安全管理器协议(Security Manager Protocol),此外还包括通用属性规范(GATT)、通用访问规范(GAP)和模式(Mode)。
控制器
- 物理设备,收发无线电信号。控制器与外界通过天线相连,与主机通过主机控制接口(HCI)相连。
主机
- 软件栈,管理多台设备之间的通信以及提供服务。主机构建位于主机控制器的上层部分,其上为逻辑链路控制和适配协议(L2CAP)。在它上面是系统的两个基本构建块:安全管理器(用于处理所有认证和安全连接等事务)以及属性协议(用于公开设备上的状态数据)。属性协议之上为通用属性规范(GATT),定义属性协议如何实现可重用的服务,而这些服务公开了设备的标准特性。最后,通用访问规范(GAP)定义了设备如何以一种可交互方式找到对方,并与之进行连接。
- 主机并未对其上层接口做明确规定,每个操作系统或者环境都会用不同的方式公开主机上层接口API。
应用程序
使用软件栈和控制器实现用户实例。
3.应用层
- 控制器和主机之上是应用层。应用层规范定义了三种类型:特性(characteristic)、服务(service)和规范(profile)。
3.1特性(characterisitic)
- 特性是采用已知格式,以通用唯一识别码(UUID)作为标记的一小块数据。由于特性要求能够重复使用,因而设计时没有设计行为。
3.2服务(service)
服务只定义了位于服务器上的相关特性行为,而不定义客户端的行为。服务有两种类型:首要服务和次要服务。首要服务表征一个给定的设备主要做些什么。次要服务是协助主要服务或者其他次要服务的服务。
3.3规范(profile)
规范是描述两个或者多个设备的说明,每个设备提供一个或者多个服务。规范描述了如何发现并连接设备,从而为每台设备确定所需的拓扑结构。规范还描述了客户端特性,用于发现服务和服务特性。规范和服务是一对多对多的功能。
建立连接
- connect方法
- 发现服务
- 寻找指定特征(写入和读取)
- 订阅特征通知
Android蓝牙通信
- 获取连接过程中的特征(有写入权限的)
- 构建数据写入特征到设备,然后通过订阅通知获取到设备响应数据,来进行交互。
- 实际开发过程中,去连接设备的时候,在上面的流程图的过程中,比如说connectGatt,discoverServices,requestMtu这些方法中都可能出现onConnectionStateChange回调报状态码错误-133(最多),19,22,为了更好的用户体验需要进行重连,重连之前需要close下。
- 另外,一般开始连接的时候,需要停止扫描,等连接结束了之后,再重新开始扫描。
常见错误与解决方法
错误码
staus 说明
0 连接成功或者失败
8 设备端已经断开(可能是复位或者断点等原因),手机端没有收到回应,等到一定时间会自动断开
19 设备端主动发起的断开。比如关机等
22 获取不到服务
40 应该是环境不好,或者射频新能不好,或者距离太远,导致这些命令包slave没有收到,然后Master一直重传到connection event counter超过instant值导致。
133 设备不在附近,或者手机端之前的连接没有断开(有时候closegatt没有效果) 或者是连接数量超过了最大值
BLE版本不同MTU不同
不同的蓝牙版本最大MTU不同,例如:蓝牙4.2的最大MTU=247Byte(不一定正确,也有说是257Byte、也有说是241Byte),蓝牙5.0的最大MTU=512Byte,有效的最大MTU还需要减去协议Byte、Opcode和Handler。
蓝牙4.2:1Byte(Opcode)+2Byte(Handler)+244Byte(BATT)=247Byte(不一定正确)
蓝牙5.0:512Byte不一定正确)