解决uniapp实现ios系统中低功耗蓝牙通讯失败问题
UniApp 实现 App 连接低功耗蓝牙(BLE)通讯
手头上有一个 uniapp 实现低功耗蓝牙通讯设备的项目,本来 Android 版本没问题已经上线,到了发布测试 iOS 出问题了,连接上了设备但是通讯失败,排查了下才发现是协议通讯中有包含六位 ID,也就是设备的 MAC 地址,因为设备主要标识符通常是设备 MAC,Android 能直接获取,但是喵的 iOS 不给,所以最终只能找硬件工程师进行协商找解决方案。
一、BLE 通讯协议说明(这是本项目协议消息体构成)
客户端发送消息体格式:
1Byte(功能ID) + 6Byte(设备ID) + 1Byte(版本号) + nByte(功能内容)
服务端回应消息体格式:
1Byte(功能ID) + nByte(功能内容)
二、Android 与 iOS 的差异与解决方案
Android
deviceId返回即为设备 Mac 地址,可直接进行数据通讯。
iOS
deviceId返回的是一个 UUID,并非真实 Mac 地址。
UUID 是如何生成的?
- iOS 使用
CBPeripheral.identifier生成一个临时 UUID。 - 此 UUID 是 iOS 系统基于 BLE 发现过程为每个设备 随机生成的唯一标识符。
- 与设备的真实物理地址无关,每次蓝牙重连或重新发现设备时可能会改变。
- Apple 这么设计是为 保护用户隐私,避免开发者追踪设备或用户。
解决方案:
方法一:连接成功后监听设备主动返回 Mac 地址
- 设备会在连接 1 秒后主动发送 Mac 地址。
- 若无回应,设备会每 2 秒重发一次,直到收到。
uni.onBLECharacteristicValueChange((res) => {
const value = ab2hex(res.value);
if (value.startsWith("01")) {
const mac = value.slice(2, 14); // 截取6字节mac
uni.setStorageSync('deviceMac', mac) // 存储mac用于后续通讯,有用 vuex 或者 pinia 等其他方法也可以
await this.send('11'); // 应答设备防止一直上报
}
});
方法二:通过广播数据 (advertisData) 提取 Mac 地址
- 每次扫描设备时,广播包中可能包含 Mac 地址字段。
- 若存在隐私顾虑,可对其 加密处理,连接设备前进行 解密并缓存。
import CryptoJS from "crypto-js";
function decryptMac(cipherHex) {
const key = CryptoJS.enc.Hex.parse("00112233445566778899aabbccddeeff"); // 16字节密钥
const iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000"); // 默认全0 IV
const encrypted = CryptoJS.enc.Hex.parse(cipherHex);
const encryptedBase64 = CryptoJS.enc.Base64.stringify(encrypted);
const decrypted = CryptoJS.AES.decrypt(encryptedBase64, key, {
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return decrypted.toString(CryptoJS.enc.Hex);
}
uni.startBluetoothDevicesDiscovery({
success() {
uni.onBluetoothDeviceFound((device) => {
const advertisData = device.advertisData;
const raw = ab2hex(advertisData);
const encryptedMac = raw.slice(10, 42); // 示例中为16字节加密
const mac = decryptMac(encryptedMac);
console.log("解密出的Mac地址:", mac);
});
},
});
三、通讯流程简单示意
async function connectBLE(device) {
await uni.createBLEConnection({ deviceId: device.deviceId });
// 监听特征值变化
uni.onBLECharacteristicValueChange((res) => handleResponse(res));
// 启用 notify 监听
await uni.notifyBLECharacteristicValueChange({
deviceId: device.deviceId,
serviceId: serviceUUID,
characteristicId: notifyUUID,
state: true,
});
// 发送数据
const platform = uni.getSystemInfoSync().platform;
const macAddress = uni.getStorageSync("deviceMac");
const payload = buildPayload(
"01",
platform == "ios" ? macAddress : device.deviceId,
"01",
content
);
await uni.writeBLECharacteristicValue({
deviceId: device.deviceId,
serviceId: serviceUUID,
characteristicId: writeUUID,
value: str2ab(payload),
});
}
️ 四、安全建议
- 广播中的 Mac 地址应加密,防止泄露。
- 通讯内容建议使用 AES 加密,提升安全等级。
- 使用 CRC16 或 hash 校验数据完整性。
五、总结
| 项目 | Android | iOS |
|---|---|---|
| deviceId | 返回真实 Mac 地址 | 返回 UUID,需特殊处理 ️ |
| 获取 Mac | 可直接使用 | 连接后监听 / 广播包解析 |
| 广播数据 | 可用,可加密携带 Mac 地址 | 推荐使用,用于连接前标识设备 |
| 加密建议 | AES 对称加密 / CRC16 校验 | 同 Android,建议一致处理方式 |
解决uniapp实现ios系统中低功耗蓝牙通讯失败问题的更多相关文章
- video 在iphone手机的ios系统和微信端无法自动播放
描述:video 在iphone手机,微信端无法自动播放,ios系统下不能自动播放视频.而且如果没有autoplay属性,在微信端点击一次,弹不出视频,要一直触着两秒后才可以打开视频.如果点击播放的话 ...
- vue项目引入FastClick组件解决IOS系统下h5页面中的按钮点击延迟,连续点击无反应的问题
异常描述: ios系统手机中访问h5页面,按钮点击有延迟,连续点击卡顿.无反应. 异常原因: 这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设 ...
- IOS系统之蓝牙外接设备
Ios系统对于蓝牙外接设备在iphone4以前都是蓝牙2.0的时候,需要通过苹果的审核,据统计通过率仅有2%左右,现在蓝牙2.0基本上处于淘汰状态,所以在这里就不考虑了. 现在iphone4s以后的设 ...
- Vue微信自定义分享时安卓系统config:ok,ios系统config:invalid signature签名错误,或者安卓和ios二次分享时均config:ok但是分享无效的解决办法
简述需求:要求指定页面可以进行微信自定义分享(自定义标题,描述,图片,链接),剩下的页面隐藏所有基础接口.二次分享依然可以正常使用,切换至其他页面也可以正常进行自定义分享. 这两天在做微信自定义分享的 ...
- uni-app 时间格式问题 new Date(str) IOS系统跟Android系统不兼容
今天做了一个需求,要在列表中把后台返回来的时间给显示出来,使用 new Date(str) 在微信开发者工具上显示是没有问题的,然后在IOS系统上显示是NAN. 原因是 IOS系统只识别 " ...
- 我遇到移动端ios系统遇到的一些坑和解决办法
我是作为一个H5移动端开发.主要是做跨平台兼容ios系统和Android系统. 在移动端中,最让我头疼的不是功能,不是业务逻辑.而是适配.俗话说:移动端适配是最头疼的事情,也是头发掉得最快的时候. 我 ...
- 深入了解ios系统机制
1.什么叫ios? ios一般指ios(Apple公司的移动操作系统) . 苹果iOS是由苹果公司开发的移动操作系统.苹果公司最早于2007年1月9日的Macworld大会 ...
- 在MacOS和iOS系统中使用OpenCV
在MacOS和iOS系统中使用OpenCV 前言 OpenCV 是一个开源的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法. 最近试着在 MacOS 和 iOS 上使用 OpenCV ...
- iOS系统提供开发环境下命令行编译工具:xcodebuild
iOS系统提供开发环境下命令行编译工具:xcodebuild[3] xcodebuild 在介绍xcodebuild之前,需要先弄清楚一些在XCode环境下的一些概念[4]: Workspace:简单 ...
- 全球最低功耗蓝牙单芯片DA14580的软件体系 -层次架构和BLE消息事件处理过程
在作者之前发表的<全球最低功耗蓝牙单芯片DA14580的系统架构和应用开发框架分析>.<全球最低功耗蓝牙单芯片DA14580的硬件架构和低功耗>.<全球最低功耗蓝牙单芯片 ...
随机推荐
- FANUC机器人M-16iB伺服马达维修参考措施
随着工业自动化技术的不断发展,机器人已经广泛应用于各个领域.其中,发那科机器人以其卓越的性能和稳定性,成为了许多企业的首选.然而,伺服电机作为机器人核心部件之一,FANUC机械手维修保养至关重要. 一 ...
- C语言中的*和&符号
之前对*和&符号一直理解的比较浅显.只知道: *p好像表示的是一个指针: &p表示的是一个地址. 然而这次当遇到了下面这个情况的时候: int a = 10; int *b = &am ...
- 别再混淆了!JVM内存模型和Java内存模型的本质区别
JVM 内存模型(JVM Memory Model)和 Java 内存模型(Java Memory Model, JMM)是 Java 开发中两个非常重要的概念,但这两个概念很容易被搞混,所以本文就来 ...
- php实现地址跳转的方式
在PHP中,实现地址跳转主要有以下几种方式: 1. 使用 header() 函数 header() 函数用于发送原始的 HTTP 头信息,常用于实现页面跳转. <?php header(&quo ...
- 一个简单的PHP单文件路由类示例
<?php class Router { protected $routes = array(); protected $basePath; public function __construc ...
- 请求方法:GET 与 POST
根据 RFC 规范,GET 的语义是从服务器获取指定的资源,GET 请求的参数位置一般是写在 URL 中,URL 规定只能支持 ASCII,所以 GET 请求的参数只允许 ASCII 字符 ,而且浏览 ...
- 「2024 年度技术精华盘点」IvorySQL & PostgreSQL 技术干货全解析!
2024 年,IvorySQL 公众号持续输出高质量技术内容,涵盖 PostgreSQL 核心技术解析 和 IvorySQL 创新实践 两大方向.无论您是数据库领域的初学者,还是经验丰富的开发者,这些 ...
- MTR工具使用说明与结果分析
免责声明: 本文档可能包含第三方产品信息,该信息仅供参考.阿里云对第三方产品的性能.可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺. 概述 当客户端访问目标服务器或负载均衡,使用pin ...
- nginx下增加https端口的方法
一.进入根目录我是使用xshell进行远程连接服务器的,连接到服务器首先输入cd /进入到根目录在这里插入图片描述二.配置nginx.conf文件首先输入cd etc/nginx进入到nginx目录在 ...
- Efficient Scalable Multi-Party Private Set Intersection
论文学习:Efficient Scalable Multi-Party Private Set Intersection 这篇论文提出了一种基于双中心零共享(Bicentric Zero-Sharin ...