【问题标题】:Issue with Scanning Specific BLE Devices扫描特定 BLE 设备的问题
【发布时间】:2021-07-28 10:36:26
【问题描述】:

我正在研究 BLE,必须使用特定 udid 扫描 BLE 设备。

目前,所有支持 BLE 的设备都作为扫描结果提供。

为了避免和只扫描特定设备,我所做的如下:

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)
    }
}

现在,在上述方法中,您可以验证我将 filtersscanSettings 作为 startScan 方法的参数传递。 p>

但是有了这两个参数,我得到了以下错误:

2021-05-06 11:16:24.295 14669-14669/? E/Android运行时:致命 例外:主进程:com.dev,PID:14669 java.lang.IndexOutOfBoundsException:索引:0,大小:0 在 java.util.ArrayList.get(ArrayList.java:437) 在 com.ble.BLEManager$scanCallback$1.onBatchScanResults(BLEManager.kt:153) 在 android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$2.run(BluetoothLeScanner.java:627) 在 android.os.Handler.handleCallback(Handler.java:938) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:246) 在 android.app.ActivityThread.main(ActivityThread.java:8506) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

使用 startScan() 中的单个参数可以正常工作,如下所示 - 没有收到此错误:

mBluetoothAdapter?.bluetoothLeScanner?.startScan(scanCallback)

所以,错误在下面的方法中:

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

编辑

删除了这个不必要的方法名为:onBatchScanResults 因为我使用的是 onScanResult

现在,错误不会出现,但无法使用过滤器和 scanSettings 扫描任何设备。

可能是什么问题?请指导。谢谢。

【问题讨论】:

  • 您可能会得到这个IndexOutOfBoundsException,因为您尝试访问索引为0 (results[0].device) 的元素,而没有先验地检查参数results 中是否有任何元素(索引为0) .
  • 没关系。但我已经评论了 onBatchScanResults() 方法。现在的问题是我在 onScanResult 中没有得到任何列表数据。
  • @Chilippso 编辑了问题。请检查。谢谢。

标签: android kotlin bluetooth-lowenergy android-bluetooth bluetooth-gatt


【解决方案1】:

步骤 1) 像这样添加过滤器:

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

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

String[] 忽略Macs = intent.getStringArrayExtra(IGNORE_MAC_LIST);

mFilter = new ScanServiceFilter.Builder() .filterNames(filterNames) .filterMacs(过滤器Macs) .ignoreMacs(忽略Macs) .build();

第二步:调用scanLeDevice()

scanLeDevice(true);

第 3 步:scanLeDevice 创建设置

                 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();
        }

第 4 步:关于 ScanCallback 检查

    if (mFilter.passesFilter(scanDevice)) {
                filteredResults.add(scanDevice);
                broadcastAction(new ScanBleActionEvent(ScanBleActionEvent.Actions.SCANNED_DEVICE, scanDevice));
            }

【讨论】:

  • 好的,稍后再试,让你知道这是否有效..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 1970-01-01
  • 2021-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多