diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b7d97a53..187ec7267 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ Change Log ========== +Version 1.3.3-SNAPSHOT +* Fixed scan filtering by name on API <21 (https://github.com/Polidea/RxAndroidBle/pull/243) + Version 1.3.2 * Fixed completing the `Observable` emitted by `RxBleConnection.setupNotification()`/`RxBleConnection.setupIndication()` when unsubscribed (https://github.com/Polidea/RxAndroidBle/issues/231) diff --git a/rxandroidble/src/main/java/com/polidea/rxandroidble/scan/ScanFilter.java b/rxandroidble/src/main/java/com/polidea/rxandroidble/scan/ScanFilter.java index f0b49ba64..8ef2761bf 100644 --- a/rxandroidble/src/main/java/com/polidea/rxandroidble/scan/ScanFilter.java +++ b/rxandroidble/src/main/java/com/polidea/rxandroidble/scan/ScanFilter.java @@ -277,8 +277,10 @@ public boolean matches(RxBleInternalScanResult scanResult) { } // Local name match. - if (mDeviceName != null && !mDeviceName.equals(scanRecord.getDeviceName())) { - return false; + if (mDeviceName != null) { + if (!(mDeviceName.equals(scanRecord.getDeviceName()) || mDeviceName.equals(device.getName()))) { + return false; + } } // UUID match. diff --git a/rxandroidble/src/test/groovy/com/polidea/rxandroidble/scan/ScanFilterTest.groovy b/rxandroidble/src/test/groovy/com/polidea/rxandroidble/scan/ScanFilterTest.groovy new file mode 100644 index 000000000..c176e730e --- /dev/null +++ b/rxandroidble/src/test/groovy/com/polidea/rxandroidble/scan/ScanFilterTest.groovy @@ -0,0 +1,60 @@ +package com.polidea.rxandroidble.scan + +import android.bluetooth.BluetoothDevice +import com.polidea.rxandroidble.internal.scan.RxBleInternalScanResult +import spock.lang.Specification + +class ScanFilterTest extends Specification { + + RxBleInternalScanResult mockInternalScanResult = Mock RxBleInternalScanResult + + BluetoothDevice mockBluetoothDevice = Mock BluetoothDevice + + ScanRecord mockScanRecord = Mock ScanRecord + + ScanFilter objectUnderTest + + def setup() { + mockInternalScanResult.getBluetoothDevice() >> mockBluetoothDevice + mockInternalScanResult.getScanRecord() >> mockScanRecord + } + + def "should match by device name if the name is present in ScanRecord"() { + + given: + String name = "xxx" + givenScanRecordWith deviceName: name + objectUnderTest = new ScanFilter.Builder().setDeviceName(name).build() + + expect: + objectUnderTest.matches(mockInternalScanResult) + } + + def "should match by device name if the name is present in BluetoothDevice"() { + + given: + String name = "xxx" + mockBluetoothDevice.getName() >> name + objectUnderTest = new ScanFilter.Builder().setDeviceName(name).build() + + expect: + objectUnderTest.matches(mockInternalScanResult) + } + + def "should not match by device name if the name is not present in BluetoothDevice nor ScanRecord"() { + + given: + String name = "xxx" + objectUnderTest = new ScanFilter.Builder().setDeviceName(name).build() + + expect: + !objectUnderTest.matches(mockInternalScanResult) + } + + private void givenScanRecordWith(Map scanRecordMap) { + mockScanRecord.getDeviceName() >> (scanRecordMap['deviceName'] ?: null) + mockScanRecord.getServiceUuids() >> (scanRecordMap['serviceUuids'] ?: null) + mockScanRecord.getServiceData(_) >> (scanRecordMap['serviceData'] ?: null) + mockScanRecord.getManufacturerSpecificData(_) >> (scanRecordMap['manufacturerSpecificData'] ?: null) + } +}