更新记录
1.0.4(2026-05-11)
- 连接接口新增RFCOMM Socket链路类型的服务UUID
1.0.3(2026-05-11)
- 新增纯血鸿蒙端
1.0.1(2026-05-11)
- 优化
平台兼容性
uni-app(4.87)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | Android插件版本 | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | × | × | 5.0 | 1.0.1 | × | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(4.87)
| Chrome | Safari | Android | Android插件版本 | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|
| × | × | 5.0 | 1.0.1 | × | √ | × |
yt-uts-bluetooth
基于 UTS 的 Android、HarmonyOS 经典蓝牙 插件:配对列表、扫描周边设备、连接、收发数据、MTU 设置与释放资源。
特别提醒
- 购买本插件前,请先试用并充分自测确认满足需求之后再行购买;虚拟物品一旦购买之后无法退款。
- 如有使用上的疑问或 bug,可进交流群联系作者;作者可承接插件定制。
- 请在合法范围内使用;若使用本插件从事非法开发,本方概不负责。
- 试用需自定义基座(见
package.json中uni_modules平台说明)。 - 当前实现仅支持 App Android、HarmonyOS(
app-ios不支持)。 - android示例安装包
- 低功耗蓝牙插件可使用这款:低功耗/BLE蓝牙
引入方式
业务侧从 uni_modules 引入 函数 与 类型(类型定义见 utssdk/interface.uts):
import *as BTManager from '@/uni_modules/yt-uts-bluetooth'
权限与初始化
initBluetooth()
- 作用:申请蓝牙相关权限;全部通过后创建内部经典蓝牙管理器。
- 参数:无。
- Android 12(API 31)及以上:申请
BLUETOOTH_SCAN、BLUETOOTH_CONNECT、ACCESS_FINE_LOCATION。 - 更低版本:申请
ACCESS_COARSE_LOCATION。 - HarmonyOS: 申请
ohos.permission.ACCESS_BLUETOOTH
未成功拿到权限时,内部管理器不会创建;后续调用 getBondList 等依赖管理器的接口会失败。
API 一览(与 utssdk/app-android/index.uts 导出一致)
| 函数 | 说明 |
|---|---|
initBluetooth() |
请求权限并初始化内部管理器 |
getBondList(options) |
获取系统已配对(绑定)设备列表 |
discoveryBluetooth(para) |
开始扫描周边设备 |
connectBluetoothWithName(options) |
按 MAC 连接设备并注册读/连接回调 |
disconnectBluetooth(address) |
按 MAC 断开指定设备 |
sendData(options) |
向已连接设备发送字节或字符串 |
setMtu(para) |
设置分片相关 MTU 下限(见类型说明) |
getMtu(para) |
查询当前 MTU |
destroy() |
释放插件内部资源;再次使用需重新 initBluetooth |
类型与回调说明
BluetoothDeviceInfo
扫描与配对列表中的设备信息:
name:名称address:MAC 地址type:设备类型(系统BluetoothDevice.getType())alias:别名(若系统支持)
GetBoundDeviceOptions
success?(devices: BluetoothDeviceInfo[]):成功返回列表fail?(err: ApiFail):失败;未先调用initBluetooth时errCode为 90001,mes为「请先调用initBluetooth」
DiscoveryPara(扫描)
showEmptyName: boolean:是否把 名称为空 的设备也回调上来btNameFilter?: string:按名称过滤(可选)onDeviceFound(res: BluetoothDeviceInfo):必填,每发现一台设备回调一次;同一次扫描内同一设备可能出现多次,业务可自行去重onDiscoveryStarted?: () => void:扫描开始onDiscoveryFinished?: () => void:扫描结束(正常结束或内部取消后也会收到)onError?: (err: string) => void:扫描无法启动或适配器异常
ConnectBluetoothOptions(连接)
address?: string:建议使用 MAC 连接;支持AA:BB:CC:DD:EE:FF、AA-BB-...或连续 12 位十六进制(内部会规范为冒号大写等形式)uuid?: string:RFCOMM socket链路类型的服务UUID。选填默认:”00001101-0000-1000-8000-00805F9B34FB”(大量蓝牙串口模块、车载、打印机使用该 UUID;)readDataHandler?(res: ReadResultInfo):收到字节数据或读通道结束时回调onConnected?(address: string):RFCOMM 连接成功onConnectFailed?(deviceAddress, code, message):连接失败(含配对失败、Socket 连接失败等);code为字符串形式的错误码onDisconnected?(deviceAddress):断开(常见于主动disconnect或读写异常导致关闭;对端主动断开的即时性感知可按需扩展)
ReadResultInfo(读回调)
deviceAddress:设备 MACdata: number[]:原始字节(数组形式)hexValue/utf8Value/gbkValue:插件侧附加转换结果(便于调试或文本协议)state:'0'表示读到一段数据;'1'表示 读循环结束(如套接字关闭、disconnect)message:说明文案
注意:单次回调 不等于 一条完整业务报文;粘包/分包请在协议层拼接解析。
SendDataOptions(发送)
deviceAddress:目标 MAC(需已连接)data?: number[]与value?: string:若同时存在,data优先,按原始字节发送- 仅发字符串时:
encoding?: number:0= UTF-8,1= GBK,2= 十六进制字符串(可含空格;偶数位0-9A-Fa-f,解码为字节后发送)
mtuOverride?: number:可选,覆盖本次写入的分片下限(字节,范围见与你底层YtClassicBtManager约定,类型注释为 1~65535)onWriteSuccess?(deviceAddress)/onWriteFailed?(deviceAddress, code, message):写成功或失败
SetMtuPara / GetMtuPara
deviceAddress:设备 MACSetMtuPara.mtu:分片下限(字节)SetMtuPara.mtuHandle(success: boolean):设置是否成功GetMtuPara.mtuHandle(mtu: number):返回当前 MTU
ApiFail
errCode: numbermes: string
推荐使用顺序
- 调用
initBluetooth(),确认权限已授予(可通过getBondList是否成功侧面验证)。 - 使用
getBondList取已配对设备,或使用discoveryBluetooth搜周边并在onDeviceFound里收集列表。 connectBluetoothWithName传入目标address,在onConnected/readDataHandler中处理连接与数据。sendData发送数据;需要时setMtu/getMtu。disconnectBluetooth(address)断开;不用蓝牙时destroy()。
权限清单
插件声明的权限以 package.json → dcloudext.declaration.permissions 为准(含定位、经典蓝牙与 Android 12+ 的扫描/连接等)。打包前请确认与业务隐私合规一致。
uniapp完整示例
<template>
<view class="content">
<view
style="font-size: 28rpx;color: cadetblue;display: flex;flex-direction: column;background-color: azure;width: 750rpx;display: flex;align-items: center;justify-content: center;">
<text>读取utf-8数据:{{blueToothValue_utf8}}</text>
<text>读取HEX数据:{{blueToothValue_hex}}</text>
<text>读取number[]数据:{{blueToothValue_number}}</text>
</view>
<view class="header">
<view class="btn" @click="boundDevices()">获取已绑定设备</view>
<view class="btn" @click="scanDevices()">扫描蓝牙</view>
<view class="btn" @click="closeBluetooth()">断开蓝牙</view>
<view class="btn" @click="sendDataAction()">发送数据</view>
</view>
<view class="header">
<view class="btn" @click="setMtuAction()">设置MTU</view>
<view class="btn" @click="getMtuAction()">获取MTU</view>
<view class="btn" @click="destroy()">释放资源</view>
</view>
<view style="width: 750rpx;display: flex;flex-direction: column;" v-if="bondDeviceList.length>0">
<view
style="width: 750rpx;height: 60rpx;background-color: bisque;display: flex;align-items: center;justify-content: center;">
<text>已配对设备</text>
</view>
<scroll-view class="bound_list" scroll-y="true">
<view class="cell" style="background-color: azure;" v-for="(item,index) in bondDeviceList"
:key="'bondDevice'+index" @click.stop="connectBluetooth(item.address)">
<text style="color:blueviolet;">名称:{{item.name}}</text>
<text style="color: blue;">地址:{{item.address}}</text>
<view class="line" style="width: 750rpx;height: 1px;background-color: rgba(0, 0, 0, 0.4);"></view>
</view>
</scroll-view>
</view>
<view style="width: 750rpx;display: flex;flex-direction: column;" v-if="discoveryList.length>0">
<view
style="width: 750rpx;height: 60rpx;background-color: bisque;display: flex;align-items: center;justify-content: center;">
<text>扫描到的设备</text>
</view>
<scroll-view class="list" scroll-y="true">
<view class="cell" style="background-color: azure;" v-for="(item,index) in discoveryList"
:key="'bondDevice'+index" @click.stop="connectBluetooth(item.address)">
<text style="color:blueviolet;">名称:{{item.name}}</text>
<text style="color: blue;">地址:{{item.address}}</text>
<view class="line" style="width: 750rpx;height: 1px;background-color: rgba(0, 0, 0, 0.4);"></view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import * as BTManager from '@/uni_modules/yt-uts-bluetooth'
export default {
data() {
return { //as BluetoothDeviceInfo[]
bondDeviceList: [], //已绑定蓝牙列表
blueToothValue_utf8: '', //蓝牙返回的数据
blueToothValue_hex: '',
blueToothValue_number: '',
discoveryList: [], //搜索周边蓝牙设备,
deviceAddress: '' //当前连接蓝牙的地址
}
},
onLoad() {
this.initBluetoothAction()
},
methods: {
initBluetoothAction() {
BTManager.initBluetooth()
},
boundDevices() {
BTManager.getBondList({
success: (res) => {
console.log(res)
this.bondDeviceList = res
},
fail: (error) => {
}
})
},
scanDevices() {
this.discoveryList = [];
BTManager.discoveryBluetooth({
showEmptyName: false,
onDeviceFound: (res) => {
this.discoveryList.push(res)
},
onDiscoveryStarted: () => {
console.log('扫描开始')
},
onDiscoveryFinished: () => {
console.log('扫描完成')
},
onError: (err) => {
console.log(err);
}
})
},
closeBluetooth() {
BTManager.disconnectBluetooth(this.deviceAddress)
},
sendDataAction() {
BTManager.sendData({
value: 'hello world',
deviceAddress: this.deviceAddress,
encoding: 1,
onWriteSuccess: (devideAdress) => {
console.log(`${devideAdress}写入成功`)
},
onWriteFailed: (deviceAddress, code, message) => {
console.log(`${deviceAddress}写入失败---code:${code}----message:${message}`);
}
})
},
connectBluetooth(address) {
BTManager.connectBluetoothWithName({
address: address,
onConnected: (address) => {
console.log(`连接成功:${address}`);
this.deviceAddress = address;
},
onConnectFailed: (address, code, mes) => {
console.log(`${address}连接失败--code:${code}---mes:${mes}`)
},
onDisconnected: (address) => {
console.log(`${address}已断开连接`)
this.deviceAddress = "";
},
readDataHandler: (result) => {
this.blueToothValue_utf8 = result.utf8Value ?? "";
this.blueToothValue_hex = result.hexValue ?? "";
this.blueToothValue_number = result.data.toString() ?? "";
}
})
},
//获取mtu
setMtuAction() {
BTManager.setMtu({
deviceAddress: this.deviceAddress,
mtu: 200,
mtuHandle: (res) => {
console.log('设置mtu:' + res)
}
})
},
getMtuAction() {
BTManager.getMtu({
deviceAddress: this.deviceAddress,
mtuHandle: (res) => {
console.log('获取mtu:' + res)
}
})
},
//释放资源
destroy() {
BTManager.destroy()
}
}
}
</script>
<style>
.content {
width: 750rpx;
display: flex;
height: 100%;
flex-direction: column;
}
.header {
width: 750rpx;
display: flex;
flex-direction: row;
align-items: center;
padding: 0 20rpx;
box-sizing: border-box;
margin-top: 20rpx;
}
.btn {
display: flex;
height: 80rpx;
padding: 0 5rpx;
align-items: center;
justify-content: center;
background-color: cadetblue;
color: white;
margin-right: 20rpx;
font-size: 28rpx;
border-radius: 6rpx;
}
.bound_list {
width: 750rpx;
height: 300rpx;
}
.list {
width: 750rpx;
height: 600rpx;
}
.cell {
display: flex;
flex-direction: column;
justify-content: center;
padding: 10rpx;
box-sizing: border-box;
background-color: antiquewhite;
}
</style>
uniapp-x完整示例
<template>
<view class="content">
<view
style="font-size: 28rpx;color: cadetblue;height: 80rpx;background-color: azure;width: 750rpx;display: flex;align-items: center;justify-content: center;">
<text>读取数据:{{blueToothValue}}</text>
</view>
<view class="header">
<view class="btn" @click="boundDevices()">获取已绑定设备</view>
<view class="btn" @click="scanDevices()">扫描蓝牙</view>
<view class="btn" @click="closeBluetooth()">断开蓝牙</view>
<view class="btn" @click="sendDataAction()">发送数据</view>
</view>
<view class="header">
<view class="btn" @click="setMtuAction()">设置MTU</view>
<view class="btn" @click="getMtuAction()">获取MTU</view>
</view>
<view style="width: 750rpx;display: flex;flex-direction: column;" v-if="bondDeviceList.length>0">
<view
style="width: 750rpx;height: 60rpx;background-color: bisque;display: flex;align-items: center;justify-content: center;">
<text>已配对设备</text>
</view>
<scroll-view class="bound_list" scroll-y="true">
<view class="cell" style="background-color: azure;" v-for="(item,index) in bondDeviceList"
:key="'bondDevice'+index" @click.stop="connectBluetooth(item.name,item.address)">
<text style="color:blueviolet;">名称:{{item.name}}</text>
<text style="color: blue;">地址:{{item.address}}</text>
<view class="line" style="width: 750rpx;height: 1px;background-color: rgba(0, 0, 0, 0.4);"></view>
</view>
</scroll-view>
</view>
<view style="width: 750rpx;display: flex;flex-direction: column;" v-if="discoveryList.length>0">
<view
style="width: 750rpx;height: 60rpx;background-color: bisque;display: flex;align-items: center;justify-content: center;">
<text>扫描到的设备</text>
</view>
<scroll-view class="list" scroll-y="true">
<view class="cell" style="background-color: azure;" v-for="(item,index) in discoveryList"
:key="'bondDevice'+index" @click.stop="connectBluetooth(item.name,item.address)">
<text style="color:blueviolet;">名称:{{item.name}}</text>
<text style="color: blue;">地址:{{item.address}}</text>
<view class="line" style="width: 750rpx;height: 1px;background-color: rgba(0, 0, 0, 0.4);"></view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import *as BTManager from '@/uni_modules/yt-uts-bluetooth'
export default {
data() {
return {//as BluetoothDeviceInfo[]
bondDeviceList: [] as BTManager.BluetoothDeviceInfo[], //已绑定蓝牙列表
blueToothValue: '', //蓝牙返回的数据
discoveryList: [] as BTManager.BluetoothDeviceInfo[],//搜索周边蓝牙设备
deviceAddress: '' //当前连接蓝牙的地址
}
},
onLoad() {
this.initBluetoothAction()
},
methods: {
initBluetoothAction() {
BTManager.initBluetooth()
},
boundDevices() {
BTManager.getBondList({
success: (res : BTManager.BluetoothDeviceInfo[]) => {
console.log(res)
this.bondDeviceList = res
},
fail: (error : BTManager.ApiFail) => {
}
} as BTManager.GetBoundDeviceOptions)
},
scanDevices() {
this.discoveryList = [];
BTManager.discoveryBluetooth({
showEmptyName: false,
onDeviceFound: (res) => {
this.discoveryList.push(res)
},
onDiscoveryStarted: () => {
console.log('扫描开始')
},
onDiscoveryFinished: () => {
console.log('扫描完成')
},
onError: (err) => {
console.log(err);
}
} as BTManager.DiscoveryPara)
},
closeBluetooth() {
BTManager.disconnectBluetooth(this.deviceAddress)
},
sendDataAction() {
BTManager.sendData({
value: 'hello world',
deviceAddress: this.deviceAddress,
encoding: 1,
onWriteSuccess: (devideAdress : string) => {
console.log(`${devideAdress}写入成功`)
},
onWriteFailed: (deviceAddress : string, code : number, message : string) => {
console.log(`${deviceAddress}写入失败---code:${code}----message:${message}`);
}
} as BTManager.SendDataOptions)
},
connectBluetooth(deviceName : string, address : string) {
BTManager.connectBluetoothWithName({
address: address,
onConnected: (address : string) => {
console.log(`连接成功:${address}`);
this.deviceAddress = address;
},
onConnectFailed: (address : string, code : string, mes : string) => {
console.log(`${address}连接失败--code:${code}---mes:${mes}`)
},
onDisconnected: (address) => {
console.log(`${address}已断开连接`)
},
readDataHandler: (result : BTManager.ReadResultInfo) => {
// console.log(result.utf8Value ?? "")
this.blueToothValue = result.utf8Value ?? "";
}
} as BTManager.ConnectBluetoothOptions)
},
//获取mtu
setMtuAction() {
BTManager.setMtu({
deviceAddress: this.deviceAddress,
mtu: 100,
mtuHandle: (res) => {
console.log('设置mtu:' + res)
}
} as BTManager.SetMtuPara)
},
getMtuAction() {
BTManager.getMtu({
deviceAddress: this.deviceAddress,
mtuHandle: (res) => {
console.log('获取mtu:' + res)
}
} as BTManager.GetMtuPara)
}
}
}
</script>
<style>
.content {
width: 750rpx;
display: flex;
height: 100%;
flex-direction: column;
}
.header {
width: 750rpx;
display: flex;
flex-direction: row;
align-items: center;
padding: 0 20rpx;
box-sizing: border-box;
margin-top: 20rpx;
}
.btn {
display: flex;
height: 80rpx;
padding: 0 5rpx;
align-items: center;
justify-content: center;
background-color: cadetblue;
color: white;
margin-right: 20rpx;
font-size: 28rpx;
border-radius: 6rpx;
}
.bound_list {
width: 750rpx;
height: 300rpx;
}
.list {
width: 750rpx;
height: 600rpx;
}
.cell {
display: flex;
flex-direction: column;
justify-content: center;
padding: 10rpx;
box-sizing: border-box;
background-color: antiquewhite;
}
</style>

收藏人数:
购买源码授权版(
试用
赞赏(2)
下载 343
赞赏 9
下载 11886113
赞赏 1912
赞赏
京公网安备:11010802035340号