完全断开蓝牙低功耗设备
Totally Disconnect a Bluetooth Low Energy Device
我使用 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()
。设备本身似乎认为它仍然处于连接状态,因为我无法将它置于广播可见性模式(如果它已经连接,则会发生这种情况)。但是,如果我终止应用程序并再次打开它,那么我可以将设备设置为广播模式。这告诉我应用程序未正确断开连接。
知道我错过了什么吗?
这完全符合逻辑,因为您在关闭 Gatt 之前没有断开连接。
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
尝试在关闭您的 GATT
之前调用此方法
问题是我在扫描期间多次连接到同一设备,导致我的应用程序同时打开多个连接。添加 !isConnected()
解决了问题:
/**
* Connects to the device. Does nothing if already connected.
* @param macAddress the address of the device.
*/
private void connectDevice(String macAddress) {
if (isConnected()) {
return;
}
device = bluetoothAdapter.getRemoteDevice(macAddress);
if (device == null) {
showToast("Device not available");
} else {
showToast("Connecting...");
gatt = device.connectGatt(this, true, gattCallback);
}
}
我遇到了同样的问题,我发现了两个可能的根本原因如下:
1. 与@nilsi 的回答相同,在一次扫描中多次连接到同一设备。
→ 通过 lock & List 解决
2. 在一次扫描中连接到设备并且没有得到 onConnectionStateChange,比我再次扫描,它导致第二次连接到同一设备。
→ 通过在调用 device.connectGatt() 时保留 BluetoothGatt 对象解决,并在扫描前调用 object.disconnect()、object.close()。
我的测试 phone 已有 4 年历史,所以有时 return onConnectionStateChange 需要 20 多秒....
如前所述,问题是多次调用connectGatt引起的。这些调用中的每一个都会创建一个新的 BluetoothGatt 实例,并且它们都保持活动状态,而您只有最后一个。考虑到有时需要多次调用 connectGatt,我只保留它 returns 的所有实例,并在完成后对所有实例调用 disconnect/close。这立即解决了断开连接问题
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()
}
}
}
我使用 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()
。设备本身似乎认为它仍然处于连接状态,因为我无法将它置于广播可见性模式(如果它已经连接,则会发生这种情况)。但是,如果我终止应用程序并再次打开它,那么我可以将设备设置为广播模式。这告诉我应用程序未正确断开连接。
知道我错过了什么吗?
这完全符合逻辑,因为您在关闭 Gatt 之前没有断开连接。
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
尝试在关闭您的 GATT
问题是我在扫描期间多次连接到同一设备,导致我的应用程序同时打开多个连接。添加 !isConnected()
解决了问题:
/**
* Connects to the device. Does nothing if already connected.
* @param macAddress the address of the device.
*/
private void connectDevice(String macAddress) {
if (isConnected()) {
return;
}
device = bluetoothAdapter.getRemoteDevice(macAddress);
if (device == null) {
showToast("Device not available");
} else {
showToast("Connecting...");
gatt = device.connectGatt(this, true, gattCallback);
}
}
我遇到了同样的问题,我发现了两个可能的根本原因如下: 1. 与@nilsi 的回答相同,在一次扫描中多次连接到同一设备。 → 通过 lock & List 解决 2. 在一次扫描中连接到设备并且没有得到 onConnectionStateChange,比我再次扫描,它导致第二次连接到同一设备。 → 通过在调用 device.connectGatt() 时保留 BluetoothGatt 对象解决,并在扫描前调用 object.disconnect()、object.close()。
我的测试 phone 已有 4 年历史,所以有时 return onConnectionStateChange 需要 20 多秒....
如前所述,问题是多次调用connectGatt引起的。这些调用中的每一个都会创建一个新的 BluetoothGatt 实例,并且它们都保持活动状态,而您只有最后一个。考虑到有时需要多次调用 connectGatt,我只保留它 returns 的所有实例,并在完成后对所有实例调用 disconnect/close。这立即解决了断开连接问题
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()
}
}
}