Took a look at the following SO resources:
But their solutions don't seem to be working.
Here's my main
file:
import { app, BrowserWindow } from "electron";
/**
* Ref: https://www.electronjs.org/docs/tutorial/quick-start#create-the-main-script-file
*/
async function createWindow(): Promise<BrowserWindow> {
// Creating a browser window
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
},
});
/**
* Handle bluetooth connection
* Ref: https://www.electronjs.org/docs/latest/tutorial/devices#web-bluetooth-api
*/
win.webContents.on("select-bluetooth-device", (event, devices, callback) => {
event.preventDefault();
if (devices.length > 0) {
callback(devices[0].deviceId);
}
});
// Load index.html
win.maximize();
await win.loadFile("./dist/renderer/index.html");
return win;
}
function setUpElectronApp(): void {
// Browser window
let win: BrowserWindow | undefined;
// Enable webBluetooth
app.commandLine.appendSwitch("enable-experimental-web-platform-features", "true");
app.commandLine.appendSwitch("enable-web-bluetooth", "true");
// Create bowser window once the electron app is initialized
app
.whenReady()
.then(() => {
createWindow()
.then((response) => {
win = response;
console.log(win);
})
.catch((err) => {
throw err as Error;
});
})
.catch((err) => {
throw err as Error;
});
// Quit the application when it no longer has any open windows
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
// The action is no-op on macOS due to the OS' behavior (https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac)
// On macOS it is common for applications and their menu bar to stay active until the user quits explicitly with Cmd + Q
app.quit();
win = undefined;
}
});
// Create a new browser window only when the application has no visible windows being activated
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
// On macOS it's common to re-create a window in the app when the dock icon is clicked and there are no other windows open.
createWindow()
.then((response) => {
win = response;
console.log(win);
})
.catch((err) => {
throw err;
});
}
});
}
setUpElectronApp();
Here's some code from the renderer
file:
function onDisconnected(event: Event) {
const device = event.target as BluetoothDevice;
console.log(`Device ${device.name} is disconnected.`);
}
export async function deviceConnect(): Promise<DeviceInfo> {
const device = await navigator.bluetooth.requestDevice({
filters: [
{
namePrefix: "Polar Sense",
manufacturerData: [{ companyIdentifier: 0x006b }], // For 'Polar Electro OY' company.
},
],
acceptAllDevices: false,
optionalServices: [0x180d, 0x180f],
});
device.addEventListener("gattserverdisconnected", onDisconnected);
const server = await device.gatt?.connect();
const heartRateService = await server?.getPrimaryService(0x180d);
const heartRate = await heartRateService?.getCharacteristic(0x2a37);
const batteryLevelService = await server?.getPrimaryService(0x180f);
const batteryLevel = await batteryLevelService?.getCharacteristic(0x2a19);
return { heartRate, batteryLevel, deviceID: device.name };
}
There's a button in my front which triggers the above function when clicked. Constantly, getting the Uncaught (in promise) DOMException: User cancelled the requestDevice() chooser.
error. Tried different versions of Electron as well. Still scratching my head.
Please let me know if accessing Web Bluetooth API in Electron is even possible. Using "electron": "^17.4.7",
on a macOS Monterey (12.4).
If you can spot anything, please suggest any issues with the approach above.