0

After reeding this article and answer on stackoverflow I wrote this BluetoothGattCallback:

private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
        if (status == GATT_SUCCESS) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                // We successfully connected, proceed with service discovery
                Log.i(TAG, "We successfully connected, proceed with service discovery");
                stopScan();
                gatt.discoverServices();

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                // We successfully disconnected on our own request
                Log.i(TAG, "We successfully disconnected on our own request");
                gatt.close();
            } else {

            }
        } else {
            // An error happened...
            gatt.close();
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        Log.i(TAG, "We are onServiceDiscovered");
        BluetoothGattCharacteristic characteristic =
                gatt.getService(Beacon.BEACON_SERVICE_UUID)
                        .getCharacteristic(Beacon.BEACON_CHAR_UUID);

        BluetoothGattDescriptor descriptor =
                characteristic.getDescriptor(convertFromInteger(0x2902));

        descriptor.setValue(
                BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);


        gatt.writeDescriptor(descriptor);

        gatt.setCharacteristicNotification(characteristic, true);

        writeCharacteristic();
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, int status) {
        Log.i(TAG, "onWrite");

    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        Log.i(TAG, "We are onCharacteristicChanged");
        dev_data_hendler.sendMessage(Message.obtain(dev_data_hendler, 0, characteristic.getValue()));
    }
};

where writeCharacteristic is:

private void writeCharacteristic() {

    class writeTask implements Runnable {
        byte [] bytes;
        writeTask(byte[] to_write){bytes = to_write;}

        public void run() {
            if (gatt == null) {
                Log.e(TAG, "lost connection");
            }

            if (gatt.getService(Beacon.BEACON_SERVICE_UUID) == null) {
                Log.e(TAG, "service not found!");
            }

            if (gatt.getService(Beacon.BEACON_SERVICE_UUID).getCharacteristic(Beacon.BEACON_CHAR_UUID) == null) {
                Log.e(TAG, "char not found!");
            }
            BluetoothGattCharacteristic characteristic = gatt.getService(Beacon.BEACON_SERVICE_UUID).getCharacteristic(Beacon.BEACON_CHAR_UUID);

            characteristic.setWriteType(WRITE_TYPE_DEFAULT);
            characteristic.setValue(bytes);
            if (gatt.writeCharacteristic(characteristic)) {
                Log.i(TAG, "Char written" + flag);
                flag++;
            } else {
                Log.e(TAG, "Char writing failure");
            }
        }
    }
    Thread t = new Thread(new writeTask(new byte[] {(byte)0x05, (byte)0x01}));
    t.start();
    try {
        t.sleep(150);
    } catch (InterruptedException e) {
        Log.i(TAG, "interrupted exception");
    }

}

and gatt.writeCharacteristic(characteristic) returns false. Writing and setting up notifications work well but separately. If I write on characteristic first, writeCharacteristic returns true, but my device has no reaction on this. It works only separetely

Ivan L
  • 1

1 Answers1

0

On Android you need to wait for a write/read to complete before you can do the next one. So you need to queue your writes/reads...

  • It works, but inspired by this answer I replace write method in onCharacteristicwrite callback method and it works. – Ivan L Feb 20 '20 at 21:24