diff options
| -rw-r--r-- | main/res/values/strings.xml | 1 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/CgeoApplication.java | 4 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/enumerations/LocationProviderType.java | 1 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/playservices/LocationProvider.java | 99 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/sensors/GeoData.java | 7 |
5 files changed, 109 insertions, 3 deletions
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index ade4bf6..a2d1b8f 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -228,6 +228,7 @@ <!-- location service --> <string name="loc_last">Last known</string> <string name="loc_net">Network</string> + <string name="loc_fused">Fused</string> <string name="loc_gps">GPS</string> <string name="loc_sat">Sat</string> <string name="loc_trying">Trying to Locate</string> diff --git a/main/src/cgeo/geocaching/CgeoApplication.java b/main/src/cgeo/geocaching/CgeoApplication.java index 1b3cb05..c8a68f4 100644 --- a/main/src/cgeo/geocaching/CgeoApplication.java +++ b/main/src/cgeo/geocaching/CgeoApplication.java @@ -1,5 +1,6 @@ package cgeo.geocaching; +import cgeo.geocaching.playservices.LocationProvider; import cgeo.geocaching.sensors.DirectionProvider; import cgeo.geocaching.sensors.GeoDataProvider; import cgeo.geocaching.sensors.GpsStatusProvider; @@ -85,7 +86,8 @@ public class CgeoApplication extends Application { public synchronized Observable<IGeoData> geoDataObservable() { if (geoDataObservable == null) { - final ConnectableObservable<IGeoData> onDemand = GeoDataProvider.create(this).replay(1); + final Observable<IGeoData> rawObservable = isGooglePlayServicesAvailable() ? LocationProvider.create(this) : GeoDataProvider.create(this); + final ConnectableObservable<IGeoData> onDemand = rawObservable.replay(1); onDemand.subscribe(new Action1<IGeoData>() { @Override public void call(final IGeoData geoData) { diff --git a/main/src/cgeo/geocaching/enumerations/LocationProviderType.java b/main/src/cgeo/geocaching/enumerations/LocationProviderType.java index f2c79fe..e6024aa 100644 --- a/main/src/cgeo/geocaching/enumerations/LocationProviderType.java +++ b/main/src/cgeo/geocaching/enumerations/LocationProviderType.java @@ -5,6 +5,7 @@ import cgeo.geocaching.R; public enum LocationProviderType { GPS(R.string.loc_gps), NETWORK(R.string.loc_net), + FUSED(R.string.loc_fused), LAST(R.string.loc_last); public final int resourceId; diff --git a/main/src/cgeo/geocaching/playservices/LocationProvider.java b/main/src/cgeo/geocaching/playservices/LocationProvider.java new file mode 100644 index 0000000..714eaeb --- /dev/null +++ b/main/src/cgeo/geocaching/playservices/LocationProvider.java @@ -0,0 +1,99 @@ +package cgeo.geocaching.playservices; + +import cgeo.geocaching.sensors.GeoData; +import cgeo.geocaching.sensors.IGeoData; +import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.RxUtils.ConnectableLooperCallbacks; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; +import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; +import com.google.android.gms.location.LocationClient; +import com.google.android.gms.location.LocationListener; +import com.google.android.gms.location.LocationRequest; + +import rx.Observable; +import rx.Observable.OnSubscribe; +import rx.Subscriber; +import rx.observables.ConnectableObservable; +import rx.subjects.BehaviorSubject; + +import android.content.Context; +import android.location.Location; +import android.os.Bundle; + +import java.util.concurrent.TimeUnit; + +public class LocationProvider implements OnSubscribe<IGeoData>, ConnectionCallbacks, OnConnectionFailedListener, LocationListener { + + private final BehaviorSubject<IGeoData> subject; + private final LocationClient locationClient; + private static final LocationRequest LOCATION_REQUEST = + LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(2000).setInterval(1000); + private static boolean firstLocation = true; + + /** + * Build a new geo data provider object. + * <p/> + * There is no need to instantiate more than one such object in an application, as observers can be added + * at will. + * + * @param context the context used to retrieve the system services + */ + protected LocationProvider(final Context context) { + locationClient = new LocationClient(context, this, this); + subject = BehaviorSubject.create(); + } + + public static Observable<IGeoData> create(final Context context) { + final LocationProvider provider = new LocationProvider(context); + return provider.worker.refCount(); + } + + @Override + public void call(final Subscriber<? super IGeoData> subscriber) { + subject.subscribe(subscriber); + } + + final ConnectableObservable<IGeoData> worker = new ConnectableLooperCallbacks<IGeoData>(this, 2500, TimeUnit.MILLISECONDS) { + @Override + protected void onStart() { + Log.d("LocationProvider: starting the location listener"); + locationClient.connect(); + } + + @Override + protected void onStop() { + Log.d("LocationProvider: stopping the location listener"); + locationClient.removeLocationUpdates(LocationProvider.this); + locationClient.disconnect(); + } + }; + + @Override + public void onConnected(final Bundle bundle) { + if (firstLocation) { + final Location initialLocation = locationClient.getLastLocation(); + if (initialLocation != null) { + subject.onNext(new GeoData(initialLocation)); + } + firstLocation = false; + } + locationClient.requestLocationUpdates(LOCATION_REQUEST, this); + } + + @Override + public void onDisconnected() { + } + + @Override + public void onConnectionFailed(final ConnectionResult connectionResult) { + Log.e("cannot connect to Google Play location service: " + connectionResult); + subject.onError(new RuntimeException("Connection failed: " + connectionResult)); + } + + @Override + public void onLocationChanged(final Location location) { + subject.onNext(new GeoData(location)); + } +} diff --git a/main/src/cgeo/geocaching/sensors/GeoData.java b/main/src/cgeo/geocaching/sensors/GeoData.java index 2061b6b..ea6c241 100644 --- a/main/src/cgeo/geocaching/sensors/GeoData.java +++ b/main/src/cgeo/geocaching/sensors/GeoData.java @@ -6,9 +6,9 @@ import cgeo.geocaching.geopoint.Geopoint; import android.location.Location; import android.location.LocationManager; -class GeoData extends Location implements IGeoData { +public class GeoData extends Location implements IGeoData { - GeoData(final Location location) { + public GeoData(final Location location) { super(location); } @@ -24,6 +24,9 @@ class GeoData extends Location implements IGeoData { if (provider.equals(LocationManager.NETWORK_PROVIDER)) { return LocationProviderType.NETWORK; } + if (provider.equals("fused")) { + return LocationProviderType.FUSED; + } return LocationProviderType.LAST; } |
