uni-app ios无法获取蓝牙的serviceData

发布于 1周前 作者 bupafengyu 来自 Uni-App

uni-app ios无法获取蓝牙的serviceData

开发环境 版本号 项目创建方式
Windows Windows 11 专业版 HBuilderX

产品分类:uniapp/App
PC开发环境操作系统:Windows
HBuilderX类型:正式
HBuilderX版本号:3.8.12
手机系统:iOS
手机系统版本号:iOS 16
手机厂商:苹果
手机机型:IPhone13
页面类型:vue
vue版本:vue3
打包方式:云端
项目创建方式:HBuilderX

示例代码:

//蓝牙识别 configBlueTooth() { let _this = this this.getBluetoothAdapterState().then(res => { if (res === ‘ok’) { //开启设备搜索 this.startBluetoothDevicesDiscovery().then(res1 => { if (res1 === ‘ok’) { this.getBluetooth() } }) }else { //开启蓝牙模块 _this.openBluetoothAdapter().then(res2 => { if (res2 === ‘ok’) { //开启设备搜索 this.startBluetoothDevicesDiscovery().then(res1 => { if (res1 === ‘ok’) { this.getBluetooth() } }) }else { // console.log(‘蓝牙初始化失败’) } }) } }) },

//获取蓝牙设备 getBluetooth() { let _this = this //监听寻找到新设备的事件 uni.onBluetoothDeviceFound(function (devices) { if(devices.devices[0].name){ _this.blueTooth.push(devices.devices[0]) console.log(_this.blueTooth) } }) },

async openBluetoothAdapter(){ let _this = this let result = new Promise( (resolve, reject) => { uni.openBluetoothAdapter({ success(res) { resolve(‘ok’) }, fail(res) { resolve(res) }, }) }) return result },

async getBluetoothAdapterState(){ let _this = this let result = new Promise( (resolve, reject) => { uni.getBluetoothAdapterState({ success(res) { resolve(‘ok’) }, fail(res) { resolve(res) }, }) }) return result },

async startBluetoothDevicesDiscovery(){ let _this = this let result = new Promise( (resolve, reject) => { uni.startBluetoothDevicesDiscovery({ success(res) { resolve(‘ok’) }, fail(res) { resolve(res) }, }) }) return result },


操作步骤:
- 先打开手机蓝牙再试

预期结果:
- IOS能打印出serviceData

实际结果:
- IOS无法打印出serviceData

bug描述:
打印 `_this.blueTooth`,安卓有serviceDataIOS没有serviceData,但是蓝牙的mac地址储存在serviceData,无法稳定获取serviceData

安卓:
```json
{
"deviceId": "52:01:23:11:00:31",
"name": "R23110049",
"RSSI": -53,
"localName": "R23110049",
"advertisServiceUUIDs": [],
"advertisData": {},
"serviceData": {
"00001803-0000-1000-8000-00805F9B34FB": {}
}
},

IOS:

{
"RSSI": -57,
"advertisData": "",
"deviceId": "AA11EF7D-B662-84A6-BA0B-8828F436AC5D",
"name": "R23110049"
},

6 回复

提供一个示例吧


startBluetoothDevicesDiscovery 允许重复获取试一下

可以了,谢谢

回复 5***@qq.com: 咋整的,指教下,我也不行,就正常的获取广播信息,然后拿不到serviceData

回复 Azikou: 你好你解决这个问题了吗?我这ios也拿不到serviceData

uni-app 中,iOS 平台无法直接获取蓝牙设备的 serviceData 是一个已知的问题。这是由于 iOS 系统的限制,iOS 的 CoreBluetooth 框架没有提供直接获取 serviceData 的 API。

原因

在 iOS 系统中,CoreBluetooth 框架的 CBAdvertisementDataServiceDataKey 只有在设备未被连接时才会返回 serviceData。一旦设备被连接,iOS 就不再提供 serviceData。这与 Android 系统不同,Android 系统可以在连接后继续获取 serviceData

解决方案

  1. 在扫描时获取 serviceData: 如果你需要在扫描时获取 serviceData,可以在 onBluetoothDeviceFound 事件中获取。iOS 在扫描时会返回 advertisData,其中可能包含 serviceData

    uni.onBluetoothDeviceFound(function (res) {
        const devices = res.devices;
        devices.forEach(device => {
            if (device.advertisData) {
                const serviceData = device.advertisData.serviceData;
                console.log('Service Data:', serviceData);
            }
        });
    });
  2. 连接后无法获取 serviceData: 如果你在连接后需要获取 serviceData,目前没有直接的解决方案。你可以考虑以下方法:

    • 在扫描时缓存 serviceData,连接后使用缓存的数据。
    • 如果 serviceData 是动态的,考虑在设备端通过自定义服务或特征值来传递这些数据。
  3. 使用原生插件: 如果上述方法无法满足需求,你可以考虑开发一个原生插件,通过原生代码来获取 serviceData。不过,这需要熟悉 iOS 的 CoreBluetooth 开发。

示例代码

以下是一个简单的示例,展示如何在扫描时获取 serviceData

uni.startBluetoothDevicesDiscovery({
    services: ['your-service-uuid'],
    success: function (res) {
        console.log('Start discovery success:', res);
    },
    fail: function (err) {
        console.error('Start discovery fail:', err);
    }
});

uni.onBluetoothDeviceFound(function (res) {
    const devices = res.devices;
    devices.forEach(device => {
        if (device.advertisData) {
            const serviceData = device.advertisData.serviceData;
            console.log('Service Data:', serviceData);
        }
    });
});
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!