Bluetooth Classic for Flutter
Discover, pair and exchange data with Bluetooth Classic devices over RFCOMM, the Serial Port Profile, from one Dart API.
Install#
flutter pub add flutter_classic_bluetoothimport 'package:flutter_classic_bluetooth/flutter_classic_bluetooth.dart';Bluetooth Classic, not Bluetooth Low Energy#
This plugin speaks RFCOMM/SPP: the classic Bluetooth serial transport that ESP32 boards, HC-05 modules, barcode scanners, thermal printers and OBD-II adapters use. It is not a BLE plugin. If your device advertises GATT services and characteristics, you want a Bluetooth Low Energy package instead.
A connection is a plain byte stream. Reading and writing feels like any other Dart Stream and Sink.
Connect and talk to a device#
final bluetooth = FlutterClassicBluetooth();
final connection = await bluetooth.connect(
address: 'AA:BB:CC:DD:EE:FF',
uuid: BtcUuid.spp,
);
connection.input.listen((bytes) => print('RX ${bytes.length} bytes'));
await connection.output.writeString('AT');
await connection.finish();Find a device first#
final devices = await bluetooth.scan(timeout: const Duration(seconds: 10));
for (final device in devices) {
print('${device.displayName} ${device.address} ${device.rssi} dBm');
}scan collects discovery results, deduplicates them by address and sorts by signal strength. For a live list that fills in as devices appear, listen to the discovery stream instead.
What it can do#
- Check and request the Bluetooth permissions each platform needs, with no extra package.
- Discover nearby devices and list the ones already paired.
- Connect over RFCOMM by MAC address and service UUID, then read and write bytes.
- Run an RFCOMM server that accepts incoming connections.
- Pair and unpair, toggle the adapter, and make the device discoverable, where the platform allows it.
- Reconnect automatically with a backoff policy when a link drops.
- Ask at runtime which of those the current platform actually supports.
Where it runs#
| Platform | Backend | Notes |
|---|---|---|
| Android | BluetoothSocket | Everything, including server mode |
| Windows | Winsock2 AF_BTH | No unpair |
| macOS | IOBluetooth | Unpair via System Settings only |
| Linux | BlueZ RFCOMM | Pairing needs a system agent |
| iOS | ExternalAccessory | MFi accessories only, no discovery |
Rather than guessing, ask:
final caps = await bluetooth.getPlatformCapabilities();
if (caps.canDiscoverDevices) {
// show the scan button
}See the desktop guide for what differs on Windows, macOS and Linux.
Start here#
Set up permissions first, since nothing works without them on Android. Then scan, connect, and move some bytes. If you are wiring up a specific board, jump straight to ESP32, HC-05, or a thermal printer.