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 فراہم کرتا ہے۔ یہ کلاس 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) — کم سے کم دریافت میں تاخیر (تقریباً 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 اسکیننگ BLE اسکیننگ کے لیے BluetoothLeScanner کا ایک طریقہ کار ہے جو اس وقت بھی کام کرتا ہے جب ایپ پس منظر میں ہو (Android 8+ پابندیوں کے ساتھ)۔ ScanCallback کے بجائے، ایک PendingIntent استعمال کیا جاتا ہے، جو BLE ڈیوائس دریافت ہونے پر سسٹم BroadcastReceiver کو Broadcast بھیجتا ہے۔ یہ ایپ کو میموری میں رہے بغیر BLE ڈیوائس اطلاعات حاصل کرنے کی اجازت دیتا ہے (سسٹم براڈکاسٹ وصول کرنے پر عمل بناتا ہے)۔

پس منظر اسکیننگ کی حدود: 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 براڈکast وصول کرنے پر BroadcastReceiver کو دوبارہ شروع کرتا ہے۔

Kotlin میں BluetoothLeScanner کے ساتھ BLE اسکینر کی مثال

مکمل مثال Kotlin میں BLE اسکینر کی جو BluetoothLeScanner کو ScanSettings، ScanFilter اور ScanCallback کے ساتھ استعمال کرتے ہوئے Heart Rate Monitor آلات تلاش کرتا ہے۔ اسکینر ملنے والے آلات کی فہرست RSSI اور سروس UUIDs کے ساتھ دکھاتا ہے، جس میں 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں