蓝牙主要功能
Uni-App 提供的蓝牙 API 允许我们开发时主要实现以下功能:
- 扫描并连接到蓝牙设备
- 发现已连接设备的服务和特征值
- 向设备发送数据
- 接收设备发送的数据
流程图:
关于开发时进行蓝牙连接的流程,总结如下:
- 初始化蓝牙适配器
- 开始搜索蓝牙设备
- 监听/获取已发现的设备
- 连接到蓝牙设备
- 获取设备服务
- 获取服务特征值uni-app 蓝牙连接全面指南
- 写入/读取数据
- 断开连接并关闭蓝牙模块
三、蓝牙核心 API 介绍
蓝牙 API 分为通用蓝牙 API 和低功耗蓝牙的 API
通用蓝牙 API
1. 初始化蓝牙模块
当开始使用蓝牙前,需要先初始化蓝牙模块,初始化蓝牙适配器成功后才可以继续使用其他的 API:
uni.openBluetoothAdapter({
success: function (res) {
console.log('初始化蓝牙适配器成功', res)
},
fail: function (err) {
console.error('初始化蓝牙适配器失败', err)
}
})
2. 开始搜索蓝牙设备
初始化成功后,就可以通过调用 startBluetoothDevicesDiscovery 方法开始搜索附近的蓝牙设备:
注意:此操作比较耗费系统资源,请在搜索并连接到设备后调用
uni.stopBluetoothDevicesDiscovery方法停止搜索。
uni.startBluetoothDevicesDiscovery({
success: function (res) {
console.log('开始搜索蓝牙设备', res)
},
fail: function (err) {
console.error('开始搜索蓝牙设备失败', err)
}
})
说明:App 端目前仅支持发现 BLE 低功耗蓝牙设备,其实我们也主要和低功耗蓝牙设备建立通信关系。一般为发送指令(开关机、蓝牙打印等),接收数据(蓝牙温度记录仪)
3. 停止搜索蓝牙设备
当不再需要继续搜索设备时,可以调用 stopBluetoothDevicesDiscovery 停止搜索:
uni.stopBluetoothDevicesDiscovery({
success: function (res) {
console.log('停止搜索蓝牙设备', res)
},
fail: function (err) {
console.error('停止搜索蓝牙设备失败', err)
}
})
4. 监听已发现的蓝牙设备
通过 onBluetoothDeviceFound 方法获取当前已发现的蓝牙设备列表,此方式是回调方法,只要发现了新的蓝牙设备,都会进入该回调:
uni.onBluetoothDeviceFound(function (devices) {
console.log('new device list has founded')
console.dir(devices)
})
5. 获取已发现的蓝牙设备列表
通过 getBluetoothDevices 方法获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
uni.getBluetoothDevices({
success: function (res) {
console.log('已发现的蓝牙设备', res.devices)
},
fail: function (err) {
console.error('获取已发现的蓝牙设备列表失败', err)
}
})
6. 关闭蓝牙模块
通过调用 closeBluetoothAdapter 方法将关闭蓝牙模块,断开所有已建立的连接并释放系统资源。
调用该方法将断开所有已建立的连接并释放系统资源。一般在使用蓝牙流程完毕后,主动调用该方法,可在页面生命周期中使用。应与
uni.openBluetoothAdapter成对调用。
uni.closeBluetoothAdapter({
success(res) {
console.log(res)
}
})
低功耗蓝牙 API
1. 连接到蓝牙设备
选择一个设备后,可以通过设备 ID 调用 createBLEConnection 方法建立与该设备的连接:
uni.createBLEConnection({
deviceId: '目标设备ID',
success: function (res) {
console.log('连接蓝牙设备成功', res)
},
fail: function (err) {
console.error('连接蓝牙设备失败', err)
}
})
2. 获取蓝牙设备的服务
连接成功后,可以通过设备 ID 调用 getBLEDeviceServices 方法获取该设备提供的服务:
uni.getBLEDeviceServices({
deviceId: '目标设备ID',
success: function (res) {
console.log('获取蓝牙设备服务成功', res.services)
},
fail: function (err) {
console.error('获取蓝牙设备服务失败', err)
}
})
3. 获取服务中的特征值
获取服务成功后,可以通过设备 ID、服务 ID 调用 getBLEDeviceCharacteristics 方法获取特定服务下的特征值:
uni.getBLEDeviceCharacteristics({
deviceId: '目标设备ID',
serviceId: '服务ID',
success: function (res) {
console.log('获取蓝牙设备特征值成功', res.characteristics)
},
fail: function (err) {
console.error('获取蓝牙设备特征值失败', err)
}
})
4. 向蓝牙设备写入数据
确定了要使用的特征值后,可以使用 writeBLECharacteristicValue 方法向蓝牙设备写入数据:
注意:只有获取到支持读写的特征值后,才可以向蓝牙设备写入数据。
uni.writeBLECharacteristicValue({
deviceId: '目标设备ID',
serviceId: '服务ID',
characteristicId: '特征值ID',
value: new ArrayBuffer(2), // 示例数据
success: function (res) {
console.log('向蓝牙设备写入数据成功', res)
},
fail: function (err) {
console.error('向蓝牙设备写入数据失败', err)
}
})
说明:蓝牙打印机主要会使用该 API,将在下一文章中说明。
5. 监听来自蓝牙设备的数据
如果需要接收来自蓝牙设备的数据,可以监听 onBLECharacteristicValueChange 事件:
uni.onBLECharacteristicValueChange(function (res) {
console.log('接收到蓝牙设备数据', res.value)
})
6. 断开蓝牙连接
通过调用 closeBLEConnection 断开与低功耗蓝牙设备的连接。
uni.closeBLEConnection({
deviceId,
success(res) {
console.log(res)
}
})
使用蓝牙 API 前的准备
在 Uni-App 中使用蓝牙功能时,尤其是真机(Android 和 iOS),需要添加蓝牙打包模块;除此之外,还需要确保在 manifest.json 文件中正确声明所需的蓝牙权限,并在运行时请求这些权限。
1. 添加蓝牙模块
在 HBuilderX 中,需要在项目配置中勾选蓝牙模块。
2. Android 权限
处理 Android 蓝牙权限需要在 manifest.json 中声明权限,首先,打开你的 manifest.json 文件,并在 app-plus 节点下添加所需的蓝牙权限。
注意:根据不同的 Android 版本,你可能需要声明不同的权限。
基本权限
在 manifest.json 配置如下权限:
{
"app-plus": {
"distribute": {
"android": {
"permissions": [
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN"
]
}
}
}
}
高级权限(Android 12 及以上)
如果应用需要扫描附近的蓝牙设备,还需要声明 ACCESS_FINE_LOCATION 权限,从 Android 12 开始,还需要声明 BLUETOOTH_SCAN、BLUETOOTH_CONNECT 和 BLUETOOTH_ADVERTISE 权限:
{
"app-plus": {
"distribute": {
"android": {
"permissions": [
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.BLUETOOTH_SCAN",
"android.permission.BLUETOOTH_CONNECT",
"android.permission.BLUETOOTH_ADVERTISE"
]
}
}
}
}
3. iOS 权限
对于 iOS 平台,和 Android 平台类似,同样需要在 manifest.json 文件,并在 app-plus 节点下添加所需的蓝牙权限。需要声明 NSBluetoothAlwaysUsageDescription 和 NSBluetoothPeripheralUsageDescription,并在其中提供用途说明。
在 manifest.json 配置如下权限:
{
"app-plus": {
"distribute": {
"ios": {
"permissions": {
"NSBluetoothAlwaysUsageDescription": "需要蓝牙权限以连接和控制外部设备",
"NSBluetoothPeripheralUsageDescription": "需要蓝牙权限以连接和控制外部设备"
}
}
}
}
}
4. 运行时请求权限
在 Uni-App 中,你可以使用 uni.authorize 方法来请求运行时权限。以下示例代码,表示如何在应用启动时请求蓝牙相关权限:
export default {
data() {
return {}
},
onReady() {
this.checkAndRequestPermissions()
},
methods: {
checkAndRequestPermissions() {
const permissions = ['scope.bluetooth', 'scope.location']
// 检查权限
uni.getSetting({
success: res => {
let authResult = true
permissions.forEach(permission => {
if (!res.authSetting[permission]) {
authResult = false
return
}
})
if (!authResult) {
// 请求权限
this.requestPermissions()
} else {
// 已经有权限,可以进行蓝牙操作
this.initBluetooth()
}
}
})
},
requestPermissions() {
const permissions = ['scope.bluetooth', 'scope.location']
permissions.forEach(permission => {
uni.authorize({
scope: permission,
success: () => {
console.log(`权限 ${permission} 请求成功`)
},
fail: err => {
console.error(`权限 ${permission} 请求失败`, err)
uni.showModal({
title: '提示',
content: '请在设置中开启蓝牙和位置权限',
showCancel: false
})
}
})
})
},
initBluetooth() {
uni.openBluetoothAdapter({
success: res => {
console.log('初始化蓝牙适配器成功', res)
// 继续进行蓝牙操作
},
fail: err => {
console.error('初始化蓝牙适配器失败', err)
}
})
}
}
}
5. 处理用户拒绝权限的情况
如果用户拒绝了权限请求,可以通过 uni.showModal 方法提示用户在设置中手动开启权限。如下所示:
uni.showModal({
title: '提示',
content: '请在设置中开启蓝牙和位置权限',
confirmText: '去设置',
success: res => {
if (res.confirm) {
uni.openSetting({
success: settingData => {
console.log('用户设置结果', settingData)
}
})
}
}
})
注意事项
在使用蓝牙 API 时,请确保用户已经开启了手机的蓝牙功能和位置信息。
-
蓝牙 API 调用时机:蓝牙相关 API 的调用必须在
uni.openBluetoothAdapter调用之后使用,否则 API 会返回错误(errCode=10000)。 -
在用户蓝牙开关未开启或者手机不支持蓝牙功能的情况下,调用
uni.openBluetoothAdapter会返回错误(errCode=10001),表示手机蓝牙功能不可用。 -
版本兼容性:部分蓝牙 API 可能因操作系统版本不同而有所差异,具体请参考官方文档。
-
用户提示:确保在请求蓝牙权限时提供清晰的提示信息,告知用户为什么需要这些权限。
-
蓝牙状态检查:在初始化蓝牙适配器之前,应检查蓝牙是否已开启。可以使用
uni.getBluetoothAdapterState方法来检查蓝牙状态,如下代码:
uni.getBluetoothAdapterState({
success: res => {
if (!res.discovering && !res.available) {
uni.showModal({
title: '提示',
content: '请确保蓝牙已开启',
showCancel: false
})
}
},
fail: err => {
console.error('检查蓝牙适配器状态失败', err)
}
})