javaandroidbluetooth-lowenergyrxandroidble

Characteristic cant be written more than once


I'm creating a simple app which should transmit input from a game controller to a HM-10 Bluetooth module. The code should write a characteristic which includes the input data each time when a new input was detected, but at first the writeCharacteristic fails a few times, then it writes the characteristic once and after one successful write any other attempts to write a characteristic don't work.

Here is the Code:

package com.example.fifaksbestbluetoothcontroller;

import static java.lang.Math.round;

import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.polidea.rxandroidble2.RxBleClient;
import com.polidea.rxandroidble2.RxBleDevice;

import java.nio.charset.StandardCharsets;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    RxBleClient rxBleClient;
    RxBleDevice rxBleDevice;
    UUID characteristicUuid = UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb");


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rxBleClient = RxBleClient.create(this);
    }

    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {

        // Check that the event came from a game controller

        float steeringInput = round(event.getAxisValue(MotionEvent.AXIS_X) * 100);
        steeringInput = steeringInput / 100;
        float throttleInput = round(event.getAxisValue(MotionEvent.AXIS_GAS) * 100 - event.getAxisValue(MotionEvent.AXIS_BRAKE) * 100);
        throttleInput = throttleInput / 100;
        String toWrite = steeringInput + "F" + throttleInput + "F";
        byte[] realToWrite = toWrite.getBytes(StandardCharsets.UTF_8);
        TextView textView = findViewById(R.id.BRUH);
        textView.setText(new String(realToWrite));

        rxBleDevice = rxBleClient.getBleDevice("18:93:D7:11:43:DF");
        rxBleDevice.establishConnection(false)
                .flatMapSingle(rxBleConnection -> rxBleConnection.writeCharacteristic(characteristicUuid, realToWrite)).retry(100)
                .subscribe(
                        characteristicValue -> Log.v("myTag", "the data was sent"),
                        throwable -> Log.v("myTag", "the data wasn't sent")
                );
        return true;
    }

}

I don't know how to resolve this problem, because I can't find any solutions based on Logcat.

Here is a snippet of the Logcat:

2021-11-06 22:13:01.857 32604-32665/? D/bt_btif: bta_av_ssm_execute(): AV Sevent(0x41)=0x1229(AVDT_DELAY_RPT) state=3(OPEN)
2021-11-06 22:13:01.857 32604-32665/? E/bt_btif: bta_av_co_audio_delay: handle: x41, delay:0x65d
2021-11-06 22:13:01.857 32604-32665/? E/bt_btif: bta_av_co_get_active_peer: active peer index: 0
2021-11-06 22:13:01.857 32604-32665/? I/btif_av: isBATEnabled: 0
2021-11-06 22:13:01.857 32604-32665/? E/bt_btif: bta_av_co_get_active_peer: active peer index: 0
2021-11-06 22:13:01.857 32604-32665/? I/chatty: uid=1002(bluetooth) btu message loo identical 2 lines
2021-11-06 22:13:01.857 32604-32665/? E/bt_btif: bta_av_co_get_active_peer: active peer index: 0
2021-11-06 22:13:01.857 705-705/? I/vendor.qti.bluetooth@1.0-ibs_handler: DeviceWakeUp: Writing IBS_WAKE_IND
2021-11-06 22:13:01.857 32604-32665/? I/btif_av: isBATEnabled: 0
2021-11-06 22:13:01.857 32604-32665/? E/bt_btif: bta_av_co_get_active_peer: active peer index: 0
2021-11-06 22:13:01.857 32604-32665/? E/bt_btif: bta_av_co_get_active_peer: active peer index: 0
2021-11-06 22:13:01.857 32604-32665/? I/bt_stack: [INFO:a2dp_encoding.cc(1370)] set_remote_delay: DELAY 162.9 ms
2021-11-06 22:13:01.857 705-32662/? I/vendor.qti.bluetooth@1.0-ibs_handler: ProcessIbsCmd: Received IBS_WAKE_ACK: 0xFC
2021-11-06 22:13:01.858 702-8805/? I/BTAudioProviderSession: OnSessionParamUpdate Update Sink Latency: 1629
2021-11-06 22:13:01.889 1826-2276/? W/BaseMiuiPhoneWindowManager: keyCode:105 down:true eventTime:1244197974 downTime:1244197974 policyFlags:22000001 flags:8 deviceId:57 isScreenOn:true keyguardActive:false repeatCount:0
2021-11-06 22:13:01.895 19384-20187/? D/BluetoothGatt: connect() - device: 18:93:D7:11:43:DF, auto: false
2021-11-06 22:13:01.896 19384-20187/? D/BluetoothGatt: registerApp()
2021-11-06 22:13:01.896 19384-20187/? D/BluetoothGatt: registerApp() - UUID=d1c2e3e7-5505-42d1-824d-3ff2a8c97dcb
2021-11-06 22:13:01.897 6594-6594/? D/AudioManager: getStreamVolume isRestricted mode = 0
2021-11-06 22:13:01.898 32604-364/? D/BtGatt.GattService: registerClient() - UUID=d1c2e3e7-5505-42d1-824d-3ff2a8c97dcb
2021-11-06 22:13:01.899 32604-32665/? I/bt_stack: [INFO:gatt_api.cc(957)] GATT_Register 592b908d-0565-f4ce-989f-2f3d65f8540b
2021-11-06 22:13:01.899 32604-32665/? I/bt_stack: [INFO:gatt_api.cc(977)] allocated gatt_if=10
2021-11-06 22:13:01.899 6594-6594/? D/AudioManager: getStreamVolume isRestricted mode = 0
2021-11-06 22:13:01.900 32604-32639/? D/BtGatt.GattService: onClientRegistered() - UUID=d1c2e3e7-5505-42d1-824d-3ff2a8c97dcb, clientIf=10
2021-11-06 22:13:01.900 19384-19417/? D/BluetoothGatt: onClientRegistered() - status=0 clientIf=10
2021-11-06 22:13:01.901 32604-364/? D/BtGatt.GattService: clientConnect() - address=18:93:D7:11:43:DF, isDirect=true, opportunistic=false, phy=1
2021-11-06 22:13:01.901 32604-32639/? D/bt_btif_config: btif_get_address_type: Device [18:93:d7:11:43:df] address type 0
2021-11-06 22:13:01.901 32604-32639/? D/bt_btif_config: btif_get_device_type: Device [18:93:d7:11:43:df] type 2
2021-11-06 22:13:01.901 32604-32665/? I/bt_stack: [INFO:gatt_api.cc(1129)] GATT_Connect gatt_if=10, address=18:93:d7:11:43:df is_direct 1
2021-11-06 22:13:01.902 32604-32639/? D/BtGatt.GattService: onConnected() - clientIf=10, connId=10, address=18:93:D7:11:43:DF
2021-11-06 22:13:01.905 19384-19417/? D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=10 device=18:93:D7:11:43:DF
2021-11-06 22:13:01.908 19384-19384/? D/myTag: the data wasn't sent
2021-11-06 22:13:01.908 19384-20187/? D/BluetoothGatt: discoverServices() - device: 18:93:D7:11:43:DF
2021-11-06 22:13:01.909 32604-364/? D/BtGatt.GattService: discoverServices() - address=18:93:D7:11:43:DF, connId=10
2021-11-06 22:13:01.910 32604-32639/? D/BtGatt.GattService: onSearchCompleted() - connId=10, status=0
2021-11-06 22:13:01.911 32604-32639/? D/bt_bta_gattc: bta_gattc_get_gatt_db
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: onGetGattDb() - address=18:93:D7:11:43:DF
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got service with UUID=00001800-0000-1000-8000-00805f9b34fb id: 1
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a00-0000-1000-8000-00805f9b34fb id: 3
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a01-0000-1000-8000-00805f9b34fb id: 5
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a02-0000-1000-8000-00805f9b34fb id: 7
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a03-0000-1000-8000-00805f9b34fb id: 9
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a04-0000-1000-8000-00805f9b34fb id: 11
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got service with UUID=00001801-0000-1000-8000-00805f9b34fb id: 12
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a05-0000-1000-8000-00805f9b34fb id: 14
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got descriptor with UUID=00002902-0000-1000-8000-00805f9b34fb id: 15
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got service with UUID=0000180a-0000-1000-8000-00805f9b34fb id: 16
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a23-0000-1000-8000-00805f9b34fb id: 18
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a24-0000-1000-8000-00805f9b34fb id: 20
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a25-0000-1000-8000-00805f9b34fb id: 22
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a26-0000-1000-8000-00805f9b34fb id: 24
2021-11-06 22:13:01.911 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a27-0000-1000-8000-00805f9b34fb id: 26
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a28-0000-1000-8000-00805f9b34fb id: 28
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a29-0000-1000-8000-00805f9b34fb id: 30
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a2a-0000-1000-8000-00805f9b34fb id: 32
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=00002a50-0000-1000-8000-00805f9b34fb id: 34
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got service with UUID=0000ffe0-0000-1000-8000-00805f9b34fb id: 35
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got characteristic with UUID=0000ffe1-0000-1000-8000-00805f9b34fb id: 37
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got descriptor with UUID=00002902-0000-1000-8000-00805f9b34fb id: 38
2021-11-06 22:13:01.912 32604-32639/? D/BtGatt.GattService: got descriptor with UUID=00002901-0000-1000-8000-00805f9b34fb id: 39
2021-11-06 22:13:01.913 19384-19417/? D/BluetoothGatt: onSearchComplete() = Device=18:93:D7:11:43:DF Status=0
2021-11-06 22:13:01.918 19384-20186/? D/myTag: the data was sent
2021-11-06 22:13:01.941 19384-19384/? D/myTag: the data wasn't sent
2021-11-06 22:13:01.974 19384-19384/? I/chatty: uid=10483(com.example.fifaksbestbluetoothcontroller) identical 1 line
2021-11-06 22:13:02.007 19384-19384/? D/myTag: the data wasn't sent
2021-11-06 22:13:02.065 523-523/? I/hwservicemanager: getTransport: Cannot find entry vendor.qti.hardware.servicetracker@1.0::IServicetracker/default in either framework or device manifest.
2021-11-06 22:13:02.107 19384-19384/? D/myTag: the data wasn't sent
2021-11-06 22:13:02.139 6594-6594/? D/AudioManager: getStreamVolume isRestricted mode = 0
2021-11-06 22:13:02.140 19384-19384/? D/myTag: the data wasn't sent
2021-11-06 22:13:02.142 6594-6594/? D/AudioManager: getStreamVolume isRestricted mode = 0
2021-11-06 22:13:02.151 2769-2769/? D/QtiCarrierConfigHelper: WARNING, no carrier configs on phone Id: 0
2021-11-06 22:13:02.151 4171-4171/? D/NfcService: Received android.intent.action.BATTERY_CHANGED

Any help would be greatly appreciated.


Solution

  • If you would check the throwable you would probably see BleAlreadyConnectedException.

    If that is the case you want to establish RxBleConnection once an reuse it. To send data with reusing the connection you could use for instance RxReplayingShare or wrapping onMotionEvent() into an Observable<MotionEvent> and wrangle it into an Observable chain.

    Observable.combineLatest(
        motionEventObservable,
        rxBleDevice.establishConnection(false),
        (motionEvent, connection) -> {
            float steeringInput = round(event.getAxisValue(MotionEvent.AXIS_X) * 100);
            steeringInput = steeringInput / 100;
            float throttleInput = round(event.getAxisValue(MotionEvent.AXIS_GAS) * 100 - event.getAxisValue(MotionEvent.AXIS_BRAKE) * 100);
            throttleInput = throttleInput / 100;
            String toWrite = steeringInput + "F" + throttleInput + "F";
            byte[] realToWrite = toWrite.getBytes(StandardCharsets.UTF_8);
            return rxBleConnection.writeCharacteristic(characteristicUuid, realToWrite);
        }
    )
        .flatMapSingle(it -> it)
        .subscribe(
            characteristicValue -> Log.v("myTag", "the data was sent"),
            throwable -> Log.v("myTag", "the data wasn't sent", throwable) // check what is the problem!
        );