ScanCallback onBatchScanResults 被无限期调用

ScanCallback onBatchScanResults is getting called indefinitly

我试图在找到我的设备后扫描 BLE 设备,或者在 10 秒后,我试图停止扫描。但由于某种原因,onBatchScanResults 被无限期地调用。

我发现即使在停止扫描后,也会调用 onBatchScanResults 直到扫描结果队列被清空。但就我而言,它永远不会停止。下面是我试图实现这一目标的代码。

public void scan() {
    scanner = BluetoothLeScannerCompat.getScanner();
    final ScanSettings settings = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setReportDelay(1000).setUseHardwareBatchingIfSupported(false).build();
    final List<ScanFilter> filters = new ArrayList<>();
    filters.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid(getFilterUUID()))
            .build());
    Log.e(TAG, "Scanning.....");
    scanner.startScan(filters, settings, scanCallback);

    mIsScanning = true;
    mHandler.postDelayed(() -> {
        if (mIsScanning) {
            showToast("Not able to find any new device.");
            stopScan();
        }
    }, SCAN_DURATION);
}

private void stopScan() {
    if (mIsScanning) {
        final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
        scanner.stopScan(scanCallback);
        mIsScanning = false;
        closeWaitDialog();
}

private ScanCallback scanCallback = new ScanCallback() {
    @Override
    public void onScanResult(final int callbackType, final ScanResult result) {
        // do nothing
        stopScan();
    }

    @Override
    public void onBatchScanResults(final List<ScanResult> results) {
        Log.e(TAG, results.toString() + " mIsScanning " + mIsScanning);
        if (results.size() == 1) {
            stopScan();
            ScanResult scanResult = results.get(0);
            launchSomeActivity();
        } else if (results.size() > 1) {
            stopScan();
            showToast("Too many new devices. Please scan one device at a time.");
        } else {
            // Do nothing. As we will stop anyway stop scanning after 5 sec.
        }
    }

    @Override
    public void onScanFailed(final int errorCode) {
        // should never be called
    }
};

非常感谢任何帮助。

您正在创建 ScanCallback 的新实例并失去对先前实例的引用。这就是为什么您无法停止 ScanCallback 旧实例的原因。 只需在 class 的开头创建一个 ScanCallBack 的实例,然后在您的扫描逻辑中使用它。

首先,您调用 stopScan() 的次数太多了。在 stopScan() 中,您正在创建具有相同名称 scannerBluetoothLeScannerCompat 的新实例。另外,从 ScanCallback 调用 stopScan() 不是一个好习惯。 这是工作示例:

BluetoothLeScannerCompat scanner;
public void scan() {
    scanner = BluetoothLeScannerCompat.getScanner();
    ScanSettings settings = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setReportDelay(10)
            .build();
    List<ScanFilter> filters = new ArrayList<>();
    filters.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid(mUUid)).build());
    scanner.startScan(filters,settings, scanCallback);


    final Handler handle = new Handler();
    handle.postDelayed(new Runnable() {
        @Override
        public void run() {
            stopScan();
        }
    },2000);
}

private void stopScan() {
    Log.i("Device Found: ", "Scan Stoped");
        scanner.stopScan(scanCallback);
}

private ScanCallback scanCallback = new ScanCallback() {
    @Override
    public void onScanResult(final int callbackType, final ScanResult result) {
    }

    @Override
    public void onBatchScanResults(final List<ScanResult> results) {
        Log.i("Device Found: ", results.size()+"");
    }

    @Override
    public void onScanFailed(final int errorCode) {
        // should never be called
    }
};

日志

当您从 scanCallback 调用 StopScan() 时:

01-17 14:52:53.870 32434-32434/com.dleague.salman.example I/OnBatchScan:                     
Scanning...
01-17 14:52:53.870 32434-32434/com.dleague.salman.example I/StopScan:     
Scanning Stop...
01-17 14:52:53.881 32434-32434/com.dleague.salman.example I/OnBatchScan: 
Scanning...
01-17 14:52:53.881 32434-32434/com.dleague.salman.example I/StopScan: 
Scanning Stop...
01-17 14:52:53.892 32434-32434/com.dleague.salman.example I/OnBatchScan: 
Scanning...
01-17 14:52:53.892 32434-32434/com.dleague.salman.example I/StopScan: 
Scanning Stop...
01-17 14:52:53.902 32434-32434/com.dleague.salman.example I/OnBatchScan: 
Scanning...
01-17 14:52:53.902 32434-32434/com.dleague.salman.example I/StopScan: 
Scanning Stop...
01-17 14:52:53.912 32434-32434/com.dleague.salman.example I/OnBatchScan: 
Scanning...
01-17 14:52:53.912 32434-32434/com.dleague.salman.example I/StopScan: 
Scanning Stop...
01-17 14:52:53.923 32434-32434/com.dleague.salman.example I/OnBatchScan: 
Scanning...

并且当您从 ScanPeriod Not 中的 StopScan() 时,在 scanCallback:

01-17 14:55:10.703 1673-1673/com.dleague.salman.example I/OnBatchScan: 
Scanning...
01-17 14:55:10.714 1673-1673/com.dleague.salman.example I/OnBatchScan:     
Scanning...
....
01-17 14:55:12.684 1673-1673/com.dleague.salman.example I/OnBatchScan: 
Scanning...
01-17 14:55:12.694 1673-1673/com.dleague.salman.example I/OnBatchScan: 
Scanning...
01-17 14:55:12.700 1673-1673/com.dleague.salman.example I/StopScan: Scanning 
Stop...

为了有答案。

此错误已在最新版本的库(Scanner Compact Library 1.2.0)中修复。

如果您想在使用 setReportDelay > 0

stopScan,只需将 .setUseHardwareBatchingIfSupported(true) 添加到您的 ScanSettings
ScanSettings settings = new ScanSettings.Builder()
            .setUseHardwareBatchingIfSupported(true)
            .setReportDelay(1000)
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .build();