BluetoothLeScanner — was es ist, Methoden und BLE-Scannen in Android

Autor: IT Sectr Veröffentlicht: 2026-07-16 Lesezeit: 10 Min.

BluetoothLeScanner ist eine Android-Klasse zum Scannen von Bluetooth Low Energy-Geräten, verfügbar ab API 21 (Android 5.0). BluetoothLeScanner ersetzte die veraltete Methode startLeScan auf BluetoothAdapter und bietet eine flexible API mit Scan-Konfiguration (ScanSettings), Filterung (ScanFilter) und Hintergrundmodus-Unterstützung (PendingIntent). Die Instanz wird über BluetoothAdapter.getBluetoothLeScanner() bezogen. Laut Android Developers, 2026 unterstützt BluetoothLeScanner drei Energiemodi und ermöglicht das Scannen von BLE-Werbe paketen mit Filterung nach Dienst-UUID, Gerätename oder MAC-Adresse.

Wichtige Punkte

  • BluetoothLeScanner — moderne Android-API (API 21+) für BLE-Scannen, Ersatz für veraltetes startLeScan
  • ScanSettings — Konfiguration des Scan-Modus: LOW_POWER, BALANCED, LOW_LATENCY und Callback-Typ
  • ScanFilter — Ergebnis filterung nach Dienst-UUID, Gerätename, MAC-Adresse, Herstellerdaten
  • ScanCallback — Ergebnis-Callbacks onScanResult, onBatchScanResults und onScanFailed mit Fehlercodes
  • PendingIntent — Hintergrundscannen über BroadcastReceiver, auch wenn die App im Hintergrund ist

Was ist BluetoothLeScanner: Wesen und Instanzerhalt

BluetoothLeScanner ist eine Systemklasse zur Verwaltung des BLE-Scannens auf Android. Im Gegensatz zu BluetoothAdapter.startLeScan(), das einen einfachen LeScanCallback akzeptiert, bietet BluetoothLeScanner eine objektorientierte API mit Einstellungen, Filtern und erweiterter Fehlerbehandlung. Diese Klasse wurde in API 21 (Android 5.0) zusammen mit BLE 4.2-Unterstützung eingeführt und bleibt die primäre BLE-Scan-Methode auf allen modernen Android-Versionen.

Das Erhalten einer BluetoothLeScanner-Instanz erfolgt über BluetoothAdapter.getBluetoothLeScanner(). Die Methode gibt null zurück, wenn der Bluetooth-Adapter nicht verfügbar ist (Bluetooth deaktiviert oder Gerät unterstützt kein BLE). Überprüfen Sie vor dem Erhalt BluetoothAdapter.isEnabled() und das Vorhandensein von FEATURE_BLUETOOTH_LE über PackageManager. Nach Erhalt des Scanners kann das Scannen in jedem Thread gestartet werden — Android plant BLE-Operationen auf einem internen Bluetooth-Stack-Thread.

kotlin
// BluetoothLeScanner erhalten
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-Verfügbarkeit prüfen
        if (!context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            return false
        }

        // Bluetooth aktiviert prüfen
        if (adapter?.isEnabled != true) {
            return false
        }

        // Scanner erhalten
        scanner = adapter?.bluetoothLeScanner
        return scanner != null
    }

    // Scanner-Verfügbarkeit prüfen
    val isAvailable: Boolean
        get() = scanner != null

    // Basis-Scan ohne Filter starten
    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}")
    }
}

Die Klasse BLEScannerManager demonstriert das sichere Erhalten und Initialisieren von BluetoothLeScanner. initScanner prüft die BLE-Verfügbarkeit über hasSystemFeature, aktiviertes Bluetooth und erfolgreichen Scanner-Erhalt. startBasicScan startet das Scannen ohne Einstellungen und Filter — erkennt alle BLE-Geräte in Reichweite. handleResult analysiert ScanResult: BluetoothDevice (Name, Adresse), RSSI (Signalstärke), scanRecord (Werbedaten).

ScanSettings: Scan-Modi und Callback-Typ

ScanSettings ist eine Klasse zur Konfiguration des BLE-Scannens. Der Hauptparameter ist der Scan-Modus (scanMode), der den Kompromiss zwischen Energieverbrauch und Erkennungslatenz bestimmt. ScanSettings.Builder ermöglicht die Konfiguration von: scanMode, callbackType (CALLBACK_TYPE_ALL_MATCHES, CALLBACK_TYPE_FIRST_MATCH, CALLBACK_TYPE_MATCH_LOST), matchMode (MATCH_MODE_AGGRESSIVE, MATCH_MODE_STICKY), reportDelay (Stapel lieferverzögerung) und phy (PHY_LE_1M, PHY_LE_2M, PHY_LE_CODED).

Drei Scan-Modi: SCAN_MODE_LOW_POWER (0) — Hintergrundscannen mit niedrigem Energieverbrauch, Erkennungsverzögerung von mehreren Sekunden. SCAN_MODE_BALANCED (1) — Ausgeglichener Modus für die meisten Szenarien. SCAN_MODE_LOW_LATENCY (2) — Minimale Erkennungsverzögerung (ca. 100 ms), maximaler Energieverbrauch. Für aktive Gerätesuche verwenden Sie LOW_LATENCY, für Hintergrundüberwachung LOW_POWER.

reportDelay — Verzögerung in Millisekunden vor der Stapelauslieferung von Ergebnissen. Bei reportDelay = 0 werden Ergebnisse sofort bei Erkennung gesendet. Bei > 0 sammelt Android Ergebnisse und sendet einen Stapel über onBatchScanResults. Die Stapelauslieferung reduziert Callback-Aufrufe und Energieverbrauch, geeignet für Hintergrundscannen mit niedriger Priorität.

kotlin
// ScanSettings-Konfiguration für verschiedene Szenarien
class ScanSettingsProvider {

    // 1. Schneller Scan (aktive Suche)
    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. Energieeffizienter Scan (Hintergrundüberwachung)
    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)  // Stapel alle 2 Sekunden
            .build()
    }

    // 3. BLE Long Range Scan (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. Nur auf 2M PHY scannen (BLE 5.0+)
    fun highSpeedScan(): ScanSettings {
        return ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setPhy(ScanSettings.PHY_LE_2M)
            .build()
    }
}

Die Klasse ScanSettingsProvider enthält typische Konfigurationen. lowLatencyScan — für UI-Scannen (Suche „jetzt und hier“). lowPowerScan — für Hintergrundüberwachung mit Stapel alle 2 Sekunden und callbackType FIRST_MATCH (nur bei erster Erkennung ausgelöst). longRangeScan verwendet PHY_LE_CODED (BLE Long Range, bis 1 km). highSpeedScan — PHY_LE_2M (2 Mbit/s, nur BLE 5.0+-Geräte).

ScanFilter: Filterung von BLE-Geräten nach UUID und Name

ScanFilter ist eine Klasse zum Filtern von BLE-Scan-Ergebnissen. Ohne Filter gibt BluetoothLeScanner alle BLE-Geräte in Reichweite zurück — in einer dichten BLE-Umgebung können das hunderte Pakete pro Minute sein. ScanFilter grenzt die Ergebnisse auf die gewünschten Geräte ein und reduziert so Energieverbrauch und App-Last. Filter werden auf Bluetooth-Stack-Ebene angewendet — ungeeignete Pakete werden verworfen, bevor sie die App erreichen.

Filtertypen: setServiceUuid — Dienst-UUID (vollständiges 128-Bit-Format erforderlich). setDeviceName — Teilzeichenfolge des Gerätenamens (Groß-/Kleinschreibung, genaue Teilzeichenfolgenübereinstimmung). setDeviceAddress — genaue MAC-Adresse. setManufacturerData — Herstellerdaten (Unternehmens-ID + Maske). Für einen einzelnen Scan können mehrere Filter gesetzt werden — das Gerät muss allen entsprechen (UND-Logik). Für ODER-Logik starten Sie mehrere Scans.

kotlin
// ScanFilter-Erstellung für verschiedene Szenarien
class ScanFilterFactory {

    // 1. Nach Dienst-UUID filtern (Herzfrequenzmonitor)
    fun byHeartRateService(): ScanFilter {
        return ScanFilter.Builder()
            .setServiceUuid(
                ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB")
            )
            .build()
    }

    // 2. Nach Gerätenamen filtern ( "iBeacon*")
    fun byDeviceName(): ScanFilter {
        return ScanFilter.Builder()
            .setDeviceName("Sensor")
            .build()
    }

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

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

    // 5.   Herstellerdaten
    fun byManufacturer(companyId: Int, data: ByteArray, mask: ByteArray): ScanFilter {
        return ScanFilter.Builder()
            .setManufacturerData(companyId, data, mask)
            .build()
    }
}

Die Klasse ScanFilterFactory zeigt alle Filtertypen. byHeartRateService filtert Geräte mit dem Herzfrequenzdienst 0x180D. byDeviceName findet Geräte, die „Sensor“ im Namen enthalten (Apple empfiehlt eindeutige Namen für die Filterung). byMacAddress — genaue Suche nach einem bestimmten Gerät. combinedFilter — UND-Filter nach UUID und Name. byManufacturer — Filter nach Herstellerdaten (z.B. für iBeacon wird die Apple-Unternehmens-ID 0x004C verwendet).

ScanCallback: Verarbeitung von Scan-Ergebnissen und Fehlern

ScanCallback ist eine abstrakte Klasse zum Empfangen von BLE-Scan-Ergebnissen. Sie enthält drei Methoden: onScanResult — Einzelergebnis (Callback-Typ, ScanResult), onBatchScanResults — Stapelergebnisse für reportDelay > 0, onScanFailed — Fehlercode. Alle Methoden werden auf dem Android-Hauptthread aufgerufen. Für lange Verarbeitung in onScanResult verwenden Sie Coroutinen oder HandlerThread.

ScanResult enthält: BluetoothDevice device, int rssi (Signalpegel in dBm), ScanRecord scanRecord (Werbedaten), long timestampNanos (Erkennungszeit seit Systemstart). ScanRecord bietet: getServiceData() — UUID + benutzerdefinierte Daten, getManufacturerSpecificData() — Herstellerdaten, getAdvertiseFlags() — BLE-Flags. Der Callback-Typ gibt an: CALLBACK_TYPE_ALL_MATCHES — Übereinstimmung mit Filter, CALLBACK_TYPE_FIRST_MATCH — erste Erkennung, CALLBACK_TYPE_MATCH_LOST — Gerät verloren.

Fehlercodes von onScanFailed: SCAN_FAILED_ALREADY_STARTED (1) — Scannen bereits gestartet, SCAN_FAILED_APPLICATION_REGISTRATION_FAILED (2) — App-Registrierung im Bluetooth-Stack fehlgeschlagen, SCAN_FAILED_INTERNAL_ERROR (3) — interner Stack-Fehler, SCAN_FAILED_FEATURE_UNSUPPORTED (4) — BLE-Scannen auf diesem Gerät nicht unterstützt.

kotlin
// Vollständige Scan-Ergebnisse und Fehlerbehandlung
class ScanResultHandler {

    private val results = mutableListOf<ScanResult>()

    val scanCallback = object : ScanCallback() {

        // 1. Einzelergebnis
        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
            }

            // Zur Liste hinzufügen (nach Adresse deduplizieren)
            val existingIndex = results.indexOfFirst {
                it.device.address == result.device.address
            }
            if (existingIndex >= 0) {
                results[existingIndex] = result  // RSSI aktualisieren
            } else {
                results.add(result)
            }

            // Daten aus Werbepaket extrahieren
            val record = result.scanRecord
            val serviceData = record?.serviceData
            val manufacturerData = record?.manufacturerSpecificData

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

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

        // 3. Scan-Fehler
        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}")
    }
}

Die Klasse ScanResultHandler behandelt alle BluetoothLeScanner-Callback-Typen. onScanResult aktualisiert die Geräteliste mit Deduplizierung nach MAC-Adresse — RSSI wird für bereits gefundene Geräte aktualisiert. CALLBACK_TYPE_MATCH_LOST signalisiert Geräteverlust (Entfernung aus der Liste). onBatchScanResults verarbeitet Stapelergebnisse für reportDelay > 0. onScanFailed ordnet Fehlercodes lesbaren Nachrichten zu — kritisch für das Debuggen von BLE-Scans.

PendingIntent: Hintergrund-BLE-Scannen über BroadcastReceiver

PendingIntent-Scannen ist ein BluetoothLeScanner-Mechanismus für BLE-Scannen, das auch funktioniert, wenn die App im Hintergrund ist (mit Android 8+-Einschränkungen). Statt ScanCallback wird ein PendingIntent verwendet, der bei Erkennung eines BLE-Geräts einen Broadcast an den systemeigenen BroadcastReceiver sendet. Dadurch kann die App BLE-Gerätebenachrichtigungen empfangen, ohne im Speicher zu bleiben (das System erstellt den Prozess beim Empfang des Broadcasts).

Einschränkungen des Hintergrundscannens: Auf Android 8+ (API 26) sind Hintergrunddienste eingeschränkt — PendingIntent-Scannen umgeht diese Einschränkung über BroadcastReceiver, den das System beim Empfang eines BLE-Ereignisses starten kann. Auf Android 10+ (API 29) ist das BLE-Hintergrundscannen zusätzlich durch Hersteller-Energiesparrichtlinien eingeschränkt (Xiaomi, Huawei, Samsung blockieren Hintergrund-BLE-Operationen). Für kritische BLE-Szenarien ist eine Vordergrunddienst-Benachrichtigung erforderlich.

kotlin
// Hintergrund-BLE-Scannen über PendingIntent
class BackgroundBLEScanner(private val context: Context) {

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

    fun startBackgroundScan() {
        // PendingIntent für BroadcastReceiver erstellen
        val intent = Intent(context, BLEBroadcastReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(
            context,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        // Hintergrund-Scan-Einstellungen
        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH)
            .setMatchMode(ScanSettings.MATCH_MODE_STICKY)
            .build()

        // Hintergrund-Scan starten
        scanner?.startScan(
            null,  // Filter
            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) {
        // Scan-Ergebnisse abrufen
        val results = BluetoothLeScanner.getPendingIntentScanResults(intent)
        results?.let { scanResults ->
            for (result in scanResults) {
                // Benachrichtigung an Benutzer senden
                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)
    }
}

Die Klasse BackgroundBLEScanner startet das Hintergrund-BLE-Scannen über PendingIntent. startBackgroundScan erstellt einen PendingIntent, der bei Erkennung eines BLE-Geräts einen Broadcast an BLEBroadcastReceiver sendet. Der BroadcastReceiver extrahiert ScanResult über getPendingIntentScanResults() und kann eine Benachrichtigung anzeigen oder Daten an den Server senden. Dieser Ansatz funktioniert auch, wenn die App vom System beendet wurde — Android startet den BroadcastReceiver beim Empfang des Broadcasts neu.

BLE-Scanner-Beispiel in Kotlin mit BluetoothLeScanner

Vollständiges Beispiel eines BLE-Scanners in Kotlin, der BluetoothLeScanner mit ScanSettings, ScanFilter und ScanCallback verwendet, um Heart Rate Monitor-Geräte zu finden. Der Scanner zeigt eine Liste der gefundenen Geräte mit RSSI und Dienst-UUIDs an, mit der Möglichkeit, über BluetoothGatt zu verbinden.

kotlin
// Vollständiger BLE-Scanner mit Coroutinen in Kotlin
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-Status prüfen
        if (adapter?.isEnabled != true) {
            close(IllegalStateException("Bluetooth disabled"))
            return@callbackFlow
        }

        // Scan-Konfiguration
        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"))
            }
        }

        // Scannen starten
        scanner?.startScan(filters, settings, callback)

        // Automatischer Stopp nach Zeit
        delay(duration)
        scanner?.stopScan(callback)
        close()
    }.flowOn(Dispatchers.IO)

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

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

Die Klasse DeviceScanner verwendet Kotlin Flow (callbackFlow) für reaktives BLE-Scannen. Das Scannen wird mit LOW_LATENCY-Einstellungen und einem Heart Rate Service UUID-Filter gestartet. Ergebnisse werden über onScanResult in einen Flow ausgegeben. Automatischer Stopp nach einer bestimmten Dauer (Standard 10 Sekunden). FlowOn(Dispatchers.IO) lagert BLE-Operationen auf einen Hintergrundthread aus. Dieser Ansatz ermöglicht BLE-Scannen in der MVVM-Architektur über viewModelScope.launch und collect.

Häufig gestellte Fragen

Was ist BluetoothLeScanner in Android?

BluetoothLeScanner ist eine Android-Klasse (API 21+) für BLE-Scannen. Sie wird über BluetoothAdapter.getBluetoothLeScanner() bezogen. Unterstützt drei Scan-Modi (LOW_POWER, BALANCED, LOW_LATENCY), Filterung nach UUID, Name und MAC-Adresse, Stapelergebnisse und PendingIntent für Hintergrundscannen. Ersetzt die veraltete Methode BluetoothAdapter.startLeScan().

Wie unterscheidet sich LOW_POWER von LOW_LATENCY?

SCAN_MODE_LOW_POWER — Hintergrundmodus mit 5–10 Sekunden Erkennungsverzögerung, minimaler Energieverbrauch. SCAN_MODE_LOW_LATENCY — aktiver Modus mit etwa 100 ms Verzögerung, maximaler Energieverbrauch. SCAN_MODE_BALANCED — Kompromiss (~2 Sekunden Verzögerung). Verwenden Sie LOW_LATENCY für UI-Scannen, LOW_POWER mit PendingIntent für Hintergrundüberwachung.

Warum findet BluetoothLeScanner keine Geräte?

Ursachen: Bluetooth deaktiviert (prüfen Sie adapter.isEnabled), fehlende Berechtigungen (BLUETOOTH_SCAN ab API 31+, ACCESS_FINE_LOCATION auf API 23–30), scanner = null (Adapter nicht verfügbar), Gerät außerhalb der Reichweite oder falscher Filter. Prüfen Sie auch onScanFailed — der Fehlercode gibt die Ursache an: SCAN_FAILED_ALREADY_STARTED (1) oder SCAN_FAILED_APPLICATION_REGISTRATION_FAILED (2).

Wie scanne ich BLE im Hintergrund auf Android?

Verwenden Sie die PendingIntent-Version von startScan() — übergeben Sie einen PendingIntent statt ScanCallback. Wenn ein BLE-Gerät erkannt wird, sendet Android einen Broadcast an den BroadcastReceiver, der vom System gestartet werden kann, auch wenn die App im Hintergrund ist. Für Android 8+ fügen Sie den BroadcastReceiver im Manifest hinzu. Auf Android 10+ beachten Sie die Hersteller-Energiespar einschränkungen.

Wie viele BLE-Geräte können in einem Scan erkannt werden?

BluetoothLeScanner hat keine Begrenzung der Anzahl erkennbarer Geräte — die Begrenzung hängt von der BLE-Sättigung der Umgebung ab. Ein Büro kann 20–50 aktive BLE-Geräte haben, ein Einkaufszentrum hunderte. Verwenden Sie ScanFilter (nach UUID, Name) zum Filtern. Ohne Filterung verarbeiten Sie die Ergebnisse asynchron — onScanResult kann dutzende Male pro Sekunde aufgerufen werden.

Zusammenfassung

  • BluetoothLeScanner — moderne Android-Klasse (API 21+) für BLE-Scannen mit Einstellungen und Filterung
  • ScanSettings — drei Modi: LOW_POWER (Hintergrund), BALANCED, LOW_LATENCY (aktiv)
  • ScanFilter — Filterung nach Dienst-UUID, Gerätename, MAC-Adresse, Herstellerdaten mit UND-Logik
  • ScanCallback — onScanResult (einzeln), onBatchScanResults (Stapel), onScanFailed (Fehlercodes)
  • PendingIntent — Hintergrundscannen über BroadcastReceiver, funktioniert bei beendeter App
  • ScanRecord — BLE-Werbedaten: serviceData, manufacturerSpecificData, advertiseFlags, TX power level
  • Kotlin Flow — callbackFlow ermöglicht die Verwendung von BluetoothLeScanner in reaktiver Architektur mit automatischem Stopp

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch