Skip to content
Back to skills

Hmos Connectivity Kit Ble Device Discovery

ASecurity

扫描周边BLE设备和发送BLE广播报文实现设备发现,支持多路扫描和广播管理,需申请蓝牙权限,适用于智能硬件配对、位置服务等场景

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 22, 2026
developmenttypescriptapi

Works with

  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 22, 2026

npx -y skills add IsKenKenYa/skills --skill hmos-connectivity-kit-ble-device-discovery --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hmos Connectivity Kit Ble Device Discovery?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Hmos Connectivity Kit Ble Device Discovery
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iskenkenya-hmos-connectivity-kit-ble-device-discovery/badge)](https://www.skillsdirectory.com/skills/iskenkenya-hmos-connectivity-kit-ble-device-discovery)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: hmos-connectivity-kit-ble-device-discovery
description: 扫描周边BLE设备和发送BLE广播报文实现设备发现,支持多路扫描和广播管理,需申请蓝牙权限,适用于智能硬件配对、位置服务等场景
---

# BLE设备发现技能

## 功能描述

本技能提供低功耗蓝牙(BLE)设备发现能力,包括BLE扫描和BLE广播两部分功能:

**BLE扫描**:扫描周边其他设备发出的BLE广播报文,发现或查找目标设备。支持API version 15开始的多路扫描方式,可同时管理多个扫描流程。

**BLE广播**:本机设备发送BLE广播报文,实现被其他设备发现的功能。支持API version 11及以后的多路广播方式,可在不释放资源的情况下多次启动停止广播。

## 使用场景

### 触发词
- "BLE扫描" - 扫描周边BLE设备
- "BLE广播" - 发送BLE广播报文
- "查找设备" - 发现周边BLE设备
- "设备发现" - 实现设备互相发现
- "蓝牙扫描" - 扫描蓝牙设备
- "蓝牙广播" - 发送蓝牙广播

### 能做
- 扫描周边BLE设备并获取设备信息(设备地址、广播数据等)
- 发送BLE广播报文让其他设备发现本机
- 管理多路BLE扫描流程(API version 15+)
- 管理多路BLE广播流程(API version 11+)
- 解析扫描到的BLE广播报文数据
- 设置扫描过滤条件和扫描参数
- 设置广播数据和广播参数

### 绝不做
- 不直接建立GATT连接(需参考连接和传输数据技能)
- 不处理非BLE类型的蓝牙设备
- 不处理超出广播报文长度限制(31字节)的情况
- 不替代权限申请流程(需用户自行申请ohos.permission.ACCESS_BLUETOOTH权限)

### 补充
- API version 15+推荐使用多路扫描方式(ble.createBleScanner())
- API version 11+推荐使用多路广播方式(ble.startAdvertising(advertisingParams))
- 广播报文长度不能超过31字节,超出会导致广播启动失败
- 扫描和广播会消耗蓝牙硬件资源和影响设备功耗,需及时停止

## 调用规范和规则

### 输入约束
- 权限要求:必须申请ohos.permission.ACCESS_BLUETOOTH权限
- API版本:BLE扫描推荐API version 15+,BLE广播推荐API version 11+
- 广播数据长度:广播报文(advertisingData)和扫描响应报文(advertisingResponse)长度均不能超过31字节
- 扫描过滤器数量:建议单个应用使用过滤器数量不超过3个
- 设备地址格式:XX:XX:XX:XX:XX:XX(例如:"11:22:33:44:55:66")
- UUID格式:标准UUID格式(例如:"00001888-0000-1000-8000-00805f9b34fb")

### 执行约束
- 扫描持续时间:建议设置扫描持续时间,避免无限扫描消耗资源
- 广播持续时间:可选参数duration,若大于0则广播发送一段时间后自动停止
- 扫描模式:dutyMode可选择SCAN_MODE_LOW_POWER(低功耗)或SCAN_MODE_BALANCED(平衡)
- 匹配模式:matchMode可选择MATCH_MODE_AGGRESSIVE(激进)或MATCH_MODE_STICKY(粘性)
- 最大扫描路数:支持多路扫描,但建议不超过系统限制
- 最大广播路数:从API version 15开始支持多路广播

### 内容约束
- 禁止生成超出31字节长度的广播报文
- 禁止使用无效的广播标识ID(advertisingId)
- 禁止携带设备名时导致广播报文超出31字节(includeDeviceName需谨慎设置)
- 禁止在未停止扫描的情况下再次发起扫描(API version 14及以前)
- 禁止混用不同API版本的扫描/广播接口

### 降级约束
- 扫描失败:提示用户检查蓝牙是否开启、权限是否已申请
- 广播失败:提示用户检查广播报文长度是否超过31字节、广播资源是否已达上限
- 设备未找到:提示用户检查扫描过滤条件、延长扫描时间
- 权限不足:引导用户申请ohos.permission.ACCESS_BLUETOOTH权限

## 调用流程和步骤

### 步骤1:申请蓝牙权限

**前置校验**:
1. 检查是否已申请ohos.permission.ACCESS_BLUETOOTH权限
2. 检查蓝牙是否已开启
3. 检查API版本是否符合要求

**权限申请示例**:
```typescript
// 在module.json5中声明权限
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.ACCESS_BLUETOOTH"
      }
    ]
  }
}
```

### 步骤2:BLE扫描流程(API version 15+)

**2.1 创建扫描实例**:
```typescript
import { ble } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';

// 创建ble扫描实例,可以管理该实例下创建的扫描流程
let bleScanner: ble.BleScanner = ble.createBleScanner();
console.info('create bleScanner success');
```

**2.2 订阅扫描结果上报事件**:
```typescript
// 定义扫描结果上报回调函数
function onReceiveEvent(scanReport: ble.ScanReport) {
  console.info('BLE scan device find result: '+ JSON.stringify(scanReport));
  if (scanReport.scanResult.length > 0) {
    console.info('BLE scan result: ' + scanReport.scanResult[0].deviceId);
    // 可在此处解析广播数据
  }
}

try {
  // 发起订阅
  bleScanner.on('BLEDeviceFind', onReceiveEvent);
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

**2.3 构造扫描过滤条件和参数**:
```typescript
// 构造扫描BLE广播的过滤条件
let manufactureId = 4567;
let manufactureData: Uint8Array = new Uint8Array([1, 2, 3, 4]);
let manufactureDataMask: Uint8Array = new Uint8Array([0xFF, 0xFF, 0xFF, 0xFF]);

let scanFilter: ble.ScanFilter = {
  manufactureId: manufactureId,
  manufactureData: manufactureData.buffer,
  manufactureDataMask: manufactureDataMask.buffer
};

// 构造扫描配置参数
let scanOptions: ble.ScanOptions = {
  interval: 0,
  dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
  matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE
};
```

**2.4 发起扫描**:
```typescript
try {
  bleScanner.startScan([scanFilter], scanOptions);
  console.info('startBleScan success');
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

**2.5 停止扫描**:
```typescript
try {
  bleScanner.off('BLEDeviceFind', onReceiveEvent);
  bleScanner.stopScan();
  console.info('stopBleScan success');
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

### 步骤3:BLE广播流程(API version 11+)

**3.1 订阅广播状态上报事件**:
```typescript
function onReceiveEvent(data: ble.AdvertisingStateChangeInfo) {
  console.info('bluetooth advertising state = ' + JSON.stringify(data));
}

try {
  ble.on('advertisingStateChange', onReceiveEvent);
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

**3.2 构造广播参数和数据**:
```typescript
// 设置广播发送的参数
let setting: ble.AdvertiseSetting = {
  interval: 160,
  txPower: 0,
  connectable: true // 发送支持连接的广播
};

// 构造广播数据
let manufactureValueBuffer = new Uint8Array(4);
manufactureValueBuffer[0] = 1;
manufactureValueBuffer[1] = 2;
manufactureValueBuffer[2] = 3;
manufactureValueBuffer[3] = 4;

let manufactureDataUnit: ble.ManufactureData = {
  manufactureId: 4567,
  manufactureValue: manufactureValueBuffer.buffer
};

let advData: ble.AdvertiseData = {
  serviceUuids: ["00001888-0000-1000-8000-00805f9b34fb"],
  manufactureData: [manufactureDataUnit],
  serviceData: [],
  includeDeviceName: false // 注意:带上设备名时容易导致广播报文长度超出31字节
};

let advResponse: ble.AdvertiseData = {
  serviceUuids: [],
  manufactureData: [],
  serviceData: []
};

// 构造广播启动完整参数AdvertisingParams
let advertisingParams: ble.AdvertisingParams = {
  advertisingSettings: setting,
  advertisingData: advData, // 注意:广播报文长度不能超过31个字节
  advertisingResponse: advResponse, // 注意:广播报文长度不能超过31个字节
  duration: 0 // 可选参数,若大于0则广播发送一段时间后会自动停止
};
```

**3.3 首次启动广播**:
```typescript
let advHandle = 0xFF; // 定义广播标识

try {
  ble.startAdvertising(advertisingParams, (err, outAdvHandle) => {
    if (err) {
      console.error('startAdvertising failed: ' + err.code);
      return;
    } else {
      advHandle = outAdvHandle;
      console.info("advHandle: " + advHandle);
    }
  });
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

**3.4 停止指定标识的广播**:
```typescript
let advertisingDisableParams: ble.AdvertisingDisableParams = {
  advertisingId: advHandle // 使用首次启动广播时获取到的广播标识ID
};

try {
  ble.disableAdvertising(advertisingDisableParams, (err) => {
    if (err) {
      console.error('disableAdvertising failed: ' + err.code);
      return;
    }
    console.info('disableAdvertising success');
  });
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

**3.5 重新启动指定标识的广播**:
```typescript
let advertisingEnableParams: ble.AdvertisingEnableParams = {
  advertisingId: advHandle, // 使用首次启动广播时获取到的广播标识ID
  duration: 300
};

try {
  ble.enableAdvertising(advertisingEnableParams, (err) => {
    if (err) {
      console.error('enableAdvertising failed: ' + err.code);
      return;
    }
    console.info('enableAdvertising success');
  });
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

**3.6 完全停止广播并释放资源**:
```typescript
try {
  ble.stopAdvertising(advHandle, (err) => {
    if (err) {
      console.error('stopAdvertising failed: ' + err.code);
      return;
    }
    console.info('stopAdvertising success');
  });
  ble.off('advertisingStateChange', onReceiveEvent);
} catch (err) {
  console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
```

### 步骤4:错误处理

**通用错误处理模式**:
```typescript
try {
  // BLE操作代码
} catch (err) {
  let error = err as BusinessError;
  console.error('errCode: ' + error.code + ', errMessage: ' + error.message);
  
  // 根据错误码进行特定处理
  switch (error.code) {
    case 201:
      console.error('Permission denied. Please apply for ohos.permission.ACCESS_BLUETOOTH permission');
      break;
    case 2900003:
      console.error('Bluetooth disabled. Please enable Bluetooth');
      break;
    case 2900010:
      console.error('The number of advertising resources reaches the upper limit');
      break;
    case 2902054:
      console.error('The length of the advertising data exceeds the upper limit (31 bytes)');
      break;
    default:
      console.error('Operation failed: ' + error.message);
  }
}
```

## 错误码说明

| 错误码 | 说明 | 解决方法 |
|-------|------|---------|
| 201 | Permission denied | 申请ohos.permission.ACCESS_BLUETOOTH权限 |
| 401 | Invalid parameter | 检查参数类型和格式是否正确 |
| 801 | Capability not supported | 检查设备是否支持该API版本 |
| 2900001 | Service stopped | 等待蓝牙服务恢复或重启蓝牙 |
| 2900003 | Bluetooth disabled | 开启蓝牙开关 |
| 2900009 | Operation failed | 检查操作流程和参数是否正确 |
| 2900010 | The number of advertising resources reaches the upper limit | 停止不必要的广播释放资源 |
| 2902054 | The length of the advertising data exceeds the upper limit | 减少广播报文数据,确保不超过31字节 |
| 2902055 | Invalid advertising id | 使用首次启动广播时获取的正确广播标识ID |

## 编译和修复问题

### 依赖声明
```json
{
  "dependencies": {
    "@kit.ConnectivityKit": "^1.0.0",
    "@kit.BasicServicesKit": "^1.0.0"
  }
}
```

### 环境要求
- HarmonyOS API version: 10+ (基础功能), 11+ (推荐广播方式), 15+ (推荐扫描方式)
- DevEco Studio: 3.1+
- ArkTS: 最新版本

### 常见编译问题

**问题1:导入模块失败**
```
Error: Cannot find module '@kit.ConnectivityKit'
```
**解决方法**:确保HarmonyOS SDK版本支持ConnectivityKit,并正确配置依赖

**问题2:权限编译错误**
```
Error: Permission ohos.permission.ACCESS_BLUETOOTH not declared
```
**解决方法**:在module.json5中声明权限

**问题3:API版本不匹配**
```
Error: Property 'createBleScanner' does not exist on type 'ble'
```
**解决方法**:检查API版本,createBleScanner需要API version 15+

## 常见问题与解决方法

### Q1:扫描不到BLE设备
**原因**:
- 蓝牙未开启
- 权限未申请
- 扫描过滤条件设置过于严格
- 目标设备未发送广播

**解决方法**:
- 检查并开启蓝牙开关
- 申请ohos.permission.ACCESS_BLUETOOTH权限
- 调整扫描过滤条件或使用空过滤器(不建议)
- 确认目标设备正在发送BLE广播

### Q2:广播启动失败
**原因**:
- 广播报文长度超过31字节
- 广播资源已达上限
- 权限未申请
- includeDeviceName设置导致超长

**解决方法**:
- 减少广播报文数据量,确保不超过31字节
- 停止不必要的广播释放资源
- 申请ohos.permission.ACCESS_BLUETOOTH权限
- 将includeDeviceName设置为false

### Q3:无法解析广播数据
**原因**:
- 广播数据格式不符合蓝牙标准协议
- 解析逻辑错误

**解决方法**:
- 参考蓝牙标准协议Core Assigned Numbers规范
- 使用完整示例中的parseScanResult方法解析

### Q4:多路扫描/广播管理混乱
**原因**:
- 不同API版本的接口混用
- 广播标识ID管理错误

**解决方法**:
- 使用推荐的API version 15+扫描方式和API version 11+广播方式
- 正确保存和管理首次启动广播时获取的广播标识ID
- 不要混用不同API版本的接口

## 输出结果报告

执行完成后输出以下信息:

```json
{
  "status": "success",
  "operation": "BLE扫描/广播",
  "deviceId": "扫描到的设备地址或本机设备地址",
  "advHandle": "广播标识ID(仅广播操作)",
  "scanResult": {
    "deviceId": "设备地址",
    "data": "广播数据",
    "rssi": "信号强度"
  },
  "apiUsed": [
    "ble.createBleScanner",
    "bleScanner.startScan",
    "bleScanner.stopScan",
    "bleScanner.on('BLEDeviceFind')",
    "ble.startAdvertising",
    "ble.enableAdvertising",
    "ble.disableAdvertising",
    "ble.stopAdvertising",
    "ble.on('advertisingStateChange')"
  ]
}
```

## 参考文档

- [BLE设备查找开发指南](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ble-development-guide)
- [蓝牙BLE API参考](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bluetooth-ble)
- [声明权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/declare-permissions)
- [向用户申请授权](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/request-user-authorization)
- [连接和传输数据](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/gatt-development-guide)

## 完整示例代码

- [ArkTS BLE扫描示例](assets/BleScanManager.ets) - 包含完整的BLE扫描流程和广播数据解析
- [ArkTS BLE广播示例](assets/BleAdvertisingManager.ets) - 包含完整的BLE广播流程管理
- [配置文件示例](assets/module.json5) - 包含权限声明配置

## 测试用例

### 正向测试用例
- [测试BLE扫描功能](tests/test_ble_scan_positive.ets) - 测试正常扫描流程
- [测试BLE广播功能](tests/test_ble_advertising_positive.ets) - 测试正常广播流程

### 边界测试用例
- [测试广播报文长度边界](tests/test_advertising_length_boundary.ets) - 测试31字节长度限制
- [测试多路扫描/广播](tests/test_multi_scan_advertising.ets) - 测试多路管理能力

### 异常测试用例
- [测试权限缺失场景](tests/test_permission_denied.ets) - 测试权限未申请时的错误处理
- [测试蓝牙未开启场景](tests/test_bluetooth_disabled.ets) - 测试蓝牙关闭时的错误处理
- [测试参数错误场景](tests/test_invalid_parameters.ets) - 测试参数错误时的错误处理

Files in this skill

  • SUB_SKILL.md15.8 KB
  • assets/BleAdvertisingManager.ets3.7 KB
  • assets/BleScanManager.ets8.9 KB
  • assets/module.json51.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…