OpenHarmony 14 Ble蓝牙报错addService 2900099

OpenHarmony 14 Ble蓝牙报错addService 2900099

gattServer.addService

调用这个方法报错2900099

10 回复

·如果必须用模拟器,检查是否开启了蓝牙模拟,部分 OpenHarmony模拟器默认是关闭的。
5.服务 UUID 格式错误/重复添加了相同服务
.UUID 必须是标准的128 位格式,比如0000ffe0-0000-1000-8000-
00805f9b34fb,不能随便写16位简写。
.同一个GattServer里,不能重复添加相同UUID的服务,否则也会报这个错误。
三、给你一套「从0 到不报错」的完整调用顺序

//1.申请权限
//2.检查蓝牙是否开启
//3.获取 GattServer 实例
// 4. 监听 stateChange,确认服务状态正常
//5.调用 addService
// 6. 再调用 startAdvertising 广播

四、你现在可以直接做的事
1.先检查 module.json5 里的蓝牙和位置权限有没有写全。
2.在addService 之前加一句 console.log(bluetooth.isBleEnabled()),看看是不是 false。
3.把 addService 移到 gattServer.on(‘stateChange’) 回调里,等状态正常再执行。
4.换一台真机测试,别用模拟器。
按这个顺序排查,90%以上的2900099问题都能解决。


// 监听服务状态
gattServer.on('stateChange', (state) => {
  console.info('GattServer 状态变化:', state);
  if (state === bluetooth.ProfileConnectionState.STATE_CONNECTED ||
      state === bluetooth.ProfileConnectionState.STATE_ON) {
    // 状态正常后再添加服务
    addBleService();
  }
});

// 2. 添加服务
function addBleService() {
  if (!gattServer) {
    console.error('GattServer 未初始化');
    return;
  }
  const serviceUuid = '0000ffe0-0000-1000-8000-00805f9b34fb';
  const charUuid = '0000ffe1-0000-1000-8000-00805f9b34fb';
  const characteristic: bluetooth.BLECharacteristic = {
    uuid: charUuid,
    properties: {
      read: true,
      write: true,
      notify: true
    },
    permissions: {
      read: true,
      write: true
    }
  };
  const service: bluetooth.BLEService = {
    uuid: serviceUuid,
    isPrimary: true,
    characteristics: [characteristic]
  };
  try {
    gattServer.addService(service);
    console.info('服务添加成功');
  } catch (err) {
    console.error('addService 失败,错误码:', (err as Error).message);
  }
}

// 4. 虚拟地址不存在 / 设备未分配蓝牙地址
// 在模拟器、部分平板/定制设备上,蓝牙虚拟地址可能未初始化,导致 GattServer 无法正常工作。
// 解决方法:用真机测试,尽量不要用模拟器跑 BLE 相关代码。

try { await atManager.requestPermissionsFromUser(context, [ ‘ohos.permission.ACCESS_BLUETOOTH’, ‘ohos.permission.ACCESS_FINE_LOCATION’ ]); } catch (err) { console.error(‘权限申请失败’, err); }

2.蓝牙没打开,也没判断状态 直接调用 addService,但设备蓝牙是关闭的,肯定会失败。 你必须先做两步:

  1. 判断蓝牙是否开启:bluetooth.isBleEnabled()
  2. 如果没开,提示用户打开,或者跳转到系统设置

示例代码:

import bluetooth from '@ohos.bluetooth';

function checkBluetoothState(): boolean {
    if (!bluetooth.isBleEnabled()) {
        console.error('蓝牙未开启,请先打开蓝牙');
        return false;
    }
    return true;
}
  1. GattServer 没初始化就调用 addService addService 必须在 GattServer 初始化成功之后调用,很多人是写在页面 onCreate 里直接执行,此时实例还没准备好。 正确的流程是:
  2. 获取 GattServer 实例
  3. 注册 stateChange 回调,确认服务状态正常
  4. 再调用 addService

示例代码:

let gattServer: bluetooth.GattServer | null = null;

// 1. 初始化 GattServer
function initGattServer() {
    gattServer = bluetooth.getGattServer();
    if (!gattServer) {
        console.error('获取 GattServer 实例失败');
        return;
    }
}

一、先搞懂:2900099 到底是什么意思

在 OpenHarmony/HarmonyOS 的 BLE(低功耗蓝牙)子系统里,2900099 是通用错误码 Operation failed,文档里的官方说明是:

满足接口调用的前置依赖条件,或在某些场景下表示"指定的虚拟地址不存在"。

翻译成大白话就是:

你调用 gattServer.addService()时,系统还没准备好,或者蓝牙本身没开、没初始化成功,所以这个操作失败了。

二、最常见的5个原因+排查顺序

  1. 蓝牙权限没给全/动态权限没申请

很多新手只在 module.json5 里写了权限,却忘了在代码里动态申请,或者权限配置不全。

正确的权限配置(ArkTS 里):

// module.json5

"requestPermissions": [
  {
    "name": "ohos.permission.ACCESS_BLUETOOTH",
    "reason": "$string:bluetooth_permission_reason",
    "usedScene": {
      "abilities": ["EntryAbility"],
      "when": "inuse"
    }
  },
  {
    "name": "ohos.permission.ACCESS_FINE_LOCATION",
    "reason": "$string:location_permission_reason",
    "usedScene": {
      "abilities": ["EntryAbility"],
      "when": "inuse"
    }
  }
]

还要在代码里做动态申请:

import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import type common from '@ohos.app.ability.common';

async function requestPermissions(context: common.UIAbilityContext) {
  const atManager = abilityAccessCtrl.createAtManager();
  // ...后续权限请求逻辑
}

HarmonyOS的分布式文件系统让我在多设备间传输文件变得轻松无比。

2900099 在蓝牙子系统里是一个通用失败码(Operation failed),文档也明确它通常表示“未满足接口调用的前置依赖条件/(某些场景)指定的虚拟地址不存在”,需要结合你的调用时机和入参对象去定位。对 gattServer.addService() 来说,最常见的是前置条件/服务定义不合法/调用时序问题。
(因此它不像 2900003 这种能直接告诉你“蓝牙开关关闭”,而是“兜底失败码”。)

下面按排查优先级给你一个 checklist:

1)先排除“能力/环境不支持”

  • 模拟器/不带蓝牙的开发板镜像:很多情况下 BLE GATT Server 直接不可用,会表现为各种失败(有时就只吐 2900099)。
  • 确认设备侧蓝牙服务正常、蓝牙已打开。

2)权限是否齐全

  • 至少要声明并授予 BLE 相关权限(文档里 BLE 模块的很多接口标注了 ohos.permission.ACCESS_BLUETOOTH)。
  • 如果是 OpenHarmony 发行版/定制系统

权限给了没有,然后是GattServer注册了吗?

1. 蓝牙权限

  • 确保蓝牙已开启:bluetooth.isBleEnabled()
  • 动态申请权限:
ohos.permission.ACCESS_BLUETOOTH
ohos.permission.MANAGE_BLUETOOTH
ohos.permission.DISCOVER_BLUETOOTH

2. GattServer 必须先注册

// 正确流程
const gattServer = ble.createGattServer();
// 1. 先注册
await gattServer.registerServer();
// 2. 再 addService
await gattServer.addService(service);

参考下面例子运行一下:

import ble from '@ohos.bluetooth.ble';

async function setupBleServer() {
  // 1. 检查蓝牙
  if (!await ble.isBleEnabled()) {
    console.error('蓝牙未开启');
    return;
  }
  // 2. 创建并注册
  const gattServer = ble.createGattServer();
  await gattServer.registerServer();
  // 3. 构造服务
  const service: ble.GattService = {
    serviceUuid: '0000FFF0-0000-1000-8000-00805F9B34FB',
    serviceType: ble.ServiceType.PRIMARY,
    characteristics: [{
      characteristicUuid: '0000FFF1-0000-1000-8000-00805F9B34FB',
      permissions: ble.Permission.READ | ble.Permission.WRITE,
      properties: ble.Property.READ | ble.Property.WRITE | ble.Property.NOTIFY,
      descriptors: [{
        descriptorUuid: '00002902-0000-1000-8000-00805F9B34FB',
        permissions: ble.Permission.READ | ble.Permission.WRITE
      }]
    }]
  };
  // 4. 添加服务
  try {
    await gattServer.addService(service);
    console.log('addService 成功');
  } catch (e) {
    console.error(`addService 失败: ${e.code} ${e.message}`);
  }
}

错误码2900099表示操作失败。

可能原因

蓝牙接口调用失败的通用错误码,常见可能原因如下:

  1. 未满足接口调用的前置依赖条件。
  2. 指定的虚拟地址不存在。

处理步骤

请重试该操作。

错误码2900099表示BleService添加失败,通常因服务UUID重复或参数格式错误导致。请检查addService传入的BleService实例及其包含的特征(Characteristic)是否已存在,并确认UUID格式符合规范(如16位或128位标准UUID)。

错误码2900099表示BLE添加GATT服务时操作失败。常见原因与处理如下:

  1. 蓝牙未开启
    确认蓝牙已通过bluetoothManager.enableBluetooth()打开,且状态为STATE_ON。

  2. 权限不足
    需要在module.json5中声明权限:
    ohos.permission.ACCESS_BLUETOOTH
    动态申请后再尝试添加服务。

  3. 服务UUID无效或重复

    • 确保Service UUID符合标准格式(如0000180D-0000-1000-8000-00805F9B34FB)。
    • 同一服务实例不能重复添加,必须先removeService再重新添加。
  4. 特征定义错误
    检查characteristicpropertiespermissions是否正确,value长度是否超限,描述符是否合法。缺少必填属性(如ReadWriteNotify)可能导致添加失败。

  5. 未停止广播
    如果正在BLE广播,某些设备要求先停止广播再修改服务。

  6. 系统资源不足
    已注册的服务数量超过上限,可尝试释放不再使用的服务。

按上述顺序排查,一般可解决该错误。

回到顶部