Can't write to BLE device's characteristic anymore after reconnect

Viewed 1194

I'm writing printing data to the BluetoothGattCharacteristic of a Zebra ZD410 printer. I do this by chunking the data into 20 byte chunks and writing a chunk at a time with the following code:

mCharacteristic.setValue(bytes);
boolean status = mGatt.writeCharacteristic(mCharacteristic);

and then waiting until I receive BluetoothGattCallback.onCharacteristicWrite() before initiating the writing of the next chunk. This works fine.

If I disconnect() and close() the BluetoothGatt and later connect to the same device again with BluetoothDevice.connectGatt() and then try to write to the Characteristic after onServicesDiscovered() has been called is done and I have my Characteristic again, writing will fail. What I mean by this is that when I write to the Characteristic now, onCharacteristicWrite() will be called with a Characteristic who's getValue() returns the value of the last write on the old Gatt.

After trying to solve this for two days and reading tons of SO posts I haven't found a solution.

How can I fix this?

EDIT Here is the code for the BluetoothGattCallback

private final BluetoothGattCallback gattCallback = new BluetoothGattCallback()
{
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
    {
        FALog.i(TAG, "onConnectionStateChange Status: " + status);
        switch (newState)
        {
            case BluetoothProfile.STATE_CONNECTED:
                FALog.i(TAG, "gattCallback STATE_CONNECTED");
                gatt.discoverServices();
                break;
            case BluetoothProfile.STATE_DISCONNECTED:
                disconnectAndCloseGatt();
                mCharacteristic = null;
                connectionFailed();
                FALog.e(TAG, "gattCallback STATE_DISCONNECTED");
                break;
            default:
                FALog.e(TAG, "gattCallback STATE_OTHER");
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status)
    {
        BluetoothGattService service = gatt.getService(PRINTER_SERVICE_UUID);
        if (service != null)
        {
            BluetoothGattCharacteristic characteristic = service.getCharacteristic
                    (PRINTER_SERVICE_CHARACTERISTIC_UUID);
            if (characteristic != null)
            {
                mCharacteristic = characteristic;
                mInternalState = STATE_CONNECTED;
                mState = State.CONNECTED;
                notifyStateChanged();
                print("~JA");
                FALog.d(TAG, "Printer connected");
                mBluetoothActivity.runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        mListener.onPrinterConnected();
                    }
                });
            }
        }
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
    {
        FALog.d(TAG, "received onCharacteristicWrite " + new String(characteristic.getValue()) + "; success: " +
                (status == BluetoothGatt.GATT_SUCCESS));
        if (status == BluetoothGatt.GATT_SUCCESS)
        {
            handler.removeCallbacks(writeRunnable);
            popQueueAndReleaseLock();
        }
    }
};
1 Answers

Try writeCharacteristic after the onDescriptorWrite() callback instead of onServicesDiscovered() callback. writeDescriptor holds the mDeviceBusy.

Related