BluetoothLeScanner — यह क्या है, विधियाँ और Android में BLE स्कैनिंग

लेखक: IT Sectr प्रकाशित: 2026-07-16 पढ़ने का समय: 10 मिनट

BluetoothLeScanner Android में Bluetooth Low Energy उपकरणों को स्कैन करने के लिए एक क्लास है, जो 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 स्कैनिंग प्रबंधित करने के लिए एक सिस्टम क्लास है। BluetoothAdapter.startLeScan() के विपरीत, जो एक सरल LeScanCallback स्वीकार करता है, BluetoothLeScanner सेटिंग्स, फ़िल्टर और उन्नत त्रुटि प्रबंधन के साथ एक ऑब्जेक्ट-ओरिएंटेड API प्रदान करता है। यह क्लास API 21 (Android 5.0) में BLE 4.2 समर्थन के साथ पेश की गई थी और सभी आधुनिक 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) — न्यूनतम खोज विलंबता (लगभग 100 ms), अधिकतम बिजली खपत। सक्रिय डिवाइस खोज के लिए 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 लॉन्ग रेंज स्कैन (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 लॉन्ग रेंज, 1 किमी तक) का उपयोग करता है। highSpeedScan — PHY_LE_2M (2 Mbit/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 स्कैनिंग BluetoothLeScanner का एक तंत्र है जो BLE स्कैनिंग के लिए है जो तब भी काम करता है जब ऐप बैकग्राउंड में हो (Android 8+ प्रतिबंधों के साथ)। ScanCallback के बजाय, एक PendingIntent का उपयोग किया जाता है, जो BLE डिवाइस मिलने पर सिस्टम BroadcastReceiver को Broadcast भेजता है। यह ऐप को मेमोरी में रहे बिना BLE डिवाइस सूचनाएँ प्राप्त करने की अनुमति देता है (सिस्टम broadcast प्राप्त करने पर प्रक्रिया बनाता है)।

बैकग्राउंड स्कैनिंग सीमाएँ: Android 8+ (API 26) पर, बैकग्राउंड सेवाएँ प्रतिबंधित हैं — PendingIntent स्कैनिंग BroadcastReceiver के माध्यम से इस सीमा को बायपास करती है, जिसे सिस्टम BLE घटना प्राप्त करने पर शुरू कर सकता है। 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 एक PendingIntent बनाता है जो BLE डिवाइस मिलने पर BLEBroadcastReceiver को Broadcast भेजता है। BroadcastReceiver getPendingIntentScanResults() के माध्यम से ScanResult निकालता है और अधिसूचना दिखा सकता है या सर्वर को डेटा भेज सकता है। यह दृष्टिकोण तब भी काम करता है जब ऐप सिस्टम द्वारा समाप्त कर दिया गया हो — Android broadcast प्राप्त करने पर BroadcastReceiver को पुनरारंभ करता है।

Kotlin में BluetoothLeScanner के साथ BLE स्कैनर उदाहरण

पूर्ण उदाहरण Kotlin में BLE स्कैनर का, जो Heart Rate Monitor उपकरणों को खोजने के लिए BluetoothLeScanner को ScanSettings, ScanFilter और ScanCallback के साथ उपयोग करता है। स्कैनर मिले उपकरणों की सूची RSSI और सेवा UUID के साथ दिखाता है, जिसमें BluetoothGatt के माध्यम से कनेक्ट करने की क्षमता है।

kotlin
// Kotlin में coroutines के साथ पूर्ण 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 — लगभग 100 ms विलंबता के साथ सक्रिय मोड, अधिकतम बिजली खपत। 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 एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें