aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/libs/androidannotations-api-3.2.jar.properties3
-rw-r--r--main/libs/annotations-3.0.0.jar (renamed from main/libs/findbugs-annotations.jar)bin77185 -> 77209 bytes
-rw-r--r--main/libs/annotations-3.0.0.jar.properties2
-rw-r--r--main/libs/butterknife-6.0.0.jar.properties2
-rw-r--r--main/libs/src/androidannotations-api-3.2-javadoc.jarbin0 -> 692279 bytes
-rw-r--r--main/libs/src/annotations-3.0.0-javadoc.jarbin0 -> 362 bytes
-rw-r--r--main/libs/src/annotations-3.0.0-sources.jarbin0 -> 362 bytes
-rw-r--r--main/libs/src/butterknife-6.0.0-javadoc.jarbin0 -> 109554 bytes
-rw-r--r--main/libs/src/butterknife-6.0.0-sources.jarbin0 -> 28805 bytes
-rw-r--r--main/project/libraries/.gitignore1
-rw-r--r--main/project/libraries/pom.xml209
-rw-r--r--main/res/drawable-hdpi/star_half.pngbin766 -> 0 bytes
-rw-r--r--main/res/drawable-ldpi/star_half.pngbin372 -> 0 bytes
-rw-r--r--main/res/drawable-mdpi/star_half.pngbin522 -> 0 bytes
-rw-r--r--main/res/drawable/star_rating.xml9
-rw-r--r--main/res/layout/cache_information_item.xml8
-rw-r--r--main/res/layout/star_image.xml11
-rw-r--r--main/res/values/changelog_master.xml2
-rw-r--r--main/res/values/strings.xml2
-rw-r--r--main/res/values/strings_not_translatable.xml2
-rw-r--r--main/res/values/styles.xml11
-rw-r--r--main/res/xml/preferences.xml3
-rw-r--r--main/src/cgeo/geocaching/AddressListActivity.java51
-rw-r--r--main/src/cgeo/geocaching/CacheListActivity.java8
-rw-r--r--main/src/cgeo/geocaching/DataStore.java4
-rw-r--r--main/src/cgeo/geocaching/Geocache.java5
-rw-r--r--main/src/cgeo/geocaching/SearchActivity.java4
-rw-r--r--main/src/cgeo/geocaching/Waypoint.java11
-rw-r--r--main/src/cgeo/geocaching/activity/ActivityMixin.java11
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/SygicNavigationApp.java14
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java26
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiClient.java1
-rw-r--r--main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java23
-rw-r--r--main/src/cgeo/geocaching/location/AndroidGeocoder.java59
-rw-r--r--main/src/cgeo/geocaching/location/GCGeocoder.java65
-rw-r--r--main/src/cgeo/geocaching/location/Geocoder.java61
-rw-r--r--main/src/cgeo/geocaching/location/GeopointParser.java2
-rw-r--r--main/src/cgeo/geocaching/location/MapQuestGeocoder.java117
-rw-r--r--main/src/cgeo/geocaching/settings/Settings.java2
-rw-r--r--main/src/cgeo/geocaching/ui/AddressListAdapter.java5
-rw-r--r--main/src/cgeo/geocaching/ui/CacheDetailsCreator.java25
-rw-r--r--tests/src/cgeo/geocaching/connector/gc/GCLoginTest.java6
-rw-r--r--tests/src/cgeo/geocaching/location/GeocoderTest.java48
43 files changed, 603 insertions, 210 deletions
diff --git a/main/libs/androidannotations-api-3.2.jar.properties b/main/libs/androidannotations-api-3.2.jar.properties
index ff6ac8c..6e05cd2 100644
--- a/main/libs/androidannotations-api-3.2.jar.properties
+++ b/main/libs/androidannotations-api-3.2.jar.properties
@@ -1 +1,2 @@
-src=src/androidannotations-api-3.2-sources.jar \ No newline at end of file
+src=src/androidannotations-api-3.2-sources.jar
+doc=src/androidannotations-api-3.2-javadoc.jar \ No newline at end of file
diff --git a/main/libs/findbugs-annotations.jar b/main/libs/annotations-3.0.0.jar
index 3641ad6..a2f68fe 100644
--- a/main/libs/findbugs-annotations.jar
+++ b/main/libs/annotations-3.0.0.jar
Binary files differ
diff --git a/main/libs/annotations-3.0.0.jar.properties b/main/libs/annotations-3.0.0.jar.properties
new file mode 100644
index 0000000..a32a2ea
--- /dev/null
+++ b/main/libs/annotations-3.0.0.jar.properties
@@ -0,0 +1,2 @@
+src=src/annotations-3.0.0-sources.jar
+doc=src/annotations-3.0.0-javadoc.jar
diff --git a/main/libs/butterknife-6.0.0.jar.properties b/main/libs/butterknife-6.0.0.jar.properties
new file mode 100644
index 0000000..d7282cc
--- /dev/null
+++ b/main/libs/butterknife-6.0.0.jar.properties
@@ -0,0 +1,2 @@
+src=src/butterknife-6.0.0-sources.jar
+doc=src/butterknife-6.0.0-javadoc.jar
diff --git a/main/libs/src/androidannotations-api-3.2-javadoc.jar b/main/libs/src/androidannotations-api-3.2-javadoc.jar
new file mode 100644
index 0000000..efdaf1f
--- /dev/null
+++ b/main/libs/src/androidannotations-api-3.2-javadoc.jar
Binary files differ
diff --git a/main/libs/src/annotations-3.0.0-javadoc.jar b/main/libs/src/annotations-3.0.0-javadoc.jar
new file mode 100644
index 0000000..0098501
--- /dev/null
+++ b/main/libs/src/annotations-3.0.0-javadoc.jar
Binary files differ
diff --git a/main/libs/src/annotations-3.0.0-sources.jar b/main/libs/src/annotations-3.0.0-sources.jar
new file mode 100644
index 0000000..0098501
--- /dev/null
+++ b/main/libs/src/annotations-3.0.0-sources.jar
Binary files differ
diff --git a/main/libs/src/butterknife-6.0.0-javadoc.jar b/main/libs/src/butterknife-6.0.0-javadoc.jar
new file mode 100644
index 0000000..1aef6df
--- /dev/null
+++ b/main/libs/src/butterknife-6.0.0-javadoc.jar
Binary files differ
diff --git a/main/libs/src/butterknife-6.0.0-sources.jar b/main/libs/src/butterknife-6.0.0-sources.jar
new file mode 100644
index 0000000..3b29f50
--- /dev/null
+++ b/main/libs/src/butterknife-6.0.0-sources.jar
Binary files differ
diff --git a/main/project/libraries/.gitignore b/main/project/libraries/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/main/project/libraries/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/main/project/libraries/pom.xml b/main/project/libraries/pom.xml
new file mode 100644
index 0000000..a86c3c7
--- /dev/null
+++ b/main/project/libraries/pom.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.cgeo</groupId>
+ <artifactId>library.check</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>c:geo dependency update check</name>
+
+ <description>This project checks or updates c:geo dependencies.
+ Run 'mvn validate' to see available dependency updates.
+ Run 'mvn install' to actually update to the latest releases. You may need to refresh your IDE afterwards.
+ </description>
+
+ <properties>
+ <AndroidAnnotationsVersion>3.2</AndroidAnnotationsVersion>
+
+ <ButterKnifeVersion>6.0.0</ButterKnifeVersion>
+
+ <CommonsCollections4Version>4.0</CommonsCollections4Version>
+ <CommonsIoVersion>2.4</CommonsIoVersion>
+ <CommonsLang3Version>3.3.2</CommonsLang3Version>
+
+ <FindbugsAnnotationsVersion>3.0.0</FindbugsAnnotationsVersion>
+
+ <JacksonAnnotationsVersion>2.4.4</JacksonAnnotationsVersion>
+ <JacksonCoreVersion>2.4.4</JacksonCoreVersion>
+ <JacksonDatabindVersion>2.4.4</JacksonDatabindVersion>
+
+ <RXAndroidVersion>0.23.0</RXAndroidVersion>
+ <RXJavaVersion>1.0.3</RXJavaVersion>
+ <RXJavaAsyncUtilVersion>0.21.0</RXJavaAsyncUtilVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.androidannotations</groupId>
+ <artifactId>androidannotations</artifactId>
+ <version>${AndroidAnnotationsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.androidannotations</groupId>
+ <artifactId>androidannotations-api</artifactId>
+ <version>${AndroidAnnotationsVersion}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.jakewharton</groupId>
+ <artifactId>butterknife</artifactId>
+ <version>${ButterKnifeVersion}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ <version>${CommonsCollections4Version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>${CommonsLang3Version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>${CommonsIoVersion}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>annotations</artifactId>
+ <version>${FindbugsAnnotationsVersion}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${JacksonAnnotationsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${JacksonCoreVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${JacksonDatabindVersion}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.reactivex</groupId>
+ <artifactId>rxjava</artifactId>
+ <version>${RXJavaVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.reactivex</groupId>
+ <artifactId>rxjava-async-util</artifactId>
+ <version>${RXJavaAsyncUtilVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.reactivex</groupId>
+ <artifactId>rxandroid</artifactId>
+ <version>${RXAndroidVersion}</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>versions-maven-plugin</artifactId>
+ <version>2.1</version>
+ <executions>
+ <execution>
+ <id>display-property-updates</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>display-property-updates</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>update-properties</id>
+ <phase>install</phase>
+ <goals>
+ <goal>update-properties</goal>
+ </goals>
+ <configuration>
+ <allowSnapshots>false</allowSnapshots>
+ <allowMajorUpdates>true</allowMajorUpdates>
+ <allowMinorUpdates>true</allowMinorUpdates>
+ <generateBackupPoms>true</generateBackupPoms>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.9</version>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${basedir}/../../libs</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <excludeTransitive>true</excludeTransitive>
+ </configuration>
+ </execution>
+ <execution>
+ <id>src-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <outputDirectory>${basedir}/../../libs/src</outputDirectory>
+ <failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
+ <overWriteReleases>true</overWriteReleases>
+ <excludeTransitive>true</excludeTransitive>
+ </configuration>
+ </execution>
+ <execution>
+ <id>javadoc-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <classifier>javadoc</classifier>
+ <outputDirectory>${basedir}/../../libs/src</outputDirectory>
+ <failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
+ <overWriteReleases>true</overWriteReleases>
+ <excludeTransitive>true</excludeTransitive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- unfinished: update properties files of source and javadoc
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.4</version>
+ <executions>
+ <execution>
+ <id>write-properties-files</id>
+ <phase>package</phase>
+ <configuration>
+ <tasks>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+ </plugins>
+ </build>
+</project>
diff --git a/main/res/drawable-hdpi/star_half.png b/main/res/drawable-hdpi/star_half.png
deleted file mode 100644
index 000208c..0000000
--- a/main/res/drawable-hdpi/star_half.png
+++ /dev/null
Binary files differ
diff --git a/main/res/drawable-ldpi/star_half.png b/main/res/drawable-ldpi/star_half.png
deleted file mode 100644
index 97fa464..0000000
--- a/main/res/drawable-ldpi/star_half.png
+++ /dev/null
Binary files differ
diff --git a/main/res/drawable-mdpi/star_half.png b/main/res/drawable-mdpi/star_half.png
deleted file mode 100644
index 1ea9152..0000000
--- a/main/res/drawable-mdpi/star_half.png
+++ /dev/null
Binary files differ
diff --git a/main/res/drawable/star_rating.xml b/main/res/drawable/star_rating.xml
new file mode 100644
index 0000000..0d8a8e2
--- /dev/null
+++ b/main/res/drawable/star_rating.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+android:id/background"
+ android:drawable="@drawable/star_off" />
+ <item android:id="@+android:id/secondaryProgress"
+ android:drawable="@drawable/star_off" />
+ <item android:id="@+android:id/progress"
+ android:drawable="@drawable/star_on" />
+</layer-list> \ No newline at end of file
diff --git a/main/res/layout/cache_information_item.xml b/main/res/layout/cache_information_item.xml
index 1b766e4..d213e56 100644
--- a/main/res/layout/cache_information_item.xml
+++ b/main/res/layout/cache_information_item.xml
@@ -34,17 +34,17 @@
android:textIsSelectable="false"
android:textSize="14sp" />
- <LinearLayout
+ <RatingBar
android:id="@+id/stars"
+ style="@style/cacheRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
+ android:layout_gravity="center_horizontal"
android:layout_toRightOf="@+id/value"
android:baselineAligned="false"
android:gravity="center_vertical"
- android:orientation="horizontal"
- android:visibility="gone" >
- </LinearLayout>
+ android:visibility="gone" />
<TextView
android:id="@+id/addition"
diff --git a/main/res/layout/star_image.xml b/main/res/layout/star_image.xml
deleted file mode 100644
index 809a17d..0000000
--- a/main/res/layout/star_image.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="12dip"
- android:layout_height="12dip"
- android:layout_gravity="center"
- android:layout_margin="1dip"
- android:gravity="center"
- android:scaleType="fitXY"
- android:src="@drawable/star_off"
- tools:context=".ui.CacheDetailsCreator" />
diff --git a/main/res/values/changelog_master.xml b/main/res/values/changelog_master.xml
index 1e3c3d4..04d2498 100644
--- a/main/res/values/changelog_master.xml
+++ b/main/res/values/changelog_master.xml
@@ -2,5 +2,7 @@
<resources>
<!-- changelog for the master branch -->
<string name="changelog_master" translatable="false">
+ <b>Next feature release:</b>\n
+ \n
</string>
</resources>
diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml
index 4be3ab6..415a97f 100644
--- a/main/res/values/strings.xml
+++ b/main/res/values/strings.xml
@@ -142,6 +142,7 @@
<string name="err_login">No Login information stored</string>
<string name="err_login_failed_toast">c:geo can\'t log in. c:geo works offline with Stored caches. Check Login settings or enable your internet connection.</string>
<string name="err_unknown">Unknown error</string>
+ <string name="err_unknown_address">c:geo was unable to map this address to an existing location</string>
<string name="err_comm">Unknown communication error</string>
<string name="err_missing_auth">No username and/or password set.</string>
<string name="err_wrong">Login information incorrect</string>
@@ -362,6 +363,7 @@
<!-- settings -->
<string name="settings_title_services">Services</string>
+ <string name="settings_summary_services">Configure user account information and access to optional services.</string>
<string name="settings_title_appearance">Appearance</string>
<string name="settings_title_cachedetails">Cache Details</string>
<string name="settings_title_offlinedata">Offline Data</string>
diff --git a/main/res/values/strings_not_translatable.xml b/main/res/values/strings_not_translatable.xml
index 585500f..35fef08 100644
--- a/main/res/values/strings_not_translatable.xml
+++ b/main/res/values/strings_not_translatable.xml
@@ -81,6 +81,8 @@
· <a href="http://rrze-icon-set.berlios.de/index.html">RRZE Icon set</a> (<a href="http://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA 3.0</a>)\n
· <a href="http://iconfindr.com/1mNr3rl">Layers icon by Cole Bemis</a> (<a href="http://creativecommons.org/licenses/by/3.0/">CC-BY 3.0</a>)\n
· <a href="https://github.com/amlcurran/Showcaseview">ShowcaseView by Alex Curran</a> (<a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache License 2.0</a>)\n
+ · <a href="http://www.mapquest.com/">Geocoding courtesy of MapQuest</a>\n
+ · <a href="http://www.openstreetmap.org/">Geocoding data from OpenStreetMap</a>\n
</string>
<!-- cache menu -->
diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml
index be1e1a4..5f280f2 100644
--- a/main/res/values/styles.xml
+++ b/main/res/values/styles.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- system definitions -->
@@ -338,4 +338,13 @@
<item name="android:src">@drawable/mark_green</item>
</style>
+ <style name="cacheRatingBar" parent="@android:style/Widget.RatingBar">
+ <item name="android:progressDrawable">@drawable/star_rating</item>
+ <item name="android:minHeight">12dip</item>
+ <item name="android:maxHeight">22dip</item>
+ <item name="android:max">5</item>
+ <item name="android:stepSize">0.5</item>
+ <item name="android:isIndicator">true</item>
+ </style>
+
</resources> \ No newline at end of file
diff --git a/main/res/xml/preferences.xml b/main/res/xml/preferences.xml
index 9648462..48d8a21 100644
--- a/main/res/xml/preferences.xml
+++ b/main/res/xml/preferences.xml
@@ -6,7 +6,8 @@
<PreferenceScreen
android:icon="?attr/settings_cloud"
android:key="@string/preference_screen_services"
- android:title="@string/settings_title_services" >
+ android:title="@string/settings_title_services"
+ android:summary="@string/settings_summary_services">
<PreferenceCategory android:title="@string/settings_category_geocaching" >
<PreferenceScreen
android:key="@string/preference_screen_gc"
diff --git a/main/src/cgeo/geocaching/AddressListActivity.java b/main/src/cgeo/geocaching/AddressListActivity.java
index 4f71ab6..4f81f8b 100644
--- a/main/src/cgeo/geocaching/AddressListActivity.java
+++ b/main/src/cgeo/geocaching/AddressListActivity.java
@@ -1,14 +1,17 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractListActivity;
-import cgeo.geocaching.location.Geocoder;
+import cgeo.geocaching.location.AndroidGeocoder;
+import cgeo.geocaching.location.GCGeocoder;
+import cgeo.geocaching.location.MapQuestGeocoder;
import cgeo.geocaching.ui.AddressListAdapter;
-import org.apache.commons.collections4.CollectionUtils;
+import rx.Observable;
+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;
@@ -19,47 +22,35 @@ public class AddressListActivity extends AbstractListActivity {
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.addresslist_activity);
- // get parameters
- final String keyword = getIntent().getStringExtra(Intents.EXTRA_KEYWORD);
-
- if (keyword == null) {
- showToast(res.getString(R.string.err_search_address_forgot));
- finish();
- return;
- }
final AddressListAdapter adapter = new AddressListAdapter(this);
setListAdapter(adapter);
+ final String keyword = getIntent().getStringExtra(Intents.EXTRA_KEYWORD);
final ProgressDialog waitDialog =
ProgressDialog.show(this, res.getString(R.string.search_address_started), keyword, true);
waitDialog.setCancelable(true);
-
lookupAddressInBackground(keyword, adapter, waitDialog);
}
private void lookupAddressInBackground(final String keyword, final AddressListAdapter adapter, final ProgressDialog waitDialog) {
- new AsyncTask<Void, Void, List<Address>>() {
-
+ final Observable<Address> geocoderObservable = new AndroidGeocoder(this).getFromLocationName(keyword)
+ .onErrorResumeNext(MapQuestGeocoder.getFromLocationName(keyword))
+ .onErrorResumeNext(GCGeocoder.getFromLocationName(keyword));
+ AndroidObservable.bindActivity(this, geocoderObservable.toList()).subscribe(new Action1<List<Address>>() {
@Override
- protected List<Address> doInBackground(final Void... params) {
- final Geocoder geocoder = new Geocoder(AddressListActivity.this);
- return geocoder.getFromLocationName(keyword);
- }
-
- @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();
+ showToast(res.getString(R.string.err_unknown_address));
+ }
+ });
}
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/CacheListActivity.java b/main/src/cgeo/geocaching/CacheListActivity.java
index c8f1101..1b6a268 100644
--- a/main/src/cgeo/geocaching/CacheListActivity.java
+++ b/main/src/cgeo/geocaching/CacheListActivity.java
@@ -27,7 +27,6 @@ import cgeo.geocaching.list.PseudoList;
import cgeo.geocaching.list.StoredList;
import cgeo.geocaching.loaders.AbstractSearchLoader;
import cgeo.geocaching.loaders.AbstractSearchLoader.CacheListLoaderType;
-import cgeo.geocaching.loaders.AddressGeocacheListLoader;
import cgeo.geocaching.loaders.CoordsGeocacheListLoader;
import cgeo.geocaching.loaders.FinderGeocacheListLoader;
import cgeo.geocaching.loaders.HistoryGeocacheListLoader;
@@ -1549,12 +1548,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
} else {
title = coords.toString();
}
- if (coords != null) {
- loader = new CoordsGeocacheListLoader(app, coords);
- }
- else {
- loader = new AddressGeocacheListLoader(app, address);
- }
+ loader = new CoordsGeocacheListLoader(app, coords);
break;
case FINDER:
final String username = extras.getString(Intents.EXTRA_USERNAME);
diff --git a/main/src/cgeo/geocaching/DataStore.java b/main/src/cgeo/geocaching/DataStore.java
index fae0d38..1081828 100644
--- a/main/src/cgeo/geocaching/DataStore.java
+++ b/main/src/cgeo/geocaching/DataStore.java
@@ -1103,7 +1103,9 @@ public class DataStore {
for (final Geocache cache : caches) {
final String geocode = cache.getGeocode();
final Geocache existingCache = existingCaches.get(geocode);
- final boolean dbUpdateRequired = !cache.gatherMissingFrom(existingCache) || cacheCache.getCacheFromCache(geocode) != null;
+ boolean dbUpdateRequired = !cache.gatherMissingFrom(existingCache) || cacheCache.getCacheFromCache(geocode) != null;
+ // parse the note AFTER merging the local information in
+ dbUpdateRequired |= cache.parseWaypointsFromNote();
cache.addStorageLocation(StorageLocation.CACHE);
cacheCache.putCacheInCache(cache);
diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java
index 69babc4..d396b93 100644
--- a/main/src/cgeo/geocaching/Geocache.java
+++ b/main/src/cgeo/geocaching/Geocache.java
@@ -1368,12 +1368,15 @@ public class Geocache implements IWaypoint {
/**
* Detect coordinates in the personal note and convert them to user defined waypoints. Works by rule of thumb.
*/
- public void parseWaypointsFromNote() {
+ public boolean parseWaypointsFromNote() {
+ boolean changed = false;
for (final Waypoint waypoint : Waypoint.parseWaypointsFromNote(StringUtils.defaultString(getPersonalNote()))) {
if (!hasIdenticalWaypoint(waypoint.getCoords())) {
addOrChangeWaypoint(waypoint, false);
+ changed = true;
}
}
+ return changed;
}
private boolean hasIdenticalWaypoint(final Geopoint point) {
diff --git a/main/src/cgeo/geocaching/SearchActivity.java b/main/src/cgeo/geocaching/SearchActivity.java
index 9de279d..1606350 100644
--- a/main/src/cgeo/geocaching/SearchActivity.java
+++ b/main/src/cgeo/geocaching/SearchActivity.java
@@ -373,7 +373,7 @@ public class SearchActivity extends AbstractActionBarActivity implements Coordin
}
private void findByGeocodeFn() {
- final String geocodeText = StringUtils.trim(geocodeEditText.getText().toString());
+ final String geocodeText = StringUtils.trimToEmpty(geocodeEditText.getText().toString());
if (StringUtils.isBlank(geocodeText) || geocodeText.equalsIgnoreCase("GC")) {
Dialogs.message(this, R.string.warn_search_help_title, R.string.warn_search_help_gccode);
@@ -384,7 +384,7 @@ public class SearchActivity extends AbstractActionBarActivity implements Coordin
}
private void findTrackableFn() {
- final String trackableText = StringUtils.trim(trackableEditText.getText().toString());
+ final String trackableText = StringUtils.trimToEmpty(trackableEditText.getText().toString());
if (StringUtils.isBlank(trackableText) || trackableText.equalsIgnoreCase("TB")) {
Dialogs.message(this, R.string.warn_search_help_title, R.string.warn_search_help_tb);
diff --git a/main/src/cgeo/geocaching/Waypoint.java b/main/src/cgeo/geocaching/Waypoint.java
index 5cfeb29..b4979e4 100644
--- a/main/src/cgeo/geocaching/Waypoint.java
+++ b/main/src/cgeo/geocaching/Waypoint.java
@@ -97,18 +97,11 @@ public class Waypoint implements IWaypoint {
if (newPrefixes.containsKey(prefix)) {
newPrefixes.get(prefix).merge(oldWaypoint);
} else if (oldWaypoint.isUserDefined() || forceMerge) {
- // personal note waypoints should always be taken from the new list only
- if (!isPersonalNoteWaypoint(oldWaypoint)) {
- newPoints.add(oldWaypoint);
- }
+ newPoints.add(oldWaypoint);
}
}
}
- private static boolean isPersonalNoteWaypoint(final @NonNull Waypoint waypoint) {
- return StringUtils.startsWith(waypoint.getName(), CgeoApplication.getInstance().getString(R.string.cache_personal_note) + " ");
- }
-
public boolean isUserDefined() {
return own || WaypointType.OWN == waypointType;
}
@@ -304,7 +297,7 @@ public class Waypoint implements IWaypoint {
((point.getLatitudeE6() % 1000) != 0 || (point.getLongitudeE6() % 1000) != 0)) {
final String name = CgeoApplication.getInstance().getString(R.string.cache_personal_note) + " " + count;
final String potentialWaypointType = note.substring(Math.max(0, matcher.start() - 15));
- final Waypoint waypoint = new Waypoint(name, parseWaypointType(potentialWaypointType), false);
+ final Waypoint waypoint = new Waypoint(name, parseWaypointType(potentialWaypointType), true);
waypoint.setCoords(point);
waypoints.add(waypoint);
count++;
diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java
index b135358..14a2fbf 100644
--- a/main/src/cgeo/geocaching/activity/ActivityMixin.java
+++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java
@@ -157,6 +157,15 @@ public final class ActivityMixin {
editText.setSelection(newCursor);
}
+ /**
+ * This is the exact code from Google to implement Up navigation, with one exception: activity.isTaskRoot() was
+ * added as {@link NavUtils#shouldUpRecreateTask(Activity, Intent)} seems not to handle the case, that this activity
+ * was created from an intent by another app, and our own app is not yet running. The bug seems to be fixed in
+ * Android 4.4.something, however.
+ *
+ * @param activity
+ * @return
+ */
public static boolean navigateUp(@NonNull final Activity activity) {
// see http://developer.android.com/training/implementing-navigation/ancestral.html
final Intent upIntent = NavUtils.getParentActivityIntent(activity);
@@ -164,7 +173,7 @@ public final class ActivityMixin {
activity.finish();
return true;
}
- if (NavUtils.shouldUpRecreateTask(activity, upIntent)) {
+ if (NavUtils.shouldUpRecreateTask(activity, upIntent) || activity.isTaskRoot()) {
// This activity is NOT part of this app's task, so create a new task
// when navigating up, with a synthesized back stack.
TaskStackBuilder.create(activity)
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/SygicNavigationApp.java b/main/src/cgeo/geocaching/apps/cache/navi/SygicNavigationApp.java
index 5d667c3..391fa90 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/SygicNavigationApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/SygicNavigationApp.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.apps.cache.navi;
import cgeo.geocaching.R;
import cgeo.geocaching.location.Geopoint;
+import cgeo.geocaching.utils.ProcessUtils;
import android.app.Activity;
import android.content.Intent;
@@ -14,10 +15,19 @@ import android.net.Uri;
*/
class SygicNavigationApp extends AbstractPointNavigationApp {
- private static final String PACKAGE = "com.sygic.aura";
+ private static final String PACKAGE_NORMAL = "com.sygic.aura";
+ /**
+ * there is a secondary edition of this app
+ */
+ private static final String PACKAGE_VOUCHER = "com.sygic.aura_voucher";
SygicNavigationApp() {
- super(getString(R.string.cache_menu_sygic), R.id.cache_app_sygic, null, PACKAGE);
+ super(getString(R.string.cache_menu_sygic), R.id.cache_app_sygic, null, PACKAGE_NORMAL);
+ }
+
+ @Override
+ public boolean isInstalled() {
+ return ProcessUtils.isLaunchable(PACKAGE_NORMAL) || ProcessUtils.isLaunchable(PACKAGE_VOUCHER);
}
@Override
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 33447c7..a0784a8 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -771,8 +771,6 @@ public abstract class GCParser {
}
}
- cache.parseWaypointsFromNote();
-
// last check for necessary cache conditions
if (StringUtils.isBlank(cache.getGeocode())) {
return UNKNOWN_PARSE_ERROR;
@@ -940,30 +938,6 @@ public abstract class GCParser {
return searchByAny(cacheType, isSearchForMyCaches(userName), showCaptcha, params, recaptchaReceiver);
}
- public static SearchResult searchByAddress(final String address, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
- if (StringUtils.isBlank(address)) {
- Log.e("GCParser.searchByAddress: No address given");
- return null;
- }
-
- final ObjectNode response = Network.requestJSON("http://www.geocaching.com/api/geocode", new Parameters("q", address));
- if (response == null) {
- return null;
- }
-
- if (!StringUtils.equalsIgnoreCase(response.path("status").asText(), "success")) {
- return null;
- }
-
- final JsonNode data = response.path("data");
- final JsonNode latNode = data.get("lat");
- final JsonNode lngNode = data.get("lng");
- if (latNode == null || lngNode == null) {
- return null;
- }
- return searchByCoords(new Geopoint(latNode.asDouble(), lngNode.asDouble()), cacheType, showCaptcha, recaptchaReceiver);
- }
-
@Nullable
public static Trackable searchTrackable(final String geocode, final String guid, final String id) {
if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid) && StringUtils.isBlank(id)) {
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
index 26e0f78..a1f8029 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
@@ -397,7 +397,6 @@ final class OkapiClient {
}
if (response.hasNonNull(CACHE_MY_NOTES)) {
cache.setPersonalNote(response.get(CACHE_MY_NOTES).asText());
- cache.parseWaypointsFromNote();
}
cache.setLogPasswordRequired(response.get(CACHE_REQ_PASSWORD).asBoolean());
diff --git a/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java
deleted file mode 100644
index e1573c9..0000000
--- a/main/src/cgeo/geocaching/loaders/AddressGeocacheListLoader.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package cgeo.geocaching.loaders;
-
-import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.connector.gc.GCParser;
-import cgeo.geocaching.settings.Settings;
-
-import android.content.Context;
-
-public class AddressGeocacheListLoader extends AbstractSearchLoader {
-
- private final String address;
-
- public AddressGeocacheListLoader(Context context, String address) {
- super(context);
- this.address = address;
- }
-
- @Override
- public SearchResult runSearch() {
- return GCParser.searchByAddress(address, Settings.getCacheType(), Settings.isShowCaptcha(), this);
- }
-
-}
diff --git a/main/src/cgeo/geocaching/location/AndroidGeocoder.java b/main/src/cgeo/geocaching/location/AndroidGeocoder.java
new file mode 100644
index 0000000..98ea285
--- /dev/null
+++ b/main/src/cgeo/geocaching/location/AndroidGeocoder.java
@@ -0,0 +1,59 @@
+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 work 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/GCGeocoder.java b/main/src/cgeo/geocaching/location/GCGeocoder.java
new file mode 100644
index 0000000..549044f
--- /dev/null
+++ b/main/src/cgeo/geocaching/location/GCGeocoder.java
@@ -0,0 +1,65 @@
+package cgeo.geocaching.location;
+
+import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.RxUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+
+import rx.Observable;
+import rx.functions.Func0;
+
+import android.location.Address;
+
+import java.util.Locale;
+
+public class GCGeocoder {
+
+ private GCGeocoder() {
+ // Do not instantiate
+ }
+
+ /**
+ * Retrieve addresses from a textual location using geocaching.com geocoding API. The work happens on the network
+ * scheduler.
+ *
+ * @param address
+ * the location
+ * @return an observable containing zero or more locations
+ *
+ * @see android.location.Geocoder#getFromLocationName(String, int)
+ */
+ public static Observable<Address> getFromLocationName(@NonNull final String address) {
+ return Observable.defer(new Func0<Observable<Address>>() {
+ @Override
+ public Observable<Address> call() {
+ if (!Settings.isGCConnectorActive()) {
+ return Observable.error(new RuntimeException("geocaching.com connector is not active"));
+ }
+ final ObjectNode response = Network.requestJSON("https://www.geocaching.com/api/geocode", new Parameters("q", address));
+ if (response == null || !StringUtils.equalsIgnoreCase(response.path("status").asText(), "success")) {
+ return Observable.error(new RuntimeException("unable to use geocaching.com geocoder"));
+ }
+
+ final JsonNode data = response.path("data");
+ final Address geocodedAddress = new Address(Locale.getDefault());
+ try {
+ geocodedAddress.setLatitude(data.get("lat").asDouble());
+ geocodedAddress.setLongitude(data.get("lng").asDouble());
+ geocodedAddress.setAddressLine(0, address);
+ return Observable.just(geocodedAddress);
+ } catch (final Exception e) {
+ Log.e("unable to decode answer from geocaching.com geocoder", e);
+ 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);
- }
- }
-}
diff --git a/main/src/cgeo/geocaching/location/GeopointParser.java b/main/src/cgeo/geocaching/location/GeopointParser.java
index e73e787..a6b8e45 100644
--- a/main/src/cgeo/geocaching/location/GeopointParser.java
+++ b/main/src/cgeo/geocaching/location/GeopointParser.java
@@ -122,7 +122,7 @@ class GeopointParser {
// Nothing found with "N 52...", try to match string as decimal degree parts (i.e. multiple doubles)
try {
- final String[] items = StringUtils.split(text.trim());
+ final String[] items = StringUtils.split(StringUtils.trimToEmpty(text));
if (items.length > 0 && items.length <= 2) {
final int index = (latlon == LatLon.LON ? items.length - 1 : 0);
final String textPart = items[index];
diff --git a/main/src/cgeo/geocaching/location/MapQuestGeocoder.java b/main/src/cgeo/geocaching/location/MapQuestGeocoder.java
new file mode 100644
index 0000000..537ae40
--- /dev/null
+++ b/main/src/cgeo/geocaching/location/MapQuestGeocoder.java
@@ -0,0 +1,117 @@
+package cgeo.geocaching.location;
+
+import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.RxUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
+
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Subscriber;
+import rx.functions.Func0;
+
+import android.location.Address;
+
+import java.util.Locale;
+
+public class MapQuestGeocoder {
+
+ private static final String MAPQUEST_KEY = "Fmjtd|luurn1u2n9,bs=o5-9wynua";
+
+ private MapQuestGeocoder() {
+ // Do not instantiate
+ }
+
+ /**
+ * Retrieve addresses from a textual location using MapQuest geocoding API. The work happens on the network
+ * scheduler.
+ *
+ * @param address
+ * the location
+ * @return an observable containing zero or more locations
+ *
+ * @see android.location.Geocoder#getFromLocationName(String, int)
+ */
+ public static Observable<Address> getFromLocationName(@NonNull final String address) {
+ return Observable.defer(new Func0<Observable<Address>>() {
+ @Override
+ public Observable<Address> call() {
+ final ObjectNode response = Network.requestJSON("https://www.mapquestapi.com/geocoding/v1/address",
+ new Parameters("key", MAPQUEST_KEY, "location", address, "maxResults", "20", "thumbMaps", "false"));
+ if (response == null) {
+ Log.w("MapQuest decoder error: no response");
+ return Observable.error(new RuntimeException("no answer from MapQuest geocoder"));
+ }
+ final int statusCode = response.path("info").path("statuscode").asInt(-1);
+ if (statusCode != 0) {
+ Log.w("MapQuest decoder error: statuscode is not 0");
+ return Observable.error(new RuntimeException("no correct answer from MapQuest geocoder"));
+ }
+ return Observable.create(new OnSubscribe<Address>() {
+ @Override
+ public void call(final Subscriber<? super Address> subscriber) {
+ try {
+ for (final JsonNode address: response.get("results").get(0).get("locations")) {
+ subscriber.onNext(mapquestToAddress(address));
+ }
+ subscriber.onCompleted();
+ } catch (final Exception e) {
+ Log.e("Error decoding MapQuest address", e);
+ subscriber.onError(e);
+ }
+ }
+ });
+ }
+ }).subscribeOn(RxUtils.networkScheduler);
+ }
+
+ private static Address mapquestToAddress(final JsonNode mapquestAddress) {
+ final Address address = new Address(Locale.getDefault());
+ for (int i = 1; i <= 6; i++) {
+ final String adminAreaName = "adminArea" + i;
+ setComponent(address, mapquestAddress, adminAreaName, mapquestAddress.path(adminAreaName + "Type").asText());
+ }
+ setComponent(address, mapquestAddress, "postalCode", "PostalCode");
+ int index = 0;
+ for (final String addressComponent: new String[]{ mapquestAddress.path("street").asText(), address.getSubLocality(), address.getLocality(),
+ address.getPostalCode(), address.getSubAdminArea(), address.getAdminArea(), address.getCountryCode() }) {
+ if (StringUtils.isNotBlank(addressComponent)) {
+ address.setAddressLine(index++, addressComponent);
+ }
+ }
+ address.setLatitude(mapquestAddress.get("latLng").get("lat").asDouble());
+ address.setLongitude(mapquestAddress.get("latLng").get("lng").asDouble());
+ return address;
+ }
+
+ private static void setComponent(final Address address, final JsonNode mapquestAddress, final String adminArea, final String adminAreaType) {
+ final String content = StringUtils.trimToNull(mapquestAddress.path(adminArea).asText());
+ switch (adminAreaType) {
+ case "City":
+ address.setLocality(content);
+ break;
+ case "Neighborhood":
+ address.setSubLocality(content);
+ break;
+ case "PostalCode":
+ address.setPostalCode(content);
+ break;
+ case "State":
+ address.setAdminArea(content);
+ break;
+ case "County":
+ address.setSubAdminArea(content);
+ break;
+ case "Country":
+ address.setCountryCode(content);
+ break;
+ }
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/settings/Settings.java b/main/src/cgeo/geocaching/settings/Settings.java
index b678d3b..8d2e13f 100644
--- a/main/src/cgeo/geocaching/settings/Settings.java
+++ b/main/src/cgeo/geocaching/settings/Settings.java
@@ -627,7 +627,7 @@ public class Settings {
}
public static boolean isMapTrail() {
- return getBoolean(R.string.pref_maptrail, true);
+ return getBoolean(R.string.pref_maptrail, false);
}
public static void setMapTrail(final boolean showTrail) {
diff --git a/main/src/cgeo/geocaching/ui/AddressListAdapter.java b/main/src/cgeo/geocaching/ui/AddressListAdapter.java
index 691c8d2..455954a 100644
--- a/main/src/cgeo/geocaching/ui/AddressListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/AddressListAdapter.java
@@ -9,6 +9,7 @@ import cgeo.geocaching.location.Geopoint;
import cgeo.geocaching.location.Units;
import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jdt.annotation.NonNull;
import android.app.Activity;
import android.location.Address;
@@ -23,7 +24,7 @@ import java.util.ArrayList;
public class AddressListAdapter extends ArrayAdapter<Address> {
final private LayoutInflater inflater;
- final private Geopoint location;
+ @NonNull final private Geopoint location;
protected static final class ViewHolder extends AbstractViewHolder {
@InjectView(R.id.label) protected TextView label;
@@ -72,7 +73,7 @@ public class AddressListAdapter extends ArrayAdapter<Address> {
}
private CharSequence getDistanceText(final Address address) {
- if (location != null && address.hasLatitude() && address.hasLongitude()) {
+ if (address.hasLatitude() && address.hasLongitude()) {
return Units.getDistanceFromKilometers(location.distanceTo(new Geopoint(address.getLatitude(), address.getLongitude())));
}
diff --git a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
index 13887c0..7dd3847 100644
--- a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
+++ b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
@@ -18,11 +18,9 @@ import org.eclipse.jdt.annotation.NonNull;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Resources;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.RatingBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -74,33 +72,18 @@ public final class CacheDetailsCreator {
final RelativeLayout layout = (RelativeLayout) activity.getLayoutInflater().inflate(R.layout.cache_information_item, null, false);
final TextView nameView = ButterKnife.findById(layout, R.id.name);
lastValueView = ButterKnife.findById(layout, R.id.value);
- final LinearLayout layoutStars = ButterKnife.findById(layout, R.id.stars);
nameView.setText(activity.getResources().getString(nameId));
lastValueView.setText(String.format("%.1f", value) + ' ' + activity.getResources().getString(R.string.cache_rating_of) + " " + String.format("%d", max));
- createStarImages(layoutStars, value, max);
+
+ final RatingBar layoutStars = ButterKnife.findById(layout, R.id.stars);
+ layoutStars.setRating(value);
layoutStars.setVisibility(View.VISIBLE);
parentView.addView(layout);
return layout;
}
- private void createStarImages(final ViewGroup starsContainer, final float value, final int max) {
- final LayoutInflater inflater = LayoutInflater.from(activity);
-
- for (int i = 0; i < max; i++) {
- final ImageView star = (ImageView) inflater.inflate(R.layout.star_image, starsContainer, false);
- if (value - i >= 0.75) {
- star.setImageResource(R.drawable.star_on);
- } else if (value - i >= 0.25) {
- star.setImageResource(R.drawable.star_half);
- } else {
- star.setImageResource(R.drawable.star_off);
- }
- starsContainer.addView(star);
- }
- }
-
public void addCacheState(final Geocache cache) {
if (cache.isLogOffline() || cache.isArchived() || cache.isDisabled() || cache.isPremiumMembersOnly() || cache.isFound()) {
final List<String> states = new ArrayList<>(5);
diff --git a/tests/src/cgeo/geocaching/connector/gc/GCLoginTest.java b/tests/src/cgeo/geocaching/connector/gc/GCLoginTest.java
index 07ba646..fc23ab3 100644
--- a/tests/src/cgeo/geocaching/connector/gc/GCLoginTest.java
+++ b/tests/src/cgeo/geocaching/connector/gc/GCLoginTest.java
@@ -6,10 +6,10 @@ import cgeo.geocaching.enumerations.StatusCode;
import org.apache.commons.lang3.StringUtils;
-import junit.framework.TestCase;
-
import android.test.suitebuilder.annotation.Suppress;
+import junit.framework.TestCase;
+
public class GCLoginTest extends TestCase {
final GCLogin instance = GCLogin.getInstance();
@@ -20,7 +20,7 @@ public class GCLoginTest extends TestCase {
assertThat(instance.login()).isEqualTo(StatusCode.NO_ERROR);
}
- public void testHomeLocation() {
+ public static void testHomeLocation() {
assertThat(StringUtils.isNotBlank(GCLogin.retrieveHomeLocation())).isTrue();
}
diff --git a/tests/src/cgeo/geocaching/location/GeocoderTest.java b/tests/src/cgeo/geocaching/location/GeocoderTest.java
new file mode 100644
index 0000000..f53c074
--- /dev/null
+++ b/tests/src/cgeo/geocaching/location/GeocoderTest.java
@@ -0,0 +1,48 @@
+package cgeo.geocaching.location;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import cgeo.CGeoTestCase;
+import cgeo.geocaching.CgeoApplication;
+
+import org.apache.commons.lang3.StringUtils;
+import org.assertj.core.data.Offset;
+
+import rx.Observable;
+
+import android.annotation.TargetApi;
+import android.location.Address;
+import android.location.Geocoder;
+import android.os.Build;
+
+public class GeocoderTest extends CGeoTestCase {
+
+ private static final String TEST_ADDRESS = "46 rue Barrault, Paris, France";
+ private static final double TEST_LATITUDE = 48.82677;
+ private static final double TEST_LONGITUDE = 2.34644;
+ private static final Offset<Double> TEST_OFFSET = Offset.offset(0.00050);
+
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+ public static void testAndroidGeocoder() {
+ // Some emulators don't have access to Google Android geocoder
+ if (Geocoder.isPresent()) {
+ testGeocoder(new AndroidGeocoder(CgeoApplication.getInstance()).getFromLocationName(TEST_ADDRESS), "Android");
+ }
+ }
+
+ public static void testGCGeocoder() {
+ testGeocoder(GCGeocoder.getFromLocationName(TEST_ADDRESS), "GC");
+ }
+
+ public static void testMapQuestGeocoder() {
+ testGeocoder(MapQuestGeocoder.getFromLocationName(TEST_ADDRESS), "MapQuest");
+ }
+
+ public static void testGeocoder(final Observable<Address> addressObservable, final String geocoder) {
+ final Address address = addressObservable.toBlocking().first();
+ assertThat(address.getLatitude()).as("latitude for " + geocoder + " geocoder").isCloseTo(TEST_LATITUDE, TEST_OFFSET);
+ assertThat(address.getLongitude()).as("longitude for " + geocoder + " geocoder").isCloseTo(TEST_LONGITUDE, TEST_OFFSET);
+ assertThat(StringUtils.lowerCase(address.getAddressLine(0))).as("street address for " + geocoder + " geocoder").startsWith("46 rue barrault");
+ }
+
+}