ARTICLE · 1062301
微信小程序蓝牙连接总体流程文档
一、UUID 与蓝牙名约定
所有 UUID 在页面入口硬编码,蓝牙名由终端号动态生成:
项 | 取值规则 |
蓝牙名 | xxxx_ + 设备号后 4 位(可自由定义,但是要有规律) |
服务 UUID | xxxx(设备硬编码) |
读特征 UUID | xxxx(设备硬编码) |
写特征 UUID | xxxx(设备硬编码) |
二、蓝牙秘钥生命周期(独立闭环)
蓝牙秘钥是 APP 与车辆之间所有加解密的共同钥匙,贯穿加密下发与上行解密两端的全过程。秘钥本身不参与蓝牙链路的建立,但链路一旦联通,必须有可用秘钥才能正常收发业务数据。
秘钥存储位置:
●统一存放在全局状态(vuex)的秘钥字段中,由加解密工具在加解密时直接读取。
●配套状态字段表示当前秘钥的健康状态:normal 表示可用,empty 表示未获取到,wait 表示等待中,anomaly 表示解密异常。
秘钥初始获取流程:
●页面初始化完成且确认已选中车辆时,自动调用秘钥查询接口。
●接口以当前车辆 ID 为入参,从服务端拉取与该车辆绑定的 AES 秘钥。
●接口返回成功后,将秘钥写入全局状态,并隐式将状态置为 normal,进入可用状态。
●接口返回失败或秘钥为空时,将状态置为 empty,并提示用户保持网络通畅后重试。
秘钥手动更新入口:
●首页控制区提供「更新秘钥」入口,弹窗提示用户在网络通畅情况下手动重新拉取秘钥。
●手动更新主要用于秘钥被服务端刷新后,APP 端本地缓存的旧秘钥失效,需要立即拉取最新秘钥的场景。
秘钥异常自愈机制:
●设备上行数据解密失败时,会返回秘钥异常信号。
●系统按出错次数计数,每累计 3 次自动重新拉取最新秘钥。
●首次检测到秘钥异常时,弹窗提示「蓝牙秘钥错误」或「未配置蓝牙秘钥」,并主动关闭当前蓝牙连接,避免后续通信持续失败。
●异常弹窗只提示一次,直到下次解密成功才会重新允许提示,避免反复打扰用户。
秘钥与连接流程的协作关系:
●秘钥获取与蓝牙连接可并行进行:页面初始化时同时启动秘钥拉取与蓝牙模块初始化。
●蓝牙链路建立后,即使秘钥暂时未到位,上行解密会失败并触发异常自愈流程。
●一旦秘钥到位,所有后续上下行数据即可正常加解密,业务指令也能正确下发。
●秘钥刷新不会主动断开已有蓝牙连接,仅在解密失败场景下被动触发重连或异常提示。
三、连接建立总流程(从进入页面到可下发指令)
整个连接过程分为七个阶段,每个阶段完成特定目标后才能进入下一阶段:
阶段 1:页面初始化与权限准备
●页面初始化时,根据终端号拼出蓝牙名,实例化蓝牙管理器并存入全局状态。
●蓝牙管理器构造时立即检查微信蓝牙授权状态。
●未授权则引导用户授权;用户拒绝时弹窗递归询问,并提供跳转设置页的入口。
●授权通过后,页面通过授权完成回调,开始监听系统蓝牙和定位开关。
阶段 2:系统状态监听与自动重连
●页面开启 5 秒一次的轮询,读取系统蓝牙和定位开关状态。
●当蓝牙和定位均开启、但蓝牙未连接且未在搜索中时,自动发起初始化流程。
●当检测到蓝牙关闭但当前显示已连接时,强制清除连接标志。
●页面每次显示时也会检查一次未连接情况,必要时重新发起连接。
●同时将历史未上传的控车日志尝试补传。
阶段 3:蓝牙模块初始化
●清理上一次残留:关闭已有连接、停止设备发现、移除所有监听事件。
●关闭蓝牙适配器并移除适配器状态监听,延时一秒确保模块完全释放。
●先后以主机模式与从机模式两次打开蓝牙适配器(双模并发)。
●初始化完成后回调页面,页面随即注册连接状态监听并启动搜索连接。
阶段 4:设备搜索与建立链路
●如有缓存的设备 ID,先主动关闭并清空,避免卡连接。
●以高功率模式启动设备发现。
●在搜索回调中按蓝牙名精确匹配目标车辆,命中后立即停止搜索并发起连接。
●连接请求设置 15 秒超时,连接成功后立即设置单包最大传输字节为 512(安卓系统必须)。
●同时启动 25 秒总超时定时器,防止长时间无响应占用界面。
●若搜索超时、连接失败或权限异常,统一通过弹窗引导用户重试。
阶段 5:UUID 校验
●连接成功后延时两秒,再查询设备服务 UUID。
●对比协议约定的服务 UUID;不匹配则视为连接异常,重启小程序。
●服务匹配后查询读写特征 UUID,两个特征都必须命中。
●任一特征缺失即视为硬件异常,重启小程序(这是 iOS 必需步骤)。
阶段 6:订阅通道与状态生效
●UUID 全部匹配后,连接正式生效,连接标志置为 true(通过属性劫持通知页面)。
●主动停止设备发现,释放资源。
●对读特征开启订阅,使 APP 能持续接收设备主动上报。
●注册蓝牙连接状态变化监听:一旦设备断开,自动清理连接并等待下次重连。
●页面收到连接成功事件后,将全局连接标志置为 true,并延时清理搜索中标志。
阶段 7:设备登录握手
●设备首次连上后会主动下发一条登录请求消息。
●响应解析模块解析后提取登录令牌,立即调用控制模块发起 APP 登录。
●登录报文按协议封装后加密下发,设备校验通过后双端登录态正式建立。
四、指令下发总流程(以开锁为例)
用户点击控制按钮后,APP 根据当前连接状态选择通道:
●若蓝牙已连接:走蓝牙通道,将控制指令通过蓝牙管理器下发。
●若蓝牙未连接:走 4G 通道,通过服务端接口下发指令(兜底)。
蓝牙指令下发的处理步骤:
●记录当前指令类型,供响应解析模块在收到应答时识别业务含义。
●将业务文本(如开锁指令)逐字符转 hex,拼装为协议消息体。
●按协议生成 4 位消息头,包含平台标志、加密标志、消息体长度。
●按协议做转义处理:用 xxxx代替 xxx,用 xxxx 代替 xx,首尾各加 xx 包裹。
●用异或算法对整包内容生成 1 字节校验码追加到尾部。
●使用 AES-ECB-PKCS7 对完整协议包加密,密钥来自全局秘钥字段。
●将加密结果转为 ArrayBuffer,写入写特征 UUID。
●写入失败时强制断开连接,提示用户重连;写入成功则等待设备应答。
五、设备响应解析总流程
设备上行数据通过蓝牙订阅回调进入响应解析模块,整体处理流程:
●将 ArrayBuffer 转 hex 字符串。
●使用同一密钥 AES 解密;解密失败标记秘钥异常,每 3 次重新拉取密钥,并提示用户。
●去除首尾的 xx 包裹、还原转义、剥离尾部校验码。
●提取 4 位消息 ID,按协议分发到不同处理分支。
主要消息分支:
●设备应答(控制命令结果):根据指令类型更新 ACC 状态、设防状态、电池类型等业务字段,并对失败场景给出具体错误提示。
●设备主动上报:解析电量、电压、续航、里程、ACC、设防、蓝牙配对等状态,实时刷新车辆信息。
●查询设备信息应答:解析动力电池类型、防盗声音开关、蓝牙无感连接开关及距离、电池额定电压、震动灵敏度、音量等参数。
●设备登录请求:提取登录令牌,立即触发 APP 登录流程。
六、断线、重连与销毁
●被动断线:由蓝牙连接状态变化监听触发,自动清理所有连接状态,等待后续自动重连。
●主动断开:调用关闭方法主动关闭蓝牙通道。
●销毁:页面卸载时执行销毁方法,彻底关闭蓝牙适配器并清理所有定时器与监听。
●重连触发点共三个:页面显示、系统状态轮询、用户主动点击蓝牙图标。
七、关键状态字段
字段 | 含义 |
蓝牙管理器实例 | 蓝牙管理模块实例对象,全局唯一 |
蓝牙连接标志 | 蓝牙是否已完成连接并登录 |
蓝牙秘钥 | AES 密钥,从秘钥查询接口拉取 |
秘钥状态 | normal / empty / wait / anomaly 四种状态 |
系统轮询定时器 | 系统状态轮询定时器句柄 |
控车日志缓存 | 控车日志缓存,网络异常时本地留存 |
八、关键入口与职责
入口 | 职责 |
页面初始化 | 创建蓝牙管理器实例并存入全局状态;调用秘钥查询接口初始化秘钥 |
页面显示 | 未连接时自动发起初始化;补传控车日志 |
系统状态轮询 | 5 秒轮询系统蓝牙/定位状态,触发自动重连 |
蓝牙模块初始化 | 初始化蓝牙模块后转入搜索连接 |
点击蓝牙图标 | 用户手动触发连接 |
搜索并连接 | 搜索目标蓝牙名并自动连接 |
连接状态监听 | 监听连接标志变化同步到全局状态 |
设备数据回调 | 接收设备返回数据并解析;触发秘钥异常自愈 |
点击控制按钮 | 根据蓝牙连接状态分发到蓝牙或 4G 通道 |
秘钥查询接口 | 拉取并刷新 AES 密钥,同时更新秘钥状态 |
日志补传 | 补传网络异常期间的控车日志 |
文档版本:v1.3 生成日期:2026-09-22