誰煮肉片 2025-12-01 18:21 采纳率: 0%
浏览 4

鸿蒙开发 蓝牙广播 设备类型名未知

加了设备名称就发不了13个uuid 数据 ,不加名称 携带的设备类型名 又是未知 ,应该怎么做 ,可用 又发送13个uuid的数据,设备类型名 还能是正确的

img


import { ble } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';

const TAG: string = 'BleAdvertisingManager';

export class BleAdvertisingManager {
  private advHandle: number = 0xFF; // 初始的无效值

  // 1. 定义广播状态上报事件
  onReceiveEvent = (data: ble.AdvertisingStateChangeInfo) => {
    console.info(TAG, 'bluetooth advertising state = ' + JSON.stringify(data));
    AppStorage.setOrCreate('advertiserState', data.state);
  };

  // 2. 首次启动广播
  public async startAdvertising() {
    // 2.1 设置广播发送的参数
    let setting: ble.AdvertiseSetting = {
      interval: 160,
      txPower: 0,
      connectable: true,
    };
    // 2.2 构造广播数据
    let manufactureValueBuffer = new Uint8Array();
    manufactureValueBuffer[0] = 1;
    manufactureValueBuffer[1] = 2;
    manufactureValueBuffer[2] = 3;
    manufactureValueBuffer[3] = 4;


    let serviceValueBuffer = new Uint8Array(4);
    serviceValueBuffer[0] = 5;
    serviceValueBuffer[1] = 6;
    serviceValueBuffer[2] = 7;
    serviceValueBuffer[3] = 8;
    let manufactureDataUnit: ble.ManufactureData = {
      manufactureId: 4567,
      manufactureValue: manufactureValueBuffer.buffer
    };
    let serviceDataUnit1: ble.ServiceData = {
      serviceUuid: "0000181A-0000-1000-8000-00805F9B34FB",
      serviceValue: serviceValueBuffer.buffer
    };
    let serviceDataUnit2: ble.ServiceData = {
      serviceUuid: "19991999-0000-1000-8000-00805f9b34fb",
      serviceValue: serviceValueBuffer.buffer
    };
    let advData: ble.AdvertiseData = {
      serviceUuids: [
        "000008F0-0000-1000-8000-00805F9B34FB",
        "00000810-0000-1000-8000-00805F9B34FB",
        "00009D13-0000-1000-8000-00805F9B34FB",
        "0000950E-0000-1000-8000-00805F9B34FB",
        "00004E2D-0000-1000-8000-00805F9B34FB",
        "000041F0-0000-1000-8000-00805F9B34FB",
        "00001DE1-0000-1000-8000-00805F9B34FB",
        "00007EB9-0000-1000-8000-00805F9B34FB",
        "0000F59C-0000-1000-8000-00805F9B34FB",
        "00002D98-0000-1000-8000-00805F9B34FB",
        "0000343D-0000-1000-8000-00805F9B34FB",
        "00002B0B-0000-1000-8000-00805F9B34FB",
        "00002D89-0000-1000-8000-00805F9B34FB"
        ],
      manufactureData: [],
      serviceData: [],
      // includeDeviceName: false,// 表示是否携带设备名,可选参数。注意:带上设备名时,容易导致广播报文长度超出31个字节,使得广播启动失败
    };
    // let advResponse: ble.AdvertiseData = {
    //   serviceUuids: [],
    //   manufactureData: [],
    //   serviceData: [serviceDataUnit1, serviceDataUnit2]
    // };
    // 2.3 构造广播启动完整参数AdvertisingParams

    let advertisingParams: ble.AdvertisingParams = {
      advertisingSettings: setting,
      advertisingData: advData, // 注意: 广播报文长度不能超过31个字节
      // advertisingResponse: advData, // 注意: 广播报文长度不能超过31个字节
      duration: 0 // 可选参数,若参数大于0,则广播发送一段时间后会停止,但分配的广播资源还在,可重新启动发送
    }

    // 2.4 首次启动广播,蓝牙子系统会分配相关资源,包括应用获取到的广播标识ID
    try {
      ble.on('advertisingStateChange', this.onReceiveEvent);
      this.advHandle = await ble.startAdvertising(advertisingParams);
    } catch (err) {
      console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }

  // 3. 停止指定标识的广播,即首次启动时分配的标识,停止后,该路广播资源仍然存在
  public async disableAdvertising() {
    // 3.1 构造停止广播参数
    let advertisingDisableParams: ble.AdvertisingDisableParams = {
      advertisingId: this.advHandle // 使用首次启动广播时获取到的广播标识ID
    }
    try {
      // 3.2 停止
      await ble.disableAdvertising(advertisingDisableParams);
    } catch (err) {
      console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }

  // 4. 启动指定标识的广播,即首次启动时分配的标识
  public async enableAdvertising(enableDuration: number) {
    // 4.1 构造启动广播参数
    let advertisingEnableParams: ble.AdvertisingEnableParams = {
      advertisingId: this.advHandle, // 使用首次启动广播时获取到的广播标识ID
      duration: enableDuration
    }
    try {
      // 4.2 再次启动
      await ble.enableAdvertising(advertisingEnableParams);
    } catch (err) {
      console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }

  // 5. 完全停止广播,释放广播资源
  public async stopAdvertising() {
    try {
      await ble.stopAdvertising(this.advHandle);
      ble.off('advertisingStateChange', this.onReceiveEvent);
    } catch (err) {
      console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  }
}

let bleAdvertisingManager = new BleAdvertisingManager();
export default bleAdvertisingManager as BleAdvertisingManager;


  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2025-12-01 18:28
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    在鸿蒙开发中,蓝牙广播(BLE Advertising)时遇到“设备类型名未知”的问题,通常是由于未正确设置设备名称或者广播数据长度超出限制导致的。你提到当添加设备名称时,UUID数量受限为13个,而不加名称时设备类型显示为未知


    一、问题分析

    1. 广播数据长度限制

    • BLE广播数据包的最大长度是 31字节
    • 当你添加设备名称时,系统会自动将设备名称包含在广播数据中,这会占用一定字节数。
    • 如果你在 advData 中设置了 includeDeviceName: true,那么设备名称会被自动加入广播数据中,从而压缩了其他字段的空间,如 serviceUuidsserviceData 等。

    2. 设备名称与设备类型关系

    • 设备类型(如:0x06 表示通用访问模式)通常由广播数据中的特定字段决定。
    • 如果你不设置设备名称(即 includeDeviceName: false),系统可能无法识别设备类型,导致显示为“未知”。

    二、解决方案

    核心解决思路

    在不牺牲设备名称的前提下,合理分配广播数据空间,确保设备类型信息正确,并且能携带13个UUID。


    解决方案步骤如下

    1. 使用 includeDeviceName: false 避免广播数据过长

      • 不自动添加设备名称,可以避免广播数据超过31字节限制。
      • 但需要手动添加设备类型(例如:0x06)以保证设备类型不为“未知”。
    2. 手动添加设备类型(Device Name Flag)

      • advData 中手动设置设备类型标志位,比如 0x06(通用访问模式)。
      • 这样即使没有设备名称,设备类型仍然可以被识别。
    3. 控制广播数据大小,确保不超过31字节

      • 检查 serviceUuidsmanufactureData 的总字节数。
      • 可以通过减少 serviceUuids 数量或缩短 manufactureValue 来优化数据长度。
    4. 使用 serviceData 替代部分 serviceUuids

      • 如果 UUID 数量较多,考虑使用 serviceData 来传递数据,而不是全部放在 serviceUuids 中。

    三、代码修改建议

    以下是对你的代码进行优化后的版本,保留设备类型信息,同时支持13个UUID

    import { ble } from '@kit.ConnectivityKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    const TAG: string = 'BleAdvertisingManager';
    
    export class BleAdvertisingManager {
      private advHandle: number = 0xFF; // 初始的无效值
    
      // 1. 定义广播状态上报事件
      onReceiveEvent = (data: ble.AdvertisingStateChangeInfo) => {
        console.info(TAG, 'bluetooth advertising state = ' + JSON.stringify(data));
        AppStorage.setOrCreate('advertiserState', data.state);
      };
    
      // 2. 首次启动广播
      public async startAdvertising() {
        // 2.1 设置广播发送的参数
        let setting: ble.AdvertiseSetting = {
          interval: 160,
          txPower: 0,
          connectable: true,
        };
    
        // 2.2 构造广播数据
        let advData: ble.AdvertiseData = {
          serviceUuids: [
            "000008F0-0000-1000-8000-00805F9B34FB",
            "00000810-0000-1000-8000-00805F9B34FB",
            "00009D13-0000-1000-8000-00805F9B34FB",
            "0000950E-0000-1000-8000-00805F9B34FB",
            "00004E2D-0000-1000-8000-00805F9B34FB",
            "000041F0-0000-1000-8000-00805F9B34FB",
            "00001DE1-0000-1000-8000-00805F9B34FB",
            "00007EB9-0000-1000-8000-00805F9B34FB",
            "0000F59C-0000-1000-8000-00805F9B34FB",
            "00002D98-0000-1000-8000-00805F9B34FB",
            "0000343D-0000-1000-8000-00805F9B34FB",
            "00002B0B-0000-1000-8000-00805F9B34FB",
            "00002D89-0000-1000-8000-00805F9B34FB"
          ],
          manufactureData: [],
          serviceData: [],
          includeDeviceName: false, // 不自动添加设备名
          // 手动添加设备类型标志位(0x06 表示通用访问模式)
          flags: [0x06] // 0x06 是设备类型标识
        };
    
        // 2.3 构造广播启动完整参数AdvertisingParams
        let advertisingParams: ble.AdvertisingParams = {
          advertisingSettings: setting,
          advertisingData: advData, // 注意: 广播报文长度不能超过31个字节
          duration: 0 // 可选参数,若参数大于0,则广播发送一段时间后会停止
        };
    
        // 2.4 首次启动广播
        try {
          ble.on('advertisingStateChange', this.onReceiveEvent);
          this.advHandle = await ble.startAdvertising(advertisingParams);
        } catch (err) {
          console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
        }
      }
    
      // 其他方法保持不变...
    }
    

    四、重点说明

    • flags: [0x06]:手动添加设备类型标志,避免设备类型显示为“未知”。
    • includeDeviceName: false:防止广播数据过长,保证能携带13个UUID。
    • 广播数据长度控制:确保 advData 总长度不超过31字节。

    五、验证方式

    1. 使用蓝牙扫描工具(如:nRF Connect)查看广播数据。
    2. 确认设备名称是否显示为“未知”,以及设备类型是否为“0x06”。
    3. 检查是否成功发送了13个UUID。

    如果你有更多关于广播数据格式的问题,也可以继续提问!

    评论

报告相同问题?

问题事件

  • 创建了问题 12月1日