Tadho
Tadho

Reputation: 83

RXJava stop observable inside flatmap

I made a geotagged social report application to report broken streets on Android. It requires location data to post a report. Either from photo's Exif, Gps sensor or set it manually from MapsPickerActivity.

I managed to make the location request using RxLocation library. There's a button that's being made enabled when the app is still getting the location from Gps. Since getting a location data from Gps might take a while, I let the user to just set a location manually at the same time. I want to stop the getGpsLocationObservable if the user pressed the button. If I don't stop the getGpsLocationObservable, I'm afraid the process would still be running and come after setting a custom location. That would be annoying. How could I achieve that?

Here's snippets of the simplified code

Main disposable :

Disposable myDisposable = imageProcessingObservable()
    .compose(getExifLocationTransformer()) //custom location button enabled here 
    .filter(isLocationSet -> isLocationSet)
    .flatmap(x->getGpsLocationObservable());

RxLocation getGpsLocationObservable :

private Observable<String> getGpsLocationObservable(){
    locationRequest = LocationRequest.create()
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        .setNumUpdates(1)
        .setInterval(3000);
    rxLocation = new RxLocation(PostActivity.this);
    rxLocation.setDefaultTimeout(10, TimeUnit.SECONDS);

    return rxLocation.settings()
        .checkAndHandleResolution(locationRequest)
        .flatMapObservable(isActivated->{
            if (isActivated) {
                return locationSettingsActivatedObservable();
            }
            else locationNotFoundObservable();
        });
}

@SuppressLint("MissingPermission")
private Observable<String> locationSettingsActivatedObservable(){
    return rxLocation.location().updates(locationRequest)
        .map(location -> {
            LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
            String street = getStreetName(latLng);
            return street;
        })
        .doOnNext(street->{
            updateUI(street);
        });
}

Upvotes: 3

Views: 1523

Answers (1)

Maxim Volgin
Maxim Volgin

Reputation: 4077

I guess it's a great use case for .amb() operator which only takes output of the observable which started emitting first and ignores all others. See http://reactivex.io/RxJava/javadoc/rx/Observable.html#amb-rx.Observable-rx.Observable-

Upvotes: 1

Related Questions