aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/src/cgeo/geocaching/AddressListActivity.java36
-rw-r--r--main/src/cgeo/geocaching/location/AndroidGeocoder.java57
-rw-r--r--main/src/cgeo/geocaching/location/Geocoder.java61
3 files changed, 72 insertions, 82 deletions
diff --git a/main/src/cgeo/geocaching/AddressListActivity.java b/main/src/cgeo/geocaching/AddressListActivity.java
index 4f71ab6..f51d37c 100644
--- a/main/src/cgeo/geocaching/AddressListActivity.java
+++ b/main/src/cgeo/geocaching/AddressListActivity.java
@@ -1,14 +1,14 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractListActivity;
-import cgeo.geocaching.location.Geocoder;
+import cgeo.geocaching.location.AndroidGeocoder;
import cgeo.geocaching.ui.AddressListAdapter;
-import org.apache.commons.collections4.CollectionUtils;
+import rx.android.observables.AndroidObservable;
+import rx.functions.Action1;
import android.app.ProgressDialog;
import android.location.Address;
-import android.os.AsyncTask;
import android.os.Bundle;
import java.util.List;
@@ -39,27 +39,21 @@ public class AddressListActivity extends AbstractListActivity {
}
private void lookupAddressInBackground(final String keyword, final AddressListAdapter adapter, final ProgressDialog waitDialog) {
- new AsyncTask<Void, Void, List<Address>>() {
-
- @Override
- protected List<Address> doInBackground(final Void... params) {
- final Geocoder geocoder = new Geocoder(AddressListActivity.this);
- return geocoder.getFromLocationName(keyword);
- }
-
+ final AndroidGeocoder geocoder = new AndroidGeocoder(this);
+ AndroidObservable.bindActivity(this, geocoder.getFromLocationName(keyword).toList()).subscribe(new Action1<List<Address>>() {
@Override
- protected void onPostExecute(final List<Address> addresses) {
+ public void call(final List<Address> addresses) {
waitDialog.dismiss();
- if (CollectionUtils.isNotEmpty(addresses)) {
- for (final Address address : addresses) {
- adapter.add(address); // don't use addAll, it's only available with API >= 11
- }
- } else {
- finish();
- CacheListActivity.startActivityAddress(AddressListActivity.this, null, keyword);
+ for (final Address address : addresses) {
+ adapter.add(address); // don't use addAll, it's only available with API >= 11
}
}
-
- }.execute();
+ }, new Action1<Throwable>() {
+ @Override
+ public void call(final Throwable throwable) {
+ finish();
+ CacheListActivity.startActivityAddress(AddressListActivity.this, null, keyword);
+ }
+ });
}
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/location/AndroidGeocoder.java b/main/src/cgeo/geocaching/location/AndroidGeocoder.java
new file mode 100644
index 0000000..373e40e
--- /dev/null
+++ b/main/src/cgeo/geocaching/location/AndroidGeocoder.java
@@ -0,0 +1,57 @@
+package cgeo.geocaching.location;
+
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.RxUtils;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.eclipse.jdt.annotation.NonNull;
+
+import rx.Observable;
+import rx.functions.Func0;
+
+import android.content.Context;
+import android.location.Address;
+import android.location.Geocoder;
+
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Encapsulation of the Android {@link Geocoder} with default error handling. All methods of this class
+ * are blocking and will do network lookups.
+ *
+ */
+public class AndroidGeocoder {
+ private final Geocoder geocoder;
+
+ public AndroidGeocoder(final Context context) {
+ geocoder = new Geocoder(context, Locale.getDefault());
+ }
+
+ /**
+ * Retrieve addresses from a textual location using Android geocoding API. The works happens on the network scheduler.
+ *
+ * @param keyword the location
+ * @return an observable containing zero or more locations
+ *
+ * @see Geocoder#getFromLocationName(String, int)
+ */
+ public Observable<Address> getFromLocationName(@NonNull final String keyword) {
+ return Observable.defer(new Func0<Observable<Address>>() {
+ @Override
+ public Observable<Address> call() {
+ try {
+ final List<Address> addresses = geocoder.getFromLocationName(keyword, 20);
+ if (CollectionUtils.isEmpty(addresses)) {
+ return Observable.error(new RuntimeException("no result from Android geocoder"));
+ }
+ return Observable.from(addresses);
+ } catch (final Exception e) {
+ Log.i("Unable to use Android geocoder: " + e.getMessage());
+ return Observable.error(e);
+ }
+ }
+ }).subscribeOn(RxUtils.networkScheduler);
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/location/Geocoder.java b/main/src/cgeo/geocaching/location/Geocoder.java
deleted file mode 100644
index 1582daa..0000000
--- a/main/src/cgeo/geocaching/location/Geocoder.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package cgeo.geocaching.location;
-
-import cgeo.geocaching.utils.Log;
-
-import org.apache.commons.lang3.StringUtils;
-import org.eclipse.jdt.annotation.NonNull;
-
-import android.content.Context;
-import android.location.Address;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Encapsulation of the Android {@link android.location.Geocoder} with default error handling. All methods of this class
- * are blocking and will do network lookups.
- *
- */
-public class Geocoder {
- private final android.location.Geocoder geocoder;
-
- public Geocoder(final Context context) {
- geocoder = new android.location.Geocoder(context, Locale.getDefault());
- }
-
- /**
- * @param keyword
- * @return
- *
- * @see android.location.Geocoder#getFromLocationName(String, int)
- */
- public @NonNull List<Address> getFromLocationName(final String keyword) {
- try {
- return geocoder.getFromLocationName(keyword, 20);
- } catch (final Exception e) {
- handleException(e);
- return Collections.emptyList();
- }
- }
-
- public @NonNull List<Address> getFromLocation(final Geopoint coords) {
- try {
- return geocoder.getFromLocation(coords.getLatitude(), coords.getLongitude(), 20);
- } catch (final IOException e) {
- handleException(e);
- return Collections.emptyList();
- }
- }
-
- private static void handleException(final Exception e) {
- // non Google devices come without the geocoder
- if (StringUtils.containsIgnoreCase(e.getMessage(), "Service not Available")) {
- Log.i("No geocoder available");
- }
- else {
- Log.e("Geocoder", e);
- }
- }
-}