Provide Reactive Extensions Artifact
Rx has become widely used in the Android community. We should consider deploying our own artifact which provides extensions to allow developers using Rx seamless integration with Lost. There are still several details to work through but here is a start:
- We create a separate Rx module,
rxlost -
rxlostwill depend on thelostmodule -
rxlostwill not impact the APIs inlostmodule in any way -
rxlostwill be written in java and any kotlin extensions we want to provide can be created in a thirdrxlost-kotlinmodule (similar to how RxJava & RxKotlin are structured)
Lets use this ticket as a place to gather and discuss high level design/api decisions as well as gauge interest in and take suggestions from the community
https://academy.realm.io/posts/360-andev-2017-kaushik-gopal-rxjava-by-example-multicasting/ for where it all began :D. There are many pointers in this talk, which point to us doing this work.
A first pass at the Rx APIs:
public enum ConnectionStatus {
CONNECTED, SUSPENDED
}
public class RxLostApiClient {
public RxLostApiClient(Context context)
public Observable<ConnectionStatus> getConnectionStatus();
}
public class RxLocationServices {
public static final RxFusedLocationProviderApi FusedLocationApi;
public static final RxGeofencingApi GeofencingApi;
public static final RxSettingsApi SettingsApi;
}
public interface RxFusedLocationProviderApi {
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Maybe<Location> getLastLocation(RxLostApiClient client);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Maybe<LocationAvailability> getLocationAvailability(RxLostApiClient client);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> requestLocationUpdates(RxLostApiClient client, LocationRequest request,
LocationListener listener);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> requestLocationUpdates(RxLostApiClient client, LocationRequest request,
LocationListener listener, Looper looper);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> requestLocationUpdates(RxLostApiClient client, LocationRequest request,
LocationCallback callback, Looper looper);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> requestLocationUpdates(RxLostApiClient client, LocationRequest request,
PendingIntent callbackIntent);
Single<Status> removeLocationUpdates(RxLostApiClient client, LocationListener listener);
Single<Status> removeLocationUpdates(RxLostApiClient client, PendingIntent callbackIntent);
Single<Status> removeLocationUpdates(RxLostApiClient client, LocationCallback callback);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Observable<Location> requestLocationUpdates(RxLostApiClient client, LocationRequest request);
Single<Status> setMockMode(RxLostApiClient client, boolean isMockMode);
Single<Status> setMockLocation(RxLostApiClient client, Location mockLocation);
Single<Status> setMockTrace(RxLostApiClient client, final String path,
final String filename);
}
public interface RxGeofencingApi {
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> addGeofences(RxLostApiClient client, GeofencingRequest geofencingRequest,
PendingIntent pendingIntent);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> addGeofences(RxLostApiClient client, List<Geofence> geofences,
PendingIntent pendingIntent);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> removeGeofences(RxLostApiClient client, List<String> geofenceRequestIds);
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
Single<Status> removeGeofences(RxLostApiClient client, PendingIntent pendingIntent);
Observable<Geofence> requestGeofences(RxLostApiClient client, GeofencingRequest geofencingRequest);
Observable<Geofence> requestGeofences(RxLostApiClient client, List<Geofence> geofences);
}
public class RxSettingsApi {
Single<LocationSettingsResult> checkLocationSettings(RxLostApiClient apiClient,
LocationSettingsRequest request);
}
Example usage:
CompositeDisposable compositeDisposable;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
compositeDisposable = new CompositeDisposable();
final RxLostApiClient client = new RxLostApiClient(this);
Observable<ConnectionStatus> observable = client.getConnectionStatus();
observable.doOnNext(new Consumer<ConnectionStatus>() {
@Override public void accept(ConnectionStatus connectionStatus) throws Exception {
if (connectionStatus == ConnectionStatus.CONNECTED) {
final LocationRequest request = LocationRequest.create().setPriority(PRIORITY_HIGH_ACCURACY);
Observable<Location> locationObservable = RxLocationServices.FusedLocationApi.
requestLocationUpdates(client, request);
locationObservable.doOnNext(new Consumer<Location>() {
@Override public void accept(Location location) throws Exception {
// do something with location
}
});
compositeDisposable.add(locationObservable.subscribe());
}
}
});
compositeDisposable.add(observable.subscribe());
}
@Override protected void onDestroy() {
super.onDestroy();
compositeDisposable.dispose();
}
Closing as this repo is no longer maintained.