我正在使用 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 。
知道如何解决这个问题吗? 谢谢!
(另请参阅我在 BLE 插件 github #597 上提出的问题,但正如所有者指出的那样,这更多是堆栈溢出的问题)
最佳答案
由于扫描是异步的,因此逻辑变得更加复杂。一种方法是等待扫描完成,然后检查结果。
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);
},
还有一个新的自动连接功能,只要手机在设备的范围内,就会自动连接和断开连接。 (这在 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);
},
参见https://gist.github.com/don/e423ed19f16e1367b96d04ecf51533cc完整版本的index.js
关于javascript - 由于异步执行 ble.scan,基于设备名称的 Cordova BLE 自动连接(无需用户操作)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50776972/