'Electron Web Bluetooth Device selection returning only 1 device

have found that in my electron application the following code from the main.js only returns a device list of length 1 (filled with one device) even though there are many devices around.

mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
    event.preventDefault();
    console.log(deviceList);
    bluetoothSelection.selectBluetoothDevice(deviceList, mainWindow, (deviceId) => {
        callback(deviceId);
    });

If I call

navigator.bluetooth.requestDevice({
    acceptAllDevices: true,
    optionalServices: [serviceUuid]
})

multiple times, the device returned changes and if I cycle through it often enough, I get the device I want eventually.. But I built a device Picker window and all that stuff and now the window opens for only one device, which makes everything quite annoying:P

Any ideas on what could cause this or even how I could fix it?



Solution 1:[1]

If you have a look at https://www.electronjs.org/docs/latest/api/web-contents#event-select-bluetooth-device you will find the example code provided by electron you probably already know:

    win.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
    event.preventDefault()
    const result = deviceList.find((device) => {
      return device.deviceName === "test"
    })
    if (!result) {
      callback('')
    } else {
      callback(result.deviceId)
    }
  })

You have to prevent the callback until you have found the device you are looking for. I suggest to open a second window and pass in the deviceList. Now you can display the devices and let the user choose one. If the user has chosen a device, you can close the second window and call the callback with this deviceId.

To communicate between the windows you can use the “contextBridge” with “ipcRenderer” and “ipcMain” and to call the callback you can make a global variable

var callbackForBluetoothEvent = null;

and fill it int the

mainWindow.webContents.on(
// stuff
callbackForBluetoothEvent = callback; //to make it accessible outside
// stuff
);

With a “ipcMain.on”

ipcMain.on("BLEScannFinished", (event, args) => {
  console.log(args);
  console.log(BLEDevicesList.find((item) => item.deviceId === args));
  let BLEDevicesChoosen = BLEDevicesList.find((item) => item.deviceId === args);
  callbackForBluetoothEvent(BLEDevicesChoosen.deviceId);
}); 

You can than call the callback

Unfortunately this is a bit to much code for a forum post but you can find a rudimentary solution of this suggestion at the link:

https://github.com/grosdode/Electron-multible-BLE-devices

The electron issues 11865 was also helpful and there is a page which shows alternative code for the suggested solution. Unfortunately also to much code to post it here.

https://technoteshelp.com/electron-web-bluetooth-api-requestdevice-error/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 grosdode