完全断开蓝牙低功耗设备

时间:2016-03-14 11:40:05

标签: android bluetooth iot bluetooth-lowenergy

我使用Android中的connectGatt()方法连接到BLE设备。这很有效。

当我断开连接时,请使用以下内容:

private void disconnectDevice() {
    gatt.disconnect();
}

当我收到回电时,我会结束。

private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        switch (newState) {
            case BluetoothProfile.STATE_CONNECTED:
                Log.d("BLED-GATT", "STATE_CONNECTED");
                setUIConnectionStatus("Discover services on device...", Color.YELLOW);
                checkEnableAddButton(simpleTrackEditText.getText().toString());
                gatt.discoverServices();
                break;
            case BluetoothProfile.STATE_DISCONNECTED:
                Log.d("BLED-GATT", "STATE_DISCONNECTED");
                setUIConnectionStatus("Not Connected!", Color.RED);
                gatt.close();
                break;
            default:
                Log.d("BLED-GATT", "STATE_OTHER");
        }
    }
}

执行此操作后,在调用disconnectDevice()后我无法再控制设备。设备本身似乎认为它仍然连接,因为我无法将其置于广播可见性模式(如果它已经有连接就会发生)。但是,如果我终止应用程序并再次打开它,那么我可以将设备设置为广播模式。这告诉我应用程序未正确断开连接。

知道我错过了什么吗?

4 个答案:

答案 0 :(得分:9)

问题是我在扫描期间多次连接到同一设备,导致我的应用程序同时打开许多连接。添加!isConnected()解决了问题:

/**
 * Connects to the device. Does nothing if already connected.
 * @param macAddress the address of the device.
 */
private void connectDevice(String macAddress) {
    if (!isConnected()) {
        device = bluetoothAdapter.getRemoteDevice(macAddress);

        if (device == null) {
            this.sendToast("Device Not Available");
        } else {
            Log.d("BLED", "Connecting...");
            gatt = device.connectGatt(this, true, gattCallback);
        }
    }
}

答案 1 :(得分:2)

这完全是逻辑因为你在关闭Gatt之前没有断开连接。

public void disconnect() {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.disconnect();
    }

尝试在关闭GATT

之前调用此方法

答案 2 :(得分:0)

我遇到了同样的问题,发现了两个可能的根本原因,如下所示: 1.与@nilsi答案相同,一次扫描多次连接到同一设备。 →通过锁和列表解决 2.在一次扫描中连接到该设备,但没有获得onConnectionStateChange,比我再次扫描时,它导致了到同一设备的第二次连接。 →通过在扫描之前调用device.connectGatt()并调用object.disconnect(),object.close()时保留BluetoothGatt对象来解决。

我的测试电话已经4岁了,所以有时需要20秒钟以上才能返回onConnectionStateChange。...

答案 3 :(得分:0)

如前所述,问题是由多次调用connectGatt引起的。这些调用中的每个调用都会创建一个新的BluetoothGatt实例,并且它们都保持活动状态,而您只有最后一个。鉴于有时需要多次调用connectGatt的事实,我只保留它返回的所有实例,并在完成后对所有实例调用断开连接/关闭。这样可以立即解决断开连接的问题

private val gattInstances = LinkedList<BluetoothGatt>()


fun connect() {
    bluetoothGatt = device?.connectGatt(
        context,
        false, gattCallback, TRANSPORT_LE
    )
    bluetoothGatt?.let { gattInstances.add(it) }
}

fun finish() {
    bluetoothGatt?.close()
    while (gattInstances.isNotEmpty()) {
        gattInstances.pop().apply {
            disconnect()
            close()
        }
    }
}