1

I use RxAndroidBle https://github.com/Polidea/RxAndroidBle library to work with ble device. But I have a problem with finding characteristicUuid.

I do all from README, but can't find characteristicUuid. In read() need to execute .flatMapSingle { rxBleConnection -> rxBleConnection.readCharacteristic(characteristicUuid) }, but there is no characteristicUuid. Where I can get it?

private lateinit var rxBleClient: RxBleClient
    private lateinit var bleDevice: RxBleDevice
    private lateinit var characteristicUuid: UUID

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    getLocationPermission()

    rxBleClient = RxBleClient.create(this)

    val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)

    button.setOnClickListener { discover() }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_OK) {
    }
}

private lateinit var scanSubscription: Disposable

private fun discover() {
    Log.i("BLE", "start scan")
    scanSubscription = rxBleClient.scanBleDevices(
        ScanSettings.Builder()
            // .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // change if needed
            // .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) // change if needed
            .build()
        // add filters if needed
    )
        .subscribe(
            { scanResult ->
                bleDevice = scanResult.bleDevice
                Log.i("BLE", "SCAN ${bleDevice.name} ${bleDevice.macAddress}")
                connect()
                scanSubscription.dispose()
                // Process scan result here.
            },
            { throwable ->
                Log.i("BLE", "ERROR SCAN ${throwable.localizedMessage}")
                // Handle an error here.
            }
        )

}

private lateinit var connectDisposable: Disposable

private fun connect() {
    val device = bleDevice

    connectDisposable = device.establishConnection(false) // <-- autoConnect flag
        .subscribe(
            { rxBleConnection ->
                Log.i("BLE", "CONNECT ${rxBleConnection.mtu}")
                read(device)
                connectDisposable.dispose()
                // All GATT operations are done through the rxBleConnection.
            },
            { throwable ->
                Log.i("BLE", "ERROR CONNECT ${throwable.localizedMessage}")
                // Handle an error here.
            }
        )

}

private fun read(device: RxBleDevice) {
    val dis = device.establishConnection(false)
        .flatMapSingle { rxBleConnection -> rxBleConnection.readCharacteristic(characteristicUuid) }
        .subscribe(
            { characteristicValue ->
                Log.i("BLE", "READ $characteristicValue")
                // Read characteristic value.
            },
            { throwable ->
                Log.i("BLE", "ERROR READ ${throwable.localizedMessage}")
                // Handle an error here.
            }
        )
}

1 Answers1

0

Characteristic's UUID probably should be mentioned in the manufacturer's manual/info about the bluetooth device you are using. From my experience, our team had an engeneer, who provided us with documentation about device's ble services&characteristics and their UUIDs.

You can get all the ble services, characteristics and their UUIDs in your device with below code

rxBleConnection.discoverServices()
   .map(rxBleDeviceServices -> {
      List<BluetoothGattService> services = rxBleDeviceServices.getBluetoothGattServices();

      for (BluetoothGattService service : services) {
         // here you can work with service's uuid
         String serviceUuid = service.getUuid().toString();

         // or with all characteristics in service
         List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();

         for (BluetoothGattCharacteristic characteristic : characteristics) {
            // here you have your characteristic's UUID
            String characteristicUuid = characteristic.getUuid().toString();
         }
   });

Then you save one of the BluetoothGattCharacteristic or UUID you have found and pass it to rxBleConnection.readCharacteristic(bluetoothGattCharacteristic)

Boris Kozyrev
  • 152
  • 1
  • 5
  • Okey, but I have another problem in `read()` have an exception _Already connected to device with MAC address FF:FF:C3:0A:62:F3_ – Dmytro Melnyk Feb 13 '19 at 11:18
  • Well, you make ```establishConnection``` call twice. Thats why you get your exception. You have to pass ```RxBleConnection``` to method ```read``` and not ```RxBleDevice``` since you already have a valid connection – Boris Kozyrev Feb 13 '19 at 11:25
  • Have another exception **service.getCharacteristic(characteristicUuid) must not be null** – Dmytro Melnyk Feb 13 '19 at 12:20
  • or if I put characteristicUuid **Characteristic not found with UUID 00001800-0000-1000-8000-00805f9b34fb** – Dmytro Melnyk Feb 13 '19 at 12:25
  • Are you sure, characteristic with this UUID exists in your device? Have you found it in manufacturer's info? I guess, I need more logs to make more detailed answer – Boris Kozyrev Feb 13 '19 at 13:03
  • I think I solved this problem. I have next code to read, but when I push buttons on BLE device there is no result `.subscribe({ characteristicValue -> characteristicValue .observeOn(AndroidSchedulers.mainThread()) .subscribe { t1, t2 -> Log.i("BLE", "READ T $t1") if (t2 != null) {Log.i("BLE", "READ T ${t2.localizedMessage}")} } }, { throwable -> Log.i("BLE", "ERROR READ ${throwable.localizedMessage}") })` – Dmytro Melnyk Feb 13 '19 at 13:08
  • If you want to be notified in code whenever you press a button, you have to set up notification via ```rxBleConnection.setupNotification(characteristic)``` – Boris Kozyrev Feb 13 '19 at 13:19
  • I try, but no result – Dmytro Melnyk Feb 13 '19 at 14:29
  • Have you tried to scan and connect to your device through other apps, for example, LightBlue, to make sure your device has accessible characteristics and permissions to read/write? – Boris Kozyrev Feb 13 '19 at 14:36
  • Well, I'm a little bit confused. If you want, you can contact me, for instance, via Telegram for more detailed info – Boris Kozyrev Feb 13 '19 at 15:32
  • Good, write me @dmeln – Dmytro Melnyk Feb 13 '19 at 15:37
  • Can you provide a Kotlin implementation, since the original question was written in Kotlin? Also, ``rxBleDeviceServices `` doesn't exist. – Martin Erlic Mar 27 '19 at 22:31
  • Looks very impolite to downvote my answer, as it completely solves Dmytro's question. Additionally, I cannot take into account the phrase "rxBleDeviceServices doesn't exist" without any proof. – Boris Kozyrev Mar 28 '19 at 11:06