You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,会打断系统的停止流程。

修复后的代码实现

  1. 将启动时的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);
  1. 修改停止广播方法:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:45:50