更新记录

1.0.1(2026-07-16)

  • 更新文档

1.0.0(2026-07-16)

  • 支持扫描过滤、设备去重、连接超时、自动重连和多设备连接
  • 支持服务与特征发现、自动识别读写/通知通道
  • 支持 read、write、notify、indicate、RSSI、MTU 与分包发送
  • 支持 Hex、UTF-8、数字数组和 ArrayBuffer 写入
  • 支持系统蓝牙状态、连接状态、数据变化等完整事件监听

平台兼容性

uni-app(3.8.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - - - 5.0 12 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(3.8.0)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - - - -

s-ble 原生低功耗蓝牙插件

s-ble 是面向 App Android 和 App iOS 的 UTS 原生 BLE Central 插件。插件提供设备扫描、扫描过滤、多设备连接、自动重连、GATT 服务发现、特征值读写、Notify/Indicate 订阅、RSSI、MTU 和分包发送等能力。

本插件是 UTS 原生插件,真机运行前必须制作并使用自定义调试基座。

功能特性

  • 支持按服务 UUID、名称、RSSI、可连接状态过滤扫描结果。
  • 支持扫描结果去重或按指定间隔重复上报。
  • 支持同时连接多个 BLE 设备,所有连接操作均通过 deviceId 隔离。
  • 支持连接超时、断线自动重连、重连次数和间隔设置。
  • 支持发现服务、特征值、Descriptor 和特征属性。
  • 自动返回首个可读、可写、可通知特征值 UUID。
  • 支持主动读取、With Response / Without Response 写入。
  • 写入值支持十六进制字符串、UTF-8/GBK 字符串、数字数组、ArrayBuffer,并可追加十六进制结束符。
  • 支持按 MTU 自动分包、自定义包长和包间隔。
  • 支持 Notify、Indicate 的开启和关闭。
  • 支持读取 RSSI,支持 Android MTU 协商和 iOS 当前 MTU 查询。
  • 支持监听系统蓝牙状态、设备发现、连接状态、特征值变化、服务发现和 MTU 变化。

安装与配置

  1. 从插件市场将插件导入项目,确认存在 uni_modules/s-ble
  2. 在 HBuilderX 中制作包含本插件的自定义调试基座。
  3. 配置蓝牙权限说明后,使用自定义基座在真机运行。

Android 权限

插件已在原生清单中声明:

  • Android 12 及以上:BLUETOOTH_SCANBLUETOOTH_CONNECT
  • Android 11 及以下:BLUETOOTHBLUETOOTH_ADMINACCESS_FINE_LOCATION

调用扫描前应先调用 requestBluetoothPermissions()。Android 6 到 Android 11 上,即使应用已获得定位权限,部分系统仍要求打开系统定位开关才能返回 BLE 扫描结果。

插件对 Android 12+ 的 BLUETOOTH_SCAN 声明了 neverForLocation。应用不会用 BLE 扫描推断位置,但 Android 可能因此过滤部分只用于定位的 Beacon 广播。如业务必须接收此类广播,应根据合规要求调整插件清单并补充位置权限和隐私说明。

iOS 权限

业务项目的 manifest.json 需要包含:

{
  "app-plus": {
    "distribute": {
      "ios": {
        "privacyDescription": {
          "NSBluetoothAlwaysUsageDescription": "用于扫描、连接并调试附近的低功耗蓝牙设备",
          "NSBluetoothPeripheralUsageDescription": "用于连接并调试低功耗蓝牙设备"
        }
      }
    }
  }
}

iOS 会在首次创建蓝牙管理器时显示系统授权弹窗。权限被拒绝后,应用不能再次主动弹出授权框,需要提示用户前往系统设置修改。

基础流程

import {
  initializeBluetooth,
  requestBluetoothPermissions,
  startBluetoothDevicesDiscovery,
  onBluetoothDeviceFound,
  connectDevice,
  discoverServices,
} from '@/uni_modules/s-ble'

onBluetoothDeviceFound(device => {
  console.log('发现设备', device.name, device.deviceId, device.RSSI)
})

initializeBluetooth({
  success() {
    requestBluetoothPermissions({
      success() {
        startBluetoothDevicesDiscovery({
          allowDuplicatesKey: false,
          success(res) {
            console.log(res.errMsg)
          },
        })
      },
    })
  },
})

推荐调用顺序:

  1. 注册需要的事件监听器。
  2. 调用 initializeBluetooth() 初始化蓝牙管理器。
  3. 调用 requestBluetoothPermissions() 请求运行时权限。
  4. 调用 startBluetoothDevicesDiscovery() 扫描。
  5. 发现目标设备后停止扫描并调用 connectDevice()
  6. 连接成功后调用 discoverServices()
  7. 选择特征值后读取、写入或订阅通知。

通用回调

除事件监听和二进制工具函数外,插件方法使用与 uni API 一致的回调结构:

参数 类型 必填 说明
success Function 操作成功回调
fail Function 操作失败回调,参数为 BLEFail
complete Function 操作完成回调,成功或失败都会执行

成功结果都包含 errMsg;失败结果包含 errSubjecterrCodeerrMsg,设备相关错误还可能包含 deviceId

初始化与权限

initializeBluetooth(options)

初始化原生蓝牙管理器并开始监听系统蓝牙状态。同一进程中可重复调用。

options 参数

参数 类型 默认值 说明
showPowerAlert Boolean true Android 蓝牙关闭时打开系统开启界面;iOS 传给 CoreBluetooth 的系统提示选项
success Function - 初始化成功回调
fail Function - 初始化失败回调
complete Function - 完成回调

success 返回值

字段 类型 说明
available Boolean 当前蓝牙是否可用
discovering Boolean 当前是否正在扫描
state String poweredOnpoweredOffunauthorizedunsupportedresettingunknown
errMsg String initializeBluetooth:ok

requestBluetoothPermissions(options)

请求当前平台需要的运行时蓝牙权限。应在初始化后、扫描前调用。

success 返回值

字段 类型 说明
granted Boolean 权限是否已授予
permissions Array<String> 当前平台检查的权限列表
errMsg String requestBluetoothPermissions:ok

closeBluetooth(options)

释放蓝牙管理器,停止扫描,断开并清理全部连接。调用后如需继续使用,必须重新调用 initializeBluetooth()

关闭蓝牙管理器会影响插件维护的所有设备连接,不应在单个设备页面卸载时调用;单设备断开应使用 disconnectDevice()

扫描设备

startBluetoothDevicesDiscovery(options)

开始扫描附近 BLE 设备。

options 参数

参数 类型 默认值 说明
services Array<String> [] 只扫描广播中包含指定服务 UUID 的设备;支持 16 位、32 位和 128 位 UUID
allowDuplicatesKey Boolean false 是否重复上报同一设备
interval Number 0 重复上报同一设备的最小间隔,单位 ms;仅在 allowDuplicatesKey: true 时生效
minRSSI Number -127 原生扫描结果的最低 RSSI,默认不过滤
namePrefix String '' 名称前缀过滤,不区分大小写
nameContains String '' 名称包含过滤,不区分大小写
connectableOnly Boolean false 是否只返回可连接设备
success / fail / complete Function - 通用回调

services 由系统扫描器执行过滤,其余条件由插件收到广播后执行。namePrefixnameContains 同时设置时,设备名称必须同时满足两个条件。

startBluetoothDevicesDiscovery({
  services: ['FFF0', '180F'],
  allowDuplicatesKey: true,
  interval: 800,
  minRSSI: -90,
  nameContains: 'sensor',
  connectableOnly: true,
})

stopBluetoothDevicesDiscovery(options)

停止当前扫描。成功结果的 discoveringfalse

getDiscoveredDevices(options)

获取本次扫描周期内插件缓存的设备列表。

devices 设备对象

字段 类型 说明
deviceId String 设备标识;Android 通常是 MAC,iOS 是当前应用可见的 UUID
name String 系统设备名称,可能为空
localName String 广播 Local Name,可能为空
RSSI Number 信号强度,单位 dBm
connectable Boolean 广播是否标记为可连接
serviceUUIDs Array<String> 广播中的服务 UUID
manufacturerData String 十六进制厂商数据
serviceData Object 服务 UUID 到十六进制数据的映射
advertisementData String 平台可提供的广播摘要十六进制数据
lastSeen Number 最近发现时间戳,单位 ms

扫描结果通过 onBluetoothDeviceFound() 实时返回;getDiscoveredDevices() 适合页面恢复或一次性读取缓存。

连接管理

connectDevice(options)

连接指定 BLE 设备。扫描得到的 deviceId 可以直接用于连接。

options 参数

参数 类型 默认值 说明
deviceId String - 必填,设备标识
timeout Number 10000 单次连接超时,单位 ms,最小 1000
autoReconnect Boolean false 意外断开后是否自动重连
reconnectAttempts Number 3 最大自动重连次数,0 表示不重试
reconnectDelay Number 1500 两次重连之间的间隔,单位 ms
success / fail / complete Function - 通用回调
connectDevice({
  deviceId,
  timeout: 12000,
  autoReconnect: true,
  reconnectAttempts: 5,
  reconnectDelay: 2000,
  success(connection) {
    console.log('连接成功', connection.deviceId)
  },
})

自动重连只在 App 进程存活且插件未调用 disconnectDevice() / closeBluetooth() 时有效。操作系统可能在后台限制扫描、连接或定时任务,插件不承诺进程被终止后的持久重连。

disconnectDevice(options)

主动断开单个设备,并关闭该设备的自动重连。

参数 类型 必填 说明
deviceId String 需要断开的设备标识

getConnectedDevices(options)

返回插件当前维护的所有已连接设备。

connection 对象

字段 类型 说明
deviceId String 设备标识
name String 设备名称
connected Boolean 是否已连接
connecting Boolean 是否正在连接或重连
mtu Number 当前 ATT MTU
autoReconnect Boolean 是否开启自动重连

多设备连接

连接 API、服务 API、读写 API 都显式携带 deviceId,可以同时维护多个设备:

targets.forEach(deviceId => {
  connectDevice({
    deviceId,
    autoReconnect: true,
    success() {
      discoverServices({ deviceId })
    },
  })
})

实际可同时连接的设备数由手机芯片、系统版本和外设连接参数决定。插件不人为限制连接数量。

服务与特征值

discoverServices(options)

发现设备的 GATT 服务、特征值和 Descriptor。

参数 类型 默认值 说明
deviceId String - 必填,已连接设备标识
force Boolean false 是否重新执行发现;false 时优先返回当前连接缓存

success 返回值

字段 类型 说明
deviceId String 设备标识
services Array<BLEService> 服务列表
readCharacteristicUUID String 首个支持 Read 的特征 UUID,没有则为空
writeCharacteristicUUID String 首个支持 Write 或 Write Without Response 的特征 UUID
notifyCharacteristicUUID String 首个支持 Notify 或 Indicate 的特征 UUID

自动识别字段只用于给出默认通道。一个设备可能有多个可读写特征,业务应根据设备协议同时保存对应的 serviceUUIDcharacteristicUUID,不要只保存特征 UUID。

BLEService

字段 类型 说明
uuid String 服务 UUID,统一为大写完整 UUID
isPrimary Boolean 是否主服务
characteristics Array<BLECharacteristic> 特征值列表

BLECharacteristic

字段 类型 说明
uuid String 特征 UUID
serviceUUID String 所属服务 UUID
properties BLECharacteristicProperties 特征属性
descriptors Array<{ uuid: string }> Descriptor 列表

properties 包含 readwritewriteNoResponsenotifyindicatebroadcastauthenticatedSignedWritesextendedProperties

读取特征值

readCharacteristicValue(options)

主动读取特征值。特征必须支持 Read。

参数 类型 必填 说明
deviceId String 设备标识
serviceUUID String 服务 UUID
characteristicUUID String 特征 UUID

成功后既执行 success,也会触发 onBLECharacteristicValueChange(),事件的 typeread

success / 数据事件返回值

字段 类型 说明
deviceId String 设备标识
serviceUUID String 服务 UUID
characteristicUUID String 特征 UUID
value ArrayBuffer 原始二进制数据
valueHex String 大写、无空格十六进制字符串
valueText String 按 UTF-8 解码的文本;不可解码时可能为空或包含替换字符
timestamp Number 接收时间戳,单位 ms
type String readnotify

写入特征值

writeCharacteristicValue(options)

向指定特征写入数据。

参数 类型 默认值 说明
deviceId String - 必填,设备标识
serviceUUID String - 必填,服务 UUID
characteristicUUID String - 必填,特征 UUID
value String / Number[] / ArrayBuffer - 必填,写入数据
format 'hex' / 'utf8' / 'gbk' 'hex' value 为字符串时的编码
appendHex String '' 编码完成后追加的十六进制字节,如 0A0D0A
writeType 'withResponse' / 'withoutResponse' 'withResponse' 写入类型,必须与特征属性匹配
split Boolean true 是否按单包上限分包
chunkSize Number 0 自定义单包字节数;0 表示自动,超过平台上限时自动收缩
interval Number 0 两包之间的附加间隔,单位 ms

十六进制字符串

writeCharacteristicValue({
  deviceId,
  serviceUUID,
  characteristicUUID,
  value: '01 02 FF 0A',
  format: 'hex',
})

十六进制输入允许空格、冒号和 0x 等分隔字符,清理后必须包含偶数个十六进制数字。

UTF-8 字符串

writeCharacteristicValue({
  deviceId,
  serviceUUID,
  characteristicUUID,
  value: '温度?',
  format: 'utf8',
})

GBK 字符串与结束符

writeCharacteristicValue({
  deviceId,
  serviceUUID,
  characteristicUUID,
  value: '读取温度',
  format: 'gbk',
  appendHex: '0D0A',
})

Android 使用系统 GBK 字符集,iOS 使用兼容 GBK 的 GB18030 字符集。appendHex 在字符串完成编码后追加,也适用于 Hex、数字数组和 ArrayBuffer;追加内容必须是偶数位有效十六进制数据。

数字数组

writeCharacteristicValue({
  deviceId,
  serviceUUID,
  characteristicUUID,
  value: [0x01, 0x02, 0xff, 0x0a],
})

数组元素必须在 0255 之间。原生层会将越界元素拒绝或限制到有效字节范围,业务应在调用前完成校验。

ArrayBuffer

const value = new Uint8Array([1, 2, 255, 10]).buffer
writeCharacteristicValue({ deviceId, serviceUUID, characteristicUUID, value })

success 返回值

字段 类型 说明
deviceId String 设备标识
serviceUUID String 服务 UUID
characteristicUUID String 特征 UUID
bytesWritten Number 本次总写入字节数
chunks Number 实际发送包数

同一设备同一时间只执行一个写队列;队列未结束时再次写入会返回 1500019。不同设备拥有独立队列,可以并行写入。

With Response 会在每个原生写回调成功后发送下一包。Without Response 会遵守 iOS 流控状态;Android 也会等待本地 onCharacteristicWrite 回调后再发送下一包。interval 在相邻分包之间生效。高速发送是否丢包仍取决于外设缓存和连接参数,必要时设置包间隔或使用 With Response。

Notify 与 Indicate

setCharacteristicNotification(options)

开启或关闭特征值通知。

参数 类型 默认值 说明
deviceId String - 必填,设备标识
serviceUUID String - 必填,服务 UUID
characteristicUUID String - 必填,特征 UUID
state Boolean true true 开启,false 关闭
mode 'notify' / 'indicate' 'notify' 订阅模式,必须与特征属性匹配
setCharacteristicNotification({
  deviceId,
  serviceUUID,
  characteristicUUID,
  state: true,
  mode: 'indicate',
  success() {
    console.log('订阅成功')
  },
})

收到的数据通过 onBLECharacteristicValueChange() 返回。Android 会写入 CCCD 0x2902;iOS 由 CoreBluetooth 完成等价配置。

RSSI 与 MTU

readRSSI(options)

读取已连接设备的当前 RSSI。

参数 类型 必填 说明
deviceId String 设备标识

成功返回 { deviceId, RSSI, errMsg }。RSSI 是瞬时值,不建议高频轮询;调试页面默认每 3 秒读取一次。

setMTU(options)

参数 类型 必填 说明
deviceId String 设备标识
mtu Number 期望 ATT MTU,插件限制在 23 到 517

Android 使用 BluetoothGatt.requestMtu() 与外设协商。iOS 不开放主动设置 MTU 的 API,调用会成功返回系统当前单包上限对应的 MTU,并设置 supported: false

getMTU(options)

读取插件当前使用的 MTU。

MTU 返回值

字段 类型 说明
deviceId String 设备标识
mtu Number 当前 ATT MTU
payloadSize Number 常规 ATT 写入可用负载,通常为 mtu - 3
supported Boolean 是否支持应用主动协商;Android 为 true,iOS 为 false

分包写入在 Android 上使用 mtu - 3,在 iOS 上使用 maximumWriteValueLength(for:) 的实时结果,因此无需先调用 setMTU() 才能安全分包。示例详情页会在 GATT 服务发现完成后自动尝试将 Android MTU 协商为 247,最终值仍由手机和外设共同决定。

事件监听

事件监听函数支持同一事件注册多个回调。传入原回调可以移除指定监听;不传参数会移除该事件的全部 JS 监听。

onBluetoothAdapterStateChange(callback)

监听系统蓝牙开关和扫描状态。回调参数见 BLEAdapterState

const listener = state => console.log(state.available, state.discovering, state.state)
onBluetoothAdapterStateChange(listener)
offBluetoothAdapterStateChange(listener)

onBluetoothDeviceFound(callback)

监听扫描设备,回调参数为 BLEDevice

onBLEConnectionStateChange(callback)

监听连接、断开和自动重连状态。

字段 类型 说明
deviceId String 设备标识
connected Boolean 是否已连接
connecting Boolean 是否正在连接
reason String connectingconnectedconnectionLostreconnectingdisconnectedtimeout
status Number 原生状态码或插件错误码
autoReconnect Boolean 是否启用自动重连
reconnectAttempt Number 当前重连次数

onBLECharacteristicValueChange(callback)

监听主动读取结果和 Notify / Indicate 数据。回调参数见“读取特征值”的数据事件返回值。

onBLEMTUChange(callback)

监听 MTU 更新,回调参数见 MTU 返回值。

onBLEServicesDiscovered(callback)

监听服务发现完成,回调参数与 discoverServices() 成功结果相同,但不包含 errMsg

对应 off 方法

  • offBluetoothAdapterStateChange(callback?)
  • offBluetoothDeviceFound(callback?)
  • offBLEConnectionStateChange(callback?)
  • offBLECharacteristicValueChange(callback?)
  • offBLEMTUChange(callback?)
  • offBLEServicesDiscovered(callback?)

页面卸载时应移除页面注册的事件,避免重复回调:

onUnload(() => {
  offBluetoothDeviceFound(handleDevice)
  offBLEConnectionStateChange(handleConnection)
  offBLECharacteristicValueChange(handleValue)
})

二进制工具

hexToBuffer(hex)

将十六进制字符串转换为 ArrayBuffer

bufferToHex(buffer)

ArrayBuffer 转换为大写、无空格的十六进制字符串。

import { hexToBuffer, bufferToHex } from '@/uni_modules/s-ble'

const buffer = hexToBuffer('01 02 FF')
console.log(bufferToHex(buffer)) // 0102FF

完整导入

import {
  initializeBluetooth,
  requestBluetoothPermissions,
  closeBluetooth,
  startBluetoothDevicesDiscovery,
  stopBluetoothDevicesDiscovery,
  getDiscoveredDevices,
  connectDevice,
  disconnectDevice,
  getConnectedDevices,
  discoverServices,
  readCharacteristicValue,
  writeCharacteristicValue,
  setCharacteristicNotification,
  readRSSI,
  setMTU,
  getMTU,
  onBluetoothAdapterStateChange,
  offBluetoothAdapterStateChange,
  onBluetoothDeviceFound,
  offBluetoothDeviceFound,
  onBLEConnectionStateChange,
  offBLEConnectionStateChange,
  onBLECharacteristicValueChange,
  offBLECharacteristicValueChange,
  onBLEMTUChange,
  offBLEMTUChange,
  onBLEServicesDiscovered,
  offBLEServicesDiscovered,
  hexToBuffer,
  bufferToHex,
} from '@/uni_modules/s-ble'

错误码

错误码 说明
1500001 当前设备不支持 BLE
1500002 蓝牙不可用或系统蓝牙已关闭
1500003 蓝牙权限被拒绝
1500004 蓝牙管理器未初始化
1500005 扫描启动或执行失败
1500006 找不到指定设备
1500007 连接或服务发现失败
1500008 连接超时
1500009 设备未连接
1500010 找不到指定服务
1500011 找不到指定特征值
1500012 特征值不支持读取
1500013 特征值不支持所选写入方式
1500014 特征值不支持所选订阅方式或缺少 CCCD
1500015 写入数据或参数无效
1500016 读取失败
1500017 写入失败
1500018 Android MTU 请求失败
1500019 当前连接已有同类操作正在执行

平台差异与注意事项

  • Android 的 deviceId 通常是蓝牙 MAC;iOS 返回 CoreBluetooth 为当前应用分配的 UUID。不要假设两个平台能使用同一设备标识,也不要把 iOS UUID 当作永久硬件序列号。
  • iOS 不允许应用主动设置 MTU;setMTU() 只返回系统当前值。Android 的最终 MTU 由手机与外设协商决定,可能小于请求值。
  • iOS 不向应用公开原始广播包,advertisementData 是可用广播字段的 JSON 摘要再转成的十六进制;Android 返回系统提供的原始 ScanRecord 字节。
  • Android 设备名称和扫描在不同系统版本上受权限约束。应在扫描前完成 requestBluetoothPermissions()
  • allowDuplicatesKey: false 时每个扫描周期只触发一次设备发现事件,但缓存中的 RSSI 和 lastSeen 仍会更新。
  • 服务、特征和 UUID 均属于当前连接。设备断开重连后,建议重新执行 discoverServices() 并重新订阅 Notify / Indicate。
  • 同一连接上,插件会拒绝重叠的同类异步操作,例如两个并发读取或两个并发写队列;不同连接互不影响。
  • BLE 数据没有消息边界保证。插件的“分包”只负责按 ATT 单包上限发送,业务协议的帧头、长度、校验和、应答与重组仍由业务层处理。
  • 系统蓝牙关闭、App 进入后台、外设超出范围、连接参数不兼容都可能造成断开。应始终监听 onBLEConnectionStateChange()

示例工程

仓库示例包含三个页面:

  • 设备列表:自动扫描、按发现顺序置顶新设备、已连接标识、搜索、排序和可选 RSSI 过滤。
  • 设备详情:设备信息、RSSI、MTU、服务与特征属性,以及读/写通道选择。支持 Notify / Indicate 的特征归入读通道。
  • BLE 调试:读通道自动订阅 Notify / Indicate,订阅就绪后开放发送;支持主动读取、自动选择写入方式、可调分包间隔、Hex、UTF-8、GBK 和常用数值类型写入、追加字节、周期发送和收发统计。

示例调试页中的 Short 16Int 32Long 64Float 32Double 64 均按小端字节序发送;整数使用有符号范围。Long 64 以十进制字符串转换,不受 JavaScript 安全整数范围限制。

示例页面在 H5 运行时只展示静态预览数据;真实 BLE 功能必须在 Android 或 iOS 自定义调试基座中验证。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android.permission.BLUETOOTH_SCAN, android.permission.BLUETOOTH_CONNECT, android.permission.ACCESS_FINE_LOCATION(Android 11及以下)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集、不上传用户数据;扫描结果与通信数据只回调给业务代码。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: