Search code examples
androidkotlinbluetoothbluetooth-lowenergyandroid-ble

How to scan BLE devices that use Extended Advertisement and Coded PHY with Android?


I try do create an Android app that scan Bluetooth Low Energy devices that advertise using Extended Advertisement and use Coded PHY for advertisement.

I have a nrf52840 peripheral that I have setup to advertise using Extended Advertisement and Coded PHY, so that it can be discovered from long range.

On my Android device, I can discover the nrf52840 peripheral using the nRF Connect app.

But I cannot discover the peripheral from my custom Android app.

I have set these ScanSettings:

    private val scanSettings = ScanSettings.Builder()
        .setScanMode(ScanSettings.SCAN_MODE_BALANCED)
        .setPhy(ScanSettings.PHY_LE_ALL_SUPPORTED)
        .build()

I created a simple ScanCallback to log found devices, many are found, but not my peripheral that use Coded PHY. I would expect that the nrf52840 peripheral was found.

    private val scanCallback = object : ScanCallback() {
        @SuppressLint("MissingPermission")
        override fun onScanResult(callbackType: Int, result: ScanResult?) {
                Log.d("BLE", "found bluetooth device " + result?.device?.address)
        }
    }

The scan code is mostly as the code in Find BLE devices but I use my ScanSettings:

        if (!isScanning) {
            handler.postDelayed({
                isScanning = false
                bleScanner?.stopScan(scanCallback)
            }, SCAN_PERIOD)

            isScanning = true
            bleScanner?.startScan(null, scanSettings, scanCallback)
        } else {
            isScanning = false
            bleScanner?.stopScan(scanCallback)
        }

I have set the SDK version to be minimum Android 12.

How can I also find devices on Extended Advertisement with Coded PHY when scanning BLE devices using Android SDK? They are found on the same device with the nRF Connect app.


Solution

  • I got it working.

    I added .setLegacy(false) to the ScanSettings:

        private val scanSettings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_BALANCED)
            .setPhy(ScanSettings.PHY_LE_ALL_SUPPORTED)
            .setLegacy(false)
            .build()
    

    and now it found my peripherial that advertise using Extended Advertisement and Coded PHY.

    From the documentation:

    Legacy advertisements include advertisements as specified by the Bluetooth core specification 4.2 and below. This is true by default for compatibility with older apps.

    boolean: true if only legacy advertisements will be returned