Android BLE应用开发:BluetoothAdapter相关空指针问题排查求助
Hey Ben,我帮你梳理下这个BLE开发中空指针问题的排查思路——毕竟在Adapter相关方法上踩空指针坑太常见了😉
排查BluetoothAdapter空指针的核心步骤
你遇到的BluetoothAdapter.isEnabled()和startScan()空指针,大概率是BluetoothAdapter实例本身为null导致的,毕竟这两个方法都是调用Adapter对象的方法,先从根源确认Adapter是否正确获取。
1. 先确认BluetoothAdapter的获取方式是否正确
官方示例里的标准获取流程是这样的,你可以对照检查:
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
这里要盯两个关键细节:
- 先判断设备是否支持BLE:如果
bluetoothManager或bluetoothAdapter是null,直接说明设备不支持BLE功能,得给用户提示或者终止后续流程。 - 权限不能漏:Android 12+需要
BLUETOOTH_SCAN、BLUETOOTH_CONNECT权限;低版本要BLUETOOTH+ACCESS_COARSE_LOCATION(扫描必须要位置权限,这个新手很容易忘!),动态权限一定要在扫描前申请完成。
2. 检查BluetoothLeService中Adapter的生命周期
你用了Gatt示例的BluetoothLeService,得注意Service里的Adapter实例是不是在正确的时机初始化:
- 是不是在
onCreate()方法里就完成了Adapter的获取? - 会不会因为Service被销毁重建,导致Adapter实例被意外置空?
- 调用
isEnabled()和startScan()前,一定要先给Adapter判空!比如加个前置判断:
if (bluetoothAdapter == null) { // 处理设备不支持BLE的情况,比如发广播通知UI提示用户 return; } if (!bluetoothAdapter.isEnabled()) { // 触发蓝牙开启请求,比如发送Intent让系统弹窗 Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }
3. startScan()空指针的额外排查点
如果Adapter已经不为null,但startScan()还是爆空指针,要检查这两个对象:
- 扫描回调
ScanCallback是不是未初始化就传进去了?比如你有没有提前实例化这个回调,而不是传了个null? - 扫描过滤条件
ScanFilter或ScanSettings是不是null?虽然官方允许传null,但部分机型可能会因此出问题,建议明确创建:
ScanSettings scanSettings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> scanFilters = new ArrayList<>(); // 可以添加目标设备的过滤条件,比如名称、UUID bluetoothAdapter.startScan(scanFilters, scanSettings, mScanCallback);
4. 多线程与生命周期陷阱
有没有可能是在组件生命周期外调用这些方法?比如Activity已经销毁了,但还在调用Service里的扫描逻辑,导致Adapter实例因为生命周期被回收?
- 调用扫描方法前,先确认Service是否处于活跃状态、Activity是否和Service绑定成功。
- 后台扫描的限制:Android 10+对后台扫描有严格限制,需要
ACCESS_BACKGROUND_LOCATION权限,虽然这不是空指针的直接原因,但权限不足可能导致Adapter状态异常,间接引发问题。
5. 日志排查小技巧
在空指针出现的代码附近,加日志打印关键对象的状态,能快速定位是哪个对象为null:
Log.d("BLE_DEBUG", "bluetoothAdapter状态: " + bluetoothAdapter); Log.d("BLE_DEBUG", "scanCallback状态: " + mScanCallback);
最后提醒下:扫描完成后一定要调用bluetoothAdapter.stopScan(mScanCallback)释放资源,而且调用stopScan前也要给Adapter判空,避免二次空指针。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

