BluetoothLeScanner — 정의, 메서드 및 Android에서 BLE 스캐닝

저자: IT Sectr 게시일: 2026-07-16 읽는 시간: 10 분

BluetoothLeScanner는 Bluetooth Low Energy 기기를 스캔하기 위한 Android 클래스로, API 21(Android 5.0)부터 사용할 수 있습니다. BluetoothLeScanner는 BluetoothAdapter의 더 이상 사용되지 않는 startLeScan 메서드를 대체하여 스캔 구성(ScanSettings), 필터링(ScanFilter) 및 백그라운드 모드 지원(PendingIntent)을 제공하는 유연한 API를 제공합니다. 인스턴스는 BluetoothAdapter.getBluetoothLeScanner()를 통해 얻습니다. Android Developers, 2026에 따르면 BluetoothLeScanner는 세 가지 전원 모드를 지원하며 서비스 UUID, 기기 이름 또는 MAC 주소로 필터링하여 BLE 광고 패킷을 스캔할 수 있습니다.

핵심 사항

  • BluetoothLeScanner — BLE 스캐닝을 위한 최신 Android API(API 21+), 더 이상 사용되지 않는 startLeScan의 대체
  • ScanSettings — 스캔 모드 구성: LOW_POWER, BALANCED, LOW_LATENCY 및 콜백 유형
  • ScanFilter — 서비스 UUID, 기기 이름, MAC 주소, 제조업체 데이터로 결과 필터링
  • ScanCallback — 결과 콜백 onScanResult, onBatchScanResults 및 오류 코드가 있는 onScanFailed
  • PendingIntent — BroadcastReceiver를 통한 백그라운드 스캐닝, 앱이 백그라운드에 있어도 작동

BluetoothLeScanner란: 개념 및 인스턴스 얻기

BluetoothLeScanner는 Android에서 BLE 스캐닝을 관리하는 시스템 클래스입니다. 간단한 LeScanCallback을 받는 BluetoothAdapter.startLeScan()과 달리 BluetoothLeScanner는 설정, 필터 및 고급 오류 처리를 제공하는 객체 지향 API를 제공합니다. 이 클래스는 BLE 4.2 지원과 함께 API 21(Android 5.0)에서 도입되었으며 모든 최신 Android 버전에서 BLE 스캐닝의 기본 방법으로 남아 있습니다.

BluetoothLeScanner 인스턴스 얻기는 BluetoothAdapter.getBluetoothLeScanner()를 통해 수행됩니다. Bluetooth 어댑터를 사용할 수 없는 경우(Bluetooth 비활성화 또는 기기가 BLE를 지원하지 않음) 메서드는 null을 반환합니다. 얻기 전에 PackageManager를 통해 BluetoothAdapter.isEnabled() 및 FEATURE_BLUETOOTH_LE의 존재를 확인하세요. 스캐너를 얻은 후에는 모든 스레드에서 스캐닝을 시작할 수 있습니다. Android는 내부 Bluetooth 스택 스레드에서 BLE 작업을 예약합니다.

kotlin
// BluetoothLeScanner 얻기
class BLEScannerManager(context: Context) {

    private val bluetoothManager: BluetoothManager =
        context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    private val adapter: BluetoothAdapter? = bluetoothManager.adapter
    private var scanner: BluetoothLeScanner? = null

    fun initScanner(): Boolean {
        // BLE 가용성 확인
        if (!context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            return false
        }

        // Bluetooth 활성화 확인
        if (adapter?.isEnabled != true) {
            return false
        }

        // 스캐너 얻기
        scanner = adapter?.bluetoothLeScanner
        return scanner != null
    }

    // 스캐너 가용성 확인
    val isAvailable: Boolean
        get() = scanner != null

    // 필터 없이 기본 스캔 시작
    fun startBasicScan() {
        scanner?.startScan(object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                handleResult(result)
            }
        })
    }

    private fun handleResult(result: ScanResult) {
        val device = result.device
        print("Device: ${device.name ?: "Unnamed"}, RSSI: ${result.rssi}, address: ${device.address}")
    }
}

BLEScannerManager 클래스는 BluetoothLeScanner의 안전한 획득 및 초기화를 보여줍니다. initScanner는 hasSystemFeature를 통한 BLE 가용성, 활성화된 Bluetooth 및 성공적인 스캐너 획득을 확인합니다. startBasicScan은 설정이나 필터 없이 스캐닝을 시작하여 범위 내의 모든 BLE 기기를 발견합니다. handleResult는 ScanResult(BluetoothDevice(이름, 주소), RSSI(신호 강도), scanRecord(광고 데이터))를 구문 분석합니다.

ScanSettings: 스캔 모드 및 콜백 유형

ScanSettings는 BLE 스캔 구성을 위한 클래스입니다. 주요 매개변수는 스캔 모드(scanMode)로, 전력 소비와 검색 지연 시간 간의 균형을 결정합니다. ScanSettings.Builder를 사용하면 scanMode, callbackType(CALLBACK_TYPE_ALL_MATCHES, CALLBACK_TYPE_FIRST_MATCH, CALLBACK_TYPE_MATCH_LOST), matchMode(MATCH_MODE_AGGRESSIVE, MATCH_MODE_STICKY), reportDelay(배치 전달 지연) 및 phy(PHY_LE_1M, PHY_LE_2M, PHY_LE_CODED)를 구성할 수 있습니다.

세 가지 스캔 모드: SCAN_MODE_LOW_POWER(0) — 낮은 전력 소비의 백그라운드 스캐닝, 몇 초의 검색 지연. SCAN_MODE_BALANCED(1) — 대부분의 시나리오에 대한 균형 모드. SCAN_MODE_LOW_LATENCY(2) — 최소 검색 지연(약 100ms), 최대 전력 소비. 활성 기기 검색에는 LOW_LATENCY를, 백그라운드 모니터링에는 LOW_POWER를 사용하세요.

reportDelay — 결과 배치 전달 전 지연 시간(밀리초). reportDelay = 0이면 결과가 발견 시 즉시 전송됩니다. > 0이면 Android가 결과를 축적하고 onBatchScanResults를 통해 배치를 전송합니다. 배치 전달은 콜백 호출과 전력 소비를 줄이며 낮은 우선순위의 백그라운드 스캐닝에 적합합니다.

kotlin
// 다양한 시나리오에 대한 ScanSettings 구성
class ScanSettingsProvider {

    // 1. 빠른 스캔(활성 검색)
    fun lowLatencyScan(): ScanSettings {
        return ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
            .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
            .setReportDelay(0)
            .setPhy(ScanSettings.PHY_LE_ALL_SUPPORTED)
            .build()
    }

    // 2. 전력 효율적 스캔(백그라운드 모니터링)
    fun lowPowerScan(): ScanSettings {
        return ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH)
            .setMatchMode(ScanSettings.MATCH_MODE_STICKY)
            .setReportDelay(2000)  // 2초마다 배치
            .build()
    }

    // 3. BLE Long Range 스캔(Coded PHY)
    fun longRangeScan(): ScanSettings {
        return ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setPhy(ScanSettings.PHY_LE_CODED)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
            .build()
    }

    // 4. 2M PHY에서만 스캔(BLE 5.0+)
    fun highSpeedScan(): ScanSettings {
        return ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setPhy(ScanSettings.PHY_LE_2M)
            .build()
    }
}

ScanSettingsProvider 클래스에는 일반적인 구성이 포함되어 있습니다. lowLatencyScan은 UI 스캐닝용(「지금 여기」 검색). lowPowerScan은 2초마다 배치와 callbackType FIRST_MATCH(첫 번째 발견 시에만 트리거)를 사용한 백그라운드 모니터링용. longRangeScan은 PHY_LE_CODED(BLE Long Range, 최대 1km)를 사용. highSpeedScan은 PHY_LE_2M(2Mbit/s, BLE 5.0+ 기기만).

ScanFilter: UUID 및 이름으로 BLE 기기 필터링

ScanFilter는 BLE 스캔 결과를 필터링하는 클래스입니다. 필터가 없으면 BluetoothLeScanner는 범위 내의 모든 BLE 기기를 반환합니다. 밀집된 BLE 환경에서는 분당 수백 개의 패킷이 될 수 있습니다. ScanFilter는 결과를 원하는 기기로 좁혀 전력 소비와 앱 부하를 줄입니다. 필터는 Bluetooth 스택 수준에서 적용되어 부적합한 패킷이 앱에 도달하기 전에 폐기됩니다.

필터 유형: setServiceUuid — 서비스 UUID(전체 128비트 형식 필요). setDeviceName — 기기 이름의 부분 문자열(대소문자 구분, 정확한 부분 문자열 일치). setDeviceAddress — 정확한 MAC 주소. setManufacturerData — 제조업체 데이터(회사 ID + 마스크). 단일 스캔에 여러 필터를 설정할 수 있으며 기기는 모두와 일치해야 합니다(AND 논리). OR 논리의 경우 여러 스캔을 시작하세요.

kotlin
// 다양한 시나리오에 대한 ScanFilter 생성
class ScanFilterFactory {

    // 1. 서비스 UUID로 필터(심박수 모니터)
    fun byHeartRateService(): ScanFilter {
        return ScanFilter.Builder()
            .setServiceUuid(
                ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB")
            )
            .build()
    }

    // 2. 기기 이름으로 필터( "iBeacon*")
    fun byDeviceName(): ScanFilter {
        return ScanFilter.Builder()
            .setDeviceName("Sensor")
            .build()
    }

    // 3.   MAC-( 기기)
    fun byMacAddress(mac: String): ScanFilter {
        return ScanFilter.Builder()
            .setDeviceAddress(mac)
            .build()
    }

    // 4. 결합 필터(UUID + )
    fun combinedFilter(): List<ScanFilter> {
        return listOf(
            ScanFilter.Builder()
                .setServiceUuid(
                    ParcelUuid.fromString("0000A001-0000-1000-8000-00805F9B34FB")
                )
                .setDeviceName("MyDevice")
                .build()
        )
    }

    // 5.   제조업체 데이터
    fun byManufacturer(companyId: Int, data: ByteArray, mask: ByteArray): ScanFilter {
        return ScanFilter.Builder()
            .setManufacturerData(companyId, data, mask)
            .build()
    }
}

ScanFilterFactory 클래스는 모든 필터 유형을 보여줍니다. byHeartRateService는 심박수 서비스 0x180D가 있는 기기를 필터링합니다. byDeviceName은 이름에 「Sensor」가 포함된 기기를 찾습니다(Apple은 필터링에 고유한 이름을 권장). byMacAddress — 특정 기기의 정확한 검색. combinedFilter — UUID 및 이름별 AND 필터. byManufacturer — 제조업체 데이터별 필터(예: iBeacon의 경우 Apple 회사 ID 0x004C 사용).

ScanCallback: 스캔 결과 및 오류 처리

ScanCallback은 BLE 스캔 결과를 수신하기 위한 추상 클래스입니다. 세 가지 메서드를 포함합니다: onScanResult — 단일 결과(콜백 유형, ScanResult), onBatchScanResults — reportDelay > 0용 배치 결과, onScanFailed — 오류 코드. 모든 메서드는 Android 메인 스레드에서 호출됩니다. onScanResult에서 긴 처리를 위해 coroutines 또는 HandlerThread를 사용하세요.

ScanResult에는 다음이 포함됩니다: BluetoothDevice device, int rssi(dBm 단위 신호 레벨), ScanRecord scanRecord(광고 데이터), long timestampNanos(시스템 부팅 이후 검색 시간). ScanRecord 제공: getServiceData() — UUID + 사용자 정의 데이터, getManufacturerSpecificData() — 제조업체 데이터, getAdvertiseFlags() — BLE 플래그. 콜백 유형은 다음을 나타냅니다: CALLBACK_TYPE_ALL_MATCHES — 필터와 일치, CALLBACK_TYPE_FIRST_MATCH — 첫 번째 검색, CALLBACK_TYPE_MATCH_LOST — 기기 손실.

onScanFailed 오류 코드: SCAN_FAILED_ALREADY_STARTED(1) — 스캔이 이미 시작됨, SCAN_FAILED_APPLICATION_REGISTRATION_FAILED(2) — Bluetooth 스택에 앱 등록 실패, SCAN_FAILED_INTERNAL_ERROR(3) — 내부 스택 오류, SCAN_FAILED_FEATURE_UNSUPPORTED(4) — 기기에서 BLE 스캐닝이 지원되지 않음.

kotlin
// 전체 스캔 결과 및 오류 처리
class ScanResultHandler {

    private val results = mutableListOf<ScanResult>()

    val scanCallback = object : ScanCallback() {

        // 1. 단일 결과
        override fun onScanResult(callbackType: Int, result: ScanResult) {
            // callbackType: 1 = ALL_MATCHES, 2 = FIRST_MATCH, 4 = MATCH_LOST
            if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
                onDeviceLost(result)
                return
            }

            // 목록에 추가(주소로 중복 제거)
            val existingIndex = results.indexOfFirst {
                it.device.address == result.device.address
            }
            if (existingIndex >= 0) {
                results[existingIndex] = result  // RSSI 업데이트
            } else {
                results.add(result)
            }

            // 광고 패킷에서 데이터 추출
            val record = result.scanRecord
            val serviceData = record?.serviceData
            val manufacturerData = record?.manufacturerSpecificData

            print("Found: ${result.device.name ?: "N/A"}, RSSI: ${result.rssi}")
        }

        // 2. 배치 결과(reportDelay > 0)
        override fun onBatchScanResults(results: MutableList<ScanResult>?) {
            results?.let { batch ->
                print("Batch: ${batch.size} devices")
            }
        }

        // 3. 스캔 오류
        override fun onScanFailed(errorCode: Int) {
            val error = when (errorCode) {
                ScanCallback.SCAN_FAILED_ALREADY_STARTED -> "Already scanning"
                ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED -> "Registration failed"
                ScanCallback.SCAN_FAILED_INTERNAL_ERROR -> "Internal error"
                ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED -> "BLE not supported"
                else -> "Unknown error: $errorCode"
            }
            print("Error: $error")
        }
    }

    private fun onDeviceLost(result: ScanResult) {
        results.removeAll { it.device.address == result.device.address }
        print("Device lost: ${result.device.address}")
    }
}

ScanResultHandler 클래스는 모든 BluetoothLeScanner 콜백 유형을 처리합니다. onScanResult는 MAC 주소로 중복 제거하여 기기 목록을 업데이트하고 이미 찾은 기기의 RSSI를 업데이트합니다. CALLBACK_TYPE_MATCH_LOST는 기기 손실(목록에서 제거)을 알립니다. onBatchScanResults는 reportDelay > 0용 배치 결과를 처리합니다. onScanFailed는 오류 코드를 사람이 읽을 수 있는 메시지로 매핑하며 BLE 스캐닝 디버깅에 중요합니다.

PendingIntent: BroadcastReceiver를 통한 백그라운드 BLE 스캐닝

PendingIntent 스캐닝은 앱이 백그라운드에 있어도 작동하는 BLE 스캐닝을 위한 BluetoothLeScanner 메커니즘입니다(Android 8+ 제한 있음). ScanCallback 대신 PendingIntent를 사용하여 BLE 기기가 발견될 때 시스템 BroadcastReceiver에 Broadcast를 보냅니다. 이를 통해 앱이 메모리에 상주하지 않고도 BLE 기기 알림을 받을 수 있습니다(시스템은 브로드캐스트 수신 시 프로세스를 생성합니다).

백그라운드 스캐닝 제한: Android 8+(API 26)에서는 백그라운드 서비스가 제한됩니다. PendingIntent 스캐닝은 BLE 이벤트 수신 시 시스템이 시작할 수 있는 BroadcastReceiver를 통해 이 제한을 우회합니다. Android 10+(API 29)에서는 백그라운드 BLE 스캐닝이 제조업체의 전원 절약 정책(Xiaomi, Huawei, Samsung이 백그라운드 BLE 작업 차단)에 의해 추가로 제한됩니다. 중요한 BLE 시나리오의 경우 포그라운드 서비스 알림이 필요합니다.

kotlin
// PendingIntent를 통한 백그라운드 BLE 스캐닝
class BackgroundBLEScanner(private val context: Context) {

    private val scanner: BluetoothLeScanner? by lazy {
        val adapter = BluetoothAdapter.getDefaultAdapter()
        adapter?.bluetoothLeScanner
    }

    fun startBackgroundScan() {
        // BroadcastReceiver용 PendingIntent 생성
        val intent = Intent(context, BLEBroadcastReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(
            context,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        // 백그라운드 스캔 설정
        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH)
            .setMatchMode(ScanSettings.MATCH_MODE_STICKY)
            .build()

        // 백그라운드 스캔 시작
        scanner?.startScan(
            null,  // 필터
            settings,
            pendingIntent
        )
    }

    fun stopBackgroundScan() {
        val intent = Intent(context, BLEBroadcastReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(
            context, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        scanner?.stopScan(pendingIntent)
    }
}

// BroadcastReceiver   BLE-
class BLEBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        // 스캔 결과 가져오기
        val results = BluetoothLeScanner.getPendingIntentScanResults(intent)
        results?.let { scanResults ->
            for (result in scanResults) {
                // 사용자에게 알림 보내기
                showNotification(context, result.device.name ?: " ")
            }
        }
    }

    private fun showNotification(context: Context, name: String) {
        val notification = Notification.Builder(context, "ble_channel")
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setContentTitle("BLE devices")
            .setContentText("Found: $name")
            .setAutoCancel(true)
            .build()
        val manager = context.getSystemService(Context.NOTIFICATION_SERVICE)
                as NotificationManager
        manager.notify(System.currentTimeMillis().toInt(), notification)
    }
}

BackgroundBLEScanner 클래스는 PendingIntent를 통해 백그라운드 BLE 스캐닝을 시작합니다. startBackgroundScan은 BLE 기기 발견 시 BLEBroadcastReceiver에 Broadcast를 보내는 PendingIntent를 생성합니다. BroadcastReceiver는 getPendingIntentScanResults()를 통해 ScanResult를 추출하고 알림을 표시하거나 서버에 데이터를 보낼 수 있습니다. 이 접근 방식은 앱이 시스템에 의해 종료된 경우에도 작동합니다. Android는 브로드캐스트 수신 시 BroadcastReceiver를 다시 시작합니다.

Kotlin에서 BluetoothLeScanner를 사용한 BLE 스캐너 예제

전체 예제: BluetoothLeScanner를 ScanSettings, ScanFilter 및 ScanCallback과 함께 사용하여 Heart Rate Monitor 기기를 찾는 Kotlin의 BLE 스캐너. 스캐너는 RSSI 및 서비스 UUID와 함께 발견된 기기 목록을 표시하며 BluetoothGatt를 통해 연결할 수 있습니다.

kotlin
// Kotlin에서 코루틴을 사용한 전체 BLE 스캐너
class DeviceScanner(private val context: Context) {

    private val adapter: BluetoothAdapter? by lazy {
        val manager = context.getSystemService(Context.BLUETOOTH_SERVICE)
                as BluetoothManager
        manager.adapter
    }

    private val scanner: BluetoothLeScanner? by lazy {
        adapter?.bluetoothLeScanner
    }

    fun startScan(duration: Long = 10000): Flow<ScanResult> = callbackFlow {
        // Bluetooth 상태 확인
        if (adapter?.isEnabled != true) {
            close(IllegalStateException("Bluetooth disabled"))
            return@callbackFlow
        }

        // 스캔 구성
        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .build()

        val filters = listOf(
            ScanFilter.Builder()
                .setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
                .build()
        )

        val callback = object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                trySend(result)
            }

            override fun onScanFailed(errorCode: Int) {
                close(BLEException("Scan failed: $errorCode"))
            }
        }

        // 스캐닝 시작
        scanner?.startScan(filters, settings, callback)

        // 시간 후 자동 중지
        delay(duration)
        scanner?.stopScan(callback)
        close()
    }.flowOn(Dispatchers.IO)

    fun stop() {
        scanner?.stopScan(object : ScanCallback() {})
    }
}

class BLEException(message: String) : Exception(message)

DeviceScanner 클래스는 반응형 BLE 스캐닝을 위해 Kotlin Flow(callbackFlow)를 사용합니다. 스캐닝은 LOW_LATENCY 설정과 Heart Rate Service UUID 필터로 시작됩니다. 결과는 onScanResult를 통해 Flow로 방출됩니다. 지정된 기간(기본 10초) 후 자동 중지. FlowOn(Dispatchers.IO)는 BLE 작업을 백그라운드 스레드로 오프로드합니다. 이 접근 방식은 viewModelScope.launch 및 collect를 통해 MVVM 아키텍처에서 BLE 스캐닝을 가능하게 합니다.

자주 묻는 질문

Android에서 BluetoothLeScanner란 무엇인가요?

BluetoothLeScanner는 BLE 스캐닝을 위한 Android 클래스(API 21+)입니다. BluetoothAdapter.getBluetoothLeScanner()를 통해 얻습니다. 세 가지 스캔 모드(LOW_POWER, BALANCED, LOW_LATENCY), UUID, 이름 및 MAC 주소로 필터링, 배치 결과 및 백그라운드 스캐닝을 위한 PendingIntent를 지원합니다. 더 이상 사용되지 않는 BluetoothAdapter.startLeScan() 메서드를 대체합니다.

LOW_POWER와 LOW_LATENCY의 차이점은 무엇인가요?

SCAN_MODE_LOW_POWER — 5~10초 검색 지연이 있는 백그라운드 모드, 최소 전력 소비. SCAN_MODE_LOW_LATENCY — 약 100ms 지연이 있는 활성 모드, 최대 전력 소비. SCAN_MODE_BALANCED — 절충(~2초 지연). UI 스캐닝에는 LOW_LATENCY를, 백그라운드 모니터링에는 PendingIntent와 함께 LOW_POWER를 사용하세요.

BluetoothLeScanner가 기기를 찾지 못하는 이유는 무엇인가요?

이유: Bluetooth 비활성화(adapter.isEnabled 확인), 권한 누락(API 31+에서는 BLUETOOTH_SCAN, API 23~30에서는 ACCESS_FINE_LOCATION), scanner = null(어댑터 사용 불가), 기기가 범위 밖에 있거나 필터가 잘못됨. onScanFailed도 확인하세요. 오류 코드가 원인을 나타냅니다: SCAN_FAILED_ALREADY_STARTED(1) 또는 SCAN_FAILED_APPLICATION_REGISTRATION_FAILED(2).

Android에서 백그라운드로 BLE를 스캔하려면 어떻게 하나요?

startScan()의 PendingIntent 버전을 사용하세요. ScanCallback 대신 PendingIntent를 전달합니다. BLE 기기가 발견되면 Android는 BroadcastReceiver에 Broadcast를 보내며, 앱이 백그라운드에 있어도 시스템이 시작할 수 있습니다. Android 8+의 경우 BroadcastReceiver를 매니페스트에 추가하세요. Android 10+에서는 제조업체의 전원 절약 제한을 고려하세요.

한 번의 스캔으로 몇 개의 BLE 기기를 발견할 수 있나요?

BluetoothLeScanner는 발견 가능한 기기 수에 제한이 없습니다. 제한은 환경의 BLE 포화도에 따라 다릅니다. 사무실에는 20~50개의 활성 BLE 기기가, 쇼핑센터에는 수백 개가 있을 수 있습니다. 필터링에는 ScanFilter(UUID, 이름으로)를 사용하세요. 필터링 없이 결과를 비동기식으로 처리하세요. onScanResult는 초당 수십 번 호출될 수 있습니다.

요약

  • BluetoothLeScanner — 설정 및 필터링을 갖춘 BLE 스캐닝을 위한 최신 Android 클래스(API 21+)
  • ScanSettings — 세 가지 모드: LOW_POWER(백그라운드), BALANCED, LOW_LATENCY(활성)
  • ScanFilter — AND 논리로 서비스 UUID, 기기 이름, MAC 주소, 제조업체 데이터로 필터링
  • ScanCallback — onScanResult(단일), onBatchScanResults(배치), onScanFailed(오류 코드)
  • PendingIntent — BroadcastReceiver를 통한 백그라운드 스캐닝, 앱 종료 시에도 작동
  • ScanRecord — BLE 광고 데이터: serviceData, manufacturerSpecificData, advertiseFlags, TX 전력 수준
  • Kotlin Flow — callbackFlow를 통해 자동 중지 기능이 있는 반응형 아키텍처에서 BluetoothLeScanner 사용 가능

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기