4

I am working on BLE and have to scan the BLE devices with specific udid.

Currently, All BLE supported devices comes as a scan result.

To avoid and scan only specific devices, what I have done is as below :

fun startScanDevices(interval: Long = Constants.DEFAULT_SCAN_TIME_OUT,
                     connectedDevices: HashMap<String, BLEDeviceModel>? = null,
                     scanWithId: String? = null, context: Activity? = null) {
    this.context = context
    if (scanWithId != null)
        this.scanWithId = scanWithId
    if (isBluetoothEnabled) {
        clearDeviceList(connectedDevices)
        val BLP_SERVICE_UUID = UUID.fromString(UUID_OF_DEVICE)
        val serviceUUIDs = arrayOf<UUID>(BLP_SERVICE_UUID)
        var filters: MutableList<ScanFilter?>? = null
        if (serviceUUIDs != null) {
            filters = ArrayList()
            for (serviceUUID in serviceUUIDs) {
                val filter: ScanFilter = ScanFilter.Builder()
                        .setServiceUuid(ParcelUuid(serviceUUID))
                        .build()
                filters!!.add(filter)
            }
        }
        val scanSettings: ScanSettings = ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
                .setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
                .setReportDelay(1L)
                .build()
        mBluetoothAdapter?.bluetoothLeScanner?.startScan(filters,scanSettings,scanCallback)
        mScanning = true
        handler.postDelayed(stopScanningRunnable, interval)
    }
}

Now, here in above method, you can verify that I am passing filters and scanSettings as a arguments of startScan method.

But with these two arguments I am getting below error :

2021-05-06 11:16:24.295 14669-14669/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.dev, PID: 14669 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.get(ArrayList.java:437) at com.ble.BLEManager$scanCallback$1.onBatchScanResults(BLEManager.kt:153) at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$2.run(BluetoothLeScanner.java:627) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:8506) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

This is working fine with single arguments in startScan() as below - not getting this error :

mBluetoothAdapter?.bluetoothLeScanner?.startScan(scanCallback)

So, Error is in below method :

override fun onBatchScanResults(results: List<ScanResult>) {
            results[0].device
            super.onBatchScanResults(results)
        }

EDIT

Removed this unnecessary Method named : onBatchScanResults since I am using onScanResult.

Now, Error is not coming but, not able to scan any devices with the filter and scanSettings.

What might be the issue? Please guide. Thanks.

Jaimin Modi
  • 1,530
  • 4
  • 20
  • 72
  • You probably get this `IndexOutOfBoundsException` because you try to access the element with index 0 (`results[0].device`) without checking a priori whether there is any element (with index 0) in the parameter `results`. – Chilippso May 07 '21 at 18:58
  • That's fine. But I have commented the onBatchScanResults() method. Now the issue is I am not getting any list data in onScanResult. – Jaimin Modi May 10 '21 at 12:46
  • @Chilippso Edited the Question. Please check. Thank you. – Jaimin Modi May 11 '21 at 07:40

1 Answers1

0

step 1) Add filter like this :

String[] filterNames = intent.getStringArrayExtra(FILTER_NAME_LIST);

String[] filterMacs = intent.getStringArrayExtra(FILTER_MAC_LIST);

String[] ignoreMacs = intent.getStringArrayExtra(IGNORE_MAC_LIST);

mFilter = new ScanServiceFilter.Builder() .filterNames(filterNames) .filterMacs(filterMacs) .ignoreMacs(ignoreMacs) .build();

step 2: call the scanLeDevice()

scanLeDevice(true);

step 3: scanLeDevice create setting

                 ScanSettings settings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setCallbackType(CALLBACK_TYPE_ALL_MATCHES)
                .setMatchMode(MATCH_MODE_AGGRESSIVE)
                .setNumOfMatches(MATCH_NUM_FEW_ADVERTISEMENT)
                .setReportDelay(0)
                .build();

        // We only want to scan for devices advertising our custom service
        ScanFilter scanFilter = new ScanFilter.Builder()
                .setServiceUuid(new ParcelUuid(UUIDConstants.RX_SERVICE_UUID)).build();
        if (mBluetoothLeScanner != null && mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
            mBluetoothLeScanner.startScan(Collections.singletonList(scanFilter), settings, mScanCallback);
            broadcastAction(new ScanBleActionEvent(ScanBleActionEvent.Actions.SCAN_STARTED));
        } else {
            bluetoothDeviceStopped();
        }

step 4: on ScanCallback check

    if (mFilter.passesFilter(scanDevice)) {
                filteredResults.add(scanDevice);
                broadcastAction(new ScanBleActionEvent(ScanBleActionEvent.Actions.SCANNED_DEVICE, scanDevice));
            }
Radhika bajaj
  • 147
  • 1
  • 8