BLE连接总是调用断开连接的操作(GATT配置文件)

时间:2017-05-29 07:59:14

标签: android bluetooth-lowenergy gatt

我建立了一个BLE连接,用于在设备之间发送数据(每10秒钟他们建立一个新连接,发送数据,然后断开连接),通常工作正常。 但是,几分钟后,设备永远不再连接,应该与另一个连接的设备处于循环调用“ ACTION_GATT_DISCONNECTED ”(此字符串指的是断开连接的接收器操作)。

在我的接收器中,我有3个相关的动作:

@Override
    public void onReceive(Context context, Intent intent) {
        customBluetoothManager = customBluetoothManager.getInstance(context, null, null);
        final String action = intent.getAction();
        Log.d("test", "onReceive");
        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
            Log.d("test", action);
        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            Log.d("test", action);
        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            Log.d("test", action);
            //....
            //Code to send data after services discovered
            //....
        }
    }

所以,在最初的几分钟内一切正常。首先是调用 ACTION_GATT_CONNECTED ,然后调用 ACTION_GATT_SERVICES_DISCOVERED 操作,然后设备发送数据,然后断开连接并释放蓝牙通信通道。 问题是,有时候,并不总是在同一点(由于这个原因,我无法找到任何模式来重现这个问题),循环总是调用 ACTION_GATT_DISCONNECTED ,所以沟通永远不会成立。

BluetoothGattCallback 类的 onConnectionSateChange 回调中分配 ACTION_GATT_DISCONNECTED

@Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                intentAction = ACTION_GATT_CONNECTED;
                mConnectionState = STATE_CONNECTED;
                broadcastUpdate(intentAction);
                Log.i(TAG, "Connected to GATT server.");
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = ACTION_GATT_DISCONNECTED;
                mConnectionState = STATE_DISCONNECTED;
                Log.i(TAG, "Disconnected from GATT server.");
                broadcastUpdate(intentAction);
                mBluetoothGatt.close();
            }
        }

我不知道会出现什么问题......有什么建议吗?

---------- UPDATE --------------

使用进行连接的回调更新:

private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi,
                                     byte[] scanRecord) {

                    String name = device.getName();
                    long epoch = System.currentTimeMillis() / 1000;
                    SharedPreferences prefs = context.getSharedPreferences(
                            "epoch", Context.MODE_PRIVATE);
                    long epochStored = prefs.getLong("epoch", 0);

                    if (name != null && name.compareTo(bluetoothDeviceName) == 0 && (epochStored == 0 || epochStored < epoch - Utils.getDelay())) {

                        mac = device.getAddress();
                        mDeviceAddress = device.getAddress();
                        final Intent gattServiceIntent = new Intent(context, BluetoothLeService.class);

                        if (!connected) {
                            Utils.setMessageLog(ac, tv, "Binding service");
                            context.bindService(gattServiceIntent, mServiceConnection, context.BIND_AUTO_CREATE);
                        } else {
                            mBluetoothLeService.connect(mac);
                        }
                    }
                }
            };

连接功能:

public boolean connect(final String address) {
        if (mBluetoothAdapter == null || address == null) {
            Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
            return false;
        }

        if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
                && mBluetoothGatt != null) {
            Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
            if (mBluetoothGatt.connect()) {
                mConnectionState = STATE_CONNECTING;
                return true;
            } else {
                return false;
            }
        }
        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.w(TAG, "Device not found.  Unable to connect.");
            return false;
        }

        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
        Log.d(TAG, "Trying to create a new connection.");
        mBluetoothDeviceAddress = address;
        mConnectionState = STATE_CONNECTING;
        return true;
    }

连接成功后,我在接收器中收到“SERVICES_DISCOVERED”动作,并通过此代码编写特征:

public void sendData() {
        List<BluetoothGattService> listServices = mBluetoothLeService.getSupportedGattServices();

        BluetoothGattService bluetoothGattService = null;
        for (BluetoothGattService gattService : listServices) {
            if (gattService.getUuid().compareTo(myUUID) == 0) {
                bluetoothGattService = gattService;
            }
        }

        if(bluetoothGattService != null) {
            List<BluetoothGattCharacteristic> gattCharacteristics = bluetoothGattService.getCharacteristics();
            ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();

            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                if (gattCharacteristic.getUuid().compareTo(myCharUUID)) == 0) {
                    charas.add(gattCharacteristic);
                    boolean status = mBluetoothLeService.writeCharacteristic(gattCharacteristic, Utils.getUserData(context, "id"));
                }
            }
        }
    }

第一次建立蓝牙通信工作正常。

-------------第二次更新--------------

我正在调用 close()来释放连接:

@Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            disconnect();
            close();
        }

close()函数:

public void close() {
        if (mBluetoothGatt == null) {
            return;
        }
        mBluetoothGatt.close();
        mBluetoothGatt = null;
    }

----------- UPDATE WITH ERROR LOG ------------

05-31 11:14:38.581 5897-6100/app D/OCSC: Status: 0
05-31 11:14:38.581 5897-6100/app  D/OCSC: New State: 2
05-31 11:15:08.361 5897-6073/app  D/OCSC: Status: 0
05-31 11:15:08.361 5897-6073/app  D/OCSC: New State: 2
05-31 11:15:35.031 5897-6010/app  D/OCSC: Status: 0
05-31 11:15:35.031 5897-6010/app  D/OCSC: New State: 2
05-31 11:16:08.331 5897-5909/app  D/OCSC: Status: 0
05-31 11:16:08.341 5897-5909/app  D/OCSC: New State: 2
05-31 11:16:36.031 5897-5908/app  D/OCSC: Status: 0
05-31 11:16:36.031 5897-5908/app  D/OCSC: New State: 2
05-31 11:17:08.341 5897-6100/app  D/OCSC: Status: 0
05-31 11:17:08.341 5897-6100/app  D/OCSC: New State: 2
05-31 11:17:38.621 5897-6100/app  D/OCSC: Status: 0
05-31 11:17:38.621 5897-6100/app  D/OCSC: New State: 2
05-31 11:18:08.431 5897-6058/app  D/OCSC: Status: 0
05-31 11:18:08.431 5897-6058/app  D/OCSC: New State: 2
05-31 11:18:38.011 5897-6123/app  D/OCSC: Status: 0
05-31 11:18:38.011 5897-6123/app  D/OCSC: New State: 2
05-31 11:19:13.451 5897-6123/app  D/OCSC: Status: 133
05-31 11:19:13.451 5897-6123/app  D/OCSC: New State: 0

当发生断开连接问题时,我看到总是将新状态显示为22或133(只有一次我看到新状态为19)。

D/OCSC: New State: 133
D/OCSC: Status: 0
D/OCSC: New State: 133
D/OCSC: Status: 0
D/OCSC: New State: 133
D/OCSC: Status: 0

D/OCSC: New State: 22
D/OCSC: Status: 0
D/OCSC: New State: 22
D/OCSC: Status: 0
D/OCSC: New State: 22
D/OCSC: Status: 0

我在btsnoop_hci.log上找到了错误:

  

Rcvd错误响应 - 找不到属性,句柄:0x0005,句柄:   0x0005(通用访问配置文件:外观)

     

按类型请求发送读取,GATT包含声明,句柄:   0x0006..0x0008

     

Rcvd错误响应 - 找不到属性,句柄:0x0006,句柄:   0x0006(通用属性配置文件)

     

...

     

Rcvd错误响应 - 找不到属性,句柄:0x0008,句柄:   0x0008(通用属性配置文件:服务已更改)

     

...

     

Rcvd错误响应 - 找不到属性,句柄:0x0102,句柄:   0x0102(未知:未知)

     

...

     

Rcvd错误响应 - 无效的属性值长度,句柄:0x0102,   句柄:0x0102(未知:未知)

Logcat(测试1):

BluetoothGatt: onClientConnectionState() - status=0 clientIf=10
OCSC    : Status: 0
OCSC    : New State: 2
OCSC    : Connected to GATT server.
BluetoothGatt: discoverServices()
BluetoothLeService: Attempting to start service discovery:true
test    : com.example.bluetooth.le.ACTION_GATT_CONNECTED
BluetoothGatt: onClientConnectionState() - status=22 clientIf=8 
BluetoothGatt: onClientConnectionState() - status=22 clientIf=10
BtGatt.GattService: onDisconnected() - clientIf=12
luetoothGatt: onClientConnectionState() - status=22 clientIf=11
BluetoothGatt: onClientConnectionState() - status=22 clientIf=12
OCSC    : Status: 22
OCSC    : New State: 0
OCSC    : Disconnected from GATT server.
OCSC    : Status: 22
OCSC    : New State: 0
OCSC    : Disconnected from GATT server.
OCSC    : Status: 22
OCSC    : New State: 0
OCSC    : Disconnected from GATT server.
OCSC    : Status: 22
OCSC    : New State: 0
OCSC    : Disconnected from GATT server.
BluetoothGatt: close()
BluetoothGatt: close()
BluetoothGatt: close()
BluetoothGatt: close()

Logcat(测试2):

BluetoothGatt: onClientConnectionState() - status=133 clientIf=7
OCSC    : Status: 133
OCSC    : New State: 0
OCSC    : Disconnected from GATT server.
BluetoothGatt: close()
BluetoothGatt: onClientConnectionState() - status=133 clientIf=7
OCSC    : Status: 133
OCSC    : New State: 0
OCSC    : Disconnected from GATT server.
BluetoothGatt: close()
BluetoothGatt: onClientConnectionState() - status=22 clientIf=12
OCSC    : Status: 22
OCSC    : New State: 0
OCSC    : Disconnected from GATT server.
BluetoothGatt: close()

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我怀疑你完成后不会清理BluetoothGatt对象。断开连接后,如果您对使用该BluetoothGatt对象不再需要连接到设备感兴趣,则必须调用该对象上的.close()以释放该对象分配的资源。所有应用程序的最大BluetoothGatt对象在最新的Android版本上为32。

您的代码中似乎覆盖了变量mBluetoothGatt。这样你就失去了引用而不能再调用close了...在删除引用之前一定要关闭它。