DEV Community

Cover image for Mastering Flutter: Bluetooth use
TheOtherDev/s
TheOtherDev/s

Posted on

Mastering Flutter: Bluetooth use

Let's face it, we are living in a connected world in which also physical objects can be used with software. Today we are going to dive into this world by looking at one of the most common ways to connect to devices: bluetooth.

flutter_blue

To enable bluetooth connectivity with your Flutter app you should consider using this package as it is the most used one. You can obviously create a custom plugin if you have specific needs but this one will be ok for most cases.

To start add it to your pubspec.yaml file:

flutter_blue: ^0.8.0
Enter fullscreen mode Exit fullscreen mode

then add these permissions for Android:

  <uses-permission android:name="android.permission.BLUETOOTH" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

Enter fullscreen mode Exit fullscreen mode

Also in the ios/Runner/Info.plist 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>
Enter fullscreen mode Exit fullscreen mode

For location permissions on iOS see more at: https://developer.apple.com/documentation/corelocation/requesting_authorization_for_location_services

Usage

The main goal of a bluetooth connection is to connect to a device, discover its services and write/read data from it. First thing first we need to find our device so let's do a good old scan!

FlutterBlue flutterBlue = FlutterBlue.instance;
flutterBlue.startScan(timeout: Duration(seconds: 4));

// Listen to scan results
var subscription = flutterBlue.scanResults.listen((results) {
    for (ScanResult r in results) {
           if(r.uuid == [YOUR DEVICE ID]){
               // Connect to the device
               await r.device.connect();

               // Disconnect from device
               r.device.disconnect();
           }
    }
});
Enter fullscreen mode Exit fullscreen mode

 To stop just

flutterBlue.stopScan();

Enter fullscreen mode Exit fullscreen mode

While you should not connect-disconnect so quickly you can see that doing it is a piece of cake.

When you are connected then you should discover device services this way:

List<BluetoothService> services = await device.discoverServices();

Enter fullscreen mode Exit fullscreen mode

Then, as each service has n characteristics, you can check all of them this way;

var characteristics = service.characteristics;

Enter fullscreen mode Exit fullscreen mode

With characteristics then you can pretty much do whatever you want like read or write:

List<int> value = await characteristic.read();
await characteristic.write([0x12, 0x34])
Enter fullscreen mode Exit fullscreen mode

We can do the same with the characteristic descriptors:

var descriptors = characteristic.descriptors;

List<int> value = await descriptor.read();
await descriptor.write([0x12, 0x34])

Enter fullscreen mode Exit fullscreen mode

Last, but not least, we can also listen to characteristics changes this way:

await characteristic.setNotifyValue(true);
characteristic.value.listen((value) {
    // do something with new value
});

Enter fullscreen mode Exit fullscreen mode

Conclusions

There you are, you can now work with bluetooth on Flutter. Be aware that Android and iOS behaviors can be a bit different, for example Android tends to cache manufacturer data so you should add "allowDuplicates" to obtain them always. Feel free to explore and experiment!

Want to check more awesome Flutter tutorials? Click here!

Discussion (0)