我正在使用cordova和BLE插件开发应用程序。我希望通过BLE自动连接到基于硬编码的已知device.name的ESP32,而无需用户按下连接按钮。
我的想法是:
在设备就绪时运行扫描:
scanForDevices: function(){
ble.scan([], 10, app.onDiscoverDevice, app.onError);
app.getDevIdFromList();
},
构建一个包含所有已发现设备的数组:
onDiscoverDevice: function(device) {
deviceList[deviceNr] = [device.name, device.id, device.rssi];
deviceNr = deviceNr + 1 ;
},
当ble.scan函数完成后,运行app.getDevIdFromList(),检查我的设备名称是否在列表中,如果是,则开始连接:
getDevIdFromList: function(){
for (var i = 0; i < deviceList.length; i++)
{ if (deviceList[i][0]== "myDeviceName")
{ myDeviceDetected = "true";
myDeviceId = deviceList[i][1];
app.connect();
}
}
if (myDeviceDetected == "false"){
app.onBtDetectionError();
} },
问题似乎是在ble.scan完成(运行异步?)之前调用了getDevIdFromList,导致getDevIdFromList处理一个不完整甚至是空的数组,即使我的设备可用,也会抛出onBtDetectionError。
知道怎么解决这个问题吗? THX!
(另请参阅我在BLE插件github #597上提出的问题,但是正如所有者指出这更像是堆栈溢出的问题)
答案 0 :(得分:1)
由于扫描是异步的,因此逻辑会更复杂一些。一种方法是等待扫描完成,然后检查结果。
connectByName: function(name) {
const devices = [];
// scan and save devices to a list
ble.startScan([], d => devices.push(d));
// check the list when the scan stop
setTimeout(() => {
ble.stopScan();
const device = devices.filter(d => d.name === name)[0];
if (device) {
ble.connect(device.id, app.onConnected, app.onDisconnected);
} else {
console.log(`Couldn't find device ${name}`);
}
}, 5000);
},
这很好,但您总是需要等待扫描完成。即使扫描立即找到设备,您也需要等待超时。另一种方法是在扫描时过滤设备。
connectByName: function(name) {
let scanning = true;
ble.startScan([], device => {
if (device.name === name) {
ble.stopScan();
scanning = false;
ble.connect(device.id, app.onConnected, app.onDisconnected);
} else {
console.log(`Skipping ${device.name} ${device.id}`);
}
});
// set timer to stop the scan after a while
setTimeout(() => {
if (scanning) {
ble.stopScan();
console.log(`Couldn't find device ${name}`);
}
}, 5000);
},
第二种方法通常更好,因为它可以更快地连接。
如果您只在Android上运行,并且您拥有设备的MAC地址,则无需扫描即可连接。 (iOS仍需要您扫描。)
onDeviceReady: function() {
// connect by MAC address on startup
const MAC_ADDRESS = 'E4:86:1E:4E:5A:FB';
ble.connect(MAC_ADDRESS, app.onConnected, app.onDisconnected);
},
还有一个新的autoConnect功能,只要手机在设备范围内,它就会自动连接和断开连接。 (这在iOS上还不行。)
onDeviceReady: function() {
// Auto connect whenever the device is in range
const MAC_ADDRESS = 'E4:86:1E:4E:5A:FB';
ble.autoConnect(MAC_ADDRESS, app.onConnected, app.onDisconnected);
},
有关index.js
的完整版本,请参阅https://gist.github.com/don/e423ed19f16e1367b96d04ecf51533cc