OpenHarmony 14 Ble蓝牙报错addService 2900099
OpenHarmony 14 Ble蓝牙报错addService 2900099
gattServer.addService
调用这个方法报错2900099
·如果必须用模拟器,检查是否开启了蓝牙模拟,部分 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问题都能解决。
try { await atManager.requestPermissionsFromUser(context, [ ‘ohos.permission.ACCESS_BLUETOOTH’, ‘ohos.permission.ACCESS_FINE_LOCATION’ ]); } catch (err) { console.error(‘权限申请失败’, err); }
2.蓝牙没打开,也没判断状态 直接调用 addService,但设备蓝牙是关闭的,肯定会失败。 你必须先做两步:
- 判断蓝牙是否开启:bluetooth.isBleEnabled()
- 如果没开,提示用户打开,或者跳转到系统设置
示例代码:
import bluetooth from '@ohos.bluetooth';
function checkBluetoothState(): boolean {
if (!bluetooth.isBleEnabled()) {
console.error('蓝牙未开启,请先打开蓝牙');
return false;
}
return true;
}
- GattServer 没初始化就调用 addService addService 必须在 GattServer 初始化成功之后调用,很多人是写在页面 onCreate 里直接执行,此时实例还没准备好。 正确的流程是:
- 获取 GattServer 实例
- 注册 stateChange 回调,确认服务状态正常
- 再调用 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个原因+排查顺序
- 蓝牙权限没给全/动态权限没申请
很多新手只在 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表示BleService添加失败,通常因服务UUID重复或参数格式错误导致。请检查addService传入的BleService实例及其包含的特征(Characteristic)是否已存在,并确认UUID格式符合规范(如16位或128位标准UUID)。
错误码2900099表示BLE添加GATT服务时操作失败。常见原因与处理如下:
-
蓝牙未开启
确认蓝牙已通过bluetoothManager.enableBluetooth()打开,且状态为STATE_ON。 -
权限不足
需要在module.json5中声明权限:
ohos.permission.ACCESS_BLUETOOTH
动态申请后再尝试添加服务。 -
服务UUID无效或重复
- 确保Service UUID符合标准格式(如
0000180D-0000-1000-8000-00805F9B34FB)。 - 同一服务实例不能重复添加,必须先
removeService再重新添加。
- 确保Service UUID符合标准格式(如
-
特征定义错误
检查characteristic的properties和permissions是否正确,value长度是否超限,描述符是否合法。缺少必填属性(如Read、Write或Notify)可能导致添加失败。 -
未停止广播
如果正在BLE广播,某些设备要求先停止广播再修改服务。 -
系统资源不足
已注册的服务数量超过上限,可尝试释放不再使用的服务。
按上述顺序排查,一般可解决该错误。


