flutter_blue_plus 1.10.8
flutter_blue_plus: ^1.10.8 copied to clipboard
Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android, iOS, and MacOS.
Note: this plugin is continuous work from FlutterBlue since maintenance stopped.
Introduction #
FlutterBluePlus is a bluetooth plugin for Flutter, a new app SDK to help developers build modern multi-platform apps.
Cross-Platform Bluetooth LE #
FlutterBluePlus aims to offer the most from all supported platforms: iOS, macOS, Android.
The code is written to be simple, robust, and incredibly easy to understand.
No Dependencies #
FlutterBluePlus has zero dependencies besides Flutter, Android, and iOS themselves.
This makes FlutterBluePlus very stable.
Usage #
Error Handling π₯ #
Flutter Blue Plus takes error handling very seriously.
Every error returned by the native platform is checked and thrown as an exception where appropriate.
Streams: At the time of writing, streams returned by Flutter Blue Plus never emit any errors and never close. There's no need to handle onError
or onDone
for stream.listen(...)
.
See the Reference section below for a complete list of throwing function.
Enable Bluetooth #
// check availability
if (await FlutterBluePlus.isAvailable() == false) {
print("Bluetooth not supported by this device");
return;
}
// turn on bluetooth ourself if we can
if (Platform.isAndroid) {
await FlutterBluePlus.turnOn();
}
// wait bluetooth to be on
await FlutterBluePlus.adapterState.where((s) => s == BluetoothAdapterState.on).first;
Scan for devices #
// Setup Listener for scan results
var subscription = FlutterBluePlus.scanResults.listen((results) {
// do something with scan results
for (ScanResult r in results) {
print('${r.device.localName} found! rssi: ${r.rssi}');
}
});
// Start scanning
FlutterBluePlus.startScan(timeout: Duration(seconds: 4));
// Stop scanning
FlutterBluePlus.stopScan();
Connect to a device #
// Connect to the device
await device.connect();
// Disconnect from device
device.disconnect();
Discover services #
List<BluetoothService> services = await device.discoverServices();
services.forEach((service) {
// do something with service
});
Read and write characteristics #
// Reads all characteristics
var characteristics = service.characteristics;
for(BluetoothCharacteristic c in characteristics) {
List<int> value = await c.read();
print(value);
}
// Writes to a characteristic
await c.write([0x12, 0x34])
Read and write descriptors #
// Reads all descriptors
var descriptors = characteristic.descriptors;
for(BluetoothDescriptor d in descriptors) {
List<int> value = await d.read();
print(value);
}
// Writes to a descriptor
await d.write([0x12, 0x34])
Set notifications and listen to changes #
// Setup Listener for characteristic reads
characteristic.onValueReceived.listen((value) {
// do something with new value
});
// enable notifications
await characteristic.setNotifyValue(true);
Read the MTU and request larger size #
final mtu = await device.mtu.first;
await device.requestMtu(512);
Note that iOS will not allow requests of MTU size, and will always try to negotiate the highest possible MTU (iOS supports up to MTU size 185)
Getting Started #
Change the minSdkVersion for Android #
flutter_blue_plus is compatible only from version 19 of Android SDK so you should change this in android/app/build.gradle:
Android {
defaultConfig {
minSdkVersion: 19
Add permissions for Bluetooth #
We need to add the permission to use Bluetooth and access location:
Android
In the android/app/src/main/AndroidManifest.xml letβs add:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
As of Android 12, ACCESS_FINE_LOCATION is no longer required. However, if you need to determine the physical location of the device via Bluetooth, you must add this permission to your android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
and set the androidUsesFineLocation flag to true when scanning:
// Start scanning
flutterBlue.startScan(timeout: Duration(seconds: 4), androidUsesFineLocation: true);
// Stop scanning
flutterBlue.stopScan();
IOS
In the ios/Runner/Info.plist letβs add:
<dict>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Need BLE permission</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Need BLE permission</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Need Location permission</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Need Location permission</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Need Location permission</string>
For location permissions on iOS see more at: https://developer.apple.com/documentation/corelocation/requesting_authorization_for_location_services
Reference #
FlutterBlue API #
Android | iOS | Throws | Description | |
---|---|---|---|---|
adapterState | β | β | Stream of state changes for the bluetooth adapter | |
isAvailable | β | β | Checks whether the device supports Bluetooth | |
isOn | β | β | Checks if Bluetooth adapter is turned on | |
turnOn | β | π₯ | Turns on the bluetooth adapter | |
turnOff | β | π₯ | Turns off the bluetooth adapter | |
scan | β | β | π₯ | Starts a scan for Ble devices and returns a stream |
startScan | β | β | π₯ | Starts a scan for Ble devices with no return value |
stopScan | β | β | π₯ | Stop an existing scan for Ble devices |
scanResults | β | β | Stream of live scan results | |
isScanning | β | β | Stream of current scanning state | |
isScanningNow | β | β | Is a scan currently running? | |
connectedDevices | β | β | List of already connected devices, even by other apps | |
setLogLevel | β | β | Configure plugin log level |
BluetoothDevice API #
Android | iOS | Throws | Description | |
---|---|---|---|---|
localName | β | β | The cached localName of the device | |
connect | β | β | π₯ | Establishes a connection to the device |
disconnect | β | β | π₯ | Cancels an active or pending connection to the device |
discoverServices | β | β | π₯ | Discover services |
servicesList | β | β | π₯ | Get services. Calls discoverServices for you, if needed |
isDiscoveryingServices | β | β | Stream of whether service discovery is in progress | |
servicesStream | β | β | Stream of service changes | |
connectionState | β | β | Stream of connection changes for the Bluetooth Device | |
mtu | β | β | π₯ | Stream of mtu size changes |
readRssi | β | β | π₯ | Read RSSI from a connected device |
requestMtu | β | π₯ | Request to change the MTU for the device | |
requestConnectionPriority | β | π₯ | Request to update a high priority, low latency connection | |
pair | β | π₯ | Calls createBond on a device | |
removeBond | β | π₯ | Remove Bluetooth Bond of device | |
setPreferredPhy | β | Set preferred RX and TX phy for connection and phy options | ||
clearGattCache | β | π₯ | Clear android cache of service discovery results |
BluetoothCharacteristic API #
Android | iOS | Throws | Description | |
---|---|---|---|---|
uuid | β | β | The uuid of characeristic | |
read | β | β | π₯ | Retrieves the value of the characteristic |
write | β | β | π₯ | Writes the value of the characteristic |
setNotifyValue | β | β | π₯ | Sets notifications or indications on the characteristic |
isNotifying | β | β | Are notifications or indications currently enabled | |
onValueReceived | β | β | Stream of characteristic value updates received from the device | |
lastValue | β | β | The most recent value of the characteristic | |
lastValueStream | β | β | Stream of lastValue + onValueReceived |
BluetoothDescriptor API #
Android | iOS | Throws | Description | |
---|---|---|---|---|
uuid | β | β | The uuid of descriptor | |
read | β | β | π₯ | Retrieves the value of the descriptor |
write | β | β | π₯ | Writes the value of the descriptor |
onValueReceived | β | β | Stream of descriptor value reads & writes | |
lastValue | β | β | The most recent value of the descriptor | |
lastValueStream | β | β | Stream of lastValue + onValueReceived |
Troubleshooting #
The easiest way to debug issues in FlutterBluePlus is to first make local copy.
cd /user/downloads
git clone https://github.com/boskokg/flutter_blue_plus.git
then in pubspec.yaml
add the repo by path:
flutter_blue_plus:
path: /user/downloads/flutter_blue_plus
Now you can edit FlutterBluePlus code and debug issues yourself.
When I scan using a service UUID filter, it doesn't find any devices. #
Make sure the device is advertising which service UUID's it supports. This is found in the advertisement packet as UUID 16 bit complete list or UUID 128 bit complete list.