Search code examples
androidkotlinreactivexrxandroidble

Struggling converting java RxBle Code to Kotlin


Im currently developing an android app with Kotlin. Its my first experience with this programming language and im currently struggeling to translate an example of Java code to Kotlin.

I want to implement the answer to this question in Kotlin.

my current implementation fails to compile because the Ovservable::from method seems to be removed.

This is my current approach:

connectionObservable!!.flatMap { connection ->
                    connection.discoverServices()
                            .flatMap { services ->
                                services.getService(UUID.fromString("My UUID")).map(BluetoothGattService::getCharacteristics)
                                          //here occurs the error, he wants a Single Source but got a observable with the ble characteristic
                                          .flatMap { characteristics: MutableList<BluetoothGattCharacteristic> -> Observable.fromIterable(characteristics) }
                                        .flatMap { characteristic: BluetoothGattCharacteristic ->
                                            connection.setupNotification(characteristic)
                                                    .flatMap { observable: Observable<ByteArray> -> observable ,Pair<BluetoothGattCharacteristic, ByteArray>(characteristic, observable)}

                                        }
                            }
                }.subscribe { pair: Pair<BluetoothGattCharacteristic, ByteArray> ->
                    genericModel[pair.first.uuid] = pair.second
                    throwable -> { /* handle errors */ }
                }

Can you point out my errors so i can understand what im doing wrong?

Thanks in advance! Jonas


Solution

  • There are several potential issues with your code.

    1. First of all the code is not syntactically correct — see this line:
    .flatMap { observable: Observable<ByteArray> -> observable ,Pair<BluetoothGattCharacteristic, ByteArray>(characteristic, observable)}
    

    I assume you probably wanted to flatMap the observable: Observable<ByteArray> (type added by me for clarity) to get from it ByteArray objects. This would look like this:

    .flatMap { observable: Observable<ByteArray> -> observable.map { bytes -> Pair(characteristic, bytes) }}
    
    1. Additionally the code will not compile as you try to return an Observable from a lambda which expects a SingleSource — exactly as your compiler says. If you have a Single and you will .flatMap it — it's lambda is supposed to return another SingleSource. There is a .flatMapObservable function that expects ObservableSource which is what you should use. The end result would look like:
        connectionObservable!!.flatMap { connection ->
            connection.discoverServices()
                .flatMapObservable { services ->
                    services.getService(UUID.fromString("My UUID")).map(BluetoothGattService::getCharacteristics)
                        //here occurs the error, he wants a Single Source but got a observable with the ble characteristic
                        .flatMapObservable { characteristics: MutableList<BluetoothGattCharacteristic> -> Observable.fromIterable(characteristics) }
                        .flatMap { characteristic: BluetoothGattCharacteristic ->
                            connection.setupNotification(characteristic)
                                .flatMap { observable: Observable<ByteArray> -> observable.map { bytes -> Pair(characteristic, bytes) }}
    
                        }
                }
        }.subscribe { pair: Pair<BluetoothGattCharacteristic, ByteArray> ->
            genericModel[pair.first.uuid] = pair.second
            throwable -> { /* handle errors */ }
        }
    
    1. Observable.fromIterable() is still the API of Observable. You probably do not use the Observable class from proper package. There is an Observable class in package java.util but we are using here one from RxJava 2 which has package io.reactivex