Android BLE onCharacteristicRead错误状态导致蓝牙停止工作

时间:2017-10-12 22:11:18

标签: java android bluetooth bluetooth-lowenergy

我正在开发一款Android应用程序,每天必须连接+/- 120个BLE GATT服务器,其中至少有3个服务器同时具有完全相同的服务和特性。即使遵循所有标准和默认模式,我也一直在体验Android BLE的各种问题。

每天都会发生这样的情况:我必须至少一次将平板电脑重置为默认设置,因为“蓝牙已停止工作”,我无法找到原因。 这令我非常沮丧,我每天都无法忍受这种类型的维护(硬复位)。

起初,我尝试了针对Android SDK 18的BLE,其中表现得非常奇怪,只用了一天就显示出糟糕的结果。 所以我开始使用操作Android BLE的Lollipop版本,它显示了一些改进。

我几天来一直在遇到这些问题,因为我得到了意想不到的结果,例如onCharacteristicRead返回,但数据为空。 或者,例如,我在onConnectionStateChanged之后使用STATE_CONNECTED调用discoverServices(),因此在调用onServicesDiscovered()一段时间后,getServices()返回null。 所有这些问题仅在与第一台服务器断开连接后才会发生。它连接的第一台服务器正确地读取和写入所有内容,但后来我断开连接()和onConnectionStateChanged(),然后我关闭()。然后我连接到下一个服务器,我开始遇到这些问题(所有GATT操作都在主线程上,所有连接都正确,并且正确处理),所以我必须断开连接,以便can app读取GATT属性正确。

我有3个要阅读的特征,在阅读完第3个特征后,我开始写3个特征。

我已经通过蓝牙日志,我可以看到意外的事情发生。这个日志是应用程序正确读取所有内容的时间(它总是只有应用程序连接到的第一个GATT服务器):

10-11 09:08:05.350 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.350 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.350 15989-15989/efp.android.sample D/BluetoothLeScanner: Start Scan
10-11 09:08:05.351 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.352 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.353 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.354 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.362 15989-15994/efp.android.sample I/art: Do partial code cache collection, code=48KB, data=60KB
10-11 09:08:05.362 15989-15994/efp.android.sample I/art: After code cache collection, code=48KB, data=60KB
10-11 09:08:05.362 15989-15994/efp.android.sample I/art: Increasing code cache capacity to 256KB
10-11 09:08:05.457 15989-16002/efp.android.sample D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5 mClientIf=0
10-11 09:08:05.513 15989-15989/efp.android.sample W/IInputConnectionWrapper: getCursorCapsMode on inactive InputConnection
10-11 09:08:05.681 15989-16023/efp.android.sample D/ScanRecord: parseFromBytes
10-11 09:08:05.681 15989-15989/efp.android.sample D/LAURASTAR_BLE: onScanResult
10-11 09:08:05.682 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.683 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.684 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.685 15989-15989/efp.android.sample D/BluetoothAdapter: STATE_ON
10-11 09:08:05.685 15989-15989/efp.android.sample D/BluetoothLeScanner: Stop Scan
10-11 09:08:05.692 15989-15989/efp.android.sample D/BluetoothGatt: connect() - device: F5:8E:C1:91:DC:CC, auto: false
10-11 09:08:05.692 15989-15989/efp.android.sample D/BluetoothAdapter: isSecureModeEnabled
10-11 09:08:05.699 15989-15989/efp.android.sample D/BluetoothGatt: registerApp()
10-11 09:08:05.699 15989-15989/efp.android.sample D/BluetoothGatt: registerApp() - UUID=ebf41986-8aad-4796-a537-7319c00f0f46
10-11 09:08:05.802 15989-16002/efp.android.sample D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
10-11 09:08:06.332 15989-16001/efp.android.sample D/LAURASTAR_BLE: onConnectionStateChange:
10-11 09:08:06.332 15989-16001/efp.android.sample D/BluetoothGatt: discoverServices() - device: F5:8E:C1:91:DC:CC
10-11 09:08:06.343 15989-16002/efp.android.sample D/BluetoothGatt: onSearchComplete() = Device=F5:8E:C1:91:DC:CC Status=0
10-11 09:08:06.343 15989-16002/efp.android.sample D/LAURASTAR_BLE: onServicesDiscovered:
10-11 09:08:07.143 15989-16002/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=51 Status=0
10-11 09:08:07.233 15989-16002/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=14 Status=0
10-11 09:08:07.324 15989-16023/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=23 Status=0
10-11 09:08:08.136 15989-16023/efp.android.sample D/BluetoothGatt: cancelOpen() - device: F5:8E:C1:91:DC:CC
10-11 09:08:08.146 15989-16001/efp.android.sample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=F5:8E:C1:91:DC:CC
10-11 09:08:08.151 15989-16001/efp.android.sample D/LAURASTAR_BLE: onConnectionStateChange:
10-11 09:08:08.265 15989-15989/efp.android.sample D/BluetoothGatt: close()
10-11 09:08:08.266 15989-15989/efp.android.sample D/BluetoothGatt: unregisterApp() - mClientIf=5

在断开与第一个GATT服务器连接以连接到第二个GATT服务器之后,我必须不断断开连接并重新连接到读取特性,尽管它总能正确读取第一个特性。

以下是有问题时读取的日志...因此,如果读取有错误,我需要断开连接并重新连接(即使重新连接后读取有错误,它也会关闭,扫描并再次尝试)。 / p>

10-12 08:03:48.133 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.133 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.134 30409-30409/efp.android.sample D/BluetoothLeScanner: Start Scan
10-12 08:03:48.134 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.137 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.260 30409-31121/efp.android.sample D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=6 mClientIf=0
10-12 08:03:48.391 30409-30422/efp.android.sample D/ScanRecord: parseFromBytes
10-12 08:03:48.395 30409-30409/efp.android.sample D/LAURASTAR_BLE: onScanResult
10-12 08:03:48.397 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.397 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.398 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.399 30409-30409/efp.android.sample D/BluetoothAdapter: STATE_ON
10-12 08:03:48.399 30409-30409/efp.android.sample D/BluetoothLeScanner: Stop Scan
10-12 08:03:48.410 30409-30409/efp.android.sample D/BluetoothGatt: connect() - device: F5:8E:C1:91:DC:CC, auto: false
10-12 08:03:48.410 30409-30409/efp.android.sample D/BluetoothAdapter: isSecureModeEnabled
10-12 08:03:48.411 30409-30409/efp.android.sample D/BluetoothGatt: registerApp()
10-12 08:03:48.411 30409-30409/efp.android.sample D/BluetoothGatt: registerApp() - UUID=ce6919e5-e4f7-4180-a313-557e168a7c5a
10-12 08:03:48.514 30409-30422/efp.android.sample D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
10-12 08:03:48.745 30409-31121/efp.android.sample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F5:8E:C1:91:DC:CC
10-12 08:03:48.755 30409-31121/efp.android.sample D/BluetoothGatt: discoverServices() - device: F5:8E:C1:91:DC:CC
10-12 08:03:48.915 30409-30414/efp.android.sample I/art: Do partial code cache collection, code=19KB, data=28KB
10-12 08:03:48.916 30409-30414/efp.android.sample I/art: After code cache collection, code=19KB, data=28KB
10-12 08:03:48.916 30409-30414/efp.android.sample I/art: Increasing code cache capacity to 128KB
10-12 08:03:48.982 30409-30422/efp.android.sample D/BluetoothGatt: onClientConnParamsChanged() - Device=F5:8E:C1:91:DC:CC interval=6 status=0 (I DONT THINK THIS SHOULD HAPPEN)
10-12 08:03:49.688 30409-30421/efp.android.sample D/BluetoothGatt: onSearchComplete() = Device=F5:8E:C1:91:DC:CC Status=0
10-12 08:03:49.689 30409-30421/efp.android.sample D/LAURASTAR_BLE: onServicesDiscovered:
10-12 08:03:49.711 30409-30422/efp.android.sample D/BluetoothGatt: onClientConnParamsChanged() - Device=F5:8E:C1:91:DC:CC interval=36 status=0
10-12 08:03:50.467 30409-31121/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=51 Status=0
10-12 08:03:50.557 30409-30422/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=14 Status=5 (status NOT SUCCESS ...)
10-12 08:03:50.830 30409-30422/efp.android.sample D/BluetoothGatt: onClientConnParamsChanged() - Device=F5:8E:C1:91:DC:CC interval=6 status=0
10-12 08:03:51.533 30409-31121/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=14 Status=137 (status NOT SUCCESS ...)
10-12 08:03:51.533 30409-31121/efp.android.sample D/LAURASTAR_BLE: Data is empty. (null)
10-12 08:03:51.533 30409-31121/efp.android.sample D/BluetoothGatt: cancelOpen() - device: F5:8E:C1:91:DC:CC
10-12 08:03:51.561 30409-30422/efp.android.sample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F5:8E:C1:91:DC:CC
10-12 08:03:51.565 30409-30422/efp.android.sample D/LAURASTAR_BLE: onConnectionStateChange:
10-12 08:03:51.565 30409-30422/efp.android.sample D/BluetoothAdapter: isSecureModeEnabled
10-12 08:03:51.609 30409-31121/efp.android.sample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F5:8E:C1:91:DC:CC
10-12 08:03:51.610 30409-31121/efp.android.sample D/LAURASTAR_BLE: onConnectionStateChange:
10-12 08:03:51.610 30409-31121/efp.android.sample D/BluetoothGatt: discoverServices() - device: F5:8E:C1:91:DC:CC
10-12 08:04:01.091 30409-31121/efp.android.sample D/BluetoothGatt: onSearchComplete() = Device=F5:8E:C1:91:DC:CC Status=0
10-12 08:04:01.091 30409-31121/efp.android.sample D/LAURASTAR_BLE: onServicesDiscovered:
10-12 08:04:02.048 30409-31121/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=51 Status=0
10-12 08:04:02.438 30409-30421/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=14 Status=0
10-12 08:04:02.829 30409-30421/efp.android.sample W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=23 Status=0
10-12 08:04:02.898 30409-30414/efp.android.sample I/art: Do partial code cache collection, code=48KB, data=61KB
10-12 08:04:02.899 30409-30414/efp.android.sample I/art: After code cache collection, code=48KB, data=61KB
10-12 08:04:02.899 30409-30414/efp.android.sample I/art: Increasing code cache capacity to 256KB
10-12 08:04:04.389 30409-30422/efp.android.sample D/BluetoothGatt: cancelOpen() - device: F5:8E:C1:91:DC:CC
10-12 08:04:04.402 30409-30421/efp.android.sample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=F5:8E:C1:91:DC:CC
10-12 08:04:04.406 30409-30421/efp.android.sample D/LAURASTAR_BLE: onConnectionStateChange:
10-12 08:04:04.502 30409-30409/efp.android.sample V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@d981ae5 nm : efp.android.sample ic=com.android.internal.widget.EditableInputConnection@41369ba
10-12 08:04:04.502 30409-30409/efp.android.sample I/InputMethodManager: [IMM] startInputInner - mService.startInputOrWindowGainedFocus
10-12 08:04:04.503 30409-30409/efp.android.sample D/InputTransport: Input channel constructed: fd=70
10-12 08:04:04.503 30409-30409/efp.android.sample D/InputTransport: Input channel destroyed: fd=73
10-12 08:04:04.519 30409-30409/efp.android.sample D/BluetoothGatt: close()
10-12 08:04:04.520 30409-30409/efp.android.sample D/BluetoothGatt: unregisterApp() - mClientIf=6

在这个日志中,在成功阅读第一个特征后,这是可见的:

W/BluetoothGatt: onCharacteristicRead() - Device=F5:8E:C1:91:DC:CC handle=14 Status=5

然后在调用discoverServices()之后调用onClientConnParamsChanged,并在调用onServicesDiscovered()之前调用它。

我的所有代码似乎都是正确的...... 所以逻辑如下:

首先接收用户所需的服务器mac地址,以便应用程序扫描并找到它。

我在EditText中实现了TextWatcher,因此当用户插入mac地址时,应用会查找插入了地址的BLE设备。

String macToFind = "";
private class ScanIronFieldsTextWatcher implements TextWatcher {

    View view;
    public ScanIronFieldsTextWatcher(View view) { this.view = view; }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}


    public void afterTextChanged(Editable editable) {

        switch (view.getId()) {
            case R.id.txt_mac_address: {
                String originalText =  txtMacAddress.getText().toString().toUpperCase();
                String macToFind = Tools.getValidMacAddress(originalText);
                if(mConnectedGatt != null && mConnectedGatt.getDevice().getAddress().equals(macToFind)) {
                    mConnectedGatt.connect();
                }
                else {
                    if(mConnectedGatt != null) {
                        mConnectedGatt.close();
                        mConnectedGatt = null;
                    }

                    //Search mac address
                    writeToActivityLog("Looking for " + macToFind +"...", LogAdapter.MESSAGE_TYPE_NORMAL);
                    hideKeyboard();
                    startScan();
                }
            }
        }
    }
}

用户插入mac地址后,启动startScan()。

startScan()

private void startScan() {
        if (!mBluetoothAdapter.isEnabled()) {
            writeToActivityLog("Bluetooth is off!", LogAdapter.MESSAGE_TYPE_ERROR);
            return;
        }
        try {
            ScanFilter scanFilter = new ScanFilter.Builder().setDeviceAddress(macToFind).build();
            ArrayList<ScanFilter> filters = new ArrayList<ScanFilter>();
            filters.add(scanFilter);

            ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_BALANCED).build();
            mBluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, mScanCallback);


            retryingHandler = new Handler();
            retryingHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    showProgress(false);
                    stopScan();

                    if (mDevices.size() == 0) {
                        writeToActivityLog("Server not found.", LogAdapter.MESSAGE_TYPE_ERROR);
                    } else {
                        mDevices.clear();
                    }
                }
            }, SCAN_TIME);
        } catch (IllegalArgumentException e) {
            writeToActivityLog("Invalid Address!", LogAdapter.MESSAGE_TYPE_ERROR);
        }
    }

mScanCallback:

private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            Log.d(TAG, "onScanResult");
            processResult(result);
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            Log.d(TAG, "onBatchScanResults: "+results.size()+" results");
            for (ScanResult result : results) {
                processResult(result);
            }
        }

        @Override
        public void onScanFailed(int errorCode) { Log.w(TAG, "LE Scan Failed: "+errorCode); }

        private void processResult(final ScanResult result) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(mConnectedGatt == null) {
                        stopScan();
                        final BluetoothDevice device = result.getDevice();
                        mDevices.put(device.hashCode(), device);

                        writeToActivityLog("Server found!", LogAdapter.MESSAGE_TYPE_NORMAL);
                        writeToActivityLog("Connecting to " + macToFind + "...", LogAdapter.MESSAGE_TYPE_NORMAL);

                        mConnectedGatt = device.connectGatt(NewDeviceControlActivity.this, false, mGattCallback);
                        retryingHandler.removeCallbacksAndMessages(null);
                    }
                }
            });
        }
    };

mGattCallback

private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);

            if (newState == BluetoothProfile.STATE_CONNECTED) {
                writeToActivityLog("Connected.", LogAdapter.MESSAGE_TYPE_SUCCESS);
                mConnected = true;

                if(!gatt.discoverServices()) {
                    writeToActivityLog("Impossible discoverServices().", LogAdapter.MESSAGE_TYPE_ERROR);
                    if(!retrying)
                        retrying = true;
                    mConnectedGatt.disconnect();
                }
            }
            else if(newState == BluetoothProfile.STATE_DISCONNECTED) {

                writeToActivityLog("Disconnected.", LogAdapter.MESSAGE_TYPE_NORMAL);
                if(!currentIron.hasCompletedSetup()) {
                    showProgress(true);

                    if(retrying) {
                        writeToActivityLog("Trying again...", LogAdapter.MESSAGE_TYPE_NORMAL);
                        if(mConnectedGatt != null)
                            mConnectedGatt.connect();
                    }
                    else {
                        writeToActivityLog("Trying again but also scanning again... (r)", LogAdapter.MESSAGE_TYPE_NORMAL);
                        retrying = false;
                        if(mConnectedGatt != null)
                            mConnectedGatt.close();
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                startScan();
                            }
                        }, 2000);
                    }
                }
            }
        }

        @Override
        public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            Log.d(TAG, "onServicesDiscovered:");

            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    startObtainingIronData(gatt);
                }
            }, 700);
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, final int status) {
            super.onCharacteristicRead(gatt, characteristic, status);


            byte[] data = characteristic.getValue();
            if(status != BluetoothGatt.GATT_SUCCESS) {
                runOnUiThread(new Runnable() { @Override public void run() {Toast.makeText(NewDeviceControlActivity.this, ("BluetoothGatt: Response != GATT_SUCCESS ("+status+")."), Toast.LENGTH_SHORT).show();}});
            }

            if (characteristic.getUuid().toString().contains(Iron.IRON_CODES[4])) {
                //First characteristic read succesfully
                final String version = new String(data);
                runOnUiThread(new Runnable() { @Override public void run() {Toast.makeText(NewDeviceControlActivity.this, ("Version "+version), Toast.LENGTH_SHORT).show();}});

                //Request to read second characteristic
                BluetoothGattCharacteristic characteristic2 = getCharacteristic(gatt, Iron.IRON_CODES[0]);
                gatt.readCharacteristic(characteristic2);
            }
            else if (characteristic.getUuid().toString().contains(Iron.IRON_CODES[0])) {
                //Read second characteristic
                if(data == null || data.length == 0) { //returns with  status=137
                    Log.d(TAG, "Data is empty " + (data == null ? "(null)" : data));//This ALWAYS happens except the first server the app connects too
                    writeToActivityLog("Data is empty. "+ (data == null ? "(null)" : data), LogAdapter.MESSAGE_TYPE_ERROR);
                    if(!retrying)
                        retrying = true;
                    mConnectedGatt.disconnect();
                    return;
                }
                else {
                    if (data[2] == 4) {
                        //Request to read third characteristic
                        BluetoothGattCharacteristic characteristic2 = getCharacteristic(gatt, Iron.IRON_CODES[1]);
                        if(characteristic2 != null)
                            gatt.readCharacteristic(characteristic2);
                        else {
                            writeToActivityLog("Impossible readCharacteristic Machine Type" , LogAdapter.MESSAGE_TYPE_ERROR);
                            if(!retrying)
                                retrying = true;

                            mConnectedGatt.disconnect();
                        }
                    }
                }
            }
            else if (characteristic.getUuid().toString().contains(Iron.IRON_CODES[1])) {
                //Read third characteristic
                if(data[0] == 0) {
                    BluetoothGattCharacteristic characteristic2 = getCharacteristic(gatt, Iron.IRON_CODES[2]);
                    long now = System.currentTimeMillis();
                    byte[] nowBytes = new byte[]{(byte) ((int) (now & 255L)), (byte) ((int) (now >> 8)), (byte) ((int) (now >> 16)), (byte) ((int) (now >> 24))};
                    characteristic2.setValue(nowBytes);

                    writeToActivityLog("Read all information succesfully.", LogAdapter.MESSAGE_TYPE_NORMAL);

                    //Request to write first characteristic
                    if (!gatt.writeCharacteristic(characteristic2)){
                        writeToActivityLog("Impossible to write timestamp.", LogAdapter.MESSAGE_TYPE_ERROR);
                        if(!retrying)
                            retrying = true;
                        mConnectedGatt.disconnect();
                    }

                }
            }
        }

        @Override
        public void onCharacteristicWrite(final BluetoothGatt gatt, BluetoothGattCharacteristic characteristic2, int status) {
            super.onCharacteristicWrite(gatt, characteristic2, status);

            if(status == BluetoothGatt.GATT_SUCCESS) {
                showProgress(false);

                if(characteristic2.getUuid().toString().contains(Iron.IRON_CODES[2])) {

                    //Wrote first characteristic
                    String intToWrite = "0x01";
                    BluetoothGattCharacteristic characteristic = getCharacteristic(gatt, Iron.IRON_CODES[1]);
                    characteristic.setValue(Integer.decode(intToWrite), BluetoothGattCharacteristic.FORMAT_UINT8, 0);

                    //Request to write second characteristic
                    if (!gatt.writeCharacteristic(characteristic)) {
                        writeToActivityLog("Impossible to write first characteristic!.", LogAdapter.MESSAGE_TYPE_ERROR);
                        if(!retrying)
                            retrying = true;
                        mConnectedGatt.disconnect();
                    }
                }
                else if(characteristic2.getUuid().toString().contains(Iron.IRON_CODES[1])) {

                        //Wrote second characteristic
                        service.sendData(), new Callback<String>() {
                                    @Override
                                    public void onResponse(Call<String> call, Response<String> response) {

                                            //Write third characteristic
                                            BluetoothGattCharacteristic characteristic = getCharacteristic(gatt, Iron.IRON_CODES[3]);
                                            characteristic.setValue(0x40, android.bluetooth.BluetoothGattCharacteristic.FORMAT_UINT8, 0);
                                            gatt.writeCharacteristic(characteristic);


                                    }
                                    @Override
                                    public void onFailure(Call<String> call, Throwable t) {

                                        if(mConnectedGatt != null)
                                            mConnectedGatt.disconnect();
                                    }
                                });
                        }
                }
                else if(characteristic2.getUuid().toString().contains(Iron.IRON_CODES[3])) {
                    //Wrote third characteristic
                    writeToActivityLog("Data written successfully.", LogAdapter.MESSAGE_TYPE_SUCCESS);

                    if(mConnectedGatt != null)
                        mConnectedGatt.disconnect();
                }

            }
        }
    };

我尝试在runOnUIThread中运行所有mConnectedGatt操作,但结果相同。所有特征UUID都是正确的,并且写入的特征 AREN&#39; T 与读取的特征相同。

我没有GATT服务器的问题&#39; walk&#39;远离应用程序,也不是太远。 我在三台三星Galaxy Tab A 10.1 2016上运行该软件  都返回相同的结果。

所以我的结果基本上就是这些:

预期(仅在应用连接的第一台服务器上发生):

  • 寻找 MAC
  • 找到服务器!
  • 连接 MAC
  • 连接。
  • (阅读第一个特征)版本:
  • (读第二个特征)
  • (阅读第三个特征)
  • (写第一个特征)
  • (写第二个特征)
  • (写第三个特征)
  • 断开。

会发生什么(尝试连接到其他服务器):

  • 寻找 MAC
  • 找到服务器!
  • 连接 MAC
  • 连接。
  • (阅读第一个特征)版本:
  • 数据是空的! (空)
  • 断开。
  • 再试一次......
  • 连接。
  • (阅读第一个特征)版本:
  • (读第二个特征)
  • (阅读第三个特征)
  • (写第一个特征)
  • (写第二个特征)
  • (写第三个特征)
  • 断开。

我猜测很多重新连接是导致蓝牙停止工作的原因。 我无法弄清楚为什么会发生这种情况!

请,如果有人可以花一些时间帮我弄清楚发生了什么,我会非常感激... 谢谢

1 个答案:

答案 0 :(得分:0)

这对我有用: -

http://www.java2s.com/Open-Source/Android_Free_Code/Development/sdk/io_relayr_ble_serviceBluetoothGattReceiver_java.htm

这是使用Rx库。请尝试以下依赖项: -

编译&#34; com.polidea.rxandroidble:rxandroidble:1.4.2&#34;

实施&#39; io.reactivex.rxjava2:rxjava:2.1.5&#39;

实施&#39; io.reactivex.rxjava2:rxandroid:2.0.1&#39;