蓝牙外设管理器 PRO

需要 Scripting PRO

BluetoothPeripheralManager 提供将设备作为 BLE 外设运行的能力,允许你:

  • 广播设备名称与服务 UUID
  • 添加并移除服务
  • 处理来自中央设备的读写请求
  • 发送通知给已订阅的中央设备
  • 管理连接参数(如连接延迟)

该 API 适用于构建如自定义传感器设备、蓝牙外设模拟器、控制器等场景。


基本状态属性

isAdvertising: Promise<boolean>

查询当前是否正在进行广播。

  • 类型Promise<boolean>
  • 示例
1const advertising = await BluetoothPeripheralManager.isAdvertising
2console.log(advertising ? "正在广播" : "已停止广播")

广播控制

startAdvertising(advertisementData): Promise<void>

启动蓝牙广播。

  • 参数

    • advertisementData(对象):

      • localName?: string:设备名称
      • serviceUUIDs?: string[]:要广播的服务 UUID
  • 示例

1await BluetoothPeripheralManager.startAdvertising({
2  localName: "MyPeripheral",
3  serviceUUIDs: ["1234", "ABCD"]
4})

stopAdvertising(): Promise<void>

停止当前的广播。

1await BluetoothPeripheralManager.stopAdvertising()

服务管理

addService(service): Promise<void>

向外设添加服务及其特征值。

  • 参数

    • service 对象:

      • uuid: 服务 UUID

      • characteristics: 特征值列表,每项包含:

        • uuid
        • properties: 如 "read", "writeWithoutResponse"
        • permissions: 如 "readable", "writeEncryptionRequired"
        • value?: 初始值(Data 类型)
  • 示例

1await BluetoothPeripheralManager.addService({
2  uuid: "180F",
3  characteristics: [
4    {
5      uuid: "2A19",
6      properties: ["read", "notify"],
7      permissions: ["readable"],
8      value: Data.fromIntArray([85]) // 初始电量 85%
9    }
10  ]
11})

removeService(serviceUUID: string): Promise<void>

移除指定 UUID 的服务(仅移除由当前脚本添加的实例)。


removeAllServices(): Promise<void>

移除所有由脚本添加的服务。


中央设备交互事件

onRestoreState: ((state) => void) | null

当系统因后台 BLE 任务恢复脚本时调用,用于恢复已添加的服务和广播状态。

类型定义:

1var onRestoreState: ((state: {
2  services: BluetoothServiceInfo[]
3  advertisementData: BluetoothAdvertisementData
4}) => void) | null

示例:

1BluetoothPeripheralManager.onRestoreState = (state) => {
2  console.log("恢复状态,已注册服务数:", state.services.length)
3}

onReadyToUpdateSubscribers: (() => void) | null

如果调用 updateValue() 发送通知时因底层队列已满而失败,系统会在队列恢复后调用此回调,你可在此时重试发送。

类型定义:

1var onReadyToUpdateSubscribers: (() => void) | null

示例:

1BluetoothPeripheralManager.onReadyToUpdateSubscribers = () => {
2  console.log("队列已空,准备重新发送通知")
3}

onReadCharacteristicValue: (characteristicId, offset, central) => Promise<{result, value}>

当远程中央设备请求读取某个特征值时调用此回调。如果你未实现该回调,则该读取请求将以 readNotPermitted 响应失败。

类型定义:

1var onReadCharacteristicValue: (
2  characteristicId: string,
3  offset: number,
4  central: {
5    id: string
6    maximumUpdateValueLength: number
7  }
8) => Promise<{
9  result: BluetoothATTResponseCode
10  value?: Data | null
11}> | null

参数说明:

  • characteristicId:请求读取的特征值 UUID 字符串。

  • offset:从哪个偏移位置开始读取(通常为 0)。

  • central:发起请求的中央设备信息:

    • id:中央设备的标识符。
    • maximumUpdateValueLength:该中央设备可接受的最大数据长度。

返回:

一个 Promise,解析为对象:

  • result:读取结果的响应码(参见 BluetoothATTResponseCode 枚举)。
  • value:如果读取成功,返回一个 Data 对象;否则为 null

示例:

1BluetoothPeripheralManager.onReadCharacteristicValue = async (id, offset, central) => {
2  if (id === "2A19") {
3    const batteryLevel = 85
4    return {
5      result: BluetoothATTResponseCode.success,
6      value: Data.fromIntArray([batteryLevel])
7    }
8  }
9  return { result: BluetoothATTResponseCode.attributeNotFound }
10}

onWriteCharacteristicValue: (characteristicId, offset, value, central) => Promise<BluetoothATTResponseCode>

当远程中央设备请求写入某个特征值时调用此回调。如果你未实现该回调,则写入请求将以 writeNotPermitted 响应失败。

类型定义:

1var onWriteCharacteristicValue: (
2  characteristicId: string,
3  offset: number,
4  value: Data,
5  central: {
6    id: string
7    maximumUpdateValueLength: number
8  }
9) => Promise<BluetoothATTResponseCode> | null

参数说明:

  • characteristicId:请求写入的特征值 UUID。
  • offset:写入偏移(一般为 0)。
  • value:远程写入的数据(Data 类型)。
  • central:发起写入请求的中央设备。

返回:

一个 Promise,解析为响应码,表示写入是否成功。

示例:

1BluetoothPeripheralManager.onWriteCharacteristicValue = async (id, offset, value, central) => {
2  console.log(`收到写入请求:${id}`, value.toIntArray())
3  if (id === "2A19") {
4    // 可存储或响应更新
5    return BluetoothATTResponseCode.success
6  }
7  return BluetoothATTResponseCode.attributeNotFound
8}

onSubscribe: (characteristicId, central) => void

当远程中央设备订阅某个支持 notify 或 indicate 的特征值时调用。

类型定义:

1var onSubscribe: (
2  characteristicId: string,
3  central: {
4    id: string
5    maximumUpdateValueLength: number
6  }
7) => void | null

示例:

1BluetoothPeripheralManager.onSubscribe = (id, central) => {
2  console.log(`设备 ${central.id} 订阅了 ${id}`)
3}

onUnsubscribe: (characteristicId, central) => void

当远程中央设备取消订阅某个特征值时调用。

类型定义:

1var onUnsubscribe: (
2  characteristicId: string,
3  central: {
4    id: string
5    maximumUpdateValueLength: number
6  }
7) => void | null

示例:

1BluetoothPeripheralManager.onUnsubscribe = (id, central) => {
2  console.log(`设备 ${central.id} 取消订阅了 ${id}`)
3}

通知与订阅管理

getSubscribers(characteristicId: string): Promise<Central[]>

获取当前订阅某个特征值的所有中央设备。

  • 返回项结构:

    • id: string
    • maximumUpdateValueLength: number

updateValue(characteristicId, value, options?): Promise<boolean>

更新特征值并向订阅者发送通知或指示。

  • options.centrals:指定要发送的中央设备 ID(否则广播给所有已订阅设备)

  • 返回值:

    • true: 发送成功
    • false: 传输队列满,需等待 onReadyToUpdateSubscribers

连接参数设置

setDesiredConnectionLatency(centralId, latency): Promise<void>

设置与指定中央设备的期望连接延迟等级:

  • latency 取值:

    • "low":高频率交互(更快但更耗电)
    • "medium":平衡模式
    • "high":低频率交互(省电)

响应码枚举:BluetoothATTResponseCode

用于表示对读取/写入操作的响应结果:

名称 数值 含义
success 0 操作成功
invalidHandle 1 无效的句柄
readNotPermitted 2 不允许读取
writeNotPermitted 3 不允许写入
invalidPdu 4 无效的 PDU
insufficientAuthentication 5 未通过身份验证
requestNotSupported 6 不支持该请求
invalidOffset 7 偏移量无效
insufficientAuthorization 8 授权不足
prepareQueueFull 9 Prepare 队列已满
attributeNotFound 10 未找到指定属性
attributeNotLong 11 属性不支持长读写
insufficientEncryptionKeySize 12 加密密钥长度不足
invalidAttributeValueLength 13 属性值长度无效
unlikelyError 14 发生了不太可能的错误
insufficientEncryption 15 未加密或加密级别不足
unsupportedGroupType 16 不支持的组类型
insufficientResources 17 系统资源不足

示例:构建一个广播电量的外围设备

1await BluetoothPeripheralManager.addService({
2  uuid: "180F",
3  characteristics: [
4    {
5      uuid: "2A19",
6      properties: ["read", "notify"],
7      permissions: ["readable"],
8      value: Data.fromIntArray([100]) // 电量 100%
9    }
10  ]
11})
12
13await BluetoothPeripheralManager.startAdvertising({
14  localName: "BatteryPeripheral",
15  serviceUUIDs: ["180F"]
16})
17
18BluetoothPeripheralManager.onReadCharacteristicValue = async (id, offset, central) => {
19  return { result: BluetoothATTResponseCode.success, value: Data.fromIntArray([90]) }
20}