DSoft.System.BluetoothLe
3.0.2607.92
dotnet add package DSoft.System.BluetoothLe --version 3.0.2607.92
NuGet\Install-Package DSoft.System.BluetoothLe -Version 3.0.2607.92
<PackageReference Include="DSoft.System.BluetoothLe" Version="3.0.2607.92" />
<PackageVersion Include="DSoft.System.BluetoothLe" Version="3.0.2607.92" />
<PackageReference Include="DSoft.System.BluetoothLe" />
paket add DSoft.System.BluetoothLe --version 3.0.2607.92
#r "nuget: DSoft.System.BluetoothLe, 3.0.2607.92"
#:package DSoft.System.BluetoothLe@3.0.2607.92
#addin nuget:?package=DSoft.System.BluetoothLe&version=3.0.2607.92
#tool nuget:?package=DSoft.System.BluetoothLe&version=3.0.2607.92
DSoft.System.BluetoothLe
DSoft.System.BluetoothLe is a cross-platform Bluetooth Low Energy library for modern .NET. It provides one API for scanning, connecting, discovering GATT services/characteristics, reading, writing, and receiving characteristic updates across mobile and desktop targets.
The library started as a fork/repackage of Plugin.BLE and has been migrated from Xamarin targets to .NET platform targets.
Supported Targets
| Target | Minimum OS |
|---|---|
net10.0-android |
Android API 21 |
net10.0-ios |
iOS 12.2 |
net10.0-maccatalyst |
Mac Catalyst 15.0 |
net10.0-macos |
macOS 12.0 |
net10.0-tvos |
tvOS 12.2 |
net10.0-windows10.0.19041.0 |
Windows 10 1809 |
net481 |
Windows 10 1809 |
net10.0 / netstandard2.0 |
API surface only; platform Bluetooth calls throw on unsupported platforms |
Install
Reference the package from your app project:
<PackageReference Include="DSoft.System.BluetoothLe" Version="1.0.0" />
When working from source, reference the project:
<ProjectReference Include="..\DSoft.System.BluetoothLe\DSoft.System.BluetoothLe.csproj" />
Use the library from the System.BluetoothLe namespace:
using System.BluetoothLe;
using System.BluetoothLe.EventArgs;
Platform Setup
Your app must request the operating-system permissions needed for Bluetooth. The library does not replace runtime permission prompts or app manifest entries.
Android
Add Bluetooth permissions to your Android manifest. For Android 12/API 31 and later, apps normally need BLUETOOTH_SCAN and BLUETOOTH_CONNECT. Older Android versions commonly require BLUETOOTH, BLUETOOTH_ADMIN, and location permission for scanning.
Example manifest entries:
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
Request dangerous permissions at runtime before scanning or connecting.
iOS, macOS, Mac Catalyst, tvOS
Add Bluetooth usage descriptions to your app's Info.plist where required by the platform:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to connect to nearby BLE devices.</string>
For iOS background BLE scenarios, also configure the appropriate background modes in your app.
Windows
Windows support uses the Windows Runtime Bluetooth APIs. The .NET for Windows and .NET Framework implementations share the same implementation and require Windows 10 1809 or later with a Bluetooth LE-capable adapter.
Packaged Windows apps should declare the Bluetooth capability in the app manifest. Desktop WPF apps should still handle unavailable Bluetooth hardware/radio states at runtime.
Quick Start
Get the current platform implementation:
var bluetooth = BluetoothLE.Current;
if (!bluetooth.IsAvailable)
{
throw new InvalidOperationException("Bluetooth LE is not available on this device.");
}
if (!bluetooth.IsOn)
{
throw new InvalidOperationException("Bluetooth is not turned on.");
}
var adapter = bluetooth.Adapter;
Scan for devices:
var adapter = BluetoothLE.Current.Adapter;
adapter.DeviceDiscovered += (sender, args) =>
{
Console.WriteLine($"Found {args.Device.NameOrId} ({args.Device.Id}) RSSI {args.Device.Rssi}");
};
adapter.ScanTimeout = 10000;
adapter.ScanMode = ScanMode.LowLatency;
await adapter.StartScanningForDevicesAsync();
Scan for devices that advertise a service:
var heartRateService = Guid.Parse("0000180d-0000-1000-8000-00805f9b34fb");
await adapter.StartScanningForDevicesAsync(
serviceUuids: new[] { heartRateService },
deviceFilter: device => !string.IsNullOrWhiteSpace(device.Name),
allowDuplicatesKey: false);
Connect to a discovered device:
var device = adapter.DiscoveredDevices.FirstOrDefault();
if (device == null)
{
throw new InvalidOperationException("No BLE device was discovered.");
}
await adapter.ConnectToDeviceAsync(device);
Connect to a known device by id:
var knownDeviceId = Guid.Parse("00000000-0000-0000-0000-000000000000");
var device = await adapter.ConnectToKnownDeviceAsync(knownDeviceId);
Discover services and characteristics:
var services = await device.GetServicesAsync();
foreach (var service in services)
{
Console.WriteLine($"{service.Name}: {service.Id}");
var characteristics = await service.GetCharacteristicsAsync();
foreach (var characteristic in characteristics)
{
Console.WriteLine($" {characteristic.Name}: {characteristic.Id} ({characteristic.Properties})");
}
}
Read and write a characteristic:
var serviceId = Guid.Parse("0000180d-0000-1000-8000-00805f9b34fb");
var characteristicId = Guid.Parse("00002a37-0000-1000-8000-00805f9b34fb");
var service = await device.GetServiceAsync(serviceId);
var characteristic = await service.GetCharacteristicAsync(characteristicId);
if (characteristic.CanRead)
{
byte[] value = await characteristic.ReadAsync();
}
if (characteristic.CanWrite)
{
await characteristic.WriteAsync(new byte[] { 0x01, 0x02, 0x03 });
}
Subscribe to characteristic updates:
characteristic.ValueUpdated += (sender, args) =>
{
var value = args.Characteristic.Value;
Console.WriteLine(BitConverter.ToString(value));
};
await characteristic.StartUpdatesAsync();
// Later:
await characteristic.StopUpdatesAsync();
Disconnect:
await adapter.DisconnectDeviceAsync(device);
Useful API Surface
BluetoothLE.Current: singleton entry point for the current platform.BluetoothLE.State,IsAvailable,IsOn: current Bluetooth state.BluetoothLE.StateChanged: Bluetooth state notifications.Adapter.StartScanningForDevicesAsync: scan for BLE devices.Adapter.DeviceDiscovered: raised the first time a device is discovered during a scan.Adapter.DeviceAdvertised: raised for matching advertisements.Adapter.ConnectToDeviceAsync: connect to a discovered device.Adapter.ConnectToKnownDeviceAsync: connect directly by known platform device id.Device.GetServicesAsync: discover GATT services.Service.GetCharacteristicsAsync: discover GATT characteristics.Characteristic.ReadAsync,WriteAsync,StartUpdatesAsync,StopUpdatesAsync: interact with characteristic values.Descriptor.ReadAsync,WriteAsync: interact with descriptors.
Notes
- BLE device identifiers are platform-specific. Persist known device ids only for the same platform/device context.
- Scanning and connecting require OS permissions and Bluetooth hardware. Always handle
BluetoothState.UnavailableandBluetoothState.Off. net10.0andnetstandard2.0builds keep the shared API available, but platform Bluetooth operations require a supported platform target.- Some Android and CoreBluetooth APIs used by the migrated implementation are marked obsolete by newer SDK analyzers. The library currently preserves the existing behavior while the platform-specific implementations continue to be modernized.
Building From Source
Restore and build the active solution with the .NET 10 SDK:
dotnet restore DSoft.System.BluetoothLe.sln
dotnet build DSoft.System.BluetoothLe.sln --no-restore
The old DSoft.System.BluetoothLeOld project remains in the repository as migration reference material, but the active solution builds the migrated DSoft.System.BluetoothLe project.
Relationship To Plugin.BLE
This project keeps the broad shape of Plugin.BLE but uses:
- Namespace:
System.BluetoothLe - Entry point:
BluetoothLE.Current - Multi-targeted partial classes instead of the original base-class layout
Existing Plugin.BLE concepts map closely to this library, but code should be updated to the names above.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-android36.0 is compatible. net10.0-browser was computed. net10.0-ios was computed. net10.0-ios26.0 is compatible. net10.0-maccatalyst was computed. net10.0-maccatalyst26.0 is compatible. net10.0-macos was computed. net10.0-macos26.0 is compatible. net10.0-tvos was computed. net10.0-tvos26.0 is compatible. net10.0-windows was computed. net10.0-windows10.0.19041 is compatible. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8.1
- Microsoft.Windows.SDK.Contracts (>= 10.0.18362.2007)
-
.NETStandard 2.0
- No dependencies.
-
net10.0
- No dependencies.
-
net10.0-android36.0
- No dependencies.
-
net10.0-ios26.0
- No dependencies.
-
net10.0-maccatalyst26.0
- No dependencies.
-
net10.0-macos26.0
- No dependencies.
-
net10.0-tvos26.0
- No dependencies.
-
net10.0-windows10.0.19041
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.2607.92 | 0 | 7/9/2026 |
| 2.0.2110.291 | 2,877 | 10/30/2021 |
| 2.0.2109.301 | 579 | 9/30/2021 |
| 2.0.2108.171 | 590 | 8/17/2021 |
| 2.0.2107.141 | 608 | 7/14/2021 |
| 2.0.2107.132 | 596 | 7/13/2021 |
| 2.0.2107.131 | 575 | 7/13/2021 |
| 2.0.2106.104 | 700 | 6/15/2021 |
| 2.0.2010.51-prerelease | 643 | 10/5/2020 |
| 2.0.2010.21-prerelease | 608 | 10/2/2020 |
| 2.0.2009.301-prerelease | 533 | 9/30/2020 |
| 2.0.2006.222-prerelease | 569 | 6/22/2020 |
| 2.0.2006.191-prerelease | 620 | 6/19/2020 |
| 2.0.2006.181-prerelease | 591 | 6/18/2020 |
| 2.0.2006.152-prerelease | 630 | 6/15/2020 |
| 1.0.2006.52 | 824 | 6/5/2020 |
Migrated to .NET 10.0