Scan for nearby devices

This guide teaches you how to scan for nearby Bluetooth devices using AbleLib.

First, make sure to initialize AbleManager in your app entry point:

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        AbleManager.initalize(this)
    }
}

Also, make sure your app has all the necessary permissions for interacting with Bluetooth devices.

The easiest way is, as always, to delegate that to AbleManager:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        AbleManager.handlePermissionRequestIfNotGranted(this)
    }
}

It's also a good idea to check if phone's Bluetooth is on before attempting any operations. AbleLib has methods to handle that as well:

// If you're not in a Contex,t, use BluetoothUtil.isOn(Context)
if (isBluetoothOn) {

}

// or
turnBluetoothOnIfOff()

Finally, scan for nearby devices with AbleManager:

Scanning is an async operation and there are three ways of going about it - coroutines, callback or the listener. Let's starting with the callback approach - it scans for the given amount of time, and returns a Result<Set<AbleDevice>>:

AbleManager.scan { result ->
        result.onSuccess { 
            // handle the devices set
        }.onFailure {
            // an exception has occurred
        }
}

The default timeout is 10 seconds, but you can specify it yourself:

AbleManager.scan(30_000) { result ->
}

The coroutines approach is cleaner and avoids callback hell:

suspend fun scanForNearbyDevices() {
    try {
        val devices = AbleManager.scan()
    } catch (e: BluetoothStateException) {
        // handle the exception
    }
}

The listener is a more powerful callback, allowing you to have insight into all parts of the scanning process - when it starts and stops, when it discovers a new device and when it encounters an error.

AbleManager.scan(object : AbleNearbyScanListener {
    override fun onStart() {
        // the scanning started
    }

    override fun onDeviceFound(device: AbleDevice) {
        // a single device was found, scanning continues
    }

    override fun onError(e: Exception) {
        // an error has occurred
    }

    override fun onStop() {
        // scanning stopped
    }
})

Exceptions in onError should only be of type BluetoothStateException.

If you need to stop an ongoing scan, use stopScan:

AbleManager.stopScan()