如何防止 BluetoothGattCallback 一次执行多次
How to prevent BluetoothGattCallback from being executed multiple times at a time
我的服务有一个 BluetoothGattCallback
public class MyService extends Service {
private BluetoothGattCallback callback;
@Override
public void onCreate() {
super.onCreate();
callback = new BluetoothGattCallback() {
@Override
public synchronized void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChanged", "Status " + status);
Log.i("onConnectionStateChanged", "New State " + newState);
}
};
}
// registration of bluetooth adapter and blah blah blah
}
当我启动应用程序时,它工作正常,回调只被调用一次,但在尝试几次后,它被调用了两次。
示例日志
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: Status 0
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: New State 2
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: Status 0
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: New State 2
更多示例日志
10-22 13:29:48.836 26944-26961/redacted.lollipop I/onConnectionStateChange: Status 8
10-22 13:29:48.836 26944-26961/redacted.lollipop I/onConnectionStateChange: New State 0
10-22 13:29:48.850 26944-30763/redacted.lollipop I/onConnectionStateChange: Status 8
10-22 13:29:48.850 26944-30763/redacted.lollipop I/onConnectionStateChange: New State 0
并且应用程序保持活动状态的时间越长,它被调用的次数就越多。我该如何防止这种情况?
要记住的一件事是每次调用
bluetoothDevice.connectGatt(context, true, callback);
它创建了 bluetoothGatt 对象的一个新实例。 check out the source for this one你会看到:
BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this, transport);
gatt.connect(autoConnect, callback);
所以一件棘手的事情是,如果您的设备断开连接并且您重新连接到它。 connectGatt(上下文,真,回调);您将获得 2 个 bluetoothGatt 实例,而不是在之前的 bluetoothGatt 实例上调用 connect(),它们都具有 gatt 回调的句柄。
最初我试图通过在重新连接之前尝试关闭并断开 bluetoothGatt 来解决问题。
if (service.bluetoothGatt!=null){
Log.i("Rides","Closeing bluetooth gatt on disconnect");
service.bluetoothGatt.close();
service.bluetoothGatt.disconnect();
service.bluetoothGatt=null;
}
但这并不奏效,不知何故我会得到多个 onConnectionStateChanged 回调。
我能够通过检查我是否有一个有效的 bluetoothGatt 对象并确保在它重新连接时调用 connect() 来解决这个问题。
----更新答案----
我发现最好在 onConnectionStateChanged 回调中调用 bluetoothGatt.close()。当您发出断开连接时,它会向蓝牙设备发送一条消息以请求断开连接。然后,一旦它响应,您就会收到回调并关闭蓝牙 gatt 连接。通过等待回调并且在完全关闭之前不打开另一个 gatt 连接,它似乎可以防止多个 gatt 对象连接到应用程序。
我的服务有一个 BluetoothGattCallback
public class MyService extends Service {
private BluetoothGattCallback callback;
@Override
public void onCreate() {
super.onCreate();
callback = new BluetoothGattCallback() {
@Override
public synchronized void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChanged", "Status " + status);
Log.i("onConnectionStateChanged", "New State " + newState);
}
};
}
// registration of bluetooth adapter and blah blah blah
}
当我启动应用程序时,它工作正常,回调只被调用一次,但在尝试几次后,它被调用了两次。
示例日志
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: Status 0
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: New State 2
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: Status 0
10-22 13:29:18.731 26944-26961/redacted.lollipop I/onConnectionStateChange: New State 2
更多示例日志
10-22 13:29:48.836 26944-26961/redacted.lollipop I/onConnectionStateChange: Status 8
10-22 13:29:48.836 26944-26961/redacted.lollipop I/onConnectionStateChange: New State 0
10-22 13:29:48.850 26944-30763/redacted.lollipop I/onConnectionStateChange: Status 8
10-22 13:29:48.850 26944-30763/redacted.lollipop I/onConnectionStateChange: New State 0
并且应用程序保持活动状态的时间越长,它被调用的次数就越多。我该如何防止这种情况?
要记住的一件事是每次调用
bluetoothDevice.connectGatt(context, true, callback);
它创建了 bluetoothGatt 对象的一个新实例。 check out the source for this one你会看到:
BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this, transport);
gatt.connect(autoConnect, callback);
所以一件棘手的事情是,如果您的设备断开连接并且您重新连接到它。 connectGatt(上下文,真,回调);您将获得 2 个 bluetoothGatt 实例,而不是在之前的 bluetoothGatt 实例上调用 connect(),它们都具有 gatt 回调的句柄。
最初我试图通过在重新连接之前尝试关闭并断开 bluetoothGatt 来解决问题。
if (service.bluetoothGatt!=null){
Log.i("Rides","Closeing bluetooth gatt on disconnect");
service.bluetoothGatt.close();
service.bluetoothGatt.disconnect();
service.bluetoothGatt=null;
}
但这并不奏效,不知何故我会得到多个 onConnectionStateChanged 回调。
我能够通过检查我是否有一个有效的 bluetoothGatt 对象并确保在它重新连接时调用 connect() 来解决这个问题。
----更新答案----
我发现最好在 onConnectionStateChanged 回调中调用 bluetoothGatt.close()。当您发出断开连接时,它会向蓝牙设备发送一条消息以请求断开连接。然后,一旦它响应,您就会收到回调并关闭蓝牙 gatt 连接。通过等待回调并且在完全关闭之前不打开另一个 gatt 连接,它似乎可以防止多个 gatt 对象连接到应用程序。