Android Java中BLE广播无法停止的技术问题求助
问题:BLE广播调用stopAdvertising后无法停止
启动BLE广播后,调用stopAdvertising方法无法停止广播,设备仍持续发送广播数据。
启动广播代码
advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser(); advSettings = new AdvertiseSettings.Builder() .setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY ) .setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_HIGH ) .setConnectable(false) .setTimeout(0) .build(); AdvertiseData data = new AdvertiseData.Builder() .setIncludeDeviceName( true ) .setIncludeTxPowerLevel(false) .addServiceUuid(serviceId) .build(); AdvertiseData response = new AdvertiseData.Builder() .setIncludeDeviceName( false ) .setIncludeTxPowerLevel(false) .addServiceData(serviceId, packet ) .build(); advertiser.startAdvertising(advSettings, data, response, new AdvertiseCallback() { @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) { super.onStartSuccess(settingsInEffect); Log.d(TAG, "Packet was successfully sent"); } @Override public void onStartFailure(int errorCode) { super.onStartFailure(errorCode); Log.e(TAG, "Advertise failed : " + errorCode); } });
停止广播方法
public void stopAdvertising(){ Log.d(TAG, "stoping advertising ..." ); advertiser.stopAdvertising(new AdvertiseCallback() { @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) { Log.d(TAG, "onStopSuccess" ); super.onStartSuccess(settingsInEffect); } @Override public void onStartFailure(int errorCode) { Log.e(TAG, "onStopFailed" + errorCode ); super.onStartFailure(errorCode); } }); advertiser = null; }
调用stopAdvertising时的日志输出
D/ContentValues: stoping advertising ... D/BluetoothAdapter: STATE_ON D/BluetoothAdapter: STATE_ON D/BluetoothLeAdvertiser: wrapper is null
问题原因与修复方案
- 日志中的
D/BluetoothLeAdvertiser: wrapper is null是关键线索,说明停止广播时advertiser对象的底层实例已失效,或代码逻辑存在错误。 - 核心错误1:停止广播使用了新的AdvertiseCallback
系统需要通过启动和停止时使用同一个AdvertiseCallback实例来匹配对应的广播任务,当前停止时新建匿名回调,导致系统无法定位到要停止的广播。 - 核心错误2:过早将advertiser置为null
在stopAdvertising调用未完成时就将advertiser设为null,会打断系统的停止流程。
修复后的代码实现
- 将启动时的AdvertiseCallback保存为成员变量:
// 定义成员变量保存回调实例 private AdvertiseCallback mAdvertiseCallback; // 启动广播时初始化并传入回调 mAdvertiseCallback = new AdvertiseCallback() { @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) { super.onStartSuccess(settingsInEffect); Log.d(TAG, "Packet was successfully sent"); } @Override public void onStartFailure(int errorCode) { super.onStartFailure(errorCode); Log.e(TAG, "Advertise failed : " + errorCode); } }; advertiser.startAdvertising(advSettings, data, response, mAdvertiseCallback);
- 修改停止广播方法:
public void stopAdvertising(){ Log.d(TAG, "stoping advertising ..." ); // 先判空避免空指针 if (advertiser != null && mAdvertiseCallback != null) { advertiser.stopAdvertising(mAdvertiseCallback); // 清空回调和advertiser对象 mAdvertiseCallback = null; advertiser = null; } }
额外注意事项
- 确保没有其他地方重复启动BLE广播,导致停止一个后仍有其他广播在运行
- 部分设备的BLE广播停止存在短暂延迟,停止后可等待1-2秒再验证
- 始终确保BluetoothAdapter处于可用(STATE_ON)状态
内容的提问来源于stack exchange,提问作者Gaspar gg
相关产品推荐
相关产品推荐

