package pl.charmas.android.reactivelocation.observables; import android.content.Context; import android.os.Bundle; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.Api; import com.google.android.gms.common.api.GoogleApiClient; import java.util.Arrays; import java.util.List; import rx.Observable; import rx.Observer; import rx.Subscriber; import rx.functions.Action0; import rx.subscriptions.Subscriptions; public abstract class BaseObservable<T> implements Observable.OnSubscribe<T> { private final Context ctx; private final List<Api<? extends Api.ApiOptions.NotRequiredOptions>> services; @SafeVarargs protected BaseObservable(Context ctx, Api<? extends Api.ApiOptions.NotRequiredOptions>... services) { this.ctx = ctx; this.services = Arrays.asList(services); } @Override public void call(Subscriber<? super T> subscriber) { final GoogleApiClient apiClient = createApiClient(subscriber); try { apiClient.connect(); } catch (Throwable ex) { subscriber.onError(ex); } subscriber.add(Subscriptions.create(new Action0() { @Override public void call() { if (apiClient.isConnected() || apiClient.isConnecting()) { onUnsubscribed(apiClient); apiClient.disconnect(); } } })); } protected GoogleApiClient createApiClient(Subscriber<? super T> subscriber) { ApiClientConnectionCallbacks apiClientConnectionCallbacks = new ApiClientConnectionCallbacks(subscriber); GoogleApiClient.Builder apiClientBuilder = new GoogleApiClient.Builder(ctx); for (Api<? extends Api.ApiOptions.NotRequiredOptions> service : services) { apiClientBuilder.addApi(service); } apiClientBuilder.addConnectionCallbacks(apiClientConnectionCallbacks); apiClientBuilder.addOnConnectionFailedListener(apiClientConnectionCallbacks); GoogleApiClient apiClient = apiClientBuilder.build(); apiClientConnectionCallbacks.setClient(apiClient); return apiClient; } protected void onUnsubscribed(GoogleApiClient locationClient) { } protected abstract void onGoogleApiClientReady(GoogleApiClient apiClient, Observer<? super T> observer); private class ApiClientConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { final private Observer<? super T> observer; private GoogleApiClient apiClient; private ApiClientConnectionCallbacks(Observer<? super T> observer) { this.observer = observer; } @Override public void onConnected(Bundle bundle) { try { onGoogleApiClientReady(apiClient, observer); } catch (Throwable ex) { observer.onError(ex); } } @Override public void onConnectionSuspended(int cause) { observer.onError(new GoogleAPIConnectionSuspendedException(cause)); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { observer.onError(new GoogleAPIConnectionException("Error connecting to GoogleApiClient.", connectionResult)); } public void setClient(GoogleApiClient client) { this.apiClient = client; } } }