Android BLE扫描部分设备名称返回null问题求助
BLE扫描时部分设备名称为null的问题解决建议
我是一名Android应用开发初学者,正在开发一款与ESP32微控制器通信的BLE应用。已成功配置应用(开启BLE和位置权限),并能扫描附近BLE设备,但发现调用BA.startDiscovery()时,部分设备的名称被检测为null。
调试日志
E/SCAN BUTTON: Clicked E/CHECK: CHECKING LOCATION PERMISSION E/INFO: LOCATION PERMISSION ALREADY GRANTED: E/INFO: LOCATION PERMISSION IS OK, START BLE DISCOVERY I/BluetoothAdapter: startDiscovery E/CALLBACK: onReceive E/BroadcastReceiver: SCANNING IN PROGRESS E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = DESKTOP-KPO80BS I/System.out: DEVICE MAC FOUND = 64:6E:69:78:B9:54 E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = null I/System.out: DEVICE MAC FOUND = 5E:52:CD:CD:EB:EA E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = [LG] webOS TV UP75003LF I/System.out: DEVICE MAC FOUND = 4C:BC:E9:4E:62:17 E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = null I/System.out: DEVICE MAC FOUND = 7F:CA:0B:28:8E:86 E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = CGATES-DV8947 I/System.out: DEVICE MAC FOUND = 10:76:36:B5:7C:A4 E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = [LG] webOS TV UP75003LF I/System.out: DEVICE MAC FOUND = 7C:5E:DC:65:EB:E9 E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = JBL Bar 5.1_5883 I/System.out: DEVICE MAC FOUND = 7E:96:FC:6A:9F:A9 E/CALLBACK: onReceive I/System.out: DEVICE NAME FOUND = null I/System.out: DEVICE MAC FOUND = 4E:AE:EC:2B:D9:52 E/CALLBACK: onReceive E/BroadcastReceiver: DISCOVERY FINISHED
设备显示效果

build.gradle配置
plugins { id 'com.android.application' } android { namespace 'com.example.location_test_v2' compileSdk 33 defaultConfig { applicationId "com.example.location_test_v2" minSdk 25 targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation "androidx.fragment:fragment:1.5.6" implementation "androidx.activity:activity:1.7.0" implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } configurations.implementation { exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' }
扫描回调代码
private final BroadcastReceiver devicesFoundReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { Log.e("CALLBACK", "onReceive"); String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); String deviceName = device.getName(); String deviceHardwareAddress = device.getAddress(); // MAC address System.out.print("DEVICE NAME FOUND = "); System.out.println(deviceName); System.out.print("DEVICE MAC FOUND = "); System.out.println(deviceHardwareAddress); list.add(deviceName); } else if(BA.ACTION_DISCOVERY_FINISHED.equals(action)){ Log.e("BroadcastReceiver", "DISCOVERY FINISHED "); ArrayAdapter adapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1,list); listview.setAdapter(adapter); } else if(BA.ACTION_DISCOVERY_STARTED.equals(action)){ listview.setAdapter(null); Log.e("BroadcastReceiver", "SCANNING IN PROGRESS"); } } };
问题解决建议
核心原因
BluetoothAdapter.startDiscovery()是经典蓝牙扫描API,并非专为BLE设备设计。对于BLE设备,它可能无法正确解析广播包中的设备名称;部分BLE设备本身未设置广播名称;或者Android系统的扫描缓存/过滤逻辑导致名称无法被获取。
方案1:改用BLE专用扫描API
替换经典扫描为BLE原生扫描API,能直接获取BLE广播数据,从中解析设备名称:
// 初始化BLE扫描器 BluetoothLeScanner bleScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner(); // 配置扫描参数 ScanSettings scanSettings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // 低延迟模式,适合主动扫描 .build(); // 开始扫描(可添加过滤条件,这里为空) bleScanner.startScan(new ArrayList<>(), scanSettings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); BluetoothDevice device = result.getDevice(); String deviceName = device.getName(); // 如果getName()为null,从广播包中解析名称 if (deviceName == null) { ScanRecord scanRecord = result.getScanRecord(); if (scanRecord != null) { deviceName = scanRecord.getDeviceName(); // 若仍为空,自定义默认名称 if (deviceName == null) deviceName = "Unknown BLE Device"; } } String macAddress = device.getAddress(); // 将设备信息添加到列表 list.add(deviceName + " (" + macAddress + ")"); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); Log.e("BLE_SCAN", "扫描失败,错误码:" + errorCode); } });
方案2:优化现有代码的null值处理
如果暂时不想切换扫描API,可在现有回调中处理null名称,避免列表显示异常:
// 修改回调中的设备名称处理逻辑 String deviceName = device.getName(); // 当名称为null时替换为自定义文本 if (deviceName == null) { deviceName = "未知设备"; } list.add(deviceName);
方案3:检查ESP32的BLE配置
确保ESP32的BLE广播中正确设置了设备名称,以Arduino代码为例:
#include <BLEDevice.h> void setup() { // 初始化BLE设备并设置广播名称 BLEDevice::init("ESP32_MyDevice"); // ... 其他BLE配置代码 }
如果ESP32未设置广播名称,扫描到的设备名称自然为null。
内容的提问来源于stack exchange,提问作者TheBestPlayer
相关产品推荐
相关产品推荐

