Bluetooth
Classic Bluetooth and Bluetooth LE printers, and the permissions on each platform.
Transports per platform
Android, macOS, Windows and Linux print over classic Bluetooth and Bluetooth LE through one call. iOS gives apps Bluetooth LE only.
| Platform | Bluetooth | What the app declares or asks for |
|---|---|---|
| iOS | Bluetooth LE only | NSBluetoothAlwaysUsageDescription, NSLocalNetworkUsageDescription (Info.plist) |
| Android | Classic Bluetooth and Bluetooth LE | BLUETOOTH_SCAN, BLUETOOTH_CONNECT (Android 12+); ACCESS_FINE_LOCATION (Android 11 and earlier) |
| macOS | Classic Bluetooth and Bluetooth LE | NSBluetoothAlwaysUsageDescription (Info.plist) |
| Windows | Classic Bluetooth and Bluetooth LE | — |
| Linux, Raspberry Pi | Classic Bluetooth and Bluetooth LE | — |
iOS
On iOS sPrint prints to Bluetooth LE printers only. A printer that has classic Bluetooth only is refused with the error "not reachable on iOS (classic Bluetooth only)", so it is never missed without a reason. Add the Bluetooth and local network usage descriptions to Info.plist.
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Prints labels on Bluetooth printers.</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Prints on printers on this network.</string>
Android
The library declares the Bluetooth, location (Android 11 and earlier), USB and network permissions. The app asks for the runtime permissions before a Bluetooth scan.
// Kotlin
requestPermissions(Discovery.bluetoothPermissions(), 1)
// Dart / Flutter
final granted = await Discovery.requestBluetoothPermissions();
Finding Bluetooth printers
Discovery lists every Bluetooth device found: the bonded devices, a classic inquiry and a Bluetooth LE scan, merged per device. Nothing is dropped by its name or its services. Likely printers and known models are marked and listed first.
// Dart / Flutter
final nearby = await Discovery.nearbyBluetoothPrinters(scanMs: 8000); // classic and LE, each printer once
final printers = nearby.where((p) => p.likelyPrinter).toList();
// Swift
let nearby = try Discovery.nearbyBluetoothPrinters(scanMs: 8000) // LE only on iOS
// Kotlin
val nearby = Discovery.nearbyBluetooth(context, scanMs = 8000)
# Python
bonded = Discovery.bluetooth_printers() # bonded; scan_ms adds an inquiry
le = Discovery.ble_printers(scan_ms=4000)
// C# / .NET
var bonded = Discovery.BluetoothPrinters();
var le = Discovery.BlePrinters(4000);
Each printer found lists the transports it was seen on. sPrint drives it over the transport it prefers for that printer: Bluetooth LE for XPP printers, otherwise classic Bluetooth when the printer is already bonded, else Bluetooth LE.
Pairing
A printer that asks to pair on its first connection gets time for the user's answer: 30 seconds on Android and 40 seconds on iOS.
An XPP printer over Bluetooth LE without a set width is drawn 832 dots wide at 203 dpi.