You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin开发BLE设备扫描无结果问题求助

解决Android BLE扫描不到设备的问题

针对BLE扫描无结果的问题,可以从以下几个关键方向排查修复:

1. 完善权限适配与检查

Android不同版本对BLE权限的要求差异很大,当前代码仅检查了ACCESS_COARSE_LOCATION,权限覆盖不全:

  • Manifest权限补充:针对Android 12+添加权限标记,确保权限生效:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>

<!-- Android 12+ 权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

<!-- 旧版本位置权限,建议用ACCESS_FINE_LOCATION更可靠 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
  • 代码中权限申请逻辑更新:一次性申请所有必要权限,避免遗漏:
fun startScan() {
    val requiredPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        arrayOf(
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    } else {
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.BLUETOOTH
        )
    }

    if (requiredPermissions.any {
            ContextCompat.checkSelfPermission(activity, it) != PackageManager.PERMISSION_GRANTED
        }) {
        ActivityCompat.requestPermissions(activity, requiredPermissions, REQUEST_PERMISSION_CODE)
        return
    }

    // 后续扫描逻辑...
}

2. 检查蓝牙状态并请求开启

代码未确认蓝牙是否开启,这是扫描无结果的常见原因:

fun startScan() {
    // 先检查蓝牙适配器是否可用,以及蓝牙是否开启
    if (bluetoothAdapter == null) {
        Log.e(TAG, "设备不支持BLE")
        return
    }
    if (!bluetoothAdapter!!.isEnabled) {
        val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
        activity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
        return
    }

    // 权限检查逻辑...
}

在MainActivity中添加蓝牙开启结果处理:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == BleScanner.REQUEST_ENABLE_BT) {
        if (resultCode == RESULT_OK) {
            bleScanner.startScan()
        } else {
            Log.w(TAG, "用户未开启蓝牙,无法扫描")
        }
    }
}

在BleScanner的companion object中添加常量:

const val REQUEST_ENABLE_BT = 456

3. 修复扫描回调,排查设备识别问题

当前回调直接假设设备是HM-10,但部分BLE设备广播名称为空,或者名称不匹配,先打印所有扫描到的设备,同时添加扫描失败回调:

private val scanCallback = object : ScanCallback() {
    override fun onScanResult(callbackType: Int, result: ScanResult) {
        super.onScanResult(callbackType, result)
        val device = result.device
        // 处理名称为空的情况
        val deviceName = device.name ?: "未知设备"
        Log.d(TAG, "扫描到设备: $deviceName (${device.address}), RSSI = ${result.rssi} dBm")
        
        // 再筛选目标HM-10设备
        if ("HM-10".equals(deviceName, ignoreCase = true)) {
            Log.d(TAG, "找到目标设备HM-10: $deviceName (${device.address}), RSSI = ${result.rssi} dBm")
        }
    }

    // 必须重写此方法,排查扫描启动失败的原因
    override fun onScanFailed(errorCode: Int) {
        super.onScanFailed(errorCode)
        val errorMsg = when(errorCode) {
            SCAN_FAILED_ALREADY_STARTED -> "扫描已启动"
            SCAN_FAILED_APPLICATION_REGISTRATION_FAILED -> "应用注册失败"
            SCAN_FAILED_FEATURE_UNSUPPORTED -> "设备不支持BLE扫描"
            SCAN_FAILED_INTERNAL_ERROR -> "内部错误"
            else -> "未知错误: $errorCode"
        }
        Log.e(TAG, "扫描失败: $errorMsg")
    }
}

4. 修正Handler初始化

避免线程问题,使用主线程Looper初始化Handler:

// MainActivity中初始化BleScanner时
bleScanner = BleScanner(this, Handler(Looper.getMainLooper()))

5. 完善权限授权回调

确保所有必要权限都被授予后再启动扫描:

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when (requestCode) {
        BleScanner.REQUEST_PERMISSION_CODE -> {
            val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
            if (allGranted) {
                bleScanner.startScan()
            } else {
                Log.w(TAG, "部分权限未授予,无法启动BLE扫描")
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Sergio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:37:05