A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
Hello @Eduardo Gomez,
Thank you for reaching out.
I believe the issue lies here:
var btDevice = await BluetoothDevice.FromIdAsync(deviceInfo.Id);
This call doesn't just retrieve device information; it also initiates a connection to the device. For devices with security features, this can result in timeouts or multiple retry attempts.
Instead, you can configure DeviceWatcher to provide device information directly. Then, in the Added event handler, extract the device information directly from deviceInfo.Properties.
public class WindowsBluetoothService : IBluetoothService {
public event Action<BluetoothDeviceModel>? DeviceFound;
private DeviceWatcher? _watcher;
private readonly HashSet<string> _seenDevices = [];
public void StartScan() {
_seenDevices.Clear();
string selector =
"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"";
_watcher = DeviceInformation.CreateWatcher(
selector,
[
"System.Devices.Aep.DeviceAddress",
"System.ItemNameDisplay",
"System.Devices.Aep.ClassOfDevice", // Device class for icon determination
"System.Devices.Aep.Category"
],
DeviceInformationKind.AssociationEndpoint
);
_watcher.Added += (s, deviceInfo) => {
string name = !string.IsNullOrWhiteSpace(deviceInfo.Name)
? deviceInfo.Name
: "Unknown Device";
if (name.EndsWith("(Bluetooth)", StringComparison.OrdinalIgnoreCase)) {
name = name.Replace("(Bluetooth)", "").Trim();
}
if (!_seenDevices.Add(name)) {
return;
}
string fontIcon = GetDeviceIcon(deviceInfo, name);
var model = new BluetoothDeviceModel {
Name = name,
Address = deviceInfo.Properties.TryGetValue("System.Devices.Aep.DeviceAddress", out var address)
? address?.ToString() ?? ""
: "",
FontIcon = fontIcon
};
Debug.WriteLine($"[FOUND] {name} ({model.FontIcon})");
MainThread.BeginInvokeOnMainThread(() => {
DeviceFound?.Invoke(model);
});
};
_watcher.Start();
}
private string GetDeviceIcon(DeviceInformation deviceInfo, string name) {
if (deviceInfo.Properties.TryGetValue("System.Devices.Aep.ClassOfDevice", out var classOfDeviceObj) &&
classOfDeviceObj is uint classOfDevice && classOfDevice > 0) {
uint majorDeviceClass = (classOfDevice >> 8) & 0x1F;
return majorDeviceClass switch {
1 => FontsConstants.Computer,
2 => FontsConstants.Smartphone,
4 => FontsConstants.Headphones,
5 => FontsConstants.Mouse,
6 => FontsConstants.Print,
_ => FontsConstants.Bluetooth_audio
};
}
return FontsConstants.Bluetooth_audio;
}
public void StopScan() {
if (_watcher != null &&
(_watcher.Status == DeviceWatcherStatus.Started ||
_watcher.Status == DeviceWatcherStatus.EnumerationCompleted)) {
_watcher.Stop();
_watcher = null;
}
}
}
I hope this helps.