Flutter Classic Bluetooth

pub package License: MIT Flutter Dart

A Flutter plugin for Bluetooth Classic (RFCOMM) communication.
Discover, pair, connect, and exchange data across Android, iOS (MFi), Windows, macOS, and Linux.

Features

  • ๐Ÿ” Device Discovery โ€” Scan for nearby Bluetooth Classic devices
  • ๐Ÿ”— Pair / Unpair โ€” Bond and unbond devices programmatically
  • ๐Ÿ“ก RFCOMM Connect โ€” Establish serial connections with data streaming
  • ๐Ÿ–ฅ๏ธ Server Mode โ€” Accept incoming RFCOMM connections
  • ๐Ÿ”„ Multiple Connections โ€” Manage several simultaneous connections
  • ๐Ÿ“Š Stream-Based I/O โ€” Read/write with Dart streams and ordered sinks
  • ๐Ÿงฉ Platform Capabilities โ€” Query feature support at runtime per platform
  • โšก Typed Exceptions โ€” Structured error hierarchy for clean error handling

Platform Support

Feature Android Windows macOS Linux iOS
Discover devices โœ… โœ… โœ… โœ… โŒ
Get paired devices โœ… โœ… โœ… โœ… โœ…ยน
Pair / Unpair โœ… โœ… โœ… โŒยฒ โŒ
Connect (RFCOMM) โœ… โœ… โœ… โœ… โœ…ยน
Server mode โœ… โœ… โœ… โœ… โŒ
Enable / Disable โœ… โŒ โŒ โŒ โŒ
Set discoverable โœ… โŒ โŒ โœ… โŒ

ยน iOS uses the ExternalAccessory framework โ€” only MFi-certified accessories are supported.
ยฒ Linux pairing requires BlueZ D-Bus agent (use bluetoothctl or system settings).

Installation

dependencies:
  flutter_classic_bluetooth: ^0.1.0

Quick Start

import 'package:flutter_classic_bluetooth/flutter_classic_bluetooth.dart';

final bluetooth = FlutterClassicBluetooth();

Check Support & Capabilities

final supported = await bluetooth.isSupported();
final enabled = await bluetooth.isEnabled();
final caps = await bluetooth.getPlatformCapabilities();

if (caps.canDiscoverDevices) {
  await bluetooth.startDiscovery();
}

Discover Devices

bluetooth.discoveryResults.listen((device) {
  print('Found: ${device.displayName} (${device.address})');
});

await bluetooth.startDiscovery();
// ...
await bluetooth.stopDiscovery();

Connect & Communicate

final connection = await bluetooth.connect(
  address: 'AA:BB:CC:DD:EE:FF',
  uuid: '00001101-0000-1000-8000-00805F9B34FB',
);

// Receive data
connection.input.listen((data) {
  print('Received ${data.length} bytes');
});

// Send data
await connection.output.add(Uint8List.fromList([0x01, 0x02, 0x03]));

// Disconnect (waits for pending writes)
await connection.finish();

Server Mode

final server = await bluetooth.startServer(
  uuid: '00001101-0000-1000-8000-00805F9B34FB',
  serviceName: 'MyService',
);

server.connections.listen((connection) {
  print('Client connected: ${connection.address}');
  connection.input.listen((data) => print('Data: $data'));
});

Paired Devices

final devices = await bluetooth.getPairedDevices();
for (final device in devices) {
  print('${device.displayName} โ€” ${device.address}');
}

API Overview

Core Classes

Class Purpose
FlutterClassicBluetooth Main entry point โ€” adapter, discovery, pairing, connection, server
BtcDevice Represents a remote Bluetooth device
BtcConnection Active RFCOMM connection with input/output streams
BtcServerSocket Listens for incoming RFCOMM connections
BtcStreamSink Ordered write sink for a connection
BtcPlatformCapabilities Platform feature support matrix

Enums

Enum Purpose
BtcAdapterState Adapter on/off/transitioning states
BtcBondState Device pairing state
BtcDeviceType Classic, LE, or Dual-mode
BtcConnectionState Connection lifecycle states

Exceptions

All exceptions extend BtcException:

Exception When
BtcUnsupportedException Feature not available on platform
BtcPermissionException Permission denied
BtcDisabledException Adapter is off
BtcConnectionException Connection failed
BtcWriteException Write failed
BtcTimeoutException Operation timed out
BtcAddressException Invalid MAC address
BtcUuidException Invalid UUID

Error Handling

try {
  await bluetooth.connect(address: addr, uuid: uuid);
} on BtcUnsupportedException catch (e) {
  print('${e.feature} not supported on ${e.platform}');
} on BtcDisabledException {
  print('Turn on Bluetooth first');
} on BtcConnectionException catch (e) {
  print('Connection failed: ${e.message}');
}

Android Setup

Add Bluetooth permissions to AndroidManifest.xml:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

iOS Setup

Add to Info.plist:

<key>UISupportedExternalAccessoryProtocols</key>
<array>
  <string>com.example.protocol</string>
</array>

Note: iOS only supports MFi-certified Bluetooth accessories via the ExternalAccessory framework. The uuid parameter in connect() is used as the MFi protocol string on iOS.

Examples

Check out the example directory for a complete demo app with 7 screens showcasing all features.

License

MIT License โ€” see LICENSE for details.


Made with โค๏ธ by Masum

Libraries

flutter_classic_bluetooth
Flutter Classic Bluetooth โ€” Bluetooth Classic (RFCOMM) communication plugin.