Interface IBluetoothRemoteDevice
- Namespace
- Bluetooth.Abstractions.Scanning
- Assembly
- Bluetooth.Abstractions.Scanning.dll
Interface representing a Bluetooth device, providing properties and methods for interacting with it.
public interface IBluetoothRemoteDevice : INotifyPropertyChanged, IAsyncDisposable
- Inherited Members
Properties
AdvertisedName
Gets the advertised name of the device.
string AdvertisedName { get; }
Property Value
BatteryLevelPercent
Gets the battery level as a value between 0 and 1.
double? BatteryLevelPercent { get; }
Property Value
CachedName
Gets the cached name of the device as seen by the native platform.
string CachedName { get; }
Property Value
CurrentRxPhy
Gets the current receive PHY mode.
PhyMode CurrentRxPhy { get; }
Property Value
CurrentTxPhy
Gets the current transmit PHY mode.
PhyMode CurrentTxPhy { get; }
Property Value
DebugName
Gets the debug name of the device.
string DebugName { get; }
Property Value
FirmwareVersion
Gets the firmware version of the device.
Version? FirmwareVersion { get; }
Property Value
HardwareVersion
Gets the hardware version of the device.
string? HardwareVersion { get; }
Property Value
Id
Gets the unique identifier of the device.
string Id { get; }
Property Value
IgnoreNextUnexpectedDisconnection
Gets or sets a value indicating whether to ignore the next unexpected disconnection.
bool IgnoreNextUnexpectedDisconnection { get; set; }
Property Value
IntervalBetweenAdvertisement
Gets the interval between advertisement information.
TimeSpan IntervalBetweenAdvertisement { get; }
Property Value
IsConnected
Gets a value indicating whether the device is connected.
bool IsConnected { get; }
Property Value
IsConnecting
Gets a value indicating whether the device is connecting.
bool IsConnecting { get; }
Property Value
IsDisconnecting
Gets a value indicating whether the device is disconnecting.
bool IsDisconnecting { get; }
Property Value
IsExploringServices
Gets a value indicating whether the device is exploring services.
bool IsExploringServices { get; }
Property Value
IsSignalStrengthProbingEnabled
Gets or sets a value indicating whether this device may be probed for its signal strength. Defaults to true.
When set to false, ReadSignalStrengthAsync(TimeSpan?, CancellationToken) stops issuing native RSSI reads and returns the
last known SignalStrengthInDbm instead.
bool IsSignalStrengthProbingEnabled { get; set; }
Property Value
Remarks
Set this to false before starting a firmware update. Nordic's DFU bootloader tends to drop the connection
when it is spammed with RSSI reads, which is particularly dangerous while an update is in flight. A read that is
already in flight when this is set to false still completes normally.
Signal strengths carried by advertisements are unaffected — those are passive and cost the device nothing.
IsStale
Gets a value indicating whether the device is stale (not seen for the configured inactivity timeout).
bool IsStale { get; }
Property Value
LastAdvertisement
Gets the latest advertisement information received.
IBluetoothAdvertisement? LastAdvertisement { get; }
Property Value
LastSeen
Gets the last time the device was seen, either by scanning or by connection.
DateTimeOffset LastSeen { get; }
Property Value
Manufacturer
Gets the manufacturer of the device.
Manufacturer Manufacturer { get; }
Property Value
Mtu
Gets the current Maximum Transmission Unit (MTU) for this connection. The MTU determines the maximum size of a single packet that can be sent.
int Mtu { get; }
Property Value
Name
Gets the name of the device, using the advertised name first, if empty it will use the cached name.
string Name { get; }
Property Value
Scanner
Gets the Bluetooth scanner associated with this device.
IBluetoothScanner Scanner { get; }
Property Value
SignalStrengthInDbm
Gets the signal strength in dBm.
int SignalStrengthInDbm { get; }
Property Value
SignalStrengthInPercent
Gets the signal strength as a percentage (between 0.00 and 1.00).
double SignalStrengthInPercent { get; }
Property Value
SoftwareVersion
Gets the software version of the device.
Version? SoftwareVersion { get; }
Property Value
UnderlyingPlatformDevice
Gets the innermost platform-specific device this instance ultimately wraps.
IBluetoothRemoteDevice UnderlyingPlatformDevice { get; }
Property Value
Remarks
A scanner's DeviceWrapper hook lets client code substitute a custom subtype (e.g. by
inheriting Bluetooth.Maui.BluetoothRemoteDevice) for the raw platform device added to
the registry. Native platform code that needs to resolve a native callback (e.g. a
CoreBluetooth or GATT delegate callback) back to the concrete implementation it can invoke
methods on should use this property rather than casting the device directly - casting a
wrapped device to a platform-specific type always fails, since the wrapper does not inherit
from it. The default implementation returns this, so unwrapped platform
devices need no override; wrapper types must override this to delegate to the device they wrap.
Methods
ClearServicesAsync()
Resets the list of services and characteristics, and stops all subscriptions and notifications.
ValueTask ClearServicesAsync()
Returns
- ValueTask
A task that represents the asynchronous operation.
ConnectAsync(ConnectionOptions?, TimeSpan?, CancellationToken)
Connects to the device asynchronously.
ValueTask ConnectAsync(ConnectionOptions? connectionOptions = null, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
connectionOptionsConnectionOptionsThe connection options to use. If null, default options will be used.
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
Exceptions
- InvalidOperationException
Thrown when the device is already connected.
- TimeoutException
Thrown if the connection attempt times out.
- OperationCanceledException
Thrown when the operation is cancelled.
ConnectIfNeededAsync(ConnectionOptions?, TimeSpan?, CancellationToken)
Connects to the device if it is not already connected asynchronously.
ValueTask ConnectIfNeededAsync(ConnectionOptions? connectionOptions = null, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
connectionOptionsConnectionOptionsThe connection options to use. If null, default options will be used.
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
Exceptions
- TimeoutException
Thrown if the connection attempt times out.
DisconnectAsync(TimeSpan?, CancellationToken)
Disconnects from the device asynchronously.
ValueTask DisconnectAsync(TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
Exceptions
- InvalidOperationException
Thrown when the device is not connected.
- TimeoutException
Thrown if the disconnection attempt times out.
- OperationCanceledException
Thrown when the operation is cancelled.
DisconnectIfNeededAsync(TimeSpan?, CancellationToken)
Disconnects from the device if it is not already disconnected asynchronously.
ValueTask DisconnectIfNeededAsync(TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
Exceptions
- TimeoutException
Thrown if the disconnection attempt times out.
ExploreServicesAsync(ServiceExplorationOptions?, TimeSpan?, CancellationToken)
Explores the services of the device asynchronously.
Task ExploreServicesAsync(ServiceExplorationOptions? options = null, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
optionsServiceExplorationOptionsOptional exploration configuration. If null, uses default options (services only, with caching enabled). Use ServicesOnly for services-only exploration, WithCharacteristics to include characteristics, or Full for full discovery (services + characteristics + descriptors). Set
UseCache = falseto force re-exploration even if services were previously discovered.timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- Task
A task that represents the asynchronous operation.
Remarks
Common Usage Patterns:
// Simple exploration (uses defaults: services only, with caching):
await device.ExploreServicesAsync();
// Explore services and characteristics: await device.ExploreServicesAsync(ServiceExplorationOptions.WithCharacteristics);
// Full exploration (services, characteristics, descriptors): await device.ExploreServicesAsync(ServiceExplorationOptions.Full);
// Force re-exploration (ignore cache): await device.ExploreServicesAsync(new() { UseCache = false });
// Custom options with UUID filtering:
await device.ExploreServicesAsync(new ServiceExplorationOptions
{
Depth = ExplorationDepth.Characteristics,
ServiceUuidFilter = uuid => uuid == myServiceUuid,
UseCache = false
});
Caching Behavior:
By default (options = null), caching is enabled (UseCache = true).
This means if services have already been explored, the method returns immediately
without re-querying the device. To force re-exploration, explicitly set UseCache = false.
Exceptions
- DeviceNotConnectedException
Thrown when the device is not connected.
- TimeoutException
Thrown when the operation times out.
- OperationCanceledException
Thrown when the operation is cancelled.
GetService(Func<IBluetoothRemoteService, bool>)
Gets the service that matches the specified filter.
IBluetoothRemoteService GetService(Func<IBluetoothRemoteService, bool> filter)
Parameters
filterFunc<IBluetoothRemoteService, bool>The filter to apply to the services.
Returns
- IBluetoothRemoteService
The service that matches the filter.
Exceptions
- ServiceNotFoundException
Thrown if no service matches the specified filter.
- MultipleServicesFoundException
Thrown if multiple services match the specified filter.
GetService(Guid)
Gets the service with the specified ID.
IBluetoothRemoteService GetService(Guid id)
Parameters
idGuidThe ID of the service to get.
Returns
- IBluetoothRemoteService
The service with the specified ID.
Exceptions
- ServiceNotFoundException
Thrown if no service with the specified ID is found.
- MultipleServicesFoundException
Thrown if multiple services match the specified filter.
GetServiceOrDefault(Func<IBluetoothRemoteService, bool>)
Gets the service that matches the specified filter.
IBluetoothRemoteService? GetServiceOrDefault(Func<IBluetoothRemoteService, bool> filter)
Parameters
filterFunc<IBluetoothRemoteService, bool>The filter to apply to the services.
Returns
- IBluetoothRemoteService
The service that matches the filter, or null if no such service exists.
Exceptions
- MultipleServicesFoundException
Thrown if multiple services match the specified filter.
GetServiceOrDefault(Guid)
Gets the service with the specified ID.
IBluetoothRemoteService? GetServiceOrDefault(Guid id)
Parameters
idGuidThe ID of the service to get.
Returns
- IBluetoothRemoteService
The service with the specified ID, or null if no such service exists.
Exceptions
- MultipleServicesFoundException
Thrown if multiple services match the specified filter.
GetServices(Func<IBluetoothRemoteService, bool>?)
Gets the services that match the specified filter.
IReadOnlyList<IBluetoothRemoteService> GetServices(Func<IBluetoothRemoteService, bool>? filter = null)
Parameters
filterFunc<IBluetoothRemoteService, bool>The filter to apply to the services.
Returns
- IReadOnlyList<IBluetoothRemoteService>
A read-only snapshot of services at the time of the call. This collection is immutable and will not be modified if services are added or removed after the call returns. To get updated results, call this method again or subscribe to ServiceListChanged event.
HasService(Func<IBluetoothRemoteService, bool>)
Determines whether the device has a service that matches the specified filter.
bool HasService(Func<IBluetoothRemoteService, bool> filter)
Parameters
filterFunc<IBluetoothRemoteService, bool>The filter to apply to the services.
Returns
- bool
True if a matching service exists; otherwise, false.
HasService(Guid)
Determines whether the device has a service with the specified ID.
bool HasService(Guid id)
Parameters
idGuidThe ID of the service to check for.
Returns
- bool
True if a service with the specified ID exists; otherwise, false.
OnAdvertisementReceived(IBluetoothAdvertisement)
Handles the advertisement information received event.
void OnAdvertisementReceived(IBluetoothAdvertisement advertisement)
Parameters
advertisementIBluetoothAdvertisementThe advertisement information received.
OpenL2CapChannelAsync(int, TimeSpan?, CancellationToken)
Opens an L2CAP channel to the specified PSM (Protocol Service Multiplexer). L2CAP channels provide connection-oriented data transfer with higher throughput than GATT.
ValueTask<IBluetoothRemoteL2CapChannel> OpenL2CapChannelAsync(int psm, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
psmintThe PSM value to connect to.
timeoutTimeSpan?The timeout for this operation.
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask<IBluetoothRemoteL2CapChannel>
A task that represents the asynchronous operation. The task result contains the opened L2CAP channel.
Remarks
Platform Support:
- iOS/macOS: Supported on iOS 11+ / macOS 10.13+ via CBPeripheral.openL2CAPChannel()
- Android: Supported on Android 10+ (API 29+) via BluetoothDevice.createL2capChannel()
- Windows: Not supported - throws PlatformNotSupportedException
L2CAP channels bypass GATT overhead and provide direct socket-like communication: - Higher throughput for bulk data transfer - Lower latency for time-sensitive data - Custom protocol implementation support
Valid PSM range is typically 0x0001-0x00FF (dynamic) or vendor-specific values.
Exceptions
- ArgumentOutOfRangeException
Thrown when
psmis invalid.- InvalidOperationException
Thrown when the device is not connected or L2CAP is not supported.
- TimeoutException
Thrown when the operation times out.
- OperationCanceledException
Thrown when the operation is cancelled.
ReadBatteryLevelAsync(TimeSpan?, CancellationToken)
Reads the battery level asynchronously.
ValueTask<double?> ReadBatteryLevelAsync(TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
timeoutTimeSpan?Optional timeout for service exploration and read operations.
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask<double?>
A task that represents the asynchronous operation. The task result contains the battery level percentage.
ReadFirmwareVersionAsync()
Reads the firmware version asynchronously.
Task<Version> ReadFirmwareVersionAsync()
Returns
- Task<Version>
A task that represents the asynchronous operation. The task result contains the firmware version.
ReadHardwareVersionAsync()
Reads the hardware version asynchronously.
Task<string> ReadHardwareVersionAsync()
Returns
- Task<string>
A task that represents the asynchronous operation. The task result contains the hardware version.
ReadSignalStrengthAsync(TimeSpan?, CancellationToken)
Reads the signal strength asynchronously. This is an operation running on a ticker when the device is connected. We can't get that value from advertisement anymore.
ValueTask<int> ReadSignalStrengthAsync(TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
Remarks
Platform Support:
- Android: Real-time RSSI reading via BluetoothGatt.readRemoteRssi() with callback
- iOS/macOS: Real-time RSSI reading via CBPeripheral.readRSSI() with delegate callback
- Windows: Limited support - RSSI may be cached or require periodic polling
Signal strength is measured in dBm (decibel-milliwatts): - Typical range: -100 dBm (very weak, ~100m) to -30 dBm (very strong, close proximity) - Values update based on radio conditions and may fluctuate - Accuracy varies by platform and hardware capabilities
Call frequency should be limited to avoid impacting performance - recommended interval: 1-5 seconds.
Returns the last known SignalStrengthInDbm without touching the radio when
IsSignalStrengthProbingEnabled is false.
Exceptions
- InvalidOperationException
Thrown when the device is not connected.
- TimeoutException
Thrown when the operation times out.
- OperationCanceledException
Thrown when the operation is cancelled.
ReadSoftwareVersionAsync()
Reads the software version asynchronously.
Task<Version> ReadSoftwareVersionAsync()
Returns
- Task<Version>
A task that represents the asynchronous operation. The task result contains the software version.
ReadVersionsAsync()
Reads all versions (firmware, software, and hardware) asynchronously.
Task ReadVersionsAsync()
Returns
- Task
A task that represents the asynchronous operation.
RequestConnectionPriorityAsync(ConnectionPriority, TimeSpan?, CancellationToken)
Requests a change in connection priority/performance mode for an active connection.
ValueTask RequestConnectionPriorityAsync(ConnectionPriority priority, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
priorityConnectionPriorityThe desired connection priority mode.
timeoutTimeSpan?The timeout for this operation.
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
Remarks
Platform Support:
- Android: Full support via BluetoothGatt.requestConnectionPriority()
- iOS/macOS: Connection parameters are system-managed. This method is a no-op.
- Windows: Connection parameters are system-managed. This method is a no-op.
On Android, this allows fine-tuning the connection parameters for different use cases: - High priority: Fast data transfer, low latency (11.25-15ms interval) - Balanced: Reasonable performance with moderate power (30-50ms interval) - Low power: Battery optimization, higher latency (100-125ms interval)
Changes typically take effect within a few connection intervals after the request.
Exceptions
- InvalidOperationException
Thrown when the device is not connected.
- TimeoutException
Thrown when the operation times out.
- OperationCanceledException
Thrown when the operation is cancelled.
RequestMtuAsync(int, TimeSpan?, CancellationToken)
Requests a new MTU size for the connection.
ValueTask<int> RequestMtuAsync(int requestedMtu, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
requestedMtuintThe desired MTU size (typically between 23 and 517 bytes).
timeoutTimeSpan?The timeout for this operation.
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask<int>
A task that represents the asynchronous operation. The task result contains the negotiated MTU size.
Remarks
Platform Support:
- Android: Full support for explicit MTU negotiation via BluetoothGatt.requestMtu() (range: 23-517 bytes, default: 23)
- iOS/macOS: MTU is automatically negotiated by the system. This method is a no-op and returns the current system-negotiated MTU.
- Windows: MTU is automatically negotiated via GATT session. This method returns the current negotiated value.
MTU (Maximum Transmission Unit) determines the maximum payload size per packet: - Larger MTU = fewer packets for large data transfers = better throughput - Default MTU is 23 bytes (20 bytes payload + 3 bytes ATT header) - Maximum MTU is typically 517 bytes but depends on hardware
The final MTU is negotiated between both devices and may be lower than requested.
Exceptions
- ArgumentOutOfRangeException
Thrown when
requestedMtuis out of valid range.- InvalidOperationException
Thrown when the device is not connected.
- TimeoutException
Thrown when the operation times out.
- OperationCanceledException
Thrown when the operation is cancelled.
SetPreferredPhyAsync(PhyMode, PhyMode, TimeSpan?, CancellationToken)
Requests a preferred PHY mode for the connection (Bluetooth 5.0+ feature).
ValueTask SetPreferredPhyAsync(PhyMode txPhy, PhyMode rxPhy, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
txPhyPhyModeThe desired transmit PHY mode.
rxPhyPhyModeThe desired receive PHY mode.
timeoutTimeSpan?The timeout for this operation.
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
Remarks
Platform Support:
- Android: Full support on Android 8.0 (API 26+) with Bluetooth 5.0 hardware via BluetoothGatt.setPreferredPhy()
- iOS/macOS: PHY selection is system-managed and automatic. This method is a no-op.
- Windows: Limited support - PHY is typically auto-negotiated by the system.
PHY modes affect range, speed, and power consumption: - 1M PHY: Standard mode with balanced range and throughput (1 Mbps) - 2M PHY: High-speed mode with reduced range (2 Mbps) - Coded PHY: Long-range mode with reduced throughput (~125-500 Kbps) but 4x range
The actual PHY used depends on negotiation with the remote device and hardware capabilities.
Exceptions
- InvalidOperationException
Thrown when the device is not connected or PHY mode is not supported.
- TimeoutException
Thrown when the operation times out.
- OperationCanceledException
Thrown when the operation is cancelled.
WaitForAdvertisementAsync(Func<IBluetoothAdvertisement?, bool>, TimeSpan?, CancellationToken)
Waits for advertisement information asynchronously.
ValueTask<IBluetoothAdvertisement> WaitForAdvertisementAsync(Func<IBluetoothAdvertisement?, bool> filter, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
filterFunc<IBluetoothAdvertisement, bool>The filter to apply to the advertisement information.
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask<IBluetoothAdvertisement>
A task that represents the asynchronous operation. The task result contains the advertisement information.
WaitForAdvertisementAsync(TimeSpan?, CancellationToken)
Waits for advertisement information asynchronously.
ValueTask<IBluetoothAdvertisement> WaitForAdvertisementAsync(TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask<IBluetoothAdvertisement>
A task that represents the asynchronous operation. The task result contains the advertisement information.
WaitForIsConnectedAsync(bool, TimeSpan?, CancellationToken)
Waits for the device to be connected or disconnected asynchronously.
ValueTask WaitForIsConnectedAsync(bool isConnected, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
isConnectedboolTrue to wait for the device to be connected, false to wait for it to be disconnected.
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
WaitForNameToChangeAsync(TimeSpan?, CancellationToken)
Waits for the name of the device to change asynchronously.
ValueTask WaitForNameToChangeAsync(TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
timeoutTimeSpan?The timeout for this operation
cancellationTokenCancellationTokenA cancellation token to cancel this operation.
Returns
- ValueTask
A task that represents the asynchronous operation.
Exceptions
- TimeoutException
Thrown when the operation times out.
- OperationCanceledException
Thrown when the operation is cancelled.
Events
AdvertisementReceived
Occurs when advertisement information is received.
event EventHandler<AdvertisementReceivedEventArgs> AdvertisementReceived
Event Type
Connected
Occurs when the device is connected.
event EventHandler Connected
Event Type
Connecting
Occurs when the device is connecting.
event EventHandler Connecting
Event Type
ConnectionStateChanged
Occurs when the connection state of the device changes.
event EventHandler<DeviceConnectionStateChangedEventArgs> ConnectionStateChanged
Event Type
Disconnected
Occurs when the device is disconnected.
event EventHandler Disconnected
Event Type
Disconnecting
Occurs when the device is disconnecting.
event EventHandler Disconnecting
Event Type
MtuChanged
Event raised when the MTU changes.
event EventHandler<MtuChangedEventArgs>? MtuChanged
Event Type
PhyChanged
Event raised when the PHY changes.
event EventHandler<PhyChangedEventArgs>? PhyChanged
Event Type
ServiceListChanged
Occurs when the service list changes.
event EventHandler<ServiceListChangedEventArgs>? ServiceListChanged
Event Type
ServicesAdded
Event triggered when services are added.
event EventHandler<ServicesAddedEventArgs>? ServicesAdded
Event Type
ServicesRemoved
Event triggered when services are removed.
event EventHandler<ServicesRemovedEventArgs>? ServicesRemoved
Event Type
UnexpectedDisconnection
Occurs when an unexpected disconnection happens.
event EventHandler<DeviceUnexpectedDisconnectionEventArgs> UnexpectedDisconnection