@@ -9,12 +9,14 @@ import android.os.ParcelUuid
99import com.benasher44.uuid.Uuid
1010import com.juul.kable.logs.Logger
1111import com.juul.kable.logs.Logging
12+ import kotlinx.coroutines.Dispatchers
1213import kotlinx.coroutines.cancel
1314import kotlinx.coroutines.channels.awaitClose
1415import kotlinx.coroutines.channels.onFailure
1516import kotlinx.coroutines.channels.trySendBlocking
1617import kotlinx.coroutines.flow.Flow
1718import kotlinx.coroutines.flow.callbackFlow
19+ import kotlinx.coroutines.flow.flowOn
1820
1921public class ScanFailedException internal constructor(
2022 public val errorCode : Int ,
@@ -32,7 +34,7 @@ public class AndroidScanner internal constructor(
3234 ? : error(" Bluetooth not supported" )
3335
3436 public override val advertisements: Flow <Advertisement > = callbackFlow {
35- check (bluetoothAdapter.isEnabled ) { " Bluetooth is disabled" }
37+ val scanner = checkNotNull (bluetoothAdapter.bluetoothLeScanner ) { " Bluetooth disabled. " }
3638
3739 val callback = object : ScanCallback () {
3840 override fun onScanResult (callbackType : Int , result : ScanResult ) {
@@ -53,22 +55,35 @@ public class AndroidScanner internal constructor(
5355 }
5456
5557 override fun onScanFailed (errorCode : Int ) {
58+ logger.error { message = " Scan could not be started, error code $errorCode ." }
5659 cancel(" Bluetooth scan failed" , ScanFailedException (errorCode))
5760 }
5861 }
5962
60- val scanFilter =
61- filterServices
62- ?.map { ScanFilter .Builder ().setServiceUuid(ParcelUuid (it)).build() }
63- ?.toList()
64- bluetoothAdapter.bluetoothLeScanner.startScan(
65- scanFilter,
66- scanSettings,
67- callback,
68- )
63+ val scanFilter = filterServices
64+ ?.map { ScanFilter .Builder ().setServiceUuid(ParcelUuid (it)).build() }
65+ ?.toList()
66+ logger.info {
67+ message = when (filterServices) {
68+ null -> " Starting scan with no service filter."
69+ else -> " Starting scan for services ${filterServices.joinToString()} ."
70+ }
71+ }
72+ scanner.startScan(scanFilter, scanSettings, callback)
6973
7074 awaitClose {
71- bluetoothAdapter.bluetoothLeScanner.stopScan(callback)
75+ logger.info {
76+ message = when (filterServices) {
77+ null -> " Stopping scan with no service filter."
78+ else -> " Stopping scan for services ${filterServices.joinToString()} ."
79+ }
80+ }
81+ // Can't check BLE state here, only Bluetooth, but should assume `IllegalStateException` means BLE has been disabled.
82+ try {
83+ scanner.stopScan(callback)
84+ } catch (e: IllegalStateException ) {
85+ logger.warn(e) { message = " Failed to stop scan. " }
86+ }
7287 }
73- }
88+ }.flowOn( Dispatchers . Main .immediate)
7489}
0 commit comments