Share via

Windows Bluetooth connectivity

Eduardo Gomez 4,316 Reputation points
2025-09-29T13:38:14.13+00:00

I am testing connecting to my phone, via Bluetooth. I already scan, and found my phne


namespace SnapLabel.Platforms.Windows {

    public class WindowsBluetoothScanner : IBluetoothService {
        public event Action<BluetoothDeviceModel>? DeviceFound;
        private BluetoothDevice? _connectedDevice;
        private StreamSocket? _socket;
        private DeviceWatcher? _watcher;
        private bool _keepScanning;
        private readonly HashSet<string> _seenDevices = [];
        public void StartScan() {
            _keepScanning = true;
            _seenDevices.Clear();
            StartWatcher();
        }
        public void StopScan() {
            _keepScanning = false;
            if(_watcher != null &&
                (_watcher.Status == DeviceWatcherStatus.Started ||
                 _watcher.Status == DeviceWatcherStatus.EnumerationCompleted)) {
                _watcher.Stop();
                _watcher = null;
            }
        }
        private void StartWatcher() {
            string selector = "System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"";
            _watcher = DeviceInformation.CreateWatcher(
                selector,
                [
                    "System.Devices.Aep.DeviceAddress",
                    "System.ItemNameDisplay"
                ],
                DeviceInformationKind.AssociationEndpoint
            );
            _watcher.Added += async (s, deviceInfo) => {
                string name = !string.IsNullOrWhiteSpace(deviceInfo.Name)
                    ? deviceInfo.Name
                    : deviceInfo.Properties.TryGetValue("System.Devices.Aep.DeviceAddress", out var addr)
                        ? addr?.ToString() ?? "Unknown"
                        : "Unknown";
                if(name.EndsWith("(Bluetooth)", StringComparison.OrdinalIgnoreCase))
                    name = name.Replace("(Bluetooth)", "").Trim();
                if(!_seenDevices.Add(name))
                    return;
                string fontIcon = FontsConstants.Bluetooth;
                try {
                    var btDevice = await BluetoothDevice.FromIdAsync(deviceInfo.Id);
                    if(btDevice != null) {
                        uint major = (uint)btDevice.ClassOfDevice.MajorClass;
                        fontIcon = major switch {
                            1 => FontsConstants.Computer,
                            2 => FontsConstants.Smartphone,
                            4 => FontsConstants.Headphones,
                            5 => FontsConstants.Mouse,
                            6 => FontsConstants.Print,
                            7 => FontsConstants.Keyboard,
                            _ => FontsConstants.Bluetooth_audio
                        };
                    }
                } catch(Exception ex) {
                    Debug.WriteLine($"[WARN] Could not get ClassOfDevice for {name}: {ex.Message}");
                }
                DeviceFound?.Invoke(new BluetoothDeviceModel {
                    Name = name,
                    FontIcon = fontIcon,
                    Address = Convert.ToUInt64(
                        deviceInfo.Properties["System.Devices.Aep.DeviceAddress"].ToString()?.Replace(":", ""),
                        16
     )
                });
            };
            _watcher.EnumerationCompleted += (s, e) => { };
            _watcher.Updated += (s, update) => { };
            _watcher.Removed += (s, update) => { };
            _watcher.Start();
        }
        public async Task<bool> ConnectAsync(ulong deviceId) {
            try {
                _connectedDevice = await BluetoothDevice.FromBluetoothAddressAsync(deviceId);
                if(_connectedDevice == null) {
                    return false;
                }
                var services = await _connectedDevice.GetRfcommServicesAsync();
                var service = (services.Services.Count > 0)
                    ? services.Services[0]
                    : null;
                if(service == null) { // here is the problem
                    return false;
                }
                _socket = new StreamSocket();
                await _socket.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName);
                return true;
            } catch(Exception ex) {
                Debug.WriteLine($"[ERROR] Could not connect to device {deviceId}: {ex.Message}");
                throw;
            }
        }
        public Task<bool> SendDataAsync(byte[] data) {
            throw new NotImplementedException();
        }
    }
}

my service is null when connecting

Developer technologies | .NET | .NET Multi-platform App UI
0 comments No comments

Answer accepted by question author

  1. Michael Le (WICLOUD CORPORATION) 11,325 Reputation points Microsoft External Staff Moderator
    2025-09-30T03:43:14.3633333+00:00

    Hello Eduardo,

    Thank you for providing the code and detailing the issue.

    In case others encounter a similar problem, I have summarized the key points below.

    The issue you're encountering where GetRfcommServicesAsync() returns no services is expected behavior when connecting to a smartphone that has not yet been paired.

    Your code is correctly attempting to find a service using the RFCOMM protocol, which is used for the Serial Port Profile (SPP). However, for security and privacy reasons, a general-purpose device like a phone does not publicly advertise its services to any device that asks. It keeps them hidden from "stranger" devices.

    You asked why the Windows Settings app can connect to your phone. The Settings app performs pairing. Pairing is the process of establishing a trusted, secure relationship between two devices. It is different from simply opening a data connection. Once a device is paired, it is no longer a stranger, and the phone will be willing to reveal its services (like RFCOMM) to it.

    To resolve this, your application must ensure a trusted relationship exists before it asks for the available services.

    Thank you for your time and patience. I hope this clarifies the situation.

    Was this answer helpful?


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.