How to Create a Bluetooth LE Scanner for Android

A simple tutorial that will guide you through the process of creating a BLE scanner app

Lorenzo Felletti
Geek Culture
4 min readOct 24, 2022

--

Photo by Pathum Danthanarayana on Unsplash

Creating a Bluetooth LE scanner for Android is not too complicated. What you need is some understanding of the Android architecture and of Java/Kotlin.

The most difficult part of building such an app would be…managing the permissions, or even finding what are the required permissions (at least for me).

What You Need to Follow This Tutorial

  • Android Studio installed on your computer
  • A BLE enabled smartphone for testing running Android 12 (or later)
  • A basic understanding of Kotlin (or Java, at least)
  • A (very) basic understanding of how to create a UI in Android

Creating the Project

I will assume that you already know how to create a project in Android Studio, so create a new project, choose Empty Activity, and name it whatever you like, I named mine SimpleBleScanner. Also, select API 31 as the Minimum SDK.
I know that requiring Android 12 could be a bit too tight of a requirement, but this choice was made to be able to experiment with the latest features.
Anyway, if you have the necessity to use an earlier version of the SDK, I think you won’t have to change much of the code.

Managing the Permissions

First, we are going to declare in the Manifest (AndroidManifest.xml) all the permissions we will use in the application. In particular, for Bluetooth LE scanning, the minimum required permissions are the following:

As weird as it might sound, access to coarse and fine location is required in order to use BLE.

Next, inside the package containing the MainActivity, I chose to create another package named permissions, in which to put all the permission utilities.

Inside this newly created package, create two Kotlin objects named PermissionsUtilities and BleScanRequiredPermissions. These two objects will help us in managing the permissions without writing too much code inside the MainActivity.

BleScanRequiredPermissions will contain only the array of the permissions we are going to require for our app.

PermissionsUtilities, on the other hand, is a more complex object, containing all the utility functions to manage permissions in our application.
Anyway, the focus of the article is not on permissions handling, so I will go fast on this part. Feel free to check the permissions package by yourself if interested.

The main functions of this module are:

Otherwise, you could check this article about a permission management library I made, and try to use it instead…

Scanning for devices

To manage the scanning, we will create a new package named blescanner, containing two sub-packages namedmodel and adapter.
The model the classes modeling the BleDevice and the BleScanCallback, while the adapter will contain the BleDeviceAdapter, used as adapter for the RecyclerView showing the results of the scan.

Other than these three classes, we will create a BleScanManager, that will manage the scanning.

The BleScanManager class contains various members to manage the scanning state and what to do before/after the scanning.

The constructor will take as input a BluetoothManager, a scan period (set to a default value if omitted), and a list of actions to do before and after the scanning. The list of actions is nothing but a list of functions that will be invoked before/after the scanning start.

The Handler is used to schedule the stopping of the scan after the scan period time.

The companion object of the BleScanManager will contain the default value of the scan period, and a function to execute the list of actions.

The last lines to complete the BleScanManager are the following

The Main Activity

The main activity will contain the code that “connects” all the modules we created so far:

  • the module managing the permissions
  • the BLE scan manager
  • the adapter for the RecyclerView

The code is pretty straightforward, the only two methods are the onCreate and the onRequestPermissionResult.

The latter is used to manage what to do “after” requesting the permissions to the user, while the former sets the ground for the application by setting the RecyclerView adapter, creating the BleScanManager, and setting the onClickListener for the button to start the scan.

Right after the BleScanManager is created, we add to it before/afterScanActions the code to enable/disable the scan button — because we want to disable the scan button while we’re performing it.

The onClickListener to start the scan checks first that the required permissions are granted, and, if so, it proceeds to start the scan, otherwise it starts permissions request flow.

The GUI

The GUI will be very (very) simple, just a Button to start the scanning, and a RecyclerView to show the scanning results.

Other than the activity_main.xml we will need another layout file to define the layout of a RecyclerView row.

Conclusions

This is all to create a simple Bluetooth LE scanner app in Android.
The results will look something like this

The application's UI while performing a scan

As you can see, the app is very simple on the UI side, this because I wanted to focus more on the functionality. If you want, feel free to fork the repo and improve the application’s UI, or extend its functionalities.

This is all for this article, I hope you enjoyed reading it and that you found it useful. Let me know with a comment!

Maybe you are interested in my new article about making it possible to command the execution of scripts from your smartphone to your laptop using Bluetooth LE.

--

--