详细问题描述(DCloud产品不会有明显的bug,所以你遇到的问题大都是在特定环境下才能重现的问题,请仔细描述你的环境和重现方式,否则DCloud很难排查解决你的问题)
[内容]
在IOS平台上先调用notifyBLECharacteristicValueChange然后再执行writeBLECharacteristicValue,但在onBLECharacteristicValueChange里监听不到返回的结果,在安卓里是没有问题的,下面是我的测试代码,反而在执行notifyBLECharacteristicValueChange时会返回上一次执行writeBLECharacteristicValue的结果
重现步骤
[以下是按如下顺序执行代码的结果:
1.uni.startBluetoothDevicesDiscovery
- uni.createBLEConnection
- uni.notifyBLECharacteristicValueChange
- uni.writeBLECharacteristicValue
]
[结果:
14:59:54.393 [LOG] : create connection success: {"errMsg":"createBLEConnection:ok"}
14:59:59.654 [LOG] : startCharacteristicsNotify success: {"message":"ok","code":0}
14:59:59.674 [LOG] : get characteristics complete: {"message":"ok","code":0}
15:00:00.714 [LOG] : characteristics value changed: {"deviceId":"E697FBED-A78B-C932-BE9E-DB42844A67DE","serviceId":"6E400001-B5A3-F393-E0A9-FD9521DD94D4","characteristicId":"6E400003-B5A3-F393-E0A9-FD9521DD94D4","value":{}}
15:00:00.734 [LOG] : Value:d014a1e243426130313031393031303130303031
15:00:06.014 [LOG] : d00f303461333136346435306164a1
15:00:06.034 [LOG] : write characteristics success: {"message":"ok","code":0}
]
[期望:
正确的结果应该是在uni.writeBLECharacteristicValue后,在uni.onBLECharacteristicValueChange返回结果,在安卓平台里也是这样运行的没有问题,但在IOS里在调用 uni.writeBLECharacteristicValue后在uni.onBLECharacteristicValueChange没有任何结果返回
]
[如果语言难以表述清晰,可以拍一个视频或截图,有图有真相]
IDE运行环境说明
[HBuilderX]
[1.6.2]
[windows7]
[mac版本号]
App运行环境说明
[Android版本号]
[iOS9.0]
[iphone5]
[模拟器型号]
代码:
export default {
data() {
return {
devices: null,
devId: 'E697FBED-A78B-C932-BE9E-DB42844A67DE',
serId: '6E400001-B5A3-F393-E0A9-FD9521DD94D4',
chaId: '6E400002-B5A3-F393-E0A9-FD9521DD94D4',
chaId1: '6E400003-B5A3-F393-E0A9-FD9521DD94D4',
value: 'D00F303461333136346435303333A1',
value1: 'D0,0F,30,34,61,33,31,36,34,64,35,30,33,33,A1',
secret: '04a3164d50ad',
secret1: '1234567890ab',
cmd: '',
logStr: ''
}
},
computed: mapState(['forcedLogin', 'hasLogin', 'userName']),
methods: {
...mapMutations(['login']),
setData() {
var p = this;
p.devId = 'D0:E3:65:C9:4D:81';
p.serId = '00001800-0000-1000-8000-00805f9b34fb';
p.chaId = '00002a00-0000-1000-8000-00805f9b34fb';
p.value = 'tiger333';
//var iv = new Int32Array(value);
//iv[0] = 120, iv[2] = 100;
//this.getBluetoothDevices();
//this.createConnection(devId);
//this.getServices(devId);
//this.getCharacteristics(devId, serId);
//this.readCharacteristics(devId, serId, chaId);
//this.listenerCharacteristicsChange();
//this.writeCharacteristics(devId, serId, chaId, value);
//this.readCharacteristics(devId, serId, chaId);
//this.closeConnection(devId);
},
radioChange: function (e) {
var p = this;
var cmds = [p.getCmd(p.secret, 'A1', ''), //注册
p.getCmd(p.secret, 'A4', 'HELLO_WORLD'), //改名称命令
p.getCmd(p.secret, 'A3', p.secret1), //设置新密钥
p.getCmd(p.secret, 'A5', '123456'), //设置密码
p.getCmd('', '', 'rest'), //复位
p.getCmd(p.secret, 'A7', ''), //开门
p.getCmd(p.secret, 'A6', '2f') //清空密码
];
this.cmd = cmds[e.detail.value];
console.log('radio发生change事件,携带value值为:' + e.detail.value);
},
startBluetoothDiscovery() {
var p = this;
uni.openBluetoothAdapter({
success: function(e) {
p.log('open success: ' + JSON.stringify(e));
uni.startBluetoothDevicesDiscovery({
success: function(e) {
p.log('start discovery success: ' + JSON.stringify(e));
p.listenerDeviceFound();
},
fail: function(e) {
p.log('start discovery failed: ' + JSON.stringify(e));
}
});
},
fail: function(e) {
if (e.code == '10001') {
uni.showModal({
title: '提示',
content: '蓝牙未开启,请打开蓝牙',
showCancel: false,
success: function(res) {
}
});
}
p.log('open failed: ' + JSON.stringify(e));
}
});
},
listenerDeviceFound() {
var p = this;
uni.onBluetoothDeviceFound(function(e) {
var devices = e.devices;
p.log('device found: ' + e.length);
for (var i in devices) {
p.log(i + ': ' + JSON.stringify(devices[i]));
}
});
},
getBluetoothDevices() {
var p = this;
uni.getBluetoothDevices({
success: function(e) {
p.devices = e.devices;
var devices = e.devices;
p.log('get devices success: ' + devices.length);
for (var i in devices) {
p.log(i + ': ' + JSON.stringify(devices[i]));
}
},
fail: function(e) {
p.log('get devices failed: ' + JSON.stringify(e));
}
});
},
createConnection() {
var p = this;
uni.createBLEConnection({
deviceId: p.devId,
success: function(e) {
p.log('create connection success: ' + JSON.stringify(e));
},
fail: function(e) {
p.log('create connection failed: ' + JSON.stringify(e));
}
});
},
getServices() {
var p = this;
uni.getBLEDeviceServices({
deviceId: p.devId,
success: function(e) {
var services = e.services;
p.log('get services success: ' + services.length);
for (var i in services) {
p.log(i + ': ' + JSON.stringify(services[i]));
//p.getCharacteristics(p.devId, services[i].uuid);
}
},
fail: function(e) {
p.log('get services failed: ' + JSON.stringify(e));
}
});
},
getCharacteristics() {
this.startCharacteristicsNotify();
var p = this;
uni.getBLEDeviceCharacteristics({
deviceId: p.devId,
serviceId: p.serId,
success: function(e) {
var characteristics = e.characteristics;
p.log('get characteristics success: ' + characteristics.length);
for (var i in characteristics) {
p.log(i + ': ' + JSON.stringify(characteristics[i]));
}
},
fail: function(e) {
p.log('get characteristics failed: ' + JSON.stringify(e));
}
});
},
readCharacteristics() {
var p = this;
uni.readBLECharacteristicValue({
deviceId: this.devId,
serviceId: this.serId,
characteristicId: this.chaId,
success: function(e) {
p.log('read characteristics success: ' + JSON.stringify(e));
},
fail: function(e) {
p.log('read characteristics failed: ' + JSON.stringify(e));
}
});
},
writeCharacteristics() {
var p = this;
//console.log(this.buf2hex(p.cmd));
for(var i=0; i<p.cmd.length; i++){
console.log(p.buf2hex(p.cmd[i]));
plus.bluetooth.writeBLECharacteristicValue({
deviceId: p.devId,
serviceId: p.serId,
characteristicId: p.chaId,
value: p.cmd[i],
success: function(e) {
p.log('write characteristics success: ' + JSON.stringify(e));
},
fail: function(e) {
p.log('write characteristics failed: ' + JSON.stringify(e));
}
});
}
//this.startCharacteristicsNotify();
},
startCharacteristicsNotify() {
var p = this;
plus.bluetooth.notifyBLECharacteristicValueChange({
state: true,
deviceId: p.devId,
serviceId: p.serId,
characteristicId: p.chaId1,
success(e) {
var characteristics = e.characteristics;
console.log('startCharacteristicsNotify success: ' + JSON.stringify(e));
for (var i in characteristics) {
p.log(i + ': ' + JSON.stringify(characteristics[i]));
}
},
fail(e) {
p.log('startCharacteristicsNotify failed: ' + JSON.stringify(e));
},
complete(e) {
p.log('get characteristics complete: ' + JSON.stringify(e));
}
});
plus.bluetooth.onBLECharacteristicValueChange(function(e) {
p.log('characteristics value changed: ' + JSON.stringify(e));
p.log('Value:' + p.buf2hex(e.value).trim());
});
},
closeConnection() {
var p = this;
uni.closeBLEConnection({
deviceId: p.devId,
success: function(e) {
p.log('close success: ' + JSON.stringify(e));
},
fail: function(e) {
p.log('close failed: ' + JSON.stringify(e));
}
});
},
stopBluetoothDiscovery() {
var p = this;
this.closeConnection();
uni.stopBluetoothDevicesDiscovery({
success: function(e) {
p.log('stop discovery success: ' + JSON.stringify(e));
uni.closeBluetoothAdapter({
success: function(e) {
p.log('close success: ' + JSON.stringify(e));
},
fail: function(e) {
p.log('close failed: ' + JSON.stringify(e));
}
});
},
fail: function(e) {
p.log('stop discovery failed: ' + JSON.stringify(e));
}
});
},
log(str) {
this.logStr += str + "\r\n";
console.log(str);
},
buf2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},
hex2buff(val) {
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
return parseInt(h, 16)
})).buffer
},
string2buffer(str) {
// 首先将字符串转为16进制
let val = ""
for (let i = 0; i < str.length; i++) {
if (val === '') {
val = str.charCodeAt(i).toString(16)
} else {
val += ',' + str.charCodeAt(i).toString(16)
}
}
console.log(val);
// 将16进制转化为ArrayBuffer
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
return parseInt(h, 16)
})).buffer
},
getCmd(secret,action,msg) {
var buffers = new Array();
var msgLen = msg.length;
var len = 3 + secret.length + msgLen;
var buffer;
var dataView;
if(msg == 'rest'){
buffer = new ArrayBuffer(4);
dataView = new DataView(buffer);
dataView.setUint8(0, 'r'.charCodeAt());
dataView.setUint8(1, 'e'.charCodeAt());
dataView.setUint8(2, 's'.charCodeAt());
dataView.setUint8(3, 't'.charCodeAt());
buffers.push(buffer);
return buffers;
}
/*
for(var i=0; i<len; i++){
dataView.setUint8(i, str.substr(i*2, 2));
}*/
if(msgLen <= 5){
buffer = new ArrayBuffer(len);
}else{
buffer = new ArrayBuffer(20);
}
dataView = new DataView(buffer);
dataView.setUint8(0, parseInt('D0',16));
dataView.setUint8(1, len);
var secretLen = secret.length;
for(var i=0; i<secretLen; i++){
dataView.setUint8(i+2, secret[i].charCodeAt());
}
dataView.setUint8(secretLen + 2, parseInt(action,16));
if(msgLen <= 5){
if(msg != ''){
for(var i=0; i<msgLen; i++){
dataView.setUint8(secretLen + 3 + i, msg[i].charCodeAt());
}
}
buffers.push(buffer);
}else{
for(var i=0; i<5; i++){
dataView.setUint8(secretLen + 3 + i, msg[i].charCodeAt());
}
buffers.push(buffer);
const buffer1 = new ArrayBuffer(msgLen-5);
const dataView1 = new DataView(buffer1);
for(var i=5; i<msgLen; i++){
dataView1.setUint8(i-5, msg[i].charCodeAt());
}
buffers.push(buffer1);
}
//console.log(buffer.length);
return buffers;
}
},
onLoad(e) {
}
联系方式
[3806994]
CLP
dcloud蓝牙功能 主流功能是完整的,部分细节会慢慢完善
2019-04-29 17:19
9***@qq.com
是用uni-app 再引apicloud 的ble模块吗
2019-04-30 13:11
9***@qq.com
回复 9***@qq.com: 是整个项目都改用apicloud的ble模块了,不过这个坑也很多。勉强能使用。
2019-04-30 14:10
XTiger (作者)
回复 CLP: 主要功能虽然完整,但坑那么多,根本没法用,做产品和做实验的要求是不一样的
2019-05-16 09:38
许香香
回复 XTiger: 什么时候完善啊,我设备服务加了定时器还有一定几率报10004错误找不到服务,然后我递归找,找不到让他一直找就死循环了……
2020-05-22 12:54
许香香
回复 XTiger: 还有就是特征值也是有一定几率找不到
2020-05-22 12:54