Android使用BluetoothLeAdvertiser基于BLE 2M PHY广播数据,扫描无结果排查
BLE 2M PHY扫描无结果问题排查
我正在开发一款基于低功耗蓝牙(BLE)广播的聊天应用,参考Android官方BLE广播教程实现客户端,但我的BluetoothLeScanner无法获取任何BLE 2M PHY的扫描结果。使用nRF Connect应用可正常实现预期效果,因此基本排除硬件问题。以下是我的广告端实现代码:
class BluetoothAdvertiser(private var bluetoothAdapter: BluetoothAdapter) { private val TAG: String = BluetoothAdvertiser::class.java.simpleName private var advertiseUUID: ParcelUuid = ParcelUuid(UUID.fromString("e889813c-5d19-49e2-8bc4-d4596b4f5250")) private var advertiser: BluetoothLeAdvertiser = bluetoothAdapter.bluetoothLeAdvertiser private var maxDataLength: Int = 0 private lateinit var currentAdvertisingData: AdvertiseData private lateinit var currentAdvertisingSet: AdvertisingSet fun init(): Boolean { Log.d(TAG, "init: ") if (!this.checkDeviceHardware()) { return false } this.initAdvertiser("123") return true } private fun checkDeviceHardware(): Boolean { if (!this.bluetoothAdapter.isLe2MPhySupported) { Log.e(TAG, "init: 2M PHY not supported") return false } if (!this.bluetoothAdapter.isLeExtendedAdvertisingSupported) { Log.e(TAG, "init: LE Extended Advertising not supported") return false } this.maxDataLength = this.bluetoothAdapter.leMaximumAdvertisingDataLength Log.d(TAG, "init: leMaximumAdvertisingDataLength: " + this.maxDataLength) return true } private fun initAdvertiser(message: String): Boolean { val setParameters: AdvertisingSetParameters = AdvertisingSetParameters.Builder() .setLegacyMode(false) .setInterval(AdvertisingSetParameters.INTERVAL_HIGH) .setTxPowerLevel(AdvertisingSetParameters.TX_POWER_MEDIUM) .setPrimaryPhy(BluetoothDevice.PHY_LE_CODED) .setSecondaryPhy(BluetoothDevice.PHY_LE_2M) .build() val advertiseData: AdvertiseData = AdvertiseData.Builder() .setIncludeDeviceName(true) .addServiceUuid(advertiseUUID) .addServiceData(advertiseUUID, message.encodeToByteArray()) .build() val periodicParameters: PeriodicAdvertisingParameters = PeriodicAdvertisingParameters.Builder() .setInterval(800) .build() return try { this.advertiser.startAdvertisingSet( setParameters, advertiseData, advertiseData, periodicParameters, advertiseData, this.advertisingSetCallback ) true } catch (e: SecurityException) { Log.w(TAG, "initAdvertiser: ",e) false } } fun changeAdvertisingData(message: String){ try{ Log.d(TAG, "changeAdvertisingData: message: $message" ) this.currentAdvertisingSet.setAdvertisingData(AdvertiseData.Builder().addServiceData(this.advertiseUUID,message.encodeToByteArray()).build()) } catch (e: SecurityException) { Log.w(TAG, "initAdvertiser: ",e) } } private var advertisingSetCallback: AdvertisingSetCallback = object : AdvertisingSetCallback() { override fun onAdvertisingSetStarted( advertisingSet: AdvertisingSet, txPower: Int, status: Int ) { Log.i( TAG, "onAdvertisingSetStarted(): txPower: $txPower , status: $status " ) currentAdvertisingSet = advertisingSet } override fun onAdvertisingSetStopped(advertisingSet: AdvertisingSet) { Log.i(TAG, "onAdvertisingSetStopped():") } } }
问题分析与解决方案
核心问题点
- 广告端主PHY配置:当前代码将主PHY设为
PHY_LE_CODED,如果扫描端未配置支持该PHY,将无法接收广告包。 - 扫描端PHY配置缺失:未提供扫描端代码,但大概率是扫描时未指定支持2M和CODED PHY,导致无法匹配广告端的PHY设置。
具体修复步骤
1. 广告端验证与调整
- 检查
onAdvertisingSetStarted回调中的status值:若status为0则广告启动成功,非0需对应排查错误码(如ADVERTISE_FAILED_DATA_TOO_LARGE表示数据超限)。 - 可尝试将主PHY改为
PHY_LE_2M测试:val setParameters: AdvertisingSetParameters = AdvertisingSetParameters.Builder() // ...其他配置 .setPrimaryPhy(BluetoothDevice.PHY_LE_2M) .setSecondaryPhy(BluetoothDevice.PHY_LE_2M) .build()
2. 扫描端关键配置补充
确保扫描时配置支持所有所需PHY:
// 构建扫描设置 val scanSettings = ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // 根据需求选择扫描模式 .setPhy(ScanSettings.PHY_LE_ALL) // 覆盖所有支持的PHY,或明确指定PHY_LE_2M | PHY_LE_CODED .build() // 启动扫描 bluetoothAdapter.bluetoothLeScanner.startScan(null, scanSettings, object : ScanCallback() { override fun onScanResult(callbackType: Int, result: ScanResult?) { super.onScanResult(callbackType, result) // 处理扫描结果 result?.let { Log.d("Scan", "Found device: ${it.device.name}, PHY: ${it.phy}") } } })
3. 权限与系统配置检查
- Android 12及以上版本需申请
BLUETOOTH_SCAN权限(在Manifest中声明,并动态申请)。 - 部分设备需开启位置权限才能正常扫描BLE设备。
内容的提问来源于stack exchange,提问作者Internetus
相关产品推荐
相关产品推荐

