Scanning For Bluetooth Low Energy Device with Android Application using Kotlin

Nutthawut Sittee
Nov 3 · 3 min read

Introduction

This is the first article or that I ever wrote on this site after a long time of lurking and reading other’s article, I finally found the courage to share the knowledge. Since I’m currently doing my project about android application and IoT device using Bluetooth as a mean of communication, I might as well document what I found along the way, so it might come as useful to others that are struggling the same problem that I found.

Objective

In order to communicate and exchange data with the Bluetooth device, the application will need to find that device first. After finishing this article, you will be able to scan and retrieve the information of the Bluetooth device, ready to exchange the data.

LeScanner

First of all, we create a Kotlin class that will be an object that will connect and handle all the works in order to get the nearby Bluetooth device.

BluetoothAdapter and BluetoothLeScanner is an object that deals with bluetooth device for the Android application. Handler will help us when we want to delay a specific action for a period of time, like the length of scan period. And finally, InitialPair is the activity that handle the scanning process.

class LeScanner {
var bta: BluetoothAdapter
var bls: BluetoothLeScanner
var handler: Handler
var isScan = false

var scanPeriod
: Long
var strengthThreshold = -60
lateinit var ip: InitialPair
.
.
.
}

Constructor

period is the length of time for the LeScanner to scan for other Le Device, and the strength is the minimum strength or signal that this Scanner will pickup, and lower than this will be ignored. -60 is a good threshold for the start. The higher the value, the stronger the signal is.

constructor(period: Long, strength: Int, activity: InitialPair){
this.scanPeriod = period
this.strengthThreshold = strength
this.ip = activity

handler = Handler()

var btm = ip.getSystemService(Context.BLUETOOTH_SERVICE)
as BluetoothManager
bta = btm.adapter
bls = bta.bluetoothLeScanner
}

Start Scanning

This function will initiate the scanning procedure, called by the activity that start this process.

bls.startScan() is how you can start the scanning and to stop, you call bls.stopScan(). You can simply call startScan() right away, but in order to stop the scanning process. You need to add a delay to this. One way you can achieve this is to use Handler function, called postDelayed(). The function take the period of time as a milliseconds unit, so 5000 scanPeriod means 5 seconds

Both of these function take ScanCallback as an argument, which we need to make next.

fun scanLeDevice(){
if(!isScan){
bls.startScan(callBack)
this.isScan = true

handler
.postDelayed(Runnable (){
bls.stopScan(callBack)
this.isScan = false
}, scanPeriod)
}
}

ScanCallback

To create a callback for this job, we declare them in the same class. Once the neaby BLE device is found, this callback will handle what to do next. Now this where you plan how to display the device that it just found. For example, we can simply store them in an ArrayList, then we can just use the ListView and Adapter together to display them nicely in the activity.

private val callBack: ScanCallback = object : ScanCallback(){
override fun onScanResult(callbackType:Int, result:ScanResult) {
super.onScanResult(callbackType, result)
var rssi = result.rssi
var bd = result.device

if(rssi > strengthThreshold){
..... // Store the bd and rssi to display later
}
}
}

Conclusion

That’s the simple way for the Android application to find the nearby Bluetooth Low Energy device. Note that in order to run this code, you cannot use an emulator, because of the Bluetooth module.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade