Reputation: 358
I am trying to scan for BLE devices once I find my device or after 10 sec, I am trying to stop the scan. But for some reason the onBatchScanResults is getting called indefinitely.
I found that even after stopping the scan the onBatchScanResults will be called until the queue of scanned results are drained. But in my case it is never getting stopped. Below is the code how I am trying to achieve this.
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
}
};
Any help is greatly appreciated.
Upvotes: 1
Views: 3468
Reputation: 358
For the sake of having an answer.
This bug is fixed in the latest version of the library(Scanner Compact Library 1.2.0).
Upvotes: 0
Reputation: 1824
Just add .setUseHardwareBatchingIfSupported(true)
to your ScanSettings
if you want to stopScan
when you are using setReportDelay > 0
ScanSettings settings = new ScanSettings.Builder()
.setUseHardwareBatchingIfSupported(true)
.setReportDelay(1000)
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
Upvotes: 1
Reputation: 462
First you are calling stopScan()
way too many times. And in stopScan()
you're creating new instance of BluetoothLeScannerCompat
with the same name scanner
. Plus, calling stopScan()
from ScanCallback
isn't a good practice.
Here's the working example:
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
}
};
Logs
When you call StopScan() from scanCallback:
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...
And when you StopScan() from ScanPeriod Not within the 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...
Upvotes: 1
Reputation: 565
You are creating new instances of ScanCallback
and losing reference to previous instances. That is why you are not able to stop ScanCallback
for older instances.
Just create one instance of ScanCallBack
at the start of the class and use it across your scan logic.
Upvotes: 0