Android Lollipop BLE外设:调用BluetoothLeAdvertiser.stopAdvertising(AdvertiseCallback)断开连接中心

时间:2015-04-01 18:50:20

标签: android bluetooth-lowenergy advertising

我希望在中央连接(并订阅特定特征)时停止广告:

private final BluetoothGattServerCallback bleCallbacks = new BluetoothGattServerCallback() {
    @Override
    public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value){
        Log.v(DEBUG_TAG, "onDescriptorWriteRequest()...");

        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
        Log.v(DEBUG_TAG, "----- characteristic: " + characteristic.getUuid().toString());

        if (characteristic.equals(peripheralCharacteristic)){
            descriptor.setValue(value);
            if (bluetoothGattServer.sendResponse(device,
                    requestId,
                    BluetoothGatt.GATT_SUCCESS,
                    offset,
                    value)){
                central = device;
                stopAdvertising(); //causes disconnection
                return;
            }
        }

        bluetoothGattServer.sendResponse(device,
                requestId,
                BluetoothGatt.GATT_WRITE_NOT_PERMITTED,
                0,
                null);
    }
...
}

private void stopAdvertising(){
    if (bluetoothLeAdvertiser != null) {
        bluetoothLeAdvertiser.stopAdvertising(advertiseCallback);
    }
}

在调用stopAdvertising()时,中央和外围设备断开连接 来自logcat:

  

04-01 11:26:06.179 7068-7085 / package.Class:onDescriptorWriteRequest()...

     

04-01 11:26:06.179 7068-7085 / package.Class:-----特色:80a1a1a5-8b5b-e88b-9d24-2e609654b852

     

04-01 11:26:06.207 7068-7085 / package D / BluetoothGattServer:onServerConnectionState() - status = 0 serverIf = 5 device = 00:07:80:2F:0F:A2

通过注释stopAdvertising(),与中心的连接(和通信)继续。

有没有人在使用Android的BLE外设实现时遇到过这个问题?在iOS中,没有这样的问题。

2 个答案:

答案 0 :(得分:1)

输入连接后,您无需致电stopAdvertising

来自LE控制器的链路层有5种状态:“闲置”,“广告”,“扫描”,“启动”和“已连接”。

当您做广告时,您处于“广告”状态。当它连接时,它进入“已连接”状态。

最有可能的是,stopAdvertising方法假设您在通话时处于“广告”状态,并且在不进行检查的情况下,当您在“广告”中调用它时应该执行的操作:它会转到“空闲”状态。

因此,当您调用它时,无论当前状态如何,LL都会进入“空闲”状态。

这似乎是来自Android的BLE主机堆栈中的一个错误。在“已连接”状态下调用stopAdvertising时的正确行为应该是返回错误代码(例如“此命令的无效状态”)或者只是忽略。

答案 1 :(得分:0)

Bogdan的回答适用于蓝牙LE 4.0。但是4.1外围设备可以连接到1个以上的中央设备,因此外设可以决定在连接完成后是否要停止广告而不会立即丢失该连接。这看起来像Android L中的一个错误,最近是5.1.1