| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- package com.narutohuo.xindazhou.ble.util
- import android.bluetooth.BluetoothAdapter
- import android.bluetooth.BluetoothDevice
- import android.bluetooth.BluetoothManager
- import android.bluetooth.le.BluetoothLeScanner
- import android.bluetooth.le.ScanCallback
- import android.bluetooth.le.ScanFilter
- import android.bluetooth.le.ScanResult
- import android.bluetooth.le.ScanSettings
- import android.content.Context
- import android.os.Handler
- import android.os.Looper
- import com.narutohuo.xindazhou.core.log.ILog
- /**
- * BLE扫描器
- *
- * 负责 BLE 设备的扫描,返回符合过滤条件的 BluetoothDevice 列表
- * 使用 Android 12+ 推荐的 BluetoothLeScanner API
- */
- class BleScanner(
- private val context: Context,
- private val onDeviceFound: (BluetoothDevice) -> Unit,
- private val onScanFinished: () -> Unit
- ) {
-
- private val tag = "BleScanner"
-
- private val bluetoothAdapter: BluetoothAdapter by lazy {
- val manager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
- manager.adapter
- }
-
- private var scanner: BluetoothLeScanner? = null
- private var scanning = false
-
- private val scanCallback = object : ScanCallback() {
- override fun onScanResult(callbackType: Int, result: ScanResult) {
- result.device?.let {
- onDeviceFound(it)
- stopScan()
- }
- }
-
- override fun onBatchScanResults(results: List<ScanResult>) {
- results.forEach {
- it.device?.let { device ->
- onDeviceFound(device)
- stopScan()
- }
- }
- }
-
- override fun onScanFailed(errorCode: Int) {
- ILog.e(tag, "BLE scan failed, error=$errorCode")
- stopScan()
- }
- }
-
- /**
- * 开始扫描(默认 10 秒后自动停止)
- */
- @android.annotation.SuppressLint("MissingPermission")
- fun startScan(filterNamePrefix: String? = null, timeoutMs: Long = 10_000L) {
- if (scanning) return
-
- scanner = bluetoothAdapter.bluetoothLeScanner
- val settings = ScanSettings.Builder()
- .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
- .build()
-
- val filters = mutableListOf<ScanFilter>()
- filterNamePrefix?.let {
- filters.add(ScanFilter.Builder().setDeviceName(it).build())
- }
-
- try {
- scanner?.startScan(filters, settings, scanCallback)
- scanning = true
- ILog.d(tag, "开始扫描BLE设备,过滤前缀: $filterNamePrefix")
-
- // 超时自动停止
- Handler(Looper.getMainLooper()).postDelayed({ stopScan() }, timeoutMs)
- } catch (e: SecurityException) {
- ILog.e(tag, "扫描权限不足", e)
- scanning = false
- } catch (e: Exception) {
- ILog.e(tag, "启动扫描失败", e)
- scanning = false
- }
- }
-
- /**
- * 停止扫描
- */
- @android.annotation.SuppressLint("MissingPermission")
- fun stopScan() {
- if (!scanning) return
-
- try {
- scanner?.stopScan(scanCallback)
- scanning = false
- ILog.d(tag, "停止扫描")
- onScanFinished()
- } catch (e: SecurityException) {
- ILog.e(tag, "停止扫描权限不足", e)
- } catch (e: Exception) {
- ILog.e(tag, "停止扫描失败", e)
- }
- }
- }
|