Android Oreo中通过代码获取蓝牙MAC地址返回null,如何解决?
原因分析
从Android 8.0(API 26)开始,Google为了加强用户隐私保护,对应用获取本机蓝牙MAC地址做了严格限制:
- 你之前使用的
Settings.Secure.getString(context.getContentResolver(), "bluetooth_address")方法会直接返回null - 哪怕调用
BluetoothAdapter.getAddress(),也只会返回固定的占位符02:00:00:00:00:00,而非真实的MAC地址
这就是你添加了权限仍无法获取结果的核心原因——权限不再是主要问题,而是系统层面的隐私限制导致的。
可行解决方案
根据你的应用类型,有不同的处理方式:
1. 系统应用/特权应用
如果你的应用是系统预装应用,或者拥有与系统一致的签名,可以申请BLUETOOTH_PRIVILEGED权限(该权限属于signature级别,普通第三方应用无法获取)。添加权限后,就能正常使用你原来的代码获取真实的蓝牙MAC地址。
2. 普通第三方应用
对于普通第三方应用,没有官方的完美方案,但可以尝试以下两种变通方法:
方法一:通过BLE扫描获取自身广播信息
- 前提:设备开启蓝牙,且你的应用已获取
ACCESS_FINE_LOCATION权限(用户已授权) - 思路:让应用作为BLE中心设备扫描周围的蓝牙广播,通过设备名称等特征识别出本机的广播,从中提取真实MAC地址。
- 示例代码:
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) { BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner(); scanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); BluetoothDevice device = result.getDevice(); // 替换成你的设备名称,以此判断是否为本机 if (device.getName() != null && device.getName().equals("MyDeviceName")) { String realMacAddress = device.getAddress(); // 拿到MAC地址后停止扫描 scanner.stopScan(this); // 后续业务处理逻辑 } } }); } - 局限性:如果设备未开启BLE广播,或者设备名称被修改,可能无法识别到本机,可靠性不是100%。
方法二:读取系统文件(需要Root权限)
如果你的目标设备已经Root,可以直接读取存储蓝牙MAC的系统文件:
- 示例代码:
try { BufferedReader reader = new BufferedReader(new FileReader("/proc/bluetooth/hci0/bdaddr")); String line = reader.readLine(); if (line != null) { // 文件内容格式类似 "BD Address: 00:11:22:33:44:55",提取MAC部分 String realMacAddress = line.trim().split(" ")[2]; // 后续业务处理逻辑 } reader.close(); } catch (IOException e) { e.printStackTrace(); } - 局限性:Root权限在普通消费级设备上并不普及,所以这个方案只适用于特定场景。
总结
对于普通第三方应用来说,目前没有官方的可靠方法获取真实的本机蓝牙MAC地址。如果业务逻辑必须依赖这个信息,建议优先尝试BLE扫描的方法,或者考虑调整业务流程,避免直接依赖蓝牙MAC地址。
内容的提问来源于stack exchange,提问作者Siddharthan
相关产品推荐
相关产品推荐

