Android 12环境下BLE应用中BluetoothDevice.getName()方法返回null问题求助
Android 12下BLE设备名称返回null的解决方案
我之前在开发BLE应用时也遇到过一模一样的问题——Android 12以下版本正常,升级后连接成功但BluetoothDevice.getName()始终返回null,即使权限都配置到位了。结合官方文档和实际调试经验,给你几个可行的解决方向:
1. 修正BLUETOOTH_SCAN权限的声明
Android 12+对BLE扫描权限做了更严格的限制,即使你的应用不需要位置信息,也必须明确声明这一点,否则系统会默认限制设备信息的获取。修改Manifest中的BLUETOOTH_SCAN权限:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
如果你的应用确实需要通过BLE扫描获取位置,那要确保ACCESS_FINE_LOCATION的运行时权限也已正确申请。
2. 在扫描阶段缓存设备名称
Android 12+对连接后获取设备名称做了限制,建议在扫描回调中提前缓存设备的地址与名称映射,后续用地址匹配获取名称:
// 全局缓存设备地址和名称的映射 private Map<String, String> deviceNameCache = new HashMap<>(); // 扫描回调中缓存名称 @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); BluetoothDevice device = result.getDevice(); if (device.getName() != null) { deviceNameCache.put(device.getAddress(), device.getName()); } } // 在onCharacteristicChanged中使用缓存的名称 public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { super.onCharacteristicChanged(gatt, characteristic); String deviceAddress = gatt.getDevice().getAddress(); // 优先从缓存取名称,取不到用地址兜底 String deviceName = deviceNameCache.getOrDefault(deviceAddress, deviceAddress); Log.e("prepareCallSMSData", "onCharacteristicChanged BluetoothGatt " + deviceName); Log.e("prepareCallSMSData", "device to app : " + MokoUtils.bytesToHexString(characteristic.getValue())); mMokoResponseCallback.onCharacteristicChanged(deviceName, characteristic, characteristic.getValue()); }
3. 主动读取GATT服务中的设备名称特征
部分BLE设备会在GATT服务中广播设备名称(通常是0x1800服务下的0x2A00特征),可以在连接成功后主动读取这个特征来获取名称:
@Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED) { // 连接成功后发现服务 gatt.discoverServices(); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if (status == BluetoothGatt.GATT_SUCCESS) { // 获取通用访问服务(0x1800) BluetoothGattService service = gatt.getService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); if (service != null) { // 获取设备名称特征(0x2A00) BluetoothGattCharacteristic nameChar = service.getCharacteristic(UUID.fromString("00002a00-0000-1000-8000-00805f9b34fb")); if (nameChar != null) { // 读取特征值 gatt.readCharacteristic(nameChar); } } } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicRead(gatt, characteristic, status); if (status == BluetoothGatt.GATT_SUCCESS) { // 解析设备名称并缓存 String deviceName = new String(characteristic.getValue()); deviceNameCache.put(gatt.getDevice().getAddress(), deviceName); } }
4. 检查BLE设备的固件设置
有些BLE设备在建立连接后会停止广播设备名称,导致系统无法获取。可以确认设备固件是否有相关配置,或者尝试在连接后重新触发一次扫描(注意Android 12+扫描需要权限)。
内容的提问来源于stack exchange,提问作者Rajesh android developer




