更新记录

1.0.0(2026-10-21)

首个发布版本。Android / iOS / 鸿蒙 NEXT 三端同构的 BLE 插件。 核心能力

  • 蓝牙适配器管理:openAdapter / closeAdapter / getAdapterState,实时状态事件(adapterState、authorization)
  • BLE 扫描:startScan / stopScan,支持按服务 UUID、设备名、名称包含/前缀、RSSI 下限、指定地址多条件过滤,支持 durationMs 自动停止与重复上报
  • 设备查询:getScannedDevices(扫描缓存)/ getBondedDevices(系统配对)/ getConnectedDevices(系统已连接)/ getKnownDevices(免扫描重连)
  • 连接管理:createConnection(连接超时保护、自动服务发现、自动重连)/ disconnect / closeConnection / isConnected
  • 服务与特征:getServices / discoverServices,读写 / 订阅(notify)/ 描述符读写,统一大写 HEX 字符串数据格式
  • 参数调节:requestMtu、readRssi、requestConnectionPriority(Android)、setPreferredPhy
  • 扩展能力:外设模式(BLE 广播 + GATT Server,Android/iOS)、经典蓝牙 SPP(Android)、打开系统蓝牙设置页
  • 统一事件总线 onBluetoothEvent / offBluetoothEvent,覆盖适配器状态、设备发现、连接状态、服务发现、特征回传、扫描启停等全部事件

    1.0.0(2026-10-21)

首个发布版本。Android / iOS / 鸿蒙 NEXT 三端同构的 BLE 插件。

核心能力

  • 蓝牙适配器管理:openAdapter / closeAdapter / getAdapterState,实时状态事件(adapterState、authorization)
  • BLE 扫描:startScan / stopScan,支持按服务 UUID、设备名、名称包含/前缀、RSSI 下限、指定地址多条件过滤,支持 durationMs 自动停止与重复上报
  • 设备查询:getScannedDevices(扫描缓存)/ getBondedDevices(系统配对)/ getConnectedDevices(系统已连接)/ getKnownDevices(免扫描重连)
  • 连接管理:createConnection(连接超时保护、自动服务发现、自动重连)/ disconnect / closeConnection / isConnected
  • 服务与特征:getServices / discoverServices,读写 / 订阅(notify)/ 描述符读写,统一大写 HEX 字符串数据格式
  • 参数调节:requestMtu、readRssi、requestConnectionPriority(Android)、setPreferredPhy
  • 扩展能力:外设模式(BLE 广播 + GATT Server,Android/iOS)、经典蓝牙 SPP(Android)、打开系统蓝牙设置页
  • 统一事件总线 onBluetoothEvent / offBluetoothEvent,覆盖适配器状态、设备发现、连接状态、服务发现、特征回传、扫描启停等全部事件

平台兼容性

uni-app(5.13)

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

uts-bluetooth

uni-app x 蓝牙插件:BLE 中心设备 + 外设模式 + 经典蓝牙,Android / iOS 接口与事件完全一致。

安装

把整个 uni_modules/uts-bluetooth 目录拷贝到你的 uni-app x 项目的 uni_modules/ 下即可(uni_modules 机制会自动生效)。

uni_modules/uts-bluetooth/
├── package.json
├── README.md
└── utssdk/
    ├── interface.uts          类型定义
    ├── app-android/
    │   ├── index.uts          UTS 薄封装
    │   ├── AndroidManifest.xml 权限(已含 neverForLocation)
    │   └── *.kt               原生实现(BleKitBridge + 核心库)
    └── app-ios/
        ├── index.uts
        ├── Info.plist          权限
        └── *.swift             原生实现(BleKitBridge + 核心库)

原生代码与仓库根目录 android/、ios/ 保持同步,改动请两边一起改(或直接改插件目录里的那份)。

快速上手

import {
  openAdapter, startScan, stopScan, createConnection, closeConnection,
  getServices, readCharacteristic, writeCharacteristic,
  notifyCharacteristicChanged, requestMtu, onBluetoothEvent
} from '@/uni_modules/uts-bluetooth'

// 1. 注册全局事件(建议只注册一次)
onBluetoothEvent((name, data) => {
  console.log(name, data)
})

// 2. 打开蓝牙
openAdapter({})

// 3. 扫描(15 秒自动停)
startScan({ durationMs: 15000, services: ['FFE0'], rssiMin: -90 })

// 4. 在 deviceFound 事件里拿到 deviceId 后连接
createConnection({ deviceId, mtu: 512, connectionPriority: 1, autoReconnect: true })

// 5. servicesDiscovered 事件后读写
notifyCharacteristicChanged({ deviceId, serviceUuid: 'FFE0', characteristicUuid: 'FFE1', enable: true })
writeCharacteristic({ deviceId, serviceUuid: 'FFE0', characteristicUuid: 'FFE2', value: 'AABB01', writeType: 2 })
readCharacteristic({ deviceId, serviceUuid: 'FFE0', characteristicUuid: 'FFE3' })

// 6. 用完必须关闭,Android 连接数有上限(约 7 个)
closeConnection({ deviceId })

API

方法 关键参数 说明
openAdapter / closeAdapter - iOS 只能返回当前状态,不能直接开关
getAdapterState - success.res.state:on/off/... ,iOS 额外返回 authorization
startScan services[] / deviceName / namePrefix / nameContains / rssiMin / allowDuplicates / durationMs / scanMode / phy Android 走硬件过滤,iOS 走软件过滤
stopScan -
getScannedDevices / getBondedDevices - 返回 res.devices[];getBondedDevices 仅 Android
getConnectedDevices services[](仅 iOS 生效) 查系统层面已连接的 BLE 设备,返回 res.devices[];iOS 必须传 services,Android 返回本机已连接的 GATT 设备
getKnownDevices deviceIds[] 按 deviceId 查已知设备(Android=MAC / iOS=peripheral UUID),免扫描直接 createConnection
createConnection deviceId / mtu / timeoutMs / autoReconnect / connectionPriority / phy / transport / autoConnect / refreshCache
closeConnection / disconnect / isConnected deviceId
getServices deviceId 返回 res.services[](缓存,不触发发现)
discoverServices deviceId / uuids[]
readCharacteristic / writeCharacteristic deviceId / serviceUuid / characteristicUuid / value writeType:2 带响应、1 无响应、4 签名写
readDescriptor / writeDescriptor + descriptorUuid
notifyCharacteristicChanged enable
requestMtu / readRssi iOS 的 requestMtu 只返回当前值
setPreferredPhy txPhy / rxPhy(1=LE 1M / 2=LE 2M / 3=LE Coded) 仅 Android 生效,iOS 返回 fail
openBluetoothSettings - 打开系统蓝牙设置页,仅 Android
requestConnectionPriority / setPreferredPhy / refreshGattCache 仅 Android,iOS 返回 fail
createBond / removeBond 仅 Android
外设 startAdvertising / stopAdvertising / addService / removeService / removeAllServices / notifySubscribers / respondToRequest 手机被别的设备连接
经典蓝牙 startClassicDiscovery / connectSpp / sppWrite / closeSpp 仅 Android(iOS 只有 MFi)
onBluetoothEvent / offBluetoothEvent / destroy

事件(onBluetoothEvent)

事件名 主要字段
adapterState state
scanStart / scanStop / scanFailed reason / code+message
deviceFound device: { deviceId, address, name, rssi, deviceType, bondState, advertisement }
connectionStateChanged deviceId, state(connecting/connected/disconnected), status, statusName
servicesDiscovered deviceId, services[](含 characteristics、descriptors)
characteristicRead / characteristicWrite / characteristicChanged deviceId, serviceUuid, characteristicUuid, value, status
descriptorRead / descriptorWrite + descriptorUuid
notificationStateChanged enabled, status
mtuChanged / rssi / phyUpdate mtu / rssi / txPhy,rxPhy
bondStateChanged bondState(仅 Android)
外设:advertiseStart / centralConnectionChanged / serviceAdded / readRequest / writeRequest / notificationSent
经典:classicDiscoveryStart / sppData / sppError
error code, message, deviceId?

两端差异(写代码时要注意)

  1. deviceId:Android = MAC;iOS = peripheral 的 UUID 字符串(没有 MAC,重装 App 会变)
  2. MTU:Android 可请求;iOS 系统自动协商,只能读(maximumWriteValueLength + 3)
  3. iOS 没有:连接优先级、PHY、刷新 GATT 缓存、主动配对、经典蓝牙 SPP
  4. 数据格式:所有字节用大写 HEX 字符串("AABB01")传输
  5. 权限:插件已声明;Android 12+ 运行时权限仍需宿主 App 触发系统授权弹窗(首次调用时系统自动弹,若被拒需引导去设置)
  6. iOS openAdapter 不是"打开蓝牙开关":只是创建 CBCentralManager 并触发系统授权。刚创建时 state=unknown 属正常(delegate 是异步回调),本次实现已把 .unknown 视为成功,真正的结果看 adapterState 事件(state + authorization 合并上报)或 getAdapterState。失败时 errMsg 形如 openAdapter:fail state=unauthorized authorization=denied。
  7. iOS 设备名:纯广播设备 CBPeripheral.name 常为 nil,插件已回退到广播包 CBAdvertisementDataLocalNameKey;两者都没有时会返回空 name,此时用 deviceId / 广播 serviceUuids 区分设备。
  8. iOS 启动卡在 state=unknown:说明最终 IPA 里没有 NSBluetoothAlwaysUsageDescription, 系统不会弹授权框。uni-app 工程请在 manifest.json → app-plus → distribute → ios → privacyDescription 里声明(插件自带的 app-ios/Info.plist 只在 uni-app x 工程保证合并),改完需重新打自定义基座/云打包。
  9. iOS 扫描:蓝牙未就绪时 startScan 返回 fail(errMsg 带 state=),同时发 scanFailed 事件, 不会再出现"startScan:ok 但扫不到设备"的假成功。

鸿蒙 NEXT(app-harmony)支持

基于 @kit.ConnectivityKit(access + ble,API 12+)实现,核心 BLE 能力与 Android/iOS 同构:

能力 鸿蒙状态
扫描(软件过滤:services/name/contains/prefix/rssiMin/address) ✅
连接(超时保护)/ 断开 / 自动重连(最多 N 次) ✅
服务发现(连接后自动发现,servicesDiscovered 事件) ✅
读 / 写 / 订阅(notify)/ 描述符读写 ✅
MTU(setBLEMtuSize,自动收敛到 22~517) ✅
经典蓝牙 SPP、外设模式(GATT Server/广播) ❌ 运行 fail(鸿蒙为另一套 API)
readRssi / PHY / 连接优先级 / refreshGattCache ❌ 运行 fail
getBondedDevices 恒空(三方无系统配对列表查询)
getConnectedDevices / getKnownDevices 从本插件扫描/连接缓存里查(无系统级查询)

鸿蒙端要点

  1. deviceId = 蓝牙 MAC 地址(与 Android 一致),服务端 device_id 可直接复用。
  2. 广播 serviceUuids 为完整大写 UUID(如 0000CEB2-0000-1000-8000-00805F9B34FB), 配套页面用 shortUuid() 比对,短码/完整/大小写都能兼容,globalData.iosDeviceId 无需改。
  3. 特征属性缺失:鸿蒙 GattService 不提供 characteristics 的 properties, 事件/getServices 里 properties 为空数组——按属性找 notify/write 特征的逻辑需自行兜底(如取第一个特征)。
  4. 权限(必须):宿主鸿蒙工程 module.json5 需声明 ohos.permission.ACCESS_BLUETOOTH (BLE 扫描建议再加 APPROXIMATE_LOCATION / LOCATION)。openAdapter 会尝试 requestPermissionsFromUser 主动申请;未声明时系统拒绝,扫描报 201。
  5. UUID 传参:系统 API 只接受完整格式,插件内部自动把短码(如 CEB2)扩展为 0000CEB2-0000-1000-8000-00805F9B34FB,页面层传短码或完整串均可。
  6. 工程要求:HBuilderX 4.25+,标准 uni-app 需先生成/使用鸿蒙工程跑自定义基座。

已知注意

  • Android 用完连接必须 closeConnection,否则连接数满后所有连接返回 133
  • Android 12+ 的 BLUETOOTH_SCAN 必须保留 neverForLocation,否则扫描返回 0 个设备
  • 首次云编译若报 UTS 类型相关错误,把报错发我,我按 UTS 语法修正(原生层已编译验证通过)

隐私、权限声明

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

Android:android.permission.BLUETOOTH(maxSdkVersion=30)、android.permission.BLUETOOTH_ADMIN(maxSdkVersion=30)、android.permission.ACCESS_FINE_LOCATION(maxSdkVersion=30,Android 11 及以下 BLE 扫描需要)、android.permission.ACCESS_COARSE_LOCATION(maxSdkVersion=30)、android.permission.BLUETOOTH_SCAN(Android 12+,带 neverForLocation)、android.permission.BLUETOOTH_CONNECT(Android 12+)、android.permission.BLUETOOTH_ADVERTISE(Android 12+,仅外设模式用)。iOS:NSBluetoothAlwaysUsageDescription、NSBluetoothPeripheralUsageDescription。鸿蒙:ohos.permission.ACCESS_BLUETOOTH。

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

本插件不采集任何数据,不内嵌任何第三方 SDK,不发送任何数据到任何服务器。插件仅调用系统蓝牙接口(Android BluetoothAdapter / iOS CoreBluetooth / 鸿蒙 ConnectivityKit)在本地完成 BLE 设备扫描、连接与数据传输,扫描结果仅通过回调返回给宿主 App,插件本身不做存储、上报或联网行为。

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

无

暂无用户评论。