如何防止BluetoothGattCallback一次多次执行

Kev*_* D. 5 android bluetooth-lowenergy android-5.1.1-lollipop

我有一个服务有一个实例 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


}
Run Code Online (Sandbox Code Playgroud)

当我启动应用程序时,它工作正常,回调只被调用一次,但经过几次尝试,它被调用两次.

样本日志

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
Run Code Online (Sandbox Code Playgroud)

更多样本日志

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
Run Code Online (Sandbox Code Playgroud)

应用程序保持活动的时间越长,它就会被调用很多次.我该如何防止这种情况?

Mar*_*arc 16

要记住的一件事是每次打电话

bluetoothDevice.connectGatt(context, true, callback);
Run Code Online (Sandbox Code Playgroud)

它创建了bluetoothGatt对象的新实例.查看您将看到的这个来源:

         BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this, transport);
         gatt.connect(autoConnect, callback);
Run Code Online (Sandbox Code Playgroud)

因此,一个棘手的问题是,如果您的设备断开连接并重新连接到它.connectGatt(context,true,callback); 而不是在之前的bluetoothGatt实例上调用connect(),你将得到2个bluetoothGatt实例,它们都有你的gatt回调的句柄.

最初我试图通过在重新连接之前关闭并断开bluetoothGatt来解决问题.

   if (service.bluetoothGatt!=null){
        Log.i("Rides","Closeing bluetooth gatt on disconnect");
        service.bluetoothGatt.close();
        service.bluetoothGatt.disconnect();
        service.bluetoothGatt=null;
    } 
Run Code Online (Sandbox Code Playgroud)

但这不能很好地工作,不知怎的,我会得到多个onConnectionStateChanged回调.

我能够通过检查我是否有一个有效的bluetoothGatt对象并确保在重新连接时调用connect()来解决这个问题.

----更新答案----

我发现在onConnectionStateChanged回调中调用bluetoothGatt.close()会更好.当您发出断开连接时,它会向蓝牙设备发送一条消息,请求断开连接.然后一旦它响应你得到回调并关闭蓝牙gatt连接.通过等待回调而不是打开另一个gatt连接直到它完全关闭它似乎可以防止多个gatt对象连接到应用程序.