Bluetooth API (Universal Windows Platform)

This section provides reference documentation for the Universal Windows Platform (UWP) APIs related to Bluetooth communication. These APIs allow your application to discover, connect to, and interact with Bluetooth devices.

Core Concepts

The UWP Bluetooth APIs are built around the concept of discovering and interacting with Bluetooth LE (Low Energy) and classic Bluetooth devices. Key classes and namespaces include:

  • Windows.Devices.Bluetooth: The root namespace for Bluetooth APIs.
  • BluetoothDevice: Represents a discovered Bluetooth device.
  • BluetoothLEDevice: Represents a discovered Bluetooth Low Energy device.
  • DeviceInformation: Used for discovering devices and their properties.
  • RfcommDeviceService: For interacting with classic Bluetooth serial port profiles (SPP).

Understanding the difference between Bluetooth LE and classic Bluetooth is crucial for selecting the correct APIs for your needs.

Tip: For most modern Bluetooth peripherals (fitness trackers, sensors, headphones), Bluetooth LE is the preferred and more power-efficient choice.

Discovering Bluetooth Devices

Device discovery is the first step in interacting with Bluetooth devices. You can discover both Bluetooth LE devices and classic Bluetooth devices.

Discovering Bluetooth LE Devices

Use the DeviceInformation.FindAllAsync method with the appropriate Bluetooth LE device selector.


using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth;

// ...

async void DiscoverLeDevices()
{
    var selector = BluetoothLEDevice.GetDeviceSelector();
    var devices = await DeviceInformation.FindAllAsync(selector);

    foreach (var deviceInfo in devices)
    {
        // Process discovered Bluetooth LE device information
        var bleDevice = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
        if (bleDevice != null)
        {
            System.WriteLine($"Found LE Device: {bleDevice.Name} ({bleDevice.Address})");
        }
    }
}
                

Discovering Classic Bluetooth Devices

Use the DeviceInformation.FindAllAsync method with the appropriate classic Bluetooth device selector.


using Windows.Devices.Enumeration;
using Windows.Networking.Proximity; // For BluetoothDevice.GetDeviceSelector()

// ...

async void DiscoverClassicDevices()
{
    var selector = BluetoothDevice.GetDeviceSelector();
    var devices = await DeviceInformation.FindAllAsync(selector);

    foreach (var deviceInfo in devices)
    {
        // Process discovered Classic Bluetooth device information
        var btDevice = await BluetoothDevice.FromIdAsync(deviceInfo.Id);
        if (btDevice != null)
        {
            System.WriteLine($"Found Classic Device: {btDevice.Name} ({btDevice.Address})");
        }
    }
}
                
Note: You need to declare the Microsoft.Bluetooth.AllowBluetooth capability in your app's manifest file.

Connecting to Bluetooth Devices

Once a device is discovered, you can establish a connection to it. The connection method depends on whether it's a Bluetooth LE device or a classic Bluetooth device.

Connecting to Bluetooth LE Devices

Bluetooth LE connections are typically handled implicitly when accessing services or characteristics. You use BluetoothLEDevice.ConnectAsync for explicit connection management if needed.


async void ConnectToLeDevice(string deviceId)
{
    var bleDevice = await BluetoothLEDevice.FromIdAsync(deviceId);
    if (bleDevice != null)
    {
        var result = await bleDevice.ConnectAsync(BluetoothConnectionPriority.High);
        if (result.ConnectionStatus == BluetoothConnectionStatus.Connected)
        {
            System.WriteLine($"Connected to {bleDevice.Name}");
            // Access services and characteristics
        }
    }
}
                

Connecting to Classic Bluetooth Devices (RFCOMM)

For classic Bluetooth devices that support the RFCOMM protocol (like serial ports), you can use RfcommDeviceService.


using Windows.Networking.Sockets;
using Windows.Networking.Proximity;
using Windows.Storage.Streams;

// ...

async void ConnectToRfcommDevice(string deviceId)
{
    var btDevice = await BluetoothDevice.FromIdAsync(deviceId);
    if (btDevice != null)
    {
        var services = await btDevice.GetRfcommServicesAsync();
        if (services.Services.Count > 0)
        {
            var service = services.Services.FirstOrDefault(); // Get the first service
            var socket = new StreamSocket();
            await socket.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName, BluetoothConnectionQuality.Unspecified);

            if (socket.Information.LocalPort != 0)
            {
                System.WriteLine($"Connected to RFCOMM service on {btDevice.Name}");
                // Use socket for sending/receiving data
            }
        }
    }
}
                

Accessing Bluetooth Services and Characteristics (LE)

Bluetooth Low Energy devices communicate through services, which expose characteristics. You can read, write, and subscribe to characteristic value changes.

Common GATT Operations

Operation Description Example Snippet
Get Services Retrieves all GATT services provided by the LE device. await bleDevice.GetGattServicesAsync()
Get Characteristics Retrieves all characteristics within a specific service. await gattService.GetCharacteristicsAsync()
Read Characteristic Value Reads the current value of a characteristic. await characteristic.ReadValueAsync()
Write Characteristic Value Writes data to a characteristic. await characteristic.WriteValueAsync(buffer)
Subscribe to Notifications Receives notifications when a characteristic's value changes. await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify)

// Example: Reading a characteristic value
async void ReadCharacteristic(GattCharacteristic characteristic)
{
    var result = await characteristic.ReadValueAsync();
    if (result.Status == GattCommunicationStatus.Success)
    {
        var reader = DataReader.FromBuffer(result.Value);
        // Process the data read from the characteristic
        byte[] data = new byte[reader.UnconsumedBufferLength];
        reader.ReadBytes(data);
        // ...
    }
}
                

Handling Bluetooth Events

You can subscribe to events to be notified of device connection status changes or characteristic value changes.

Device Connection Status

The BluetoothLEDevice.ConnectionStatusChanged event fires when the connection status of an LE device changes.

Characteristic Value Changes

The GattCharacteristic.ValueChanged event fires when a subscribed characteristic's value changes on an LE device.


// Ensure you have subscribed to notifications first
characteristic.ValueChanged += Characteristic_ValueChanged;

// ...

void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
    var reader = DataReader.FromBuffer(args.CharacteristicValue);
    // Process the new value from the characteristic
    byte[] data = new byte[reader.UnconsumedBufferLength];
    reader.ReadBytes(data);
    // ...
}
                

Error Handling and Permissions

Always handle potential exceptions and ensure your application has the necessary Bluetooth permissions declared in its manifest.

Important: Users must grant your application permission to access Bluetooth devices. Your app should inform the user why this permission is needed.

Common issues include:

  • Device not found or out of range.
  • Device is already connected to another application.
  • Incorrect Bluetooth service or characteristic UUIDs.
  • Missing capabilities in the app manifest.