Connecting BLE Devices with Flutter (Part 1) – Bluetooth State

Introduction 

Nowadays, Bluetooth is a necessary feature required in any smartphone.  Gadget development is rising, and each new gadget needs to be synced with the consumer’s mobile phones. This influx of production and development means that each gadget has its own set of unique uses, such as various kinds of wearables and smartwatches, wireless earbuds, stereo systems, etc. All these BLE devices come with an embedded application vital for the devices’ connectivity with mobile phones. These applications can be made on multiple frameworks such as Native, Flutter, React, etc. And can control the device’s Bluetooth state, connectivity, and many other features. 

The application can control all administrative and consumer-based features of BLE device, such as performing the firmware upgrade, syncing time and date, changing the theme of a wearable, or music settings for an audio device.  

In this blog series, we will learn how to build a mobile application that will connect to a specific Bluetooth device and perform various operations in sync with it. In the first tutorial, we will be setting up our Bluetooth package and OS-level permissions. We will also get the Bluetooth permissions from the user and constantly keep an eye on the devices’ Bluetooth state. We will also implement the functionality of turning the device’s Bluetooth on or off directly from the mobile application for the Android operating system! 

Framework 

This tutorial is divided into multiple parts. In part 1 of our tutorial, we will work on the front-end application. The front-end application will be developed on the Flutter Framework for iOS and Android platforms. 

In the future, we may require back-end services that can be developed using Node.js for the web APIs and Cosmos DB hosted on either Azure or AWS (Amazon Web Services) platforms. 

Packages 

The following packages are used and added in our projects pubspec.yaml file: 

  1. https://pub.dev/packages/flutter_blue_plus 
  2. https://pub.dev/packages/permission_handler 

There are other BLE-related packages available in the pub.dev repository. However, we are using the Flutter Blue Plus package as it is a more updated and maintained version of the most popular BLE package on the pub store, Flutter Blue.  

On the other hand, the permission handler package is the best library on the market for handling OS-level permissions for all frameworks supported by Flutter and works seamlessly for Bluetooth integrations. 

Setup 

The permission handler package does not require any OS-level permissions by itself. A certain code must be added to use Bluetooth services on both iOS and Android. 

iOS 

It is important to add the following permissions inside the info.plist file in your iOS project. All code must be added within the ‘dict’ tag.

iOS 

Android 

For Android, the setup is quite simple but takes up more time. We must first add the following permissions inside the AndroidManifest.xml file within the ‘application’ tag. 

Android 

The ‘BLUETOOTH_CONNECT’ permission is only used for Android SDK API level 31 and above (mainly Android 12 and the version above it). The rest of the Bluetooth permissions are used for API levels 30 and less. Location permissions will come in handy later. 

Next, the minimum and target SDK versions must be set to at least 19 and 31, respectively. These can be changed inside the app/build.gradle file within the ‘android’ section. You will want to set these numbers high to ensure your application is updated compatible. 

BLUETOOTH_CONNECT - android

Code 

Once we have set up our application, we will now start coding our app. We will divide this section into fragments, explaining each type of code in detail. Our application, in its current form, will keep tabs on the Bluetooth state of the device, whether the Bluetooth is on or off, etc. This is a vital and fundamental feature required in every BLE application to handle changes in Bluetooth state and inform the user of the change.  

Our app will automatically traverse to and from the ‘Bluetooth Connected’ and ‘Bluetooth Disconnected’ states. And manually as well by enabling it or disabling it via the application in the case of Android. 

Learn How to Connect BLE Devices Using Flutter

Contact Us

UI 

Our first task would be to develop and design both the Bluetooth Connected and Disconnected screens, which would traverse between one another depending on the Bluetooth state. Code snippets of both screens are displayed below.  

The connected screen would have a blue background, as set inside the Scaffold widget’s ‘backgroundColor’ property, and the disconnected screen would have a red background. Both screens would contain a Column, and inside there would be an icon depicting the Bluetooth status and a text String stating the status.  

The disconnected page would have a connect button at the bottom of the column, while the connected page would have the disconnect button in the screen’s app bar as an action button. This was done as the body of the screen would be used to display all nearby discoverable devices in future tutorials. 

Bluetooth Connected Screen 

Bluetooth Connected Screen 

Bluetooth Disconnected Screen 

Bluetooth Disconnected Screen 

Logic 

One important functionality in the application is to listen to the state changes in the devices’ Bluetooth. It also needs to override the Bluetooth state in the case of Android manually. Well, that’s where the Flutter Blue Plus package handles most things for us. 

Bluetooth State

The answer lies at the root of the application. While defining the ‘home’ field inside the MaterialApp widget, the root would be a StreamBuilder of type ‘BluetoothState’. The Flutter Blue Plus package provides a Stream type get method which returns a snapshot of the Bluetooth state every time it changes. The StreamBuilder widget listens to the state stream and changes the UI depending on the result of each snapshot

Bluetooth State

Bluetooth Toggle On/Off (Android)

The Android OS gives the user the ability via the mobile application to turn on or off their Bluetooth service, given the user has approved the relevant permissions. The Flutter Blue package also handles this for us by providing 2 simple methods to be called whenever the developer needs this feature. The method can be called straight from the plugin’s static singleton constructor. 

  • FlutterBluePlus.instance.turnOn() 
  • FlutterBluePlus.instance.turnOff() 

However, the user would require enabling Bluetooth permissions for this to work. This is where the Permission Handler package prompts the user to enable Bluetooth permissions. The following code snippet displays the entire methodology. The code for the toggle-off button will be the same. Please note that only the method for turning it off needs to be changed, as explained above. 

Bluetooth permissions

Result 

In the end, our app looks something like the following. 

Result - Connecting BLE Devices result

Conclusion 

 In this tutorial, we have successfully set up our application’s Bluetooth services and permissions and taken the first step to making a future competitor to Apple Health:). Further on, we will dive more into creating a full-fledged product, connecting our app with BLE devices, and keeping them running in the background. 

We hope you found our article informative and comprehensive, and we hope you stick around for more.😉.