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

Android BLE AdvertisingSet未发送ScanResponse问题求助

关于Android BLE AdvertisingSet未发送指定ScanResponse的问题

我在Android BLE开发中遇到了AdvertisingSet未发送传入参数指定的ScanResponse的问题,扫描回调返回的结果里serviceData为空,无法获取到预期的ScanResponse数据。以下是我的代码实现和扫描结果,想请教哪里操作有误?

AdvertisingSet 实现代码

AdvertisingSetParameters parameters = (new AdvertisingSetParameters.Builder())
                .setConnectable(false)
                .setLegacyMode(true)
                .setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
                .setTxPowerLevel(AdvertisingSetParameters.TX_POWER_MEDIUM)
                .build();

byte[] packet = "hello".getBytes(StandardCharsets.UTF_8);


AdvertiseData data = new AdvertiseData.Builder()
        .setIncludeDeviceName( true )
        .setIncludeTxPowerLevel(false)
        .addServiceUuid(serviceId)
        .build();

AdvertiseData response = new AdvertiseData.Builder()
        .setIncludeDeviceName( false )
        .setIncludeTxPowerLevel(false)
        .addServiceUuid(serviceId)
        .addServiceData(serviceId, packet )
        .build();
        

advertiser.startAdvertisingSet(parameters, data, response, null, null,callback);

Scanner 实现代码

List<ScanFilter> filters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder()
        .setServiceUuid(serviceId)
        .build();
filters.add( filter );

// Setting scanning mode to low latency
ScanSettings scanSettings = new ScanSettings.Builder()
        .setScanMode( ScanSettings.SCAN_MODE_LOW_LATENCY )
        .build();



bluetoothLeScanner.startScan(filters, scanSettings,
        new ScanCallback() {
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                super.onScanResult(callbackType, result);
                Log.d(TAG, scanResult.toString());

            }

            @Override
            public void onBatchScanResults(List<ScanResult> results) {
                super.onBatchScanResults(results);
            }

            @Override
            public void onScanFailed(int errorCode) {
                super.onScanFailed(errorCode);
                Log.e(TAG, "onScanFailed: " + errorCode);
            }
        });

扫描回调结果

ScanResult{device=6F:26:02:1A:91:E7,
 scanRecord=ScanRecord [mAdvertiseFlags=-1,
 mServiceUuids=[0000950d-0000-1000-8000-00805f9b34fb],
 mManufacturerSpecificData={},
 mServiceData={},
 mTxPowerLevel=-2147483648,
 mDeviceName=1RLjXZvX/Default user],
 rssi=-62,
 timestampNanos=11220453733034,
 eventType=16,
 primaryPhy=1,
 secondaryPhy=0,
 advertisingSid=255,
 txPower=127,
 periodicAdvertisingInterval=0}

问题排查与解决方案

1. 非可连接模式的限制

你设置了setConnectable(false),在非可连接广播模式下,Android BLE不会发送ScanResponse。ScanResponse的触发逻辑是:扫描设备发送Scan Request后,广播设备才会返回响应,而只有可连接的广播设备才会监听并响应这类请求。

修改广播参数为可连接模式:

AdvertisingSetParameters parameters = (new AdvertisingSetParameters.Builder())
        .setConnectable(true) // 改为可连接模式
        .setLegacyMode(true)
        .setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
        .setTxPowerLevel(AdvertisingSetParameters.TX_POWER_MEDIUM)
        .build();

2. 扫描设备需启用主动扫描

即使广播设备设为可连接模式,扫描设备也需要主动发送Scan Request才能触发响应。默认扫描模式可能不会主动发起请求,需要在ScanSettings中配置主动扫描相关参数:

ScanSettings scanSettings = new ScanSettings.Builder()
        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
        .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
        .setMatchMode(ScanSettings.MATCH_MODE_STICKY)
        .setNumOfMatches(ScanSettings.NUM_OF_MATCHES_MAX_ADVERTISEMENT)
        .setReportDelay(0)
        .build();

3. 检查广播数据长度限制

Legacy模式下BLE广播包最大长度为31字节,若主广播包(data)已经占满字节,ScanResponse可能无法被正常发送。你当前的主广播包包含设备名称和服务UUID,需要确认总字节数是否超限。如果超出,可以尝试移除主广播包中的设备名称,或精简内容为ScanResponse预留空间。

4. 验证AdvertisingSet启动状态

在startAdvertisingSet的回调中检查启动状态,确保广播集成功启动无错误:

private AdvertisingSetCallback callback = new AdvertisingSetCallback() {
    @Override
    public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
        super.onAdvertisingSetStarted(advertisingSet, txPower, status);
        if (status == BluetoothAdvertiser.ADVERTISE_SUCCESS) {
            Log.d(TAG, "Advertising set started successfully");
        } else {
            Log.e(TAG, "Advertising set start failed, status: " + status);
        }
    }

    @Override
    public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
        super.onAdvertisingSetStopped(advertisingSet);
    }
};

内容的提问来源于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 06:35:19