Android 8中ScanResult.getDevice().getName()始终为null的问题求助
Android 8中BLE扫描返回deviceName始终为null的解决方案
核心原因
Android 8(API 26)开始,系统不会自动通过BluetoothDevice.getName()返回BLE设备名称,而是需要从ScanResult的ScanRecord广播数据中手动解析设备名称字段,这是系统对BLE扫描行为的调整,用于减少不必要的设备信息解析开销。
解决方案
1. 从ScanRecord中手动解析设备名称
实现工具方法,从扫描返回的ScanRecord中提取设备名称(支持完整名称和短名称),解析失败时回退到BluetoothDevice.getName():
import java.nio.charset.StandardCharsets; import java.util.Arrays; private String getDeviceNameFromScanRecord(ScanResult result) { ScanRecord scanRecord = result.getScanRecord(); if (scanRecord == null) { return result.getDevice().getName(); } byte[] scanData = scanRecord.getBytes(); int offset = 0; while (offset < scanData.length - 1) { int length = scanData[offset] & 0xFF; if (length == 0) break; offset++; int adType = scanData[offset] & 0xFF; // 0x08: 短设备名称, 0x09: 完整设备名称 if (adType == 0x08 || adType == 0x09) { return new String( Arrays.copyOfRange(scanData, offset + 1, offset + length), StandardCharsets.UTF_8 ); } offset += length; } // 解析不到时回退到BluetoothDevice的名称 return result.getDevice().getName(); }
2. 修改扫描回调逻辑
将原来依赖BluetoothDevice.getName()的代码替换为上述工具方法:
@Override @SuppressLint("MissingPermission") public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); String deviceName = getDeviceNameFromScanRecord(result); if(deviceName != null) { txtLog.append("\nDN" + deviceName); mDiscoveredDevices.add(result.getDevice()); } }
3. 验证Android 8的权限与系统设置
- 确认
ACCESS_FINE_LOCATION权限已授予:你的运行时权限请求逻辑已覆盖Android 8,需确保用户完成授权操作。 - 开启设备位置服务:Android 8开始,即使拥有位置权限,关闭位置服务会导致BLE扫描无法获取完整设备信息(包括名称),需引导用户开启位置服务。
额外说明
- 该方案兼容Android 6+所有版本,不会影响你在Android 6、10、12上的现有功能。
- 优先从
ScanRecord解析设备名称更可靠:除Android 8外,部分低功耗设备也可能不会主动将名称写入BluetoothDevice对象。
内容的提问来源于stack exchange,提问作者Lipsyor
相关产品推荐
相关产品推荐

