uni-app 小程序在iOS设备上能正常跟蓝牙设备交互数据 Android上开启蓝牙数据监听失败
uni-app 小程序在iOS设备上能正常跟蓝牙设备交互数据 Android上开启蓝牙数据监听失败
| 信息项 | 描述 |
|---|---|
| 产品分类 | uni小程序SDK |
| 手机系统 | Android |
| 手机系统版本 | Android 9.0 |
| 手机机型 | 安卓设备 |
| 页面类型 | vue |
| SDK版本号 | SDK 3.2.3 V1 版本 |
示例代码:
========== 链接蓝牙页面代码----蓝牙模块开始================
// 初始化蓝牙
InitBle() {
let _this = this
uni.openBluetoothAdapter({ //初始化蓝牙模块
success(res) {
console.log('初始化蓝牙', res);
// uni.showToast({
// title: '初始化成功',
// icon: 'success',
// duration: 800
// })
// _this.SearchBle(); //2.0
},
fail(err) {
uni.showToast({
title: '请检查是否已开启蓝牙',
icon: 'none',
duration: 1500
})
}
})
},
// 搜索蓝牙
SearchBle() {
let _this = this
_this.linkStatus = 1;
uni.startBluetoothDevicesDiscovery({
success(res) {
console.log('蓝牙开启搜索', res)
_this.Loading = true
_this.timer1 = setTimeout(() => { //加个延迟、目的是为了设备搜索完毕再获取列表,不然获取为空列表
_this.GetBleList() //3.0
}, 3000)
},
fail(res) {
_this.linkStatus = 0;
console.log("查找设备失败!");
uni.showToast({
icon: "none",
title: "查找设备失败!",
duration: 3000
})
}
})
},
// 搜索到的蓝牙列表
GetBleList() {
var _this = this;
uni.getBluetoothDevices({
success: function(res) {
var bluetoothArr = res.devices.filter(function(obj) {
console.log("obj: ----- " + JSON.stringify(obj));
var uuids = obj.advertisServiceUUIDs;
var uuid = '';
if (Array.isArray(uuids)) {
if (uuids.length > 0) {
let str = uuids[0];
if (str.length >= 8) {
uuid = str.slice(4, 8);
if (uuid == '6837') {
_this.ConnectBle(obj.deviceId);
}
}
}
}
return uuid == '6837';
// return obj.name != "未知设备" && obj.name == 'mycar_ble'; //这里过滤自己想要的设备
})
// console.log('蓝牙设备列表==2过滤后==', bluetoothArr)
_this.bluetoothList = bluetoothArr
// _this.bluetoothList = []
},
fail: function() {
_this.linkStatus = 0;
console.log("搜索蓝牙设备失败");
uni.showToast({
title: '搜索蓝牙设备失败或附件暂无开启的蓝牙设备',
icon: 'none',
duration: 2000
})
},
complete: function() {
console.log('搜索完成')
_this.Loading = false
_this.StopSearchBle()
}
})
},
// 蓝牙连接 根据某一id连接设备,4.0
ConnectBle(deviceId) {
var _this = this;
uni.createBLEConnection({
deviceId: deviceId, //设备id
success: (res) => {
console.log('连接蓝牙成功==', res)
// _this.postDeviceInfo() //提交蓝牙信息到后台
_this.deviceId = deviceId
_this.linkStatus = 2;
// 设置蓝牙最大传输单元。
// uni.setBLEMTU(22,512)
_this.NoticeConnection(); //连接成功后,开始监听异常
_this.timer2 = setTimeout(() => { //加个延迟、目的是为了确保连接成功后,再获取服务列表--可以显示正在连接效果
_this.Loading = false
_this.GetServiceId(deviceId); //5.0
uni.showToast({
title: '连接成功',
icon: 'success',
duration: 800
})
}, 3000)
},
fail: function(err) {
_this.linkStatus = 0;
console.log('蓝牙连接失败err===', err)
if (err.errMsg == 'createBLEConnection:fail already connect') {
_this.Loading = false
_this.status_txt = '已有蓝牙连接'
} else {
_this.status_txt = err.errMsg
}
},
complete: function() {
console.log('蓝牙连接完成')
}
})
},
//获取蓝牙设备的服务uuid,5.0 //服务uuid可能有多个
GetServiceId(deviceId) {
console.log('连接的蓝牙设备deviceId====', deviceId)
var _this = this
uni.getBLEDeviceServices({
deviceId,
success(res) {
console.log('获取蓝牙四个服务==', JSON.stringify(res.services))
_this.serviceid_list = res.services //蓝牙服务列表放在data里面只是备用
_this.serviceId = res.services[0].uuid //这是用来监听蓝牙下发和接收的服务uuid
_this.GetCharacteIdNotify(_this.serviceId,
deviceId) //6.0 获取第2个服务uuid的特征值 (关于获取第几个uuid服务,看蓝牙方面提供的协议
}
})
},
// 根据服务uuid获取蓝牙特征值,开始监听写入和接收
GetCharacteIdNotify(serviceId, deviceId) {
console.log('serviceId:-----' + serviceId);
console.log('deviceId:-----' + deviceId);
let _this = this
uni.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success(res) {
console.log('获取蓝牙特征值', res.characteristics)
_this.writeId = res.characteristics[0].uuid //写入id
_this.notifyId = res.characteristics[0].uuid //接收id
_this.startNoticeBle(_this.notifyId) //7.0,开始侦听数据
}
})
},
// 开启蓝牙数据监听
startNoticeBle(notifyId) {
console.log('开启蓝牙数据监听', notifyId)
let _this = this
uni.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
deviceId: _this.deviceId,
serviceId: _this.serviceId,
characteristicId: notifyId,
success(res) {
console.log("监听成功===", res.errMsg, 'deviceId===', _this.deviceId)
_this.GetDataFromBle();
},
fail: function(err) {
console.log('开启监听失败', err)
}
})
},
// 设备返回的数据接收
GetDataFromBle() {
var _this = this;
wx.onBLECharacteristicValueChange((res) => {
// 此时可以拿到蓝牙设备返回来的数据是一个ArrayBuffer类型数据,所以需要通过一个方法转换成字符串
// console.log('res:-----' + JSON.stringify(res.value)); // 0a010001060002daff000013
// console.log('返回的十六进制', _this.ab2hex(res.value));
_this.bleData = _this.ab2hex(res.value)
let data = _this.ab2hex(res.value)
console.log('data:-----' + data);
// 0a0100010600021dcf000000
})
},
// 向蓝牙写入数据
BleWrite(instruction) {
// 向蓝牙设备发送一个0x00的16进制数据
let _this = this
let serviceId = _this.serviceId
let characteristicId = _this.writeId
let deviceId = _this.deviceId
const buffer = _this.hexStringToArrayBuffer(instruction);
// const dataView = new DataView(buffer)
// dataView.setUint8(0, 0)
uni.writeBLECharacteristicValue({
deviceId, // 蓝牙设备 deviceId
serviceId, // 蓝牙服务uuid,即第二个uuid
characteristicId, // 蓝牙特征值的 (即 writeId)
value: buffer, // 这里的value是ArrayBuffer类型
success(res) {
console.log('指令下发成功==', res.errMsg, res)
},
fail(err) {
console.log('写入数据失败', err)
uni.showToast({
icon: "none",
title: "请确保您的手机已连接设备",
duration: 3000
})
}
})
},
// 停止搜索蓝牙
StopSearchBle() {
this.linkStatus = 0;
uni.stopBluetoothDevicesDiscovery({
success(res) {
console.log('停止搜索蓝牙', res)
}
})
},
// 重新搜索蓝牙
ReSearchBle() {
console.log('重新扫描')
this.SearchBle()
},
// 关闭蓝牙模块
CloseBle() {
this.linkStatus = 0;
uni.closeBluetoothAdapter({
success: function(res) {
console.log("断开蓝牙")
},
fail: function(err) {}
})
},
// 监听蓝牙连接状态
NoticeConnection() {
var _this = this;
uni.onBLEConnectionStateChange((res) => {
console.log('开始监听蓝牙状态', res)
if (!res.connected) {
_this.linkStatus = 0;
console.log('连接已断开');
uni.showModal({
title: '提示',
content: '蓝牙已断开,请重新搜索重连!',
success(res) {}
})
// clearInterval(_this.data.timer)
}
})
},
/* ===========蓝牙模块结束================ */
// 工具函数
// ArrayBuffer转16进度字符串示例
ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
},
hexStringToArrayBuffer(str) {
if (!str) {
return new ArrayBuffer(0);
}
var buffer = new ArrayBuffer(str.length);
let dataView = new DataView(buffer)
let ind = 0;
for (var i = 0, len = str.length; i < len; i += 2) {
let code = parseInt(str.substr(i, 2), 16)
dataView.setUint8(ind, code)
ind++
}
return buffer;
},
==========蓝牙模块结束================
更多关于uni-app 小程序在iOS设备上能正常跟蓝牙设备交互数据 Android上开启蓝牙数据监听失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于uni-app 小程序在iOS设备上能正常跟蓝牙设备交互数据 Android上开启蓝牙数据监听失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html
根据你提供的代码和问题描述,在iOS上正常但在Android上开启蓝牙数据监听失败,主要问题可能出在以下几个方面:
1. Android权限问题
Android 6.0+需要动态申请位置权限才能正常使用蓝牙:
// 在初始化蓝牙前添加权限检查
uni.getLocation({
type: 'wgs84',
success: function () {
console.log('位置权限已授权')
_this.InitBle()
},
fail: function () {
uni.showModal({
title: '提示',
content: '需要位置权限才能使用蓝牙功能',
success: function (res) {
if (res.confirm) {
uni.openSetting()
}
}
})
}
})
2. 特征值选择问题
你的代码中writeId和notifyId使用了同一个特征值:
_this.writeId = res.characteristics[0].uuid //写入id
_this.notifyId = res.characteristics[0].uuid //接收id
这可能导致Android设备无法正确识别特征值属性。需要根据特征值的properties属性区分:
res.characteristics.forEach(char => {
if (char.properties.write) {
_this.writeId = char.uuid
}
if (char.properties.notify || char.properties.indicate) {
_this.notifyId = char.uuid
}
})
3. Android API兼容性问题
在GetDataFromBle()方法中,你使用了wx.onBLECharacteristicValueChange,这是微信小程序的API,在uni-app中应该使用:
uni.onBLECharacteristicValueChange((res) => {
// 处理数据
})
4. 时序问题
Android设备对蓝牙操作时序要求更严格,建议在连接成功后增加延迟:
// 在ConnectBle成功后
setTimeout(() => {
_this.GetServiceId(deviceId)
}, 1000) // 适当延长延迟时间
5. 调试建议
在Android上添加更详细的错误日志:
uni.notifyBLECharacteristicValueChange({
state: true,
deviceId: _this.deviceId,
serviceId: _this.serviceId,
characteristicId: notifyId,
success(res) {
console.log("监听成功", res)
},
fail: function(err) {
console.log('开启监听失败详细:',
'errCode:', err.errCode,
'errMsg:', err.errMsg,
'deviceId:', _this.deviceId,
'serviceId:', _this.serviceId,
'characteristicId:', notifyId
)
}
})
6. Android特定处理
某些Android设备需要在连接后先读取一次特征值才能开启监听:
// 在开启监听前先读取一次
uni.readBLECharacteristicValue({
deviceId: _this.deviceId,
serviceId: _this.serviceId,
characteristicId: notifyId,
success() {
// 然后再开启监听
_this.startNoticeBle(notifyId)
}
})

