aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo')
-rw-r--r--main/src/cgeo/geocaching/AdressListActivity.java21
-rw-r--r--main/src/cgeo/geocaching/CacheCache.java39
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java490
-rw-r--r--main/src/cgeo/geocaching/Destination.java44
-rw-r--r--main/src/cgeo/geocaching/GeoDataProvider.java305
-rw-r--r--main/src/cgeo/geocaching/GeoObserver.java13
-rw-r--r--main/src/cgeo/geocaching/IBasicCache.java2
-rw-r--r--main/src/cgeo/geocaching/ICache.java10
-rw-r--r--main/src/cgeo/geocaching/ICoordinates.java9
-rw-r--r--main/src/cgeo/geocaching/IGeoData.java21
-rw-r--r--main/src/cgeo/geocaching/IWaypoint.java7
-rw-r--r--main/src/cgeo/geocaching/LiveMapInfo.java4
-rw-r--r--main/src/cgeo/geocaching/LogEntry.java86
-rw-r--r--main/src/cgeo/geocaching/SearchResult.java37
-rw-r--r--main/src/cgeo/geocaching/Settings.java220
-rw-r--r--main/src/cgeo/geocaching/StaticMapsActivity.java29
-rw-r--r--main/src/cgeo/geocaching/StaticMapsProvider.java104
-rw-r--r--main/src/cgeo/geocaching/StoredList.java118
-rw-r--r--main/src/cgeo/geocaching/TrackableLog.java18
-rw-r--r--main/src/cgeo/geocaching/UpdateLocationCallback.java5
-rw-r--r--main/src/cgeo/geocaching/VisitCacheActivity.java111
-rw-r--r--main/src/cgeo/geocaching/activity/AbstractActivity.java9
-rw-r--r--main/src/cgeo/geocaching/activity/AbstractListActivity.java2
-rw-r--r--main/src/cgeo/geocaching/activity/ActivityMixin.java14
-rw-r--r--main/src/cgeo/geocaching/activity/IAbstractActivity.java11
-rw-r--r--main/src/cgeo/geocaching/activity/Progress.java14
-rw-r--r--main/src/cgeo/geocaching/apps/AbstractApp.java3
-rw-r--r--main/src/cgeo/geocaching/apps/AbstractLocusApp.java17
-rw-r--r--main/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java5
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java19
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java4
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java5
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java15
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java4
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java8
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java6
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java75
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java4
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java34
-rw-r--r--main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java6
-rw-r--r--main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java62
-rw-r--r--main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java6
-rw-r--r--main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java17
-rw-r--r--main/src/cgeo/geocaching/backup/CentralBackupAgent.java4
-rw-r--r--main/src/cgeo/geocaching/cgCache.java389
-rw-r--r--main/src/cgeo/geocaching/cgCoord.java168
-rw-r--r--main/src/cgeo/geocaching/cgData.java1456
-rw-r--r--main/src/cgeo/geocaching/cgDestination.java74
-rw-r--r--main/src/cgeo/geocaching/cgGeo.java252
-rw-r--r--main/src/cgeo/geocaching/cgLog.java39
-rw-r--r--main/src/cgeo/geocaching/cgSearchHandler.java5
-rw-r--r--main/src/cgeo/geocaching/cgSearchThread.java5
-rw-r--r--main/src/cgeo/geocaching/cgTrackable.java21
-rw-r--r--main/src/cgeo/geocaching/cgTrackableLog.java11
-rw-r--r--main/src/cgeo/geocaching/cgWaypoint.java17
-rw-r--r--main/src/cgeo/geocaching/cgeo.java229
-rw-r--r--main/src/cgeo/geocaching/cgeoabout.java11
-rw-r--r--main/src/cgeo/geocaching/cgeoadvsearch.java131
-rw-r--r--main/src/cgeo/geocaching/cgeoapplication.java207
-rw-r--r--main/src/cgeo/geocaching/cgeocaches.java923
-rw-r--r--main/src/cgeo/geocaching/cgeocoords.java33
-rw-r--r--main/src/cgeo/geocaching/cgeoimages.java12
-rw-r--r--main/src/cgeo/geocaching/cgeoinit.java76
-rw-r--r--main/src/cgeo/geocaching/cgeonavigate.java241
-rw-r--r--main/src/cgeo/geocaching/cgeopoint.java120
-rw-r--r--main/src/cgeo/geocaching/cgeopopup.java122
-rw-r--r--main/src/cgeo/geocaching/cgeotouch.java75
-rw-r--r--main/src/cgeo/geocaching/cgeotrackable.java79
-rw-r--r--main/src/cgeo/geocaching/cgeowaypoint.java193
-rw-r--r--main/src/cgeo/geocaching/cgeowaypointadd.java103
-rw-r--r--main/src/cgeo/geocaching/compatibility/AndroidLevel8.java5
-rw-r--r--main/src/cgeo/geocaching/compatibility/Compatibility.java22
-rw-r--r--main/src/cgeo/geocaching/concurrent/Task.java16
-rw-r--r--main/src/cgeo/geocaching/connector/OXConnector.java6
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCBase.java209
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java27
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java (renamed from main/src/cgeo/geocaching/cgBase.java)1382
-rw-r--r--main/src/cgeo/geocaching/connector/gc/IconDecoder.java2
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Login.java (renamed from main/src/cgeo/geocaching/network/Login.java)185
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Tile.java45
-rw-r--r--main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java4
-rw-r--r--main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java62
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheAttribute.java140
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheSize.java11
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheType.java17
-rw-r--r--main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java11
-rw-r--r--main/src/cgeo/geocaching/enumerations/LogType.java16
-rw-r--r--main/src/cgeo/geocaching/enumerations/StatusCode.java49
-rw-r--r--main/src/cgeo/geocaching/enumerations/WaypointType.java16
-rw-r--r--main/src/cgeo/geocaching/export/AbstractExport.java32
-rw-r--r--main/src/cgeo/geocaching/export/Export.java29
-rw-r--r--main/src/cgeo/geocaching/export/ExportFactory.java65
-rw-r--r--main/src/cgeo/geocaching/export/FieldnoteExport.java257
-rw-r--r--main/src/cgeo/geocaching/export/GpxExport.java328
-rw-r--r--main/src/cgeo/geocaching/files/FileList.java40
-rw-r--r--main/src/cgeo/geocaching/files/FileParser.java2
-rw-r--r--main/src/cgeo/geocaching/files/GPXImporter.java63
-rw-r--r--main/src/cgeo/geocaching/files/GPXParser.java35
-rw-r--r--main/src/cgeo/geocaching/files/LocParser.java141
-rw-r--r--main/src/cgeo/geocaching/files/LocalStorage.java93
-rw-r--r--main/src/cgeo/geocaching/filter/AbstractFilter.java10
-rw-r--r--main/src/cgeo/geocaching/filter/AbstractRangeFilter.java16
-rw-r--r--main/src/cgeo/geocaching/filter/AttributeFilter.java24
-rw-r--r--main/src/cgeo/geocaching/filter/DifficultyFilter.java31
-rw-r--r--main/src/cgeo/geocaching/filter/FilterUserInterface.java122
-rw-r--r--main/src/cgeo/geocaching/filter/IFilterFactory.java5
-rw-r--r--main/src/cgeo/geocaching/filter/ModifiedFilter.java13
-rw-r--r--main/src/cgeo/geocaching/filter/SizeFilter.java21
-rw-r--r--main/src/cgeo/geocaching/filter/StateFilter.java70
-rw-r--r--main/src/cgeo/geocaching/filter/TerrainFilter.java31
-rw-r--r--main/src/cgeo/geocaching/filter/TrackablesFilter.java14
-rw-r--r--main/src/cgeo/geocaching/filter/TypeFilter.java21
-rw-r--r--main/src/cgeo/geocaching/gcvote/GCVote.java37
-rw-r--r--main/src/cgeo/geocaching/geopoint/Geopoint.java301
-rw-r--r--main/src/cgeo/geocaching/geopoint/GeopointFormatter.java4
-rw-r--r--main/src/cgeo/geocaching/geopoint/GeopointParser.java57
-rw-r--r--main/src/cgeo/geocaching/geopoint/HumanDistance.java61
-rw-r--r--main/src/cgeo/geocaching/geopoint/Viewport.java186
-rw-r--r--main/src/cgeo/geocaching/geopoint/direction/DDD.java47
-rw-r--r--main/src/cgeo/geocaching/geopoint/direction/DMM.java56
-rw-r--r--main/src/cgeo/geocaching/geopoint/direction/DMS.java62
-rw-r--r--main/src/cgeo/geocaching/geopoint/direction/Direction.java29
-rw-r--r--main/src/cgeo/geocaching/go4cache/Go4Cache.java30
-rw-r--r--main/src/cgeo/geocaching/go4cache/Go4CacheUser.java8
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java526
-rw-r--r--main/src/cgeo/geocaching/maps/CachesOverlay.java146
-rw-r--r--main/src/cgeo/geocaching/maps/MapProviderFactory.java17
-rw-r--r--main/src/cgeo/geocaching/maps/OtherCachersOverlay.java14
-rw-r--r--main/src/cgeo/geocaching/maps/OtherCachersOverlayItem.java2
-rw-r--r--main/src/cgeo/geocaching/maps/PositionOverlay.java4
-rw-r--r--main/src/cgeo/geocaching/maps/ScaleOverlay.java73
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleCacheOverlayItem.java8
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleGeoPoint.java6
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java10
-rw-r--r--main/src/cgeo/geocaching/maps/google/GoogleMapView.java12
-rw-r--r--main/src/cgeo/geocaching/maps/interfaces/CachesOverlayItemImpl.java4
-rw-r--r--main/src/cgeo/geocaching/maps/interfaces/GeoPointImpl.java4
-rw-r--r--main/src/cgeo/geocaching/maps/interfaces/MapProvider.java4
-rw-r--r--main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java3
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlayItem.java8
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/MapsforgeGeoPoint.java6
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapProvider.java16
-rw-r--r--main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java28
-rw-r--r--main/src/cgeo/geocaching/network/Cookies.java47
-rw-r--r--main/src/cgeo/geocaching/network/HtmlImage.java70
-rw-r--r--main/src/cgeo/geocaching/network/Network.java328
-rw-r--r--main/src/cgeo/geocaching/network/OAuth.java4
-rw-r--r--main/src/cgeo/geocaching/network/Parameters.java43
-rw-r--r--main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java14
-rw-r--r--main/src/cgeo/geocaching/sorting/DifficultyComparator.java7
-rw-r--r--main/src/cgeo/geocaching/sorting/EventDateComparator.java12
-rw-r--r--main/src/cgeo/geocaching/sorting/FindsComparator.java2
-rw-r--r--main/src/cgeo/geocaching/sorting/GeocodeComparator.java10
-rw-r--r--main/src/cgeo/geocaching/sorting/InventoryComparator.java13
-rw-r--r--main/src/cgeo/geocaching/sorting/PopularityComparator.java11
-rw-r--r--main/src/cgeo/geocaching/sorting/RatingComparator.java25
-rw-r--r--main/src/cgeo/geocaching/sorting/TerrainComparator.java11
-rw-r--r--main/src/cgeo/geocaching/sorting/VisitComparator.java11
-rw-r--r--main/src/cgeo/geocaching/sorting/VoteComparator.java11
-rw-r--r--main/src/cgeo/geocaching/twitter/Twitter.java8
-rw-r--r--main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java10
-rw-r--r--main/src/cgeo/geocaching/ui/AddressListAdapter.java27
-rw-r--r--main/src/cgeo/geocaching/ui/CacheListAdapter.java78
-rw-r--r--main/src/cgeo/geocaching/ui/CompassMiniView.java8
-rw-r--r--main/src/cgeo/geocaching/ui/CompassView.java17
-rw-r--r--main/src/cgeo/geocaching/ui/DirectionImage.java2
-rw-r--r--main/src/cgeo/geocaching/ui/Formatter.java74
-rw-r--r--main/src/cgeo/geocaching/ui/GPXListAdapter.java7
-rw-r--r--main/src/cgeo/geocaching/ui/MapfileListAdapter.java7
-rw-r--r--main/src/cgeo/geocaching/utils/BaseUtils.java13
-rw-r--r--main/src/cgeo/geocaching/utils/CancellableHandler.java8
-rw-r--r--main/src/cgeo/geocaching/utils/ClipboardUtils.java1
-rw-r--r--main/src/cgeo/geocaching/utils/CryptUtils.java51
-rw-r--r--main/src/cgeo/geocaching/utils/IObserver.java22
-rw-r--r--main/src/cgeo/geocaching/utils/ISubject.java57
-rw-r--r--main/src/cgeo/geocaching/utils/LRUList.java46
-rw-r--r--main/src/cgeo/geocaching/utils/LeastRecentlyUsedCache.java24
-rw-r--r--main/src/cgeo/geocaching/utils/LeastRecentlyUsedMap.java139
-rw-r--r--main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java198
-rw-r--r--main/src/cgeo/geocaching/utils/Log.java69
-rw-r--r--main/src/cgeo/geocaching/utils/LogTemplateProvider.java15
-rw-r--r--main/src/cgeo/geocaching/utils/MemorySubject.java45
-rw-r--r--main/src/cgeo/geocaching/utils/PeriodicHandler.java74
-rw-r--r--main/src/cgeo/geocaching/utils/Subject.java76
184 files changed, 7192 insertions, 6989 deletions
diff --git a/main/src/cgeo/geocaching/AdressListActivity.java b/main/src/cgeo/geocaching/AdressListActivity.java
index 5357e9a..a67f4a2 100644
--- a/main/src/cgeo/geocaching/AdressListActivity.java
+++ b/main/src/cgeo/geocaching/AdressListActivity.java
@@ -2,6 +2,7 @@ package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractListActivity;
import cgeo.geocaching.ui.AddressListAdapter;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
@@ -10,7 +11,6 @@ import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.util.Log;
import java.util.List;
import java.util.Locale;
@@ -49,7 +49,7 @@ public class AdressListActivity extends AbstractListActivity {
try {
return geocoder.getFromLocationName(keyword, 20);
} catch (Exception e) {
- Log.e(Settings.tag, "AdressListActivity.doInBackground", e);
+ Log.e("AdressListActivity.doInBackground", e);
return null;
}
}
@@ -57,18 +57,13 @@ public class AdressListActivity extends AbstractListActivity {
@Override
protected void onPostExecute(final List<Address> addresses) {
waitDialog.dismiss();
- try {
- if (CollectionUtils.isEmpty(addresses)) {
- showToast(res.getString(R.string.err_search_address_no_match));
- finish();
- return;
- } else {
- for (Address address : addresses) {
- adapter.add(address); // don't use addAll, it's only available with API >= 11
- }
+ if (CollectionUtils.isNotEmpty(addresses)) {
+ for (final Address address : addresses) {
+ adapter.add(address); // don't use addAll, it's only available with API >= 11
}
- } catch (Exception e) {
- Log.e(Settings.tag, "AdressListActivity.onPostExecute", e);
+ } else {
+ showToast(res.getString(R.string.err_search_address_no_match));
+ finish();
}
}
diff --git a/main/src/cgeo/geocaching/CacheCache.java b/main/src/cgeo/geocaching/CacheCache.java
index a2b5324..1ada88c 100644
--- a/main/src/cgeo/geocaching/CacheCache.java
+++ b/main/src/cgeo/geocaching/CacheCache.java
@@ -1,10 +1,18 @@
package cgeo.geocaching;
import cgeo.geocaching.cgData.StorageLocation;
-import cgeo.geocaching.utils.LeastRecentlyUsedCache;
+import cgeo.geocaching.connector.gc.GCBase;
+import cgeo.geocaching.enumerations.CacheType;
+import cgeo.geocaching.geopoint.Viewport;
+import cgeo.geocaching.utils.LeastRecentlyUsedMap;
+import cgeo.geocaching.utils.LeastRecentlyUsedMap.RemoveHandler;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Cache for Caches. Every cache is stored in memory while c:geo is active to
* speed up the app and to minimize network request - which are slow.
@@ -14,12 +22,13 @@ import org.apache.commons.lang3.StringUtils;
public class CacheCache {
private static final int MAX_CACHED_CACHES = 1000;
- final private LeastRecentlyUsedCache<String, cgCache> cachesCache;
+ final private LeastRecentlyUsedMap<String, cgCache> cachesCache;
private static CacheCache instance = null;
private CacheCache() {
- cachesCache = new LeastRecentlyUsedCache<String, cgCache>(MAX_CACHED_CACHES);
+ cachesCache = new LeastRecentlyUsedMap.LruCache<String, cgCache>(MAX_CACHED_CACHES);
+ cachesCache.setRemoveHandler(new CacheRemoveHandler());
}
public static CacheCache getInstance() {
@@ -74,9 +83,33 @@ public class CacheCache {
return cachesCache.get(geocode);
}
+ public Set<String> getInViewport(final Viewport viewport, final CacheType cacheType) {
+ final Set<String> geocodes = new HashSet<String>();
+ for (final cgCache cache : cachesCache.values()) {
+ if (cache.getCoords() == null) {
+ // FIXME: this kludge must be removed, it is only present to help us debug the cases where
+ // caches contain null coordinates.
+ Log.e("CacheCache.getInViewport: got cache with null coordinates: " + cache.getGeocode());
+ continue;
+ }
+ if ((CacheType.ALL == cacheType || cache.getType() == cacheType) && viewport.contains(cache)) {
+ geocodes.add(cache.getGeocode());
+ }
+ }
+ return geocodes;
+ }
+
@Override
public String toString() {
return StringUtils.join(cachesCache.keySet(), ' ');
}
+ private static class CacheRemoveHandler implements RemoveHandler<cgCache> {
+
+ @Override
+ public void onRemove(cgCache removed) {
+ GCBase.removeFromTileCache(removed);
+ }
+ }
+
}
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index 1be9ed6..54943f9 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -7,8 +7,9 @@ import cgeo.geocaching.apps.cache.GeneralAppsFactory;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.LoadFlags;
-import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.WaypointType;
@@ -16,7 +17,6 @@ import cgeo.geocaching.geopoint.GeopointFormatter;
import cgeo.geocaching.geopoint.HumanDistance;
import cgeo.geocaching.geopoint.IConversion;
import cgeo.geocaching.network.HtmlImage;
-import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.ui.DecryptTextClickListener;
import cgeo.geocaching.ui.Formatter;
@@ -24,12 +24,12 @@ import cgeo.geocaching.utils.BaseUtils;
import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.ClipboardUtils;
import cgeo.geocaching.utils.CryptUtils;
+import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.TranslationUtils;
import cgeo.geocaching.utils.UnknownTagsHandler;
import com.viewpagerindicator.TitlePageIndicator;
import com.viewpagerindicator.TitleProvider;
-
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
@@ -39,6 +39,8 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
@@ -61,7 +63,6 @@ import android.text.method.LinkMovementMethod;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
@@ -122,7 +123,6 @@ public class CacheDetailActivity extends AbstractActivity {
private static final String CALENDAR_ADDON_URI = "market://details?id=cgeo.calendar";
- private cgGeo geolocation;
private cgCache cache;
private final Progress progress = new Progress();
private SearchResult search;
@@ -186,10 +186,6 @@ public class CacheDetailActivity extends AbstractActivity {
setContentView(R.layout.cacheview);
setTitle(res.getString(R.string.cache));
- if (geolocation == null) {
- geolocation = app.startGeo(locationUpdater);
- }
-
String geocode = null;
String guid = null;
String name = null;
@@ -220,9 +216,9 @@ public class CacheDetailActivity extends AbstractActivity {
String uriQuery = uri.getQuery();
if (uriQuery != null) {
- Log.i(Settings.tag, "Opening URI: " + uriHost + uriPath + "?" + uriQuery);
+ Log.i("Opening URI: " + uriHost + uriPath + "?" + uriQuery);
} else {
- Log.i(Settings.tag, "Opening URI: " + uriHost + uriPath);
+ Log.i("Opening URI: " + uriHost + uriPath);
}
if (uriHost.contains("geocaching.com")) {
@@ -328,9 +324,7 @@ public class CacheDetailActivity extends AbstractActivity {
public void onResume() {
super.onResume();
- if (geolocation == null) {
- geolocation = app.startGeo(locationUpdater);
- }
+ app.addGeoObserver(locationUpdater);
if (refreshOnResume) {
notifyDataSetChanged();
refreshOnResume = false;
@@ -339,19 +333,11 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void onDestroy() {
- if (geolocation != null) {
- geolocation = app.removeGeo();
- }
-
super.onDestroy();
}
@Override
public void onStop() {
- if (geolocation != null) {
- geolocation = app.removeGeo();
- }
-
if (cache != null) {
cache.setChangeNotificationHandler(null);
}
@@ -361,9 +347,7 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void onPause() {
- if (geolocation != null) {
- geolocation = app.removeGeo();
- }
+ app.deleteGeoObserver(locationUpdater);
super.onPause();
}
@@ -468,6 +452,7 @@ public class CacheDetailActivity extends AbstractActivity {
switch (index) {
case MENU_FIELD_COPY:
ClipboardUtils.copyToClipboard(clickedItemText);
+ showToast(res.getString(R.string.clipboard_copy_ok));
return true;
case MENU_FIELD_TRANSLATE:
TranslationUtils.startActivityTranslate(this, Locale.getDefault().getLanguage(), clickedItemText.toString());
@@ -486,15 +471,16 @@ public class CacheDetailActivity extends AbstractActivity {
}
break;
- case CONTEXT_MENU_WAYPOINT_EDIT:
- if (cache.hasWaypoints() && index < cache.getWaypoints().size()) {
- final cgWaypoint waypoint = cache.getWaypoints().get(index);
+ case CONTEXT_MENU_WAYPOINT_EDIT: {
+ final cgWaypoint waypoint = cache.getWaypoint(index);
+ if (waypoint != null) {
Intent editIntent = new Intent(this, cgeowaypointadd.class);
editIntent.putExtra("waypoint", waypoint.getId());
startActivity(editIntent);
refreshOnResume = true;
}
break;
+ }
case CONTEXT_MENU_WAYPOINT_DUPLICATE:
if (cache.duplicateWaypoint(index)) {
app.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
@@ -510,14 +496,14 @@ public class CacheDetailActivity extends AbstractActivity {
case CONTEXT_MENU_WAYPOINT_DEFAULT_NAVIGATION: {
final cgWaypoint waypoint = cache.getWaypoint(index);
if (waypoint != null) {
- NavigationAppFactory.startDefaultNavigationApplication(geolocation, this, null, waypoint, null);
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), this, null, waypoint, null);
}
}
break;
case CONTEXT_MENU_WAYPOINT_NAVIGATE: {
final cgWaypoint waypoint = cache.getWaypoint(contextMenuWPIndex);
if (waypoint != null) {
- NavigationAppFactory.showNavigationMenu(geolocation, this, null, waypoint, null);
+ NavigationAppFactory.showNavigationMenu(app.currentGeo(), this, null, waypoint, null);
}
}
break;
@@ -565,50 +551,48 @@ public class CacheDetailActivity extends AbstractActivity {
public boolean onOptionsItemSelected(MenuItem item) {
final int menuItem = item.getItemId();
- // no menu selected, but a new sub menu shown
- if (menuItem == 0) {
- return false;
- }
-
- if (menuItem == MENU_DEFAULT_NAVIGATION) {
- startDefaultNavigation();
- return true;
- } else if (menuItem == MENU_LOG_VISIT) {
- refreshOnResume = true;
- cache.logVisit(this);
- return true;
- } else if (menuItem == MENU_BROWSER) {
- cache.openInBrowser(this);
- return true;
- } else if (menuItem == MENU_CACHES_AROUND) {
- cachesAround();
- return true;
- } else if (menuItem == MENU_CALENDAR) {
- addToCalendarWithIntent();
- return true;
- } else if (menuItem == MENU_SHARE) {
- if (cache != null) {
- cache.shareCache(this, res);
+ switch(menuItem) {
+ case 0:
+ // no menu selected, but a new sub menu shown
+ return false;
+ case MENU_DEFAULT_NAVIGATION:
+ startDefaultNavigation();
return true;
- }
- return false;
+ case MENU_LOG_VISIT:
+ refreshOnResume = true;
+ cache.logVisit(this);
+ return true;
+ case MENU_BROWSER:
+ cache.openInBrowser(this);
+ return true;
+ case MENU_CACHES_AROUND:
+ cgeocaches.startActivityCachesAround(this, cache.getCoords());
+ return true;
+ case MENU_CALENDAR:
+ addToCalendarWithIntent();
+ return true;
+ case MENU_SHARE:
+ if (cache != null) {
+ cache.shareCache(this, res);
+ return true;
+ }
+ return false;
}
- if (NavigationAppFactory.onMenuItemSelected(item, geolocation, this, cache, null, null)) {
+ if (NavigationAppFactory.onMenuItemSelected(item, app.currentGeo(), this, cache, null, null)) {
return true;
}
if (GeneralAppsFactory.onMenuItemSelected(item, this, cache)) {
return true;
}
- int logType = menuItem - MENU_LOG_VISIT_OFFLINE;
- cache.logOffline(this, LogType.getById(logType));
+ cache.logOffline(this, LogType.getById(menuItem - MENU_LOG_VISIT_OFFLINE));
return true;
}
private class LoadCacheHandler extends CancellableHandler {
@Override
public void handleRegularMessage(final Message msg) {
- if (cgBase.UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
+ if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
updateStatusMsg((String) msg.obj);
} else {
if (search == null) {
@@ -706,12 +690,9 @@ public class CacheDetailActivity extends AbstractActivity {
progress.dismiss();
}
- private class LocationUpdater implements UpdateLocationCallback {
+ private class LocationUpdater extends GeoObserver {
@Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
- }
+ public void updateLocation(final IGeoData geo) {
if (cacheDistanceView == null) {
return;
}
@@ -719,13 +700,13 @@ public class CacheDetailActivity extends AbstractActivity {
try {
StringBuilder dist = new StringBuilder();
- if (geo.coordsNow != null && cache != null && cache.getCoords() != null) {
- dist.append(HumanDistance.getHumanDistance(geo.coordsNow.distanceTo(cache.getCoords())));
+ if (geo.getCoords() != null && cache != null && cache.getCoords() != null) {
+ dist.append(HumanDistance.getHumanDistance(geo.getCoords().distanceTo(cache.getCoords())));
}
if (cache != null && cache.getElevation() != null) {
- if (geo.altitudeNow != null) {
- double diff = (cache.getElevation() - geo.altitudeNow);
+ if (geo.getAltitude() != 0.0) {
+ double diff = cache.getElevation() - geo.getAltitude();
if (diff >= 0) {
dist.append(" ↗");
} else if (diff < 0) {
@@ -744,7 +725,7 @@ public class CacheDetailActivity extends AbstractActivity {
cacheDistanceView.setText(dist.toString());
cacheDistanceView.bringToFront();
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
+ Log.w("Failed to update location.");
}
}
}
@@ -774,25 +755,43 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void run() {
- search = cgBase.searchByGeocode(geocode, StringUtils.isBlank(geocode) ? guid : null, 0, false, handler);
+ search = cgCache.searchByGeocode(geocode, StringUtils.isBlank(geocode) ? guid : null, 0, false, handler);
handler.sendMessage(Message.obtain());
}
}
/**
- * Starts activity to search for caches near this cache.
+ * Indicates whether the specified action can be used as an intent. This
+ * method queries the package manager for installed packages that can
+ * respond to an intent with the specified action. If no suitable package is
+ * found, this method returns false.
+ *
+ * @param context
+ * The application's environment.
+ * @param action
+ * The Intent action to check for availability.
+ * @param uri
+ * The Intent URI to check for availability.
*
- * Also finishes this activity.
+ * @return True if an Intent with the specified action can be sent and
+ * responded to, false otherwise.
*/
- private void cachesAround() {
- cgeocaches.startActivityCachesAround(this, cache.getCoords());
-
- finish();
+ private static boolean isIntentAvailable(Context context, String action, Uri uri) {
+ final PackageManager packageManager = context.getPackageManager();
+ final Intent intent;
+ if (uri == null) {
+ intent = new Intent(action);
+ } else {
+ intent = new Intent(action, uri);
+ }
+ List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+ return list.size() > 0;
}
private void addToCalendarWithIntent() {
- final boolean calendarAddOnAvailable = cgBase.isIntentAvailable(this, ICalendar.INTENT, Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST));
+ final boolean calendarAddOnAvailable = isIntentAvailable(this, ICalendar.INTENT, Uri.parse(ICalendar.URI_SCHEME + "://" + ICalendar.URI_HOST));
if (calendarAddOnAvailable) {
final Parameters params = new Parameters(
@@ -833,49 +832,6 @@ public class CacheDetailActivity extends AbstractActivity {
}
/**
- * Creates a {@link List} of all coordinates (cache and waypoints) for the current cache.
- *
- * @return A {@link List} of all coordinates
- */
- public List<cgCoord> getCoordinates() {
- List<cgCoord> coordinates = new ArrayList<cgCoord>();
-
- // cache
- try {
- final cgCoord coords = new cgCoord();
- coords.setCoordType("cache");
- if (StringUtils.isNotBlank(cache.getName())) {
- coords.setName(cache.getName());
- } else {
- coords.setName(cache.getGeocode().toUpperCase());
- }
- coords.setCoords(cache.getCoords());
- coordinates.add(coords);
- } catch (Exception e) {
- Log.e(Settings.tag, "CacheDetailActivity.getCoordinates (cache)", e);
- }
-
- // waypoints
- try {
- if (cache.hasWaypoints()) {
- for (cgWaypoint waypoint : cache.getWaypoints()) {
- if (null != waypoint.getCoords()) {
- final cgCoord coords = new cgCoord();
- coords.setCoordType("waypoint");
- coords.setName(waypoint.getName());
- coords.setCoords(waypoint.getCoords());
- coordinates.add(coords);
- }
- }
- }
- } catch (Exception e) {
- Log.e(Settings.tag, "CacheDetailActivity.getCoordinates (waypoint)", e);
- }
-
- return coordinates;
- }
-
- /**
* Tries to navigate to the {@link cgCache} of this activity.
*/
private void startDefaultNavigation() {
@@ -885,7 +841,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
//TODO: previously this used also the search argument "search". check if still needed
- NavigationAppFactory.startDefaultNavigationApplication(geolocation, this, cache, null, null);
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), this, cache, null, null);
}
/**
@@ -898,7 +854,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
//TODO: previously this used also the search argument "search". check if still needed
- NavigationAppFactory.startDefaultNavigationApplication2(geolocation, this, cache, null, null);
+ NavigationAppFactory.startDefaultNavigationApplication2(app.currentGeo(), this, cache, null, null);
}
/**
@@ -916,7 +872,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
private void showNavigationMenu() {
- NavigationAppFactory.showNavigationMenu(geolocation, this, cache, null, null);
+ NavigationAppFactory.showNavigationMenu(app.currentGeo(), this, cache, null, null);
}
/**
@@ -969,7 +925,7 @@ public class CacheDetailActivity extends AbstractActivity {
res.getString(R.string.user_menu_open_browser)
};
- AlertDialog.Builder builder = new AlertDialog.Builder(CacheDetailActivity.this);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(res.getString(R.string.user_menu_title) + " " + name);
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
@@ -1063,7 +1019,7 @@ public class CacheDetailActivity extends AbstractActivity {
((ViewPager) container).addView(view, 0);
}
} catch (Exception e) {
- Log.e(Settings.tag, "ViewPagerAdapter.instantiateItem ", e);
+ Log.e("ViewPagerAdapter.instantiateItem ", e);
}
return view;
@@ -1102,7 +1058,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
// show number of waypoints directly in waypoint title
if (page == Page.WAYPOINTS) {
- int waypointCount = (cache.hasWaypoints() ? cache.getWaypoints().size() : 0);
+ final int waypointCount = cache.getWaypoints().size();
return res.getQuantityString(R.plurals.waypoints, waypointCount, waypointCount);
}
return res.getString(page.titleStringId);
@@ -1182,7 +1138,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
/**
- * lazy-creates the layout holding the icons of the chaches attributes
+ * lazy-creates the layout holding the icons of the caches attributes
* and makes it visible
*/
private void showAttributeIcons(LinearLayout attribBox, int parentWidth) {
@@ -1200,7 +1156,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
/**
- * lazy-creates the layout holding the discriptions of the chaches attributes
+ * lazy-creates the layout holding the descriptions of the caches attributes
* and makes it visible
*/
private void showAttributeDescriptions(LinearLayout attribBox) {
@@ -1230,7 +1186,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
private ViewGroup createAttributeIconsLayout(int parentWidth) {
- LinearLayout rows = new LinearLayout(CacheDetailActivity.this);
+ final LinearLayout rows = new LinearLayout(CacheDetailActivity.this);
rows.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
rows.setOrientation(LinearLayout.VERTICAL);
@@ -1239,13 +1195,7 @@ public class CacheDetailActivity extends AbstractActivity {
noAttributeIconsFound = true;
- final String packageName = cgeoapplication.getInstance().getBaseContext().getPackageName();
for (String attributeName : cache.getAttributes()) {
- boolean strikethru = attributeName.endsWith("_no");
- // cut off _yes / _no
- if (attributeName.endsWith("_no") || attributeName.endsWith("_yes")) {
- attributeName = attributeName.substring(0, attributeName.lastIndexOf('_'));
- }
// check if another attribute icon fits in this row
attributeRow.measure(0, 0);
int rowWidth = attributeRow.getMeasuredWidth();
@@ -1257,12 +1207,11 @@ public class CacheDetailActivity extends AbstractActivity {
rows.addView(attributeRow);
}
- // dynamically search icon of the attribute
- Drawable d = null;
- int id = res.getIdentifier("attribute_" + attributeName, "drawable", packageName);
- if (id > 0) {
+ final boolean strikethru = !CacheAttribute.isEnabled(attributeName);
+ final CacheAttribute attrib = CacheAttribute.getByGcRawName(CacheAttribute.trimAttributeName(attributeName));
+ if (attrib != CacheAttribute.UNKNOWN) {
noAttributeIconsFound = false;
- d = res.getDrawable(id);
+ Drawable d = res.getDrawable(attrib.drawableId);
iv.setImageDrawable(d);
// strike through?
if (strikethru) {
@@ -1274,7 +1223,7 @@ public class CacheDetailActivity extends AbstractActivity {
fl.addView(strikethruImage);
}
} else {
- d = res.getDrawable(R.drawable.attribute_icon_not_found);
+ Drawable d = res.getDrawable(R.drawable.attribute_icon_not_found);
iv.setImageDrawable(d);
}
@@ -1295,25 +1244,22 @@ public class CacheDetailActivity extends AbstractActivity {
private ViewGroup createAttributeDescriptionsLayout() {
final LinearLayout descriptions = (LinearLayout) getLayoutInflater().inflate(
R.layout.attribute_descriptions, null);
- TextView attribView = (TextView) descriptions.getChildAt(0);
+ final TextView attribView = (TextView) descriptions.getChildAt(0);
- StringBuilder buffer = new StringBuilder();
- final String packageName = cgeoapplication.getInstance().getBaseContext().getPackageName();
+ final StringBuilder buffer = new StringBuilder();
final List<String> attributes = cache.getAttributes();
- for (String attribute : attributes) {
- // dynamically search for a translation of the attribute
- int id = res.getIdentifier("attribute_" + attribute, "string", packageName);
- if (id > 0) {
- String translated = res.getString(id);
- if (StringUtils.isNotBlank(translated)) {
- attribute = translated;
- }
+ for (String attributeName : attributes) {
+ final boolean enabled = CacheAttribute.isEnabled(attributeName);
+ // search for a translation of the attribute
+ CacheAttribute attrib = CacheAttribute.getByGcRawName(CacheAttribute.trimAttributeName(attributeName));
+ if (attrib != CacheAttribute.UNKNOWN) {
+ attributeName = attrib.getL10n(enabled);
}
if (buffer.length() > 0) {
buffer.append('\n');
}
- buffer.append(attribute);
+ buffer.append(attributeName);
}
if (noAttributeIconsFound) {
@@ -1482,7 +1428,7 @@ public class CacheDetailActivity extends AbstractActivity {
if (cache.getHiddenDate() != null) {
long time = cache.getHiddenDate().getTime();
if (time > 0) {
- String dateString = cgBase.formatFullDate(time);
+ String dateString = Formatter.formatFullDate(time);
if (cache.isEventCache()) {
dateString = DateUtils.formatDateTime(cgeoapplication.getInstance().getBaseContext(), time, DateUtils.FORMAT_SHOW_WEEKDAY) + ", " + dateString;
}
@@ -1548,10 +1494,6 @@ public class CacheDetailActivity extends AbstractActivity {
}
}
- if (geolocation != null) {
- locationUpdater.updateLocation(geolocation);
- }
-
return view;
}
@@ -1581,20 +1523,11 @@ public class CacheDetailActivity extends AbstractActivity {
private class StoreCacheHandler extends CancellableHandler {
@Override
public void handleRegularMessage(Message msg) {
- if (cgBase.UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
+ if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
updateStatusMsg((String) msg.obj);
} else {
storeThread = null;
-
- try {
- cache = search.getFirstCacheFromResult(LoadFlags.LOAD_ALL_DB_ONLY); // reload cache details
- } catch (Exception e) {
- showToast(res.getString(R.string.err_store_failed));
-
- Log.e(Settings.tag, "CacheDetailActivity.storeCacheHandler: " + e.toString());
- }
-
- CacheDetailActivity.this.notifyDataSetChanged();
+ CacheDetailActivity.this.notifyDataSetChanged(); // reload cache details
}
}
@@ -1608,20 +1541,11 @@ public class CacheDetailActivity extends AbstractActivity {
private class RefreshCacheHandler extends CancellableHandler {
@Override
public void handleRegularMessage(Message msg) {
- if (cgBase.UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
+ if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
updateStatusMsg((String) msg.obj);
} else {
refreshThread = null;
-
- try {
- cache = search.getFirstCacheFromResult(LoadFlags.LOAD_ALL_DB_ONLY); // reload cache details
- } catch (Exception e) {
- showToast(res.getString(R.string.err_refresh_failed));
-
- Log.e(Settings.tag, "CacheDetailActivity.refreshCacheHandler: " + e.toString());
- }
-
- CacheDetailActivity.this.notifyDataSetChanged();
+ CacheDetailActivity.this.notifyDataSetChanged(); // reload cache details
}
}
@@ -1701,8 +1625,7 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void run() {
- app.removeCache(cache.getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE));
- search = cgBase.searchByGeocode(cache.getGeocode(), null, 0, true, handler);
+ cache.refresh(CacheDetailActivity.this, cache.getListId(), handler);
handler.sendEmptyMessage(0);
}
@@ -1732,7 +1655,7 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void run() {
- cgBase.dropCache(cache, handler);
+ cache.drop(handler);
}
}
@@ -1788,7 +1711,7 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void run() {
- handler.sendEmptyMessage(cgBase.addToWatchlist(cache));
+ handler.sendEmptyMessage(GCParser.addToWatchlist(cache));
}
}
@@ -1802,7 +1725,7 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void run() {
- handler.sendEmptyMessage(cgBase.removeFromWatchlist(cache));
+ handler.sendEmptyMessage(GCParser.removeFromWatchlist(cache));
}
}
@@ -1856,7 +1779,7 @@ public class CacheDetailActivity extends AbstractActivity {
if (cache.getListId() >= StoredList.STANDARD_LIST_ID) {
long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.getDetailedUpdate() / (60 * 1000)); // minutes
- String ago = "";
+ String ago;
if (diff < 15) {
ago = res.getString(R.string.cache_offline_time_mins_few);
} else if (diff < 50) {
@@ -1889,9 +1812,7 @@ public class CacheDetailActivity extends AbstractActivity {
private class PreviewMapTask extends AsyncTask<Void, Void, BitmapDrawable> {
@Override
- protected BitmapDrawable doInBackground(Void... params) {
- BitmapDrawable image = null;
-
+ protected BitmapDrawable doInBackground(Void... parameters) {
try {
final String latlonMap = cache.getCoords().format(GeopointFormatter.Format.LAT_LON_DECDEGREE_COMMA);
@@ -1902,15 +1823,15 @@ public class CacheDetailActivity extends AbstractActivity {
final int height = (int) (110 * metrics.density);
// TODO move this code to StaticMapProvider and use its constant values
- final String markerUrl = Network.urlencode_rfc3986("http://cgeo.carnero.cc/_markers/my_location_mdpi.png");
+ final String markerUrl = "http://cgeo.carnero.cc/_markers/my_location_mdpi.png";
final HtmlImage mapGetter = new HtmlImage(CacheDetailActivity.this, cache.getGeocode(), false, 0, false);
- image = mapGetter.getDrawable("http://maps.google.com/maps/api/staticmap?zoom=15&size=" + width + "x" + height + "&maptype=roadmap&markers=icon%3A" + markerUrl + "%7Cshadow:false%7C" + latlonMap + "&sensor=false");
+ final Parameters params = new Parameters("zoom", "15", "size", width + "x" + height, "maptype", "roadmap", "markers", "icon:" + markerUrl + "|shadow:false|" + latlonMap, "sensor", "false");
+ return mapGetter.getDrawable("http://maps.google.com/maps/api/staticmap?" + params);
} catch (Exception e) {
- Log.w(Settings.tag, "CacheDetailActivity.PreviewMapTask", e);
+ Log.w("CacheDetailActivity.PreviewMapTask", e);
+ return null;
}
-
- return image;
}
@Override
@@ -2109,7 +2030,7 @@ public class CacheDetailActivity extends AbstractActivity {
// if description has HTML table, add a note at the end of the long description
if (unknownTagsHandler.isTableDetected() && descriptionView == view.findViewById(R.id.longdesc)) {
final int startPos = description.length();
- ((Editable) description).append("\n\n" + res.getString(R.string.cache_description_table_note));
+ ((Editable) description).append("\n\n").append(res.getString(R.string.cache_description_table_note));
((Editable) description).setSpan(new StyleSpan(Typeface.ITALIC), startPos, description.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
publishProgress();
}
@@ -2234,7 +2155,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
}
- view.setAdapter(new ArrayAdapter<cgLog>(CacheDetailActivity.this, R.layout.cacheview_logs_item, cache.getLogs(allLogs)) {
+ view.setAdapter(new ArrayAdapter<LogEntry>(CacheDetailActivity.this, R.layout.cacheview_logs_item, cache.getLogs(allLogs)) {
final UserActionsClickListener userActionsClickListener = new UserActionsClickListener();
final DecryptTextClickListener decryptTextClickListener = new DecryptTextClickListener();
@@ -2250,10 +2171,10 @@ public class CacheDetailActivity extends AbstractActivity {
rowView.setTag(holder);
}
- final cgLog log = getItem(position);
+ final LogEntry log = getItem(position);
if (log.date > 0) {
- holder.date.setText(cgBase.formatShortDate(log.date));
+ holder.date.setText(Formatter.formatShortDate(log.date));
holder.date.setVisibility(View.VISIBLE);
} else {
holder.date.setVisibility(View.GONE);
@@ -2283,10 +2204,10 @@ public class CacheDetailActivity extends AbstractActivity {
}
// images
- if (CollectionUtils.isNotEmpty(log.logImages)) {
+ if (log.hasLogImages()) {
List<String> titles = new ArrayList<String>(5);
- for (cgImage image : log.logImages) {
+ for (cgImage image : log.getLogImages()) {
if (StringUtils.isNotBlank(image.getTitle())) {
titles.add(image.getTitle());
}
@@ -2300,7 +2221,7 @@ public class CacheDetailActivity extends AbstractActivity {
holder.images.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- cgeoimages.startActivityLogImages(CacheDetailActivity.this, cache.getGeocode(), new ArrayList<cgImage>(log.logImages));
+ cgeoimages.startActivityLogImages(CacheDetailActivity.this, cache.getGeocode(), new ArrayList<cgImage>(log.getLogImages()));
}
});
} else {
@@ -2391,92 +2312,88 @@ public class CacheDetailActivity extends AbstractActivity {
view = (ScrollView) getLayoutInflater().inflate(R.layout.cacheview_waypoints, null);
- LinearLayout waypoints = (LinearLayout) view.findViewById(R.id.waypoints);
+ final LinearLayout waypoints = (LinearLayout) view.findViewById(R.id.waypoints);
- if (cache.hasWaypoints()) {
- LinearLayout waypointView;
+ // sort waypoints: PP, Sx, FI, OWN
+ final List<cgWaypoint> sortedWaypoints = new ArrayList<cgWaypoint>(cache.getWaypoints());
+ Collections.sort(sortedWaypoints);
- // sort waypoints: PP, Sx, FI, OWN
- List<cgWaypoint> sortedWaypoints = new ArrayList<cgWaypoint>(cache.getWaypoints());
- Collections.sort(sortedWaypoints);
+ for (final cgWaypoint wpt : sortedWaypoints) {
+ final LinearLayout waypointView = (LinearLayout) getLayoutInflater().inflate(R.layout.waypoint_item, null);
- for (final cgWaypoint wpt : sortedWaypoints) {
- waypointView = (LinearLayout) getLayoutInflater().inflate(R.layout.waypoint_item, null);
+ // coordinates
+ if (null != wpt.getCoords()) {
+ final TextView coordinatesView = (TextView) waypointView.findViewById(R.id.coordinates);
+ coordinatesView.setText(wpt.getCoords().toString());
+ coordinatesView.setVisibility(View.VISIBLE);
+ }
- // coordinates
- if (null != wpt.getCoords()) {
- final TextView coordinatesView = (TextView) waypointView.findViewById(R.id.coordinates);
- coordinatesView.setText(wpt.getCoords().toString());
- coordinatesView.setVisibility(View.VISIBLE);
+ // info
+ final List<String> infoTextList = new ArrayList<String>(3);
+ if (WaypointType.ALL_TYPES_EXCEPT_OWN.contains(wpt.getWaypointType())) {
+ infoTextList.add(wpt.getWaypointType().getL10n());
+ }
+ if (cgWaypoint.PREFIX_OWN.equalsIgnoreCase(wpt.getPrefix())) {
+ infoTextList.add(res.getString(R.string.waypoint_custom));
+ } else {
+ if (StringUtils.isNotBlank(wpt.getPrefix())) {
+ infoTextList.add(wpt.getPrefix());
}
-
- // info
- final List<String> infoTextList = new ArrayList<String>(3);
- if (WaypointType.ALL_TYPES_EXCEPT_OWN.containsKey(wpt.getWaypointType())) {
- infoTextList.add(wpt.getWaypointType().getL10n());
+ if (StringUtils.isNotBlank(wpt.getLookup())) {
+ infoTextList.add(wpt.getLookup());
}
- if (cgWaypoint.PREFIX_OWN.equalsIgnoreCase(wpt.getPrefix())) {
- infoTextList.add(res.getString(R.string.waypoint_custom));
- } else {
- if (StringUtils.isNotBlank(wpt.getPrefix())) {
- infoTextList.add(wpt.getPrefix());
- }
- if (StringUtils.isNotBlank(wpt.getLookup())) {
- infoTextList.add(wpt.getLookup());
- }
+ }
+ if (CollectionUtils.isNotEmpty(infoTextList)) {
+ final TextView infoView = (TextView) waypointView.findViewById(R.id.info);
+ infoView.setText(StringUtils.join(infoTextList, Formatter.SEPARATOR));
+ infoView.setVisibility(View.VISIBLE);
+ }
+
+ // title
+ final TextView nameView = (TextView) waypointView.findViewById(R.id.name);
+ if (StringUtils.isNotBlank(wpt.getName())) {
+ nameView.setText(StringEscapeUtils.unescapeHtml4(wpt.getName()));
+ } else if (null != wpt.getCoords()) {
+ nameView.setText(wpt.getCoords().toString());
+ } else {
+ nameView.setText(res.getString(R.string.waypoint));
+ }
+ wpt.setIcon(res, nameView);
+
+ // note
+ if (StringUtils.isNotBlank(wpt.getNote())) {
+ final TextView noteView = (TextView) waypointView.findViewById(R.id.note);
+ noteView.setVisibility(View.VISIBLE);
+ if (BaseUtils.containsHtml(wpt.getNote())) {
+ noteView.setText(Html.fromHtml(wpt.getNote()), TextView.BufferType.SPANNABLE);
}
- if (CollectionUtils.isNotEmpty(infoTextList)) {
- final TextView infoView = (TextView) waypointView.findViewById(R.id.info);
- infoView.setText(StringUtils.join(infoTextList, Formatter.SEPARATOR));
- infoView.setVisibility(View.VISIBLE);
+ else {
+ noteView.setText(wpt.getNote());
}
+ }
- // title
- TextView nameView = (TextView) waypointView.findViewById(R.id.name);
- if (StringUtils.isNotBlank(wpt.getName())) {
- nameView.setText(StringEscapeUtils.unescapeHtml4(wpt.getName()));
- } else if (null != wpt.getCoords()) {
- nameView.setText(wpt.getCoords().toString());
- } else {
- nameView.setText(res.getString(R.string.waypoint));
+ final View wpNavView = waypointView.findViewById(R.id.wpDefaultNavigation);
+ wpNavView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), CacheDetailActivity.this, null, wpt, null);
}
- wpt.setIcon(res, nameView);
-
- // note
- if (StringUtils.isNotBlank(wpt.getNote())) {
- final TextView noteView = (TextView) waypointView.findViewById(R.id.note);
- noteView.setVisibility(View.VISIBLE);
- if (BaseUtils.containsHtml(wpt.getNote())) {
- noteView.setText(Html.fromHtml(wpt.getNote()), TextView.BufferType.SPANNABLE);
- }
- else {
- noteView.setText(wpt.getNote());
- }
+ });
+ wpNavView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ NavigationAppFactory.startDefaultNavigationApplication2(app.currentGeo(), CacheDetailActivity.this, null, wpt, null);
+ return true;
}
+ });
- View wpNavView = waypointView.findViewById(R.id.wpDefaultNavigation);
- wpNavView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- NavigationAppFactory.startDefaultNavigationApplication(geolocation, CacheDetailActivity.this, null, wpt, null);
- }
- });
- wpNavView.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- NavigationAppFactory.startDefaultNavigationApplication2(geolocation, CacheDetailActivity.this, null, wpt, null);
- return true;
- }
- });
-
- registerForContextMenu(waypointView);
- waypointView.setOnClickListener(new WaypointInfoClickListener());
+ registerForContextMenu(waypointView);
+ waypointView.setOnClickListener(new WaypointInfoClickListener());
- waypoints.addView(waypointView);
- }
+ waypoints.addView(waypointView);
}
- Button addWaypoint = (Button) view.findViewById(R.id.add_waypoint);
+ final Button addWaypoint = (Button) view.findViewById(R.id.add_waypoint);
addWaypoint.setClickable(true);
addWaypoint.setOnClickListener(new AddWaypointClickListener());
@@ -2485,16 +2402,9 @@ public class CacheDetailActivity extends AbstractActivity {
private class AddWaypointClickListener implements View.OnClickListener {
- public void onClick(View view) {
- Intent addWptIntent = new Intent(CacheDetailActivity.this, cgeowaypointadd.class);
-
- addWptIntent.putExtra("geocode", cache.getGeocode());
- int wpCount = 0;
- if (cache.hasWaypoints()) {
- wpCount = cache.getWaypoints().size();
- }
- addWptIntent.putExtra("count", wpCount);
-
+ public void onClick(final View view) {
+ final Intent addWptIntent = new Intent(CacheDetailActivity.this, cgeowaypointadd.class);
+ addWptIntent.putExtra("geocode", cache.getGeocode()).putExtra("count", cache.getWaypoints().size());
startActivity(addWptIntent);
refreshOnResume = true;
}
@@ -2550,4 +2460,18 @@ public class CacheDetailActivity extends AbstractActivity {
return view;
}
}
+
+ public static void startActivity(final Context context, final String geocode, final String cacheName) {
+ final Intent cachesIntent = new Intent(context, CacheDetailActivity.class);
+ cachesIntent.putExtra("geocode", geocode);
+ cachesIntent.putExtra("name", cacheName);
+ context.startActivity(cachesIntent);
+ }
+
+ public static void startActivityGuid(final Context context, final String guid, final String cacheName) {
+ final Intent cacheIntent = new Intent(context, CacheDetailActivity.class);
+ cacheIntent.putExtra("guid", guid);
+ cacheIntent.putExtra("name", cacheName);
+ context.startActivity(cacheIntent);
+ }
}
diff --git a/main/src/cgeo/geocaching/Destination.java b/main/src/cgeo/geocaching/Destination.java
new file mode 100644
index 0000000..441e959
--- /dev/null
+++ b/main/src/cgeo/geocaching/Destination.java
@@ -0,0 +1,44 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.geopoint.Geopoint;
+
+public final class Destination implements ICoordinates {
+
+ final private long id;
+ final private long date;
+ final private Geopoint coords;
+
+ public Destination(long id, long date, final Geopoint coords) {
+ this.id = id;
+ this.date = date;
+ this.coords = coords;
+ }
+
+ public Destination(final Geopoint coords) {
+ this(0, System.currentTimeMillis(), coords);
+ }
+
+ public long getDate() {
+ return date;
+ }
+
+ @Override
+ public Geopoint getCoords() {
+ return coords;
+ }
+
+ @Override
+ public int hashCode() {
+ return coords.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return obj != null && obj instanceof Destination && ((Destination) obj).coords.equals(coords);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/GeoDataProvider.java b/main/src/cgeo/geocaching/GeoDataProvider.java
new file mode 100644
index 0000000..58b0696
--- /dev/null
+++ b/main/src/cgeo/geocaching/GeoDataProvider.java
@@ -0,0 +1,305 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.enumerations.LocationProviderType;
+import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.go4cache.Go4Cache;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.MemorySubject;
+
+import android.content.Context;
+import android.location.GpsSatellite;
+import android.location.GpsStatus;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Provide information about the user location. This class should be instantiated only once per application.
+ */
+class GeoDataProvider extends MemorySubject<IGeoData> {
+
+ private static final String LAST_LOCATION_PSEUDO_PROVIDER = "last";
+ private final LocationManager geoManager;
+ private final GpsStatus.Listener gpsStatusListener = new GpsStatusListener();
+ private final LocationData gpsLocation = new LocationData();
+ private final LocationData netLocation = new LocationData();
+ private final Listener networkListener = new Listener(LocationManager.NETWORK_PROVIDER, netLocation);
+ private final Listener gpsListener = new Listener(LocationManager.GPS_PROVIDER, gpsLocation);
+ private final Unregisterer unregisterer = new Unregisterer();
+ public boolean gpsEnabled = false;
+ public int satellitesVisible = 0;
+ public int satellitesFixed = 0;
+
+ private static class LocationData {
+ public Location location;
+ public long timestamp = 0;
+
+ public void update(final Location location) {
+ this.location = location;
+ timestamp = System.currentTimeMillis();
+ }
+
+ public boolean isRecent() {
+ return isValid() && System.currentTimeMillis() < timestamp + 30000;
+ }
+
+ public boolean isValid() {
+ return location != null;
+ }
+ }
+
+ private static class GeoData extends Location implements IGeoData {
+ public boolean gpsEnabled = false;
+ public int satellitesVisible = 0;
+ public int satellitesFixed = 0;
+
+ GeoData(final Location location, final boolean gpsEnabled, final int satellitesVisible, final int satellitesFixed) {
+ super(location);
+ this.gpsEnabled = gpsEnabled;
+ this.satellitesVisible = satellitesVisible;
+ this.satellitesFixed = satellitesFixed;
+ }
+
+ @Override
+ public Location getLocation() {
+ return this;
+ }
+
+ private static LocationProviderType getLocationProviderType(final String provider) {
+ if (provider.equals(LocationManager.GPS_PROVIDER)) {
+ return LocationProviderType.GPS;
+ }
+ if (provider.equals(LocationManager.NETWORK_PROVIDER)) {
+ return LocationProviderType.NETWORK;
+ }
+ return LocationProviderType.LAST;
+ }
+
+ @Override
+ public LocationProviderType getLocationProvider() {
+ return getLocationProviderType(getProvider());
+ }
+
+ @Override
+ public Geopoint getCoords() {
+ return new Geopoint(this);
+ }
+
+ @Override
+ public boolean getGpsEnabled() {
+ return gpsEnabled;
+ }
+
+ @Override
+ public int getSatellitesVisible() {
+ return satellitesVisible;
+ }
+
+ @Override
+ public int getSatellitesFixed() {
+ return satellitesFixed;
+ }
+ }
+
+ private class Unregisterer extends Thread {
+
+ private boolean unregisterRequested = false;
+ private final ArrayBlockingQueue<Boolean> queue = new ArrayBlockingQueue<Boolean>(1);
+
+ public void cancelUnregister() {
+ try {
+ queue.put(false);
+ } catch (final InterruptedException e) {
+ // Do nothing
+ }
+ }
+
+ public void lateUnregister() {
+ try {
+ queue.put(true);
+ } catch (final InterruptedException e) {
+ // Do nothing
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (true) {
+ if (unregisterRequested) {
+ final Boolean element = queue.poll(2500, TimeUnit.MILLISECONDS);
+ if (element == null) {
+ // Timeout
+ unregisterListeners();
+ unregisterRequested = false;
+ } else {
+ unregisterRequested = element;
+ }
+ } else {
+ unregisterRequested = queue.take();
+ }
+ }
+ } catch (final InterruptedException e) {
+ // Do nothing
+ }
+ }
+
+ }
+
+ /**
+ * 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
+ */
+ GeoDataProvider(final Context context) {
+ geoManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ unregisterer.start();
+ // Start with an empty GeoData just in case someone queries it before we get
+ // a chance to get any information.
+ notifyObservers(new GeoData(new Location(LAST_LOCATION_PSEUDO_PROVIDER), false, 0, 0));
+ }
+
+ private void registerListeners() {
+ geoManager.addGpsStatusListener(gpsStatusListener);
+
+ for (final Listener listener : new Listener[] { networkListener, gpsListener }) {
+ try {
+ geoManager.requestLocationUpdates(listener.locationProvider, 0, 0, listener);
+ } catch (final Exception e) {
+ Log.w("There is no location provider " + listener.locationProvider);
+ }
+ }
+ }
+
+ private synchronized void unregisterListeners() {
+ // This method must be synchronized because it will be called asynchronously from the Unregisterer thread.
+ // We check that no observers have been re-added to prevent a race condition.
+ if (sizeObservers() == 0) {
+ geoManager.removeUpdates(networkListener);
+ geoManager.removeUpdates(gpsListener);
+ geoManager.removeGpsStatusListener(gpsStatusListener);
+ }
+ }
+
+ @Override
+ protected void onFirstObserver() {
+ unregisterer.cancelUnregister();
+ registerListeners();
+ }
+
+ @Override
+ protected void onLastObserver() {
+ unregisterer.lateUnregister();
+ }
+
+ private class Listener implements LocationListener {
+ private final String locationProvider;
+ private final LocationData locationData;
+
+ Listener(final String locationProvider, final LocationData locationData) {
+ this.locationProvider = locationProvider;
+ this.locationData = locationData;
+ }
+
+ @Override
+ public void onStatusChanged(final String provider, final int status, final Bundle extras) {
+ // nothing
+ }
+
+ @Override
+ public void onProviderDisabled(final String provider) {
+ // nothing
+ }
+
+ @Override
+ public void onProviderEnabled(final String provider) {
+ // nothing
+ }
+
+ @Override
+ public void onLocationChanged(final Location location) {
+ locationData.update(location);
+ selectBest();
+ }
+ }
+
+ private final class GpsStatusListener implements GpsStatus.Listener {
+
+ @Override
+ public void onGpsStatusChanged(final int event) {
+ boolean changed = false;
+ switch (event) {
+ case GpsStatus.GPS_EVENT_SATELLITE_STATUS: {
+ final GpsStatus status = geoManager.getGpsStatus(null);
+ int visible = 0;
+ int fixed = 0;
+ for (final GpsSatellite satellite : status.getSatellites()) {
+ if (satellite.usedInFix()) {
+ fixed++;
+ }
+ visible++;
+ }
+ if (visible != satellitesVisible || fixed != satellitesFixed) {
+ satellitesVisible = visible;
+ satellitesFixed = fixed;
+ changed = true;
+ }
+ break;
+ }
+ case GpsStatus.GPS_EVENT_STARTED:
+ if (!gpsEnabled) {
+ gpsEnabled = true;
+ changed = true;
+ }
+ break;
+ case GpsStatus.GPS_EVENT_STOPPED:
+ if (gpsEnabled) {
+ gpsEnabled = false;
+ satellitesFixed = 0;
+ satellitesVisible = 0;
+ changed = true;
+ }
+ break;
+ }
+
+ if (changed) {
+ selectBest();
+ }
+ }
+ }
+
+ private LocationData best() {
+ if (gpsLocation.isRecent() || !netLocation.isValid()) {
+ return gpsLocation.isValid() ? gpsLocation : null;
+ }
+ if (!gpsLocation.isValid()) {
+ return netLocation;
+ }
+ return gpsLocation.timestamp > netLocation.timestamp ? gpsLocation : netLocation;
+ }
+
+ private void selectBest() {
+ assign(best());
+ }
+
+ private void assign(final LocationData locationData) {
+ if (locationData == null) {
+ return;
+ }
+
+ // We do not necessarily get signalled when satellites go to 0/0.
+ final int visible = gpsLocation.isRecent() ? satellitesVisible : 0;
+ final IGeoData current = new GeoData(locationData.location, gpsEnabled, visible, satellitesFixed);
+ notifyObservers(current);
+
+ Go4Cache.signalCoordinates(current.getCoords());
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/GeoObserver.java b/main/src/cgeo/geocaching/GeoObserver.java
new file mode 100644
index 0000000..8d5475f
--- /dev/null
+++ b/main/src/cgeo/geocaching/GeoObserver.java
@@ -0,0 +1,13 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.utils.IObserver;
+
+public abstract class GeoObserver implements IObserver<IGeoData> {
+
+ abstract protected void updateLocation(final IGeoData geo);
+
+ @Override
+ public void update(final IGeoData geo) {
+ updateLocation(geo);
+ }
+}
diff --git a/main/src/cgeo/geocaching/IBasicCache.java b/main/src/cgeo/geocaching/IBasicCache.java
index 5e67b2d..195572b 100644
--- a/main/src/cgeo/geocaching/IBasicCache.java
+++ b/main/src/cgeo/geocaching/IBasicCache.java
@@ -11,7 +11,7 @@ import cgeo.geocaching.enumerations.CacheType;
* @author blafoo
*
*/
-public interface IBasicCache extends ILogable {
+public interface IBasicCache extends ILogable, ICoordinates {
public abstract String getGuid();
diff --git a/main/src/cgeo/geocaching/ICache.java b/main/src/cgeo/geocaching/ICache.java
index b6a809f..dccdb85 100644
--- a/main/src/cgeo/geocaching/ICache.java
+++ b/main/src/cgeo/geocaching/ICache.java
@@ -28,16 +28,6 @@ public interface ICache extends IBasicCache {
public String getOwnerReal();
/**
- * @return Latitude, e.g. N 52° 12.345
- */
- public String getLatitude();
-
- /**
- * @return Longitude, e.g. E 9° 34.567
- */
- public String getLongitude();
-
- /**
* @return true if the user is the owner of the cache, false else
*/
public boolean isOwn();
diff --git a/main/src/cgeo/geocaching/ICoordinates.java b/main/src/cgeo/geocaching/ICoordinates.java
new file mode 100644
index 0000000..b70e4ac
--- /dev/null
+++ b/main/src/cgeo/geocaching/ICoordinates.java
@@ -0,0 +1,9 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.geopoint.Geopoint;
+
+public interface ICoordinates {
+
+ public abstract Geopoint getCoords();
+
+}
diff --git a/main/src/cgeo/geocaching/IGeoData.java b/main/src/cgeo/geocaching/IGeoData.java
new file mode 100644
index 0000000..9696b27
--- /dev/null
+++ b/main/src/cgeo/geocaching/IGeoData.java
@@ -0,0 +1,21 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.enumerations.LocationProviderType;
+import cgeo.geocaching.geopoint.Geopoint;
+
+import android.location.Location;
+
+public interface IGeoData {
+
+ public Location getLocation();
+ public LocationProviderType getLocationProvider();
+ public Geopoint getCoords();
+ public double getAltitude();
+ public float getBearing();
+ public float getSpeed();
+ public float getAccuracy();
+ public boolean getGpsEnabled();
+ public int getSatellitesVisible();
+ public int getSatellitesFixed();
+
+}
diff --git a/main/src/cgeo/geocaching/IWaypoint.java b/main/src/cgeo/geocaching/IWaypoint.java
index 870fb12..ad12d48 100644
--- a/main/src/cgeo/geocaching/IWaypoint.java
+++ b/main/src/cgeo/geocaching/IWaypoint.java
@@ -4,18 +4,17 @@
package cgeo.geocaching;
import cgeo.geocaching.enumerations.WaypointType;
-import cgeo.geocaching.geopoint.Geopoint;
/**
* @author blafoo
*
*/
-public interface IWaypoint extends ILogable {
+public interface IWaypoint extends ILogable, ICoordinates {
public abstract int getId();
- public abstract Geopoint getCoords();
-
public abstract WaypointType getWaypointType();
+ public abstract String getCoordType();
+
}
diff --git a/main/src/cgeo/geocaching/LiveMapInfo.java b/main/src/cgeo/geocaching/LiveMapInfo.java
index 3d6d110..822fbf6 100644
--- a/main/src/cgeo/geocaching/LiveMapInfo.java
+++ b/main/src/cgeo/geocaching/LiveMapInfo.java
@@ -9,8 +9,6 @@ import android.widget.CheckBox;
public class LiveMapInfo extends AbstractActivity {
- private int showCount;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -18,7 +16,7 @@ public class LiveMapInfo extends AbstractActivity {
setTheme(R.style.transparent);
setContentView(R.layout.livemapinfo);
- showCount = Settings.getLiveMapHintShowCount();
+ final int showCount = Settings.getLiveMapHintShowCount();
if (showCount > 2) {
final CheckBox cb = (CheckBox) findViewById(R.id.live_map_hint_hide);
diff --git a/main/src/cgeo/geocaching/LogEntry.java b/main/src/cgeo/geocaching/LogEntry.java
new file mode 100644
index 0000000..9864f89
--- /dev/null
+++ b/main/src/cgeo/geocaching/LogEntry.java
@@ -0,0 +1,86 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.enumerations.LogType;
+
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+
+public final class LogEntry {
+ /**
+ * avoid creating new empty lists all the time using this constant. We could also return Collections.EMPTY_LIST
+ * using a cast, but that might trigger static code analysis tools.
+ */
+ private static final List<cgImage> EMPTY_LIST = Collections.emptyList();
+
+ public int id = 0;
+ public LogType type = LogType.LOG_NOTE; // note
+ public String author = "";
+ public String log = "";
+ public long date = 0;
+ public int found = -1;
+ /** Friend's log entry */
+ public boolean friend = false;
+ private List<cgImage> logImages = null;
+ public String cacheName = ""; // used for trackables
+ public String cacheGuid = ""; // used for trackables
+
+ public LogEntry(final Calendar date, final LogType type, final String text) {
+ this(Settings.getUsername(), date.getTimeInMillis(), type, text);
+ }
+
+ public LogEntry(final long dateInMilliSeconds, final LogType type, final String text) {
+ this(Settings.getUsername(), dateInMilliSeconds, type, text);
+ }
+
+ public LogEntry(final String author, long dateInMilliSeconds, final LogType type, final String text) {
+ this.author = author;
+ this.date = dateInMilliSeconds;
+ this.type = type;
+ this.log = text;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) date * type.hashCode() * author.hashCode() * log.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof LogEntry)) {
+ return false;
+ }
+ final LogEntry otherLog = (LogEntry) obj;
+ return date == otherLog.date &&
+ type == otherLog.type &&
+ author.compareTo(otherLog.author) == 0 &&
+ log.compareTo(otherLog.log) == 0;
+ }
+
+ public void addLogImage(final cgImage image) {
+ if (logImages == null) {
+ logImages = new ArrayList<cgImage>();
+ }
+ logImages.add(image);
+ }
+
+ /**
+ * @return the log images or an empty list, never <code>null</code>
+ */
+ public List<cgImage> getLogImages() {
+ if (logImages == null) {
+ return EMPTY_LIST;
+ }
+ return logImages;
+ }
+
+ public boolean hasLogImages() {
+ return CollectionUtils.isNotEmpty(logImages);
+ }
+}
diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java
index bac9c23..2e56c7c 100644
--- a/main/src/cgeo/geocaching/SearchResult.java
+++ b/main/src/cgeo/geocaching/SearchResult.java
@@ -1,5 +1,6 @@
package cgeo.geocaching;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LoadFlags.LoadFlag;
@@ -7,7 +8,6 @@ import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.gcvote.GCVote;
-import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import android.os.Parcel;
@@ -22,10 +22,10 @@ import java.util.Set;
public class SearchResult implements Parcelable {
final private Set<String> geocodes;
- public StatusCode error = null;
+ private StatusCode error = null;
private String url = "";
public String[] viewstates = null;
- public int totalCnt = 0;
+ private int totalCnt = 0;
final public static Parcelable.Creator<SearchResult> CREATOR = new Parcelable.Creator<SearchResult>() {
public SearchResult createFromParcel(Parcel in) {
@@ -47,19 +47,24 @@ public class SearchResult implements Parcelable {
this.error = searchResult.error;
this.url = searchResult.url;
this.viewstates = searchResult.viewstates;
- this.totalCnt = searchResult.totalCnt;
+ this.setTotal(searchResult.getTotal());
} else {
this.geocodes = new HashSet<String>();
}
}
- public SearchResult(final Set<String> geocodes) {
+ public SearchResult(final Set<String> geocodes, final int total) {
if (geocodes == null) {
this.geocodes = new HashSet<String>();
} else {
this.geocodes = new HashSet<String>(geocodes.size());
this.geocodes.addAll(geocodes);
}
+ this.setTotal(total);
+ }
+
+ public SearchResult(final Set<String> geocodes) {
+ this(geocodes, geocodes == null ? 0 : geocodes.size());
}
public SearchResult(final Parcel in) {
@@ -73,7 +78,7 @@ public class SearchResult implements Parcelable {
viewstates = new String[length];
in.readStringArray(viewstates);
}
- totalCnt = in.readInt();
+ setTotal(in.readInt());
}
@Override
@@ -87,7 +92,7 @@ public class SearchResult implements Parcelable {
out.writeInt(viewstates.length);
out.writeStringArray(viewstates);
}
- out.writeInt(totalCnt);
+ out.writeInt(getTotal());
}
@Override
@@ -124,7 +129,7 @@ public class SearchResult implements Parcelable {
}
public void setViewstates(String[] viewstates) {
- if (cgBase.isEmpty(viewstates)) {
+ if (Login.isEmpty(viewstates)) {
return;
}
@@ -135,6 +140,10 @@ public class SearchResult implements Parcelable {
return totalCnt;
}
+ public void setTotal(int totalCnt) {
+ this.totalCnt = totalCnt;
+ }
+
/**
* @param excludeDisabled
* @param excludeMine
@@ -192,14 +201,8 @@ public class SearchResult implements Parcelable {
return cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE));
}
- /** Add the cache geocodes to the search and store them in the CacheCache */
- public void addCaches(final Set<cgCache> caches) {
- if (CollectionUtils.isEmpty(caches)) {
- return;
- }
-
- for (final cgCache cache : caches) {
- addCache(cache);
- }
+ public boolean isEmpty() {
+ return geocodes.isEmpty();
}
+
}
diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java
index f2ec497..3b36b23 100644
--- a/main/src/cgeo/geocaching/Settings.java
+++ b/main/src/cgeo/geocaching/Settings.java
@@ -5,17 +5,19 @@ import cgeo.geocaching.enumerations.LiveMapStrategy.Strategy;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.maps.MapProviderFactory;
import cgeo.geocaching.maps.interfaces.MapProvider;
+import cgeo.geocaching.maps.mapsforge.MapsforgeMapProvider;
import cgeo.geocaching.utils.CryptUtils;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.mapsforge.android.maps.MapDatabase;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.preference.PreferenceManager;
import java.util.Locale;
@@ -79,11 +81,12 @@ public final class Settings {
private static final String KEY_DEFAULT_NAVIGATION_TOOL = "defaultNavigationTool";
private static final String KEY_DEFAULT_NAVIGATION_TOOL_2 = "defaultNavigationTool2";
private static final String KEY_LIVE_MAP_STRATEGY = "livemapstrategy";
+ private static final String KEY_DEBUG = "debug";
private static final String KEY_HIDE_LIVE_MAP_HINT = "hidelivemaphint";
private static final String KEY_LIVE_MAP_HINT_SHOW_COUNT = "livemaphintshowcount";
+ private static final String KEY_SETTINGS_VERSION = "settingsversion";
private final static int unitsMetric = 1;
- private final static int unitsImperial = 2;
// twitter api keys
private final static String keyConsumerPublic = CryptUtils.rot13("ESnsCvAv3kEupF1GCR3jGj");
@@ -101,24 +104,22 @@ public final class Settings {
static coordInputFormatEnum fromInt(int id) {
final coordInputFormatEnum[] values = coordInputFormatEnum.values();
- if (id >= 0 && id < values.length) {
- return values[id];
- } else {
+ if (id < 0 || id >= values.length) {
return Min;
}
+ return values[id];
}
}
- // usable values
- public static final String tag = "cgeo";
-
- /** Name of the preferences file */
- public static final String preferences = "cgeo.pref";
-
- private static final SharedPreferences sharedPrefs = cgeoapplication.getInstance().getSharedPreferences(Settings.preferences, Context.MODE_PRIVATE);
private static String username = null;
private static String password = null;
+ private static final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(cgeoapplication.getInstance().getBaseContext());
+ static {
+ migrateSettings();
+ Log.setDebugUnsaved(sharedPrefs.getBoolean(KEY_DEBUG, false));
+ }
+
// maps
private static MapProvider mapProvider = null;
@@ -126,6 +127,77 @@ public final class Settings {
// this class is not to be instantiated;
}
+ private static void migrateSettings() {
+ // migrate from non standard file location and integer based boolean types
+ if (sharedPrefs.getInt(KEY_SETTINGS_VERSION, 0) < 1) {
+ final String oldPreferencesName = "cgeo.pref";
+ final SharedPreferences old = cgeoapplication.getInstance().getSharedPreferences(oldPreferencesName, Context.MODE_PRIVATE);
+ final Editor e = sharedPrefs.edit();
+
+ e.putString(KEY_TEMP_TOKEN_SECRET, old.getString(KEY_TEMP_TOKEN_SECRET, null));
+ e.putString(KEY_TEMP_TOKEN_PUBLIC, old.getString(KEY_TEMP_TOKEN_PUBLIC, null));
+ e.putBoolean(KEY_HELP_SHOWN, old.getInt(KEY_HELP_SHOWN, 0) != 0);
+ e.putFloat(KEY_ANYLONGITUDE, old.getFloat(KEY_ANYLONGITUDE, 0));
+ e.putFloat(KEY_ANYLATITUDE, old.getFloat(KEY_ANYLATITUDE, 0));
+ e.putBoolean(KEY_PUBLICLOC, 0 != old.getInt(KEY_PUBLICLOC, 0));
+ e.putBoolean(KEY_USE_OFFLINEMAPS, 0 != old.getInt(KEY_USE_OFFLINEMAPS, 1));
+ e.putBoolean(KEY_USE_OFFLINEWPMAPS, 0 != old.getInt(KEY_USE_OFFLINEWPMAPS, 0));
+ e.putString(KEY_WEB_DEVICE_CODE, old.getString(KEY_WEB_DEVICE_CODE, null));
+ e.putString(KEY_WEBDEVICE_NAME, old.getString(KEY_WEBDEVICE_NAME, null));
+ e.putBoolean(KEY_MAP_LIVE, old.getInt(KEY_MAP_LIVE, 1) != 0);
+ e.putInt(KEY_MAP_SOURCE, old.getInt(KEY_MAP_SOURCE, 0));
+ e.putBoolean(KEY_USE_TWITTER, 0 != old.getInt(KEY_USE_TWITTER, 0));
+ e.putBoolean(KEY_SHOW_ADDRESS, 0 != old.getInt(KEY_SHOW_ADDRESS, 1));
+ e.putBoolean(KEY_SHOW_CAPTCHA, old.getBoolean(KEY_SHOW_CAPTCHA, false));
+ e.putBoolean(KEY_MAP_TRAIL, old.getInt(KEY_MAP_TRAIL, 1) != 0);
+ e.putInt(KEY_LAST_MAP_ZOOM, old.getInt(KEY_LAST_MAP_ZOOM, 14));
+ e.putBoolean(KEY_LIVE_LIST, 0 != old.getInt(KEY_LIVE_LIST, 1));
+ e.putBoolean(KEY_METRIC_UNITS, old.getInt(KEY_METRIC_UNITS, unitsMetric) == unitsMetric);
+ e.putBoolean(KEY_SKIN, old.getInt(KEY_SKIN, 0) != 0);
+ e.putInt(KEY_LAST_USED_LIST, old.getInt(KEY_LAST_USED_LIST, StoredList.STANDARD_LIST_ID));
+ e.putString(KEY_CACHE_TYPE, old.getString(KEY_CACHE_TYPE, CacheType.ALL.id));
+ e.putString(KEY_TWITTER_TOKEN_SECRET, old.getString(KEY_TWITTER_TOKEN_SECRET, null));
+ e.putString(KEY_TWITTER_TOKEN_PUBLIC, old.getString(KEY_TWITTER_TOKEN_PUBLIC, null));
+ e.putInt(KEY_VERSION, old.getInt(KEY_VERSION, 0));
+ e.putBoolean(KEY_LOAD_DESCRIPTION, 0 != old.getInt(KEY_LOAD_DESCRIPTION, 0));
+ e.putBoolean(KEY_RATING_WANTED, old.getBoolean(KEY_RATING_WANTED, true));
+ e.putBoolean(KEY_ELEVATION_WANTED, old.getBoolean(KEY_ELEVATION_WANTED, true));
+ e.putBoolean(KEY_FRIENDLOGS_WANTED, old.getBoolean(KEY_FRIENDLOGS_WANTED, true));
+ e.putBoolean(KEY_USE_ENGLISH, old.getBoolean(KEY_USE_ENGLISH, false));
+ e.putBoolean(KEY_USE_COMPASS, 0 != old.getInt(KEY_USE_COMPASS, 1));
+ e.putBoolean(KEY_AUTO_VISIT_TRACKABLES, old.getBoolean(KEY_AUTO_VISIT_TRACKABLES, false));
+ e.putBoolean(KEY_AUTO_INSERT_SIGNATURE, old.getBoolean(KEY_AUTO_INSERT_SIGNATURE, false));
+ e.putInt(KEY_ALTITUDE_CORRECTION, old.getInt(KEY_ALTITUDE_CORRECTION, 0));
+ e.putBoolean(KEY_USE_GOOGLE_NAVIGATION, 0 != old.getInt(KEY_USE_GOOGLE_NAVIGATION, 1));
+ e.putBoolean(KEY_STORE_LOG_IMAGES, old.getBoolean(KEY_STORE_LOG_IMAGES, false));
+ e.putBoolean(KEY_EXCLUDE_DISABLED, 0 != old.getInt(KEY_EXCLUDE_DISABLED, 0));
+ e.putBoolean(KEY_EXCLUDE_OWN, 0 != old.getInt(KEY_EXCLUDE_OWN, 0));
+ e.putString(KEY_MAPFILE, old.getString(KEY_MAPFILE, null));
+ e.putString(KEY_SIGNATURE, old.getString(KEY_SIGNATURE, null));
+ e.putString(KEY_GCVOTE_PASSWORD, old.getString(KEY_GCVOTE_PASSWORD, null));
+ e.putString(KEY_PASSWORD, old.getString(KEY_PASSWORD, null));
+ e.putString(KEY_USERNAME, old.getString(KEY_USERNAME, null));
+ e.putString(KEY_MEMBER_STATUS, old.getString(KEY_MEMBER_STATUS, ""));
+ e.putInt(KEY_COORD_INPUT_FORMAT, old.getInt(KEY_COORD_INPUT_FORMAT, 0));
+ e.putBoolean(KEY_LOG_OFFLINE, old.getBoolean(KEY_LOG_OFFLINE, false));
+ e.putBoolean(KEY_LOAD_DIRECTION_IMG, old.getBoolean(KEY_LOAD_DIRECTION_IMG, true));
+ e.putString(KEY_GC_CUSTOM_DATE, old.getString(KEY_GC_CUSTOM_DATE, null));
+ e.putInt(KEY_SHOW_WAYPOINTS_THRESHOLD, old.getInt(KEY_SHOW_WAYPOINTS_THRESHOLD, 0));
+ e.putString(KEY_COOKIE_STORE, old.getString(KEY_COOKIE_STORE, null));
+ e.putBoolean(KEY_OPEN_LAST_DETAILS_PAGE, old.getBoolean(KEY_OPEN_LAST_DETAILS_PAGE, false));
+ e.putInt(KEY_LAST_DETAILS_PAGE, old.getInt(KEY_LAST_DETAILS_PAGE, 1));
+ e.putInt(KEY_DEFAULT_NAVIGATION_TOOL, old.getInt(KEY_DEFAULT_NAVIGATION_TOOL, 0));
+ e.putInt(KEY_DEFAULT_NAVIGATION_TOOL_2, old.getInt(KEY_DEFAULT_NAVIGATION_TOOL_2, 0));
+ e.putInt(KEY_LIVE_MAP_STRATEGY, old.getInt(KEY_LIVE_MAP_STRATEGY, Strategy.AUTO.id));
+ e.putBoolean(KEY_DEBUG, old.getBoolean(KEY_DEBUG, false));
+ e.putBoolean(KEY_HIDE_LIVE_MAP_HINT, old.getInt(KEY_HIDE_LIVE_MAP_HINT, 0) != 0);
+ e.putInt(KEY_LIVE_MAP_HINT_SHOW_COUNT, old.getInt(KEY_LIVE_MAP_HINT_SHOW_COUNT, 0));
+
+ e.putInt(KEY_SETTINGS_VERSION, 1) ; // mark migrated
+ e.commit();
+ }
+ }
+
public static void setLanguage(boolean useEnglish) {
final Configuration config = new Configuration();
config.locale = useEnglish ? new Locale("en") : Locale.getDefault();
@@ -161,11 +233,7 @@ public final class Settings {
}
public static String getUsername() {
- if (null == username) {
- return sharedPrefs.getString(KEY_USERNAME, null);
- } else {
- return username;
- }
+ return username != null ? username : sharedPrefs.getString(KEY_USERNAME, null);
}
public static boolean setLogin(final String username, final String password) {
@@ -311,15 +379,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_MAP_LIVE, live ? 1 : 0);
+ edit.putBoolean(KEY_MAP_LIVE, live);
}
});
}
public static int getLastList() {
- final int listId = sharedPrefs.getInt(KEY_LAST_USED_LIST, StoredList.STANDARD_LIST_ID);
-
- return listId;
+ return sharedPrefs.getInt(KEY_LAST_USED_LIST, StoredList.STANDARD_LIST_ID);
}
public static void saveLastList(final int listId) {
@@ -356,26 +422,16 @@ public final class Settings {
}
public static boolean setMapFile(final String mapFile) {
- final boolean commitResult = editSharedSettings(new PrefRunnable() {
-
+ return editSharedSettings(new PrefRunnable() {
@Override
public void edit(Editor edit) {
edit.putString(KEY_MAPFILE, mapFile);
}
});
-
- return commitResult;
}
- public static boolean isValidMapFile() {
- return checkMapfile(getMapFile());
- }
-
- private static boolean checkMapfile(final String mapFileIn) {
- if (null == mapFileIn) {
- return false;
- }
- return MapDatabase.isValidMapFile(mapFileIn);
+ public static boolean isValidMapFile(final String mapFileIn) {
+ return MapsforgeMapProvider.isValidMapFile(mapFileIn);
}
public static coordInputFormatEnum getCoordInputFormat() {
@@ -417,7 +473,7 @@ public final class Settings {
}
public static boolean getLoadDirImg() {
- return isPremiumMember() ? false : sharedPrefs.getBoolean(KEY_LOAD_DIRECTION_IMG, true);
+ return !isPremiumMember() && sharedPrefs.getBoolean(KEY_LOAD_DIRECTION_IMG, true);
}
public static void setGcCustomDate(final String format) {
@@ -439,7 +495,7 @@ public final class Settings {
}
public static boolean isExcludeMyCaches() {
- return 0 != sharedPrefs.getInt(KEY_EXCLUDE_OWN, 0);
+ return sharedPrefs.getBoolean(KEY_EXCLUDE_OWN, false);
}
/**
@@ -459,7 +515,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_EXCLUDE_OWN, exclude ? 1 : 0);
+ edit.putBoolean(KEY_EXCLUDE_OWN, exclude);
}
});
}
@@ -479,7 +535,7 @@ public final class Settings {
}
public static boolean isShowAddress() {
- return 0 != sharedPrefs.getInt(KEY_SHOW_ADDRESS, 1);
+ return sharedPrefs.getBoolean(KEY_SHOW_ADDRESS, true);
}
public static void setShowAddress(final boolean showAddress) {
@@ -487,13 +543,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_SHOW_ADDRESS, showAddress ? 1 : 0);
+ edit.putBoolean(KEY_SHOW_ADDRESS, showAddress);
}
});
}
public static boolean isShowCaptcha() {
- return isPremiumMember() ? false : sharedPrefs.getBoolean(KEY_SHOW_CAPTCHA, false);
+ return !isPremiumMember() && sharedPrefs.getBoolean(KEY_SHOW_CAPTCHA, false);
}
public static void setShowCaptcha(final boolean showCaptcha) {
@@ -507,7 +563,7 @@ public final class Settings {
}
public static boolean isExcludeDisabledCaches() {
- return 0 != sharedPrefs.getInt(KEY_EXCLUDE_DISABLED, 0);
+ return sharedPrefs.getBoolean(KEY_EXCLUDE_DISABLED, false);
}
public static void setExcludeDisabledCaches(final boolean exclude) {
@@ -515,13 +571,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_EXCLUDE_DISABLED, exclude ? 1 : 0);
+ edit.putBoolean(KEY_EXCLUDE_DISABLED, exclude);
}
});
}
public static boolean isStoreOfflineMaps() {
- return 0 != sharedPrefs.getInt(KEY_USE_OFFLINEMAPS, 1);
+ return sharedPrefs.getBoolean(KEY_USE_OFFLINEMAPS, true);
}
public static void setStoreOfflineMaps(final boolean offlineMaps) {
@@ -529,13 +585,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_USE_OFFLINEMAPS, offlineMaps ? 1 : 0);
+ edit.putBoolean(KEY_USE_OFFLINEMAPS, offlineMaps);
}
});
}
public static boolean isStoreOfflineWpMaps() {
- return 0 != sharedPrefs.getInt(KEY_USE_OFFLINEWPMAPS, 0);
+ return sharedPrefs.getBoolean(KEY_USE_OFFLINEWPMAPS, false);
}
public static void setStoreOfflineWpMaps(final boolean offlineMaps) {
@@ -543,7 +599,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_USE_OFFLINEWPMAPS, offlineMaps ? 1 : 0);
+ edit.putBoolean(KEY_USE_OFFLINEWPMAPS, offlineMaps);
}
});
}
@@ -563,7 +619,7 @@ public final class Settings {
}
public static boolean isUseGoogleNavigation() {
- return 0 != sharedPrefs.getInt(KEY_USE_GOOGLE_NAVIGATION, 1);
+ return sharedPrefs.getBoolean(KEY_USE_GOOGLE_NAVIGATION, true);
}
public static void setUseGoogleNavigation(final boolean useGoogleNavigation) {
@@ -571,13 +627,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_USE_GOOGLE_NAVIGATION, useGoogleNavigation ? 1 : 0);
+ edit.putBoolean(KEY_USE_GOOGLE_NAVIGATION, useGoogleNavigation);
}
});
}
public static boolean isAutoLoadDescription() {
- return 0 != sharedPrefs.getInt(KEY_LOAD_DESCRIPTION, 0);
+ return sharedPrefs.getBoolean(KEY_LOAD_DESCRIPTION, false);
}
public static void setAutoLoadDesc(final boolean autoLoad) {
@@ -585,7 +641,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_LOAD_DESCRIPTION, autoLoad ? 1 : 0);
+ edit.putBoolean(KEY_LOAD_DESCRIPTION, autoLoad);
}
});
}
@@ -637,7 +693,7 @@ public final class Settings {
}
public static boolean isLiveList() {
- return 0 != sharedPrefs.getInt(KEY_LIVE_LIST, 1);
+ return sharedPrefs.getBoolean(KEY_LIVE_LIST, true);
}
public static void setLiveList(final boolean liveList) {
@@ -645,13 +701,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_LIVE_LIST, liveList ? 1 : 0);
+ edit.putBoolean(KEY_LIVE_LIST, liveList);
}
});
}
public static boolean isPublicLoc() {
- return 0 != sharedPrefs.getInt(KEY_PUBLICLOC, 0);
+ return sharedPrefs.getBoolean(KEY_PUBLICLOC, false);
}
public static void setPublicLoc(final boolean publicLocation) {
@@ -659,7 +715,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_PUBLICLOC, publicLocation ? 1 : 0);
+ edit.putBoolean(KEY_PUBLICLOC, publicLocation);
}
});
}
@@ -693,7 +749,7 @@ public final class Settings {
}
public static boolean isUseMetricUnits() {
- return sharedPrefs.getInt(KEY_METRIC_UNITS, unitsMetric) == unitsMetric;
+ return sharedPrefs.getBoolean(KEY_METRIC_UNITS, true);
}
public static void setUseMetricUnits(final boolean metric) {
@@ -701,17 +757,17 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_METRIC_UNITS, metric ? unitsMetric : unitsImperial);
+ edit.putBoolean(KEY_METRIC_UNITS, metric);
}
});
}
public static boolean isLiveMap() {
- return sharedPrefs.getInt(KEY_MAP_LIVE, 1) != 0;
+ return sharedPrefs.getBoolean(KEY_MAP_LIVE, true);
}
public static boolean isMapTrail() {
- return sharedPrefs.getInt(KEY_MAP_TRAIL, 1) != 0;
+ return sharedPrefs.getBoolean(KEY_MAP_TRAIL, true);
}
public static void setMapTrail(final boolean showTrail) {
@@ -719,7 +775,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_MAP_TRAIL, showTrail ? 1 : 0);
+ edit.putBoolean(KEY_MAP_TRAIL, showTrail);
}
});
}
@@ -782,7 +838,7 @@ public final class Settings {
}
public static boolean isUseCompass() {
- return 0 != sharedPrefs.getInt(KEY_USE_COMPASS, 1);
+ return sharedPrefs.getBoolean(KEY_USE_COMPASS, true);
}
public static void setUseCompass(final boolean useCompass) {
@@ -790,13 +846,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_USE_COMPASS, useCompass ? 1 : 0);
+ edit.putBoolean(KEY_USE_COMPASS, useCompass);
}
});
}
public static boolean isHelpShown() {
- return sharedPrefs.getInt(KEY_HELP_SHOWN, 0) != 0;
+ return sharedPrefs.getBoolean(KEY_HELP_SHOWN, false);
}
public static void setHelpShown() {
@@ -804,13 +860,13 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_HELP_SHOWN, 1);
+ edit.putBoolean(KEY_HELP_SHOWN, true);
}
});
}
public static boolean isLightSkin() {
- return sharedPrefs.getInt(KEY_SKIN, 0) != 0;
+ return sharedPrefs.getBoolean(KEY_SKIN, false);
}
public static void setLightSkin(final boolean lightSkin) {
@@ -818,7 +874,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_SKIN, lightSkin ? 1 : 0);
+ edit.putBoolean(KEY_SKIN, lightSkin);
}
});
}
@@ -860,6 +916,12 @@ public final class Settings {
return CacheType.getById(sharedPrefs.getString(KEY_CACHE_TYPE, CacheType.ALL.id));
}
+ /**
+ * The Threshold for the showing of child waypoints
+ *
+ * @return
+ */
+
public static int getWayPointsThreshold() {
return sharedPrefs.getInt(KEY_SHOW_WAYPOINTS_THRESHOLD, 0);
}
@@ -875,7 +937,7 @@ public final class Settings {
}
public static boolean isUseTwitter() {
- return 0 != sharedPrefs.getInt(KEY_USE_TWITTER, 0);
+ return sharedPrefs.getBoolean(KEY_USE_TWITTER, false);
}
public static void setUseTwitter(final boolean useTwitter) {
@@ -883,7 +945,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_USE_TWITTER, useTwitter ? 1 : 0);
+ edit.putBoolean(KEY_USE_TWITTER, useTwitter);
}
});
}
@@ -1017,8 +1079,23 @@ public final class Settings {
});
}
+
+ public static boolean isDebug() {
+ return Log.isDebug();
+ }
+
+ public static void setDebug(final boolean debug) {
+ editSharedSettings(new PrefRunnable() {
+
+ @Override public void edit(Editor edit) {
+ edit.putBoolean(KEY_DEBUG, debug);
+ }
+ });
+ Log.setDebugUnsaved(debug);
+ }
+
public static boolean getHideLiveMapHint() {
- return sharedPrefs.getInt(KEY_HIDE_LIVE_MAP_HINT, 0) == 0 ? false : true;
+ return sharedPrefs.getBoolean(KEY_HIDE_LIVE_MAP_HINT, false);
}
public static void setHideLiveHint(final boolean hide) {
@@ -1026,7 +1103,7 @@ public final class Settings {
@Override
public void edit(Editor edit) {
- edit.putInt(KEY_HIDE_LIVE_MAP_HINT, hide ? 1 : 0);
+ edit.putBoolean(KEY_HIDE_LIVE_MAP_HINT, hide);
}
});
}
@@ -1044,4 +1121,9 @@ public final class Settings {
}
});
}
+
+ public static String getPreferencesName() {
+ // there is currently no Android API to get the file name of the shared preferences
+ return cgeoapplication.getInstance().getPackageName() + "_preferences";
+ }
}
diff --git a/main/src/cgeo/geocaching/StaticMapsActivity.java b/main/src/cgeo/geocaching/StaticMapsActivity.java
index e7c975c..2e5f423 100644
--- a/main/src/cgeo/geocaching/StaticMapsActivity.java
+++ b/main/src/cgeo/geocaching/StaticMapsActivity.java
@@ -2,6 +2,7 @@ package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.enumerations.LoadFlags;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
@@ -13,7 +14,6 @@ import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -37,26 +37,20 @@ public class StaticMapsActivity extends AbstractActivity {
@Override
public void handleMessage(Message msg) {
+ if (waitDialog != null) {
+ waitDialog.dismiss();
+ }
try {
if (CollectionUtils.isEmpty(maps)) {
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
-
if ((waypoint_id != null && Settings.isStoreOfflineWpMaps()) || (waypoint_id == null && Settings.isStoreOfflineMaps())) {
- AlertDialog.Builder builder = new AlertDialog.Builder(StaticMapsActivity.this);
+ final AlertDialog.Builder builder = new AlertDialog.Builder(StaticMapsActivity.this);
builder.setMessage(R.string.err_detail_ask_store_map_static).setPositiveButton(android.R.string.yes, dialogClickListener)
.setNegativeButton(android.R.string.no, dialogClickListener).show();
} else {
showToast(res.getString(R.string.err_detail_not_load_map_static));
finish();
}
- return;
} else {
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
-
if (inflater == null) {
inflater = getLayoutInflater();
}
@@ -66,7 +60,7 @@ public class StaticMapsActivity extends AbstractActivity {
}
smapsView.removeAllViews();
- for (Bitmap image : maps) {
+ for (final Bitmap image : maps) {
if (image != null) {
final ImageView map = (ImageView) inflater.inflate(R.layout.map_static_item, null);
map.setImageBitmap(image);
@@ -75,10 +69,7 @@ public class StaticMapsActivity extends AbstractActivity {
}
}
} catch (Exception e) {
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
- Log.e(Settings.tag, "StaticMapsActivity.loadMapsHandler: " + e.toString());
+ Log.e("StaticMapsActivity.loadMapsHandler: " + e.toString());
}
}
};
@@ -160,7 +151,7 @@ public class StaticMapsActivity extends AbstractActivity {
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "StaticMapsActivity.LoadMapsThread.run.1: " + e.toString());
+ Log.e("StaticMapsActivity.LoadMapsThread.run.1: " + e.toString());
}
}
@@ -179,14 +170,14 @@ public class StaticMapsActivity extends AbstractActivity {
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "StaticMapsActivity.LoadMapsThread.run.2: " + e.toString());
+ Log.e("StaticMapsActivity.LoadMapsThread.run.2: " + e.toString());
}
}
}
loadMapsHandler.sendMessage(Message.obtain());
} catch (Exception e) {
- Log.e(Settings.tag, "StaticMapsActivity.LoadMapsThread.run: " + e.toString());
+ Log.e("StaticMapsActivity.LoadMapsThread.run: " + e.toString());
}
}
}
diff --git a/main/src/cgeo/geocaching/StaticMapsProvider.java b/main/src/cgeo/geocaching/StaticMapsProvider.java
index fcb8ed9..9fbf429 100644
--- a/main/src/cgeo/geocaching/StaticMapsProvider.java
+++ b/main/src/cgeo/geocaching/StaticMapsProvider.java
@@ -1,10 +1,11 @@
package cgeo.geocaching;
import cgeo.geocaching.concurrent.BlockingThreadPool;
-import cgeo.geocaching.concurrent.Task;
import cgeo.geocaching.files.LocalStorage;
import cgeo.geocaching.geopoint.GeopointFormatter.Format;
import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -12,7 +13,6 @@ import org.apache.http.HttpResponse;
import android.app.Activity;
import android.content.Context;
-import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
@@ -30,28 +30,43 @@ public class StaticMapsProvider {
return LocalStorage.getStorageFile(geocode, "map_" + prefix + level, false, createDirs);
}
- private static void downloadDifferentZooms(final cgCache cache, String markerUrl, String prefix, String latlonMap, int edge, String waypoints) {
- downloadMap(cache, 20, "satellite", markerUrl, prefix, 1, latlonMap, edge, waypoints);
- downloadMap(cache, 18, "satellite", markerUrl, prefix, 2, latlonMap, edge, waypoints);
- downloadMap(cache, 16, "roadmap", markerUrl, prefix, 3, latlonMap, edge, waypoints);
- downloadMap(cache, 14, "roadmap", markerUrl, prefix, 4, latlonMap, edge, waypoints);
- downloadMap(cache, 11, "roadmap", markerUrl, prefix, 5, latlonMap, edge, waypoints);
- }
-
- private static void downloadMap(cgCache cache, int zoom, String mapType, String markerUrl, String prefix, int level, String latlonMap, int edge, String waypoints) {
- final String mapUrl = "http://maps.google.com/maps/api/staticmap?center=" + latlonMap;
- final String url = mapUrl + "&zoom=" + zoom + "&size=" + edge + "x" + edge + "&maptype=" + mapType + "&markers=icon%3A" + markerUrl + "%7C" + latlonMap + waypoints + "&sensor=false";
- final File file = getMapFile(cache.getGeocode(), prefix, level, true);
- final HttpResponse httpResponse = Network.request(url, null, false);
+ private static void downloadDifferentZooms(final String geocode, String markerUrl, String prefix, String latlonMap, int edge, final Parameters waypoints) {
+ downloadMap(geocode, 20, "satellite", markerUrl, prefix, 1, latlonMap, edge, waypoints);
+ downloadMap(geocode, 18, "satellite", markerUrl, prefix, 2, latlonMap, edge, waypoints);
+ downloadMap(geocode, 16, "roadmap", markerUrl, prefix, 3, latlonMap, edge, waypoints);
+ downloadMap(geocode, 14, "roadmap", markerUrl, prefix, 4, latlonMap, edge, waypoints);
+ downloadMap(geocode, 11, "roadmap", markerUrl, prefix, 5, latlonMap, edge, waypoints);
+ }
+
+ private static void downloadMap(String geocode, int zoom, String mapType, String markerUrl, String prefix, int level, String latlonMap, int edge, final Parameters waypoints) {
+ final String mapUrl = "http://maps.google.com/maps/api/staticmap";
+ final Parameters params = new Parameters(
+ "center", latlonMap,
+ "zoom", String.valueOf(zoom),
+ "size", edge + "x" + edge,
+ "maptype", mapType,
+ "markers", "icon:" + markerUrl + '|' + latlonMap,
+ "sensor", "false");
+ if (waypoints != null) {
+ params.addAll(waypoints);
+ }
+ final HttpResponse httpResponse = Network.getRequest(mapUrl, params);
if (httpResponse != null) {
- if (LocalStorage.saveEntityToFile(httpResponse, file)) {
- // Delete image if it has no contents
- final long fileSize = file.length();
- if (fileSize < MIN_MAP_IMAGE_BYTES) {
- file.delete();
+ if (httpResponse.getStatusLine().getStatusCode() == 200) {
+ final File file = getMapFile(geocode, prefix, level, true);
+ if (LocalStorage.saveEntityToFile(httpResponse, file)) {
+ // Delete image if it has no contents
+ final long fileSize = file.length();
+ if (fileSize < MIN_MAP_IMAGE_BYTES) {
+ file.delete();
+ }
}
+ } else {
+ Log.d("StaticMapsProvider.downloadMap: httpResponseCode = " + httpResponse.getStatusLine().getStatusCode());
}
+ } else {
+ Log.e("StaticMapsProvider.downloadMap: httpResponse is null");
}
}
@@ -79,24 +94,24 @@ public class StaticMapsProvider {
// download static map for current waypoints
if (Settings.isStoreOfflineWpMaps() && CollectionUtils.isNotEmpty(cache.getWaypoints())) {
for (cgWaypoint waypoint : cache.getWaypoints()) {
- storeWaypointStaticMap(cache, edge, waypoint, false);
+ storeWaypointStaticMap(cache.getGeocode(), edge, waypoint, false);
}
}
}
public static void storeWaypointStaticMap(cgCache cache, Activity activity, cgWaypoint waypoint, boolean waitForResult) {
int edge = StaticMapsProvider.guessMinDisplaySide(activity);
- storeWaypointStaticMap(cache, edge, waypoint, waitForResult);
+ storeWaypointStaticMap(cache.getGeocode(), edge, waypoint, waitForResult);
}
- private static void storeWaypointStaticMap(cgCache cache, int edge, cgWaypoint waypoint, final boolean waitForResult) {
+ private static void storeWaypointStaticMap(final String geocode, int edge, cgWaypoint waypoint, final boolean waitForResult) {
if (waypoint.getCoords() == null) {
return;
}
String wpLatlonMap = waypoint.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA);
String wpMarkerUrl = getWpMarkerUrl(waypoint);
// download map images in separate background thread for higher performance
- downloadMaps(cache, wpMarkerUrl, "wp" + waypoint.getId() + "_", wpLatlonMap, edge, "", waitForResult);
+ downloadMaps(geocode, wpMarkerUrl, "wp" + waypoint.getId() + "_", wpLatlonMap, edge, null, waitForResult);
}
public static void storeCacheStaticMap(cgCache cache, Activity activity, final boolean waitForResult) {
@@ -104,30 +119,25 @@ public class StaticMapsProvider {
storeCacheStaticMap(cache, edge, waitForResult);
}
- private static void storeCacheStaticMap(cgCache cache, int edge, final boolean waitForResult) {
+ private static void storeCacheStaticMap(final cgCache cache, final int edge, final boolean waitForResult) {
final String latlonMap = cache.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA);
- final StringBuilder waypoints = new StringBuilder();
- if (cache.hasWaypoints()) {
- for (cgWaypoint waypoint : cache.getWaypoints()) {
- if (waypoint.getCoords() == null) {
- continue;
- }
- String wpMarkerUrl = getWpMarkerUrl(waypoint);
- waypoints.append("&markers=icon%3A");
- waypoints.append(wpMarkerUrl);
- waypoints.append("%7C");
- waypoints.append(waypoint.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA));
+ final Parameters waypoints = new Parameters();
+ for (final cgWaypoint waypoint : cache.getWaypoints()) {
+ if (waypoint.getCoords() == null) {
+ continue;
}
+ final String wpMarkerUrl = getWpMarkerUrl(waypoint);
+ waypoints.put("markers", "icon:" + wpMarkerUrl + "|" + waypoint.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA));
}
// download map images in separate background thread for higher performance
final String cacheMarkerUrl = getCacheMarkerUrl(cache);
- downloadMaps(cache, cacheMarkerUrl, "", latlonMap, edge, waypoints.toString(), waitForResult);
+ downloadMaps(cache.getGeocode(), cacheMarkerUrl, "", latlonMap, edge, waypoints, waitForResult);
}
private static int guessMinDisplaySide(Display display) {
final int maxWidth = display.getWidth() - 25;
final int maxHeight = display.getHeight() - 25;
- int edge = 0;
+ int edge;
if (maxWidth > maxHeight) {
edge = maxWidth;
} else {
@@ -140,22 +150,22 @@ public class StaticMapsProvider {
return guessMinDisplaySide(((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay());
}
- private static void downloadMaps(final cgCache cache, final String markerUrl, final String prefix, final String latlonMap, final int edge,
- final String waypoints, boolean waitForResult) {
+ private static void downloadMaps(final String geocode, final String markerUrl, final String prefix, final String latlonMap, final int edge,
+ final Parameters waypoints, boolean waitForResult) {
if (waitForResult) {
- downloadDifferentZooms(cache, markerUrl, prefix, latlonMap, edge, waypoints);
+ downloadDifferentZooms(geocode, markerUrl, prefix, latlonMap, edge, waypoints);
}
else {
- Task currentTask = new Task("getting static map") {
+ final Runnable currentTask = new Runnable() {
@Override
public void run() {
- downloadDifferentZooms(cache, markerUrl, prefix, latlonMap, edge, waypoints);
+ downloadDifferentZooms(geocode, markerUrl, prefix, latlonMap, edge, waypoints);
}
};
try {
pool.add(currentTask, 20, TimeUnit.SECONDS);
} catch (InterruptedException e) {
- Log.e(Settings.tag, "StaticMapsProvider.downloadMaps error adding task: " + e.toString());
+ Log.e("StaticMapsProvider.downloadMaps error adding task: " + e.toString());
}
}
}
@@ -168,12 +178,12 @@ public class StaticMapsProvider {
type += "_disabled";
}
- return Network.urlencode_rfc3986(MARKERS_URL + "marker_cache_" + type + ".png");
+ return MARKERS_URL + "marker_cache_" + type + ".png";
}
private static String getWpMarkerUrl(final cgWaypoint waypoint) {
String type = waypoint.getWaypointType() != null ? waypoint.getWaypointType().id : null;
- return Network.urlencode_rfc3986(MARKERS_URL + "marker_waypoint_" + type + ".png");
+ return MARKERS_URL + "marker_waypoint_" + type + ".png";
}
public static void removeWpStaticMaps(int wp_id, String geocode) {
@@ -183,7 +193,7 @@ public class StaticMapsProvider {
StaticMapsProvider.getMapFile(geocode, "wp" + wp_id + "_", level, false).delete();
}
} catch (Exception e) {
- Log.e(Settings.tag, "StaticMapsProvider.removeWpStaticMaps: " + e.toString());
+ Log.e("StaticMapsProvider.removeWpStaticMaps: " + e.toString());
}
}
}
diff --git a/main/src/cgeo/geocaching/StoredList.java b/main/src/cgeo/geocaching/StoredList.java
index 3b5a47a..eaf677d 100644
--- a/main/src/cgeo/geocaching/StoredList.java
+++ b/main/src/cgeo/geocaching/StoredList.java
@@ -1,5 +1,19 @@
package cgeo.geocaching;
+import cgeo.geocaching.activity.IAbstractActivity;
+import cgeo.geocaching.utils.RunnableWithArgument;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.view.View;
+import android.widget.EditText;
+
+import java.util.ArrayList;
+import java.util.List;
public class StoredList {
public static final int TEMPORARY_LIST_ID = 0;
@@ -18,4 +32,108 @@ public class StoredList {
public String getTitleAndCount() {
return title + " [" + count + "]";
}
+
+ public static class UserInterface {
+ private final IAbstractActivity activity;
+ private final cgeoapplication app;
+ private final Resources res;
+
+ public UserInterface(final IAbstractActivity activity) {
+ this.activity = activity;
+ app = cgeoapplication.getInstance();
+ res = app.getResources();
+ }
+
+ public void promptForListSelection(final int titleId, final RunnableWithArgument<Integer> runAfterwards) {
+ final List<StoredList> lists = app.getLists();
+
+ if (lists == null) {
+ return;
+ }
+
+ final List<CharSequence> listsTitle = new ArrayList<CharSequence>();
+ for (StoredList list : lists) {
+ listsTitle.add(list.getTitleAndCount());
+ }
+ listsTitle.add("<" + res.getString(R.string.list_menu_create) + ">");
+
+ final CharSequence[] items = new CharSequence[listsTitle.size()];
+
+ AlertDialog.Builder builder = new AlertDialog.Builder((Activity) activity);
+ builder.setTitle(res.getString(titleId));
+ builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialogInterface, int itemId) {
+ if (itemId >= lists.size()) {
+ // create new list on the fly
+ promptForListCreation(runAfterwards);
+ }
+ else {
+ if (runAfterwards != null) {
+ runAfterwards.run(lists.get(itemId).id);
+ }
+ }
+ }
+ });
+ builder.create().show();
+ }
+
+ public void promptForListCreation(final RunnableWithArgument<Integer> runAfterwards) {
+ handleListNameInput("", R.string.list_dialog_create_title, R.string.list_dialog_create, new RunnableWithArgument<String>() {
+
+ @Override
+ public void run(final String listName) {
+ final int newId = app.createList(listName);
+
+ if (newId >= cgData.customListIdOffset) {
+ activity.showToast(res.getString(R.string.list_dialog_create_ok));
+ if (runAfterwards != null) {
+ runAfterwards.run(newId);
+ }
+ } else {
+ activity.showToast(res.getString(R.string.list_dialog_create_err));
+ }
+ }
+ });
+ }
+
+ private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final RunnableWithArgument<String> runnable) {
+ final AlertDialog.Builder alert = new AlertDialog.Builder((Activity) activity);
+ final View view = ((Activity) activity).getLayoutInflater().inflate(R.layout.list_create_dialog, null);
+ final EditText input = (EditText) view.findViewById(R.id.text);
+ input.setText(defaultValue);
+
+ alert.setTitle(dialogTitle);
+ alert.setView(view);
+ alert.setPositiveButton(buttonTitle, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ // remove whitespaces added by autocompletion of Android keyboard
+ String listName = StringUtils.trim(input.getText().toString());
+ if (StringUtils.isNotBlank(listName)) {
+ runnable.run(listName);
+ }
+ }
+ });
+ alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ dialog.dismiss();
+ }
+ });
+
+ alert.show();
+ }
+
+ public void promptForListRename(final int listId, final Runnable runAfterRename) {
+ final StoredList list = app.getList(listId);
+ handleListNameInput(list.title, R.string.list_dialog_rename_title, R.string.list_dialog_rename, new RunnableWithArgument<String>() {
+
+ @Override
+ public void run(final String listName) {
+ app.renameList(listId, listName);
+ if (runAfterRename != null) {
+ runAfterRename.run();
+ }
+ }
+ });
+ }
+ }
}
diff --git a/main/src/cgeo/geocaching/TrackableLog.java b/main/src/cgeo/geocaching/TrackableLog.java
new file mode 100644
index 0000000..8e2ad90
--- /dev/null
+++ b/main/src/cgeo/geocaching/TrackableLog.java
@@ -0,0 +1,18 @@
+package cgeo.geocaching;
+
+import cgeo.geocaching.enumerations.LogTypeTrackable;
+
+public final class TrackableLog {
+ public TrackableLog(String trackCode, String name, int id, int ctl) {
+ this.trackCode = trackCode;
+ this.name = name;
+ this.id = id;
+ this.ctl = ctl;
+ }
+
+ public final int ctl;
+ public final int id;
+ public final String trackCode;
+ public final String name;
+ public LogTypeTrackable action = LogTypeTrackable.DO_NOTHING; // base.logTrackablesAction - no action
+}
diff --git a/main/src/cgeo/geocaching/UpdateLocationCallback.java b/main/src/cgeo/geocaching/UpdateLocationCallback.java
deleted file mode 100644
index f0334a1..0000000
--- a/main/src/cgeo/geocaching/UpdateLocationCallback.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package cgeo.geocaching;
-
-public interface UpdateLocationCallback {
- public void updateLocation(cgGeo geo);
-}
diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java
index f0acd97..72e70e9 100644
--- a/main/src/cgeo/geocaching/VisitCacheActivity.java
+++ b/main/src/cgeo/geocaching/VisitCacheActivity.java
@@ -1,18 +1,20 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.enumerations.LoadFlags;
-import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.LogTypeTrackable;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.gcvote.GCVote;
-import cgeo.geocaching.network.Login;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.twitter.Twitter;
import cgeo.geocaching.ui.DateDialog;
+import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.LogTemplateProvider;
import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate;
@@ -26,7 +28,6 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -64,12 +65,11 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
private List<LogType> possibleLogTypes = new ArrayList<LogType>();
private String[] viewstates = null;
private boolean gettingViewstate = true;
- private List<cgTrackableLog> trackables = null;
+ private List<TrackableLog> trackables = null;
private Calendar date = Calendar.getInstance();
private LogType typeSelected = LogType.LOG_UNKNOWN;
private int attempts = 0;
private Button postButton = null;
- private Button saveButton = null;
private Button clearButton = null;
private CheckBox tweetCheck = null;
private LinearLayout tweetBox = null;
@@ -88,16 +88,13 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
showToast(res.getString(R.string.info_log_type_changed));
}
- if (cgBase.isEmpty(viewstates) && attempts < 2) {
- final LoadDataThread thread;
- thread = new LoadDataThread();
- thread.start();
-
- return;
- } else if (cgBase.isEmpty(viewstates) && attempts >= 2) {
- showToast(res.getString(R.string.err_log_load_data));
- showProgress(false);
-
+ if (Login.isEmpty(viewstates)) {
+ if (attempts < 2) {
+ new LoadDataThread().start();
+ } else {
+ showToast(res.getString(R.string.err_log_load_data));
+ showProgress(false);
+ }
return;
}
@@ -114,7 +111,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
final LinearLayout inventoryView = (LinearLayout) findViewById(R.id.inventory);
inventoryView.removeAllViews();
- for (cgTrackableLog tb : trackables) {
+ for (TrackableLog tb : trackables) {
LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.visit_trackable, null);
((TextView) inventoryItem.findViewById(R.id.trackcode)).setText(tb.trackCode);
@@ -295,7 +292,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- SubMenu menuLog = null;
+ SubMenu menuLog;
menuLog = menu.addSubMenu(0, 0, 0, res.getString(R.string.log_add)).setIcon(android.R.drawable.ic_menu_add);
for (LogTemplate template : LogTemplateProvider.getTemplates()) {
@@ -336,7 +333,9 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
if (id == MENU_SIGNATURE) {
insertIntoLog(LogTemplateProvider.applyTemplates(Settings.getSignature(), false), true);
return true;
- } else if (id >= 10 && id <= 19) {
+ }
+
+ if (id >= 10 && id <= 19) {
rating = (id - 9) / 2.0;
if (rating < 1) {
rating = 0;
@@ -344,12 +343,13 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
updatePostButtonText();
return true;
}
+
final LogTemplate template = LogTemplateProvider.getTemplate(id);
if (template != null) {
- final String newText = template.getValue(false);
- insertIntoLog(newText, true);
+ insertIntoLog(template.getValue(false), true);
return true;
}
+
return false;
}
@@ -370,7 +370,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
if (viewId == R.id.type) {
for (final LogType typeOne : possibleLogTypes) {
menu.add(viewId, typeOne.id, 0, typeOne.getL10n());
- Log.w(Settings.tag, "Adding " + typeOne + " " + typeOne.getL10n());
+ Log.w("Adding " + typeOne + " " + typeOne.getL10n());
}
} else if (viewId == R.id.changebutton) {
final int textId = ((TextView) findViewById(viewId)).getId();
@@ -382,7 +382,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
} else {
final int realViewId = ((LinearLayout) findViewById(viewId)).getId();
- for (final cgTrackableLog tb : trackables) {
+ for (final TrackableLog tb : trackables) {
if (tb.id == realViewId) {
menu.setHeaderTitle(tb.name);
}
@@ -400,9 +400,10 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
if (group == R.id.type) {
setType(LogType.getById(id));
-
return true;
- } else if (group == R.id.changebutton) {
+ }
+
+ if (group == R.id.changebutton) {
try {
final LogTypeTrackable logType = LogTypeTrackable.findById(id);
if (logType != null) {
@@ -419,14 +420,14 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
}
tbText.setText(res.getString(logType.resourceId) + " â–¼");
}
- for (cgTrackableLog tb : trackables) {
+ for (TrackableLog tb : trackables) {
tb.action = logType;
}
tbChanged = true;
return true;
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeovisit.onContextItemSelected: " + e.toString());
+ Log.e("cgeovisit.onContextItemSelected: " + e.toString());
}
} else {
try {
@@ -442,21 +443,21 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
return false;
}
- for (cgTrackableLog tb : trackables) {
+ for (TrackableLog tb : trackables) {
if (tb.id == group) {
tbChanged = true;
tb.action = logType;
tbText.setText(res.getString(logType.resourceId) + " â–¼");
- Log.i(Settings.tag, "Trackable " + tb.trackCode + " (" + tb.name + ") has new action: #" + id);
+ Log.i("Trackable " + tb.trackCode + " (" + tb.name + ") has new action: #" + id);
}
}
return true;
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeovisit.onContextItemSelected: " + e.toString());
+ Log.e("cgeovisit.onContextItemSelected: " + e.toString());
}
}
@@ -471,11 +472,11 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
tweetBox = (LinearLayout) findViewById(R.id.tweet_box);
tweetCheck = (CheckBox) findViewById(R.id.tweet);
clearButton = (Button) findViewById(R.id.clear);
- saveButton = (Button) findViewById(R.id.save);
+ final Button saveButton = (Button) findViewById(R.id.save);
possibleLogTypes = cache.getPossibleLogTypes();
- final cgLog log = app.loadLogOffline(geocode);
+ final LogEntry log = app.loadLogOffline(geocode);
if (log != null) {
typeSelected = log.type;
date.setTime(new Date(log.date));
@@ -507,7 +508,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
});
final Button dateButton = (Button) findViewById(R.id.date);
- dateButton.setText(cgBase.formatShortDate(date.getTime().getTime()));
+ dateButton.setText(Formatter.formatShortDate(date.getTime().getTime()));
dateButton.setOnClickListener(new DateListener());
final EditText logView = (EditText) findViewById(R.id.log);
@@ -522,7 +523,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
lastState.restore(this);
}
- if (cgBase.isEmpty(viewstates)) {
+ if (Login.isEmpty(viewstates)) {
enablePostButton(false);
new LoadDataThread().start();
} else {
@@ -545,7 +546,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
date = dateIn;
final Button dateButton = (Button) findViewById(R.id.date);
- dateButton.setText(cgBase.formatShortDate(date.getTime().getTime()));
+ dateButton.setText(Formatter.formatShortDate(date.getTime().getTime()));
}
public void setType(LogType type) {
@@ -609,7 +610,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
setType(typeSelected);
final Button dateButton = (Button) findViewById(R.id.date);
- dateButton.setText(cgBase.formatShortDate(date.getTime().getTime()));
+ dateButton.setText(Formatter.formatShortDate(date.getTime().getTime()));
dateButton.setOnClickListener(new DateListener());
final EditText logView = (EditText) findViewById(R.id.log);
@@ -633,7 +634,6 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
}
if (!Settings.isLogin()) { // allow offline logging
showToast(res.getString(R.string.err_login));
- return;
}
}
@@ -656,19 +656,19 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
return;
}
- final String page = Network.getResponseData(Network.request("http://www.geocaching.com/seek/log.aspx", params, false, false, false));
+ final String page = Network.getResponseData(Network.getRequest("http://www.geocaching.com/seek/log.aspx", params));
viewstates = Login.getViewstates(page);
- trackables = cgBase.parseTrackableLog(page);
+ trackables = GCParser.parseTrackableLog(page);
- final List<LogType> typesPre = cgBase.parseTypes(page);
+ final List<LogType> typesPre = GCParser.parseTypes(page);
if (CollectionUtils.isNotEmpty(typesPre)) {
possibleLogTypes.clear();
possibleLogTypes.addAll(typesPre);
possibleLogTypes.remove(LogType.LOG_UPDATE_COORDINATES);
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeovisit.loadData.run: " + e.toString());
+ Log.e("cgeovisit.loadData.run: " + e.toString());
}
loadDataHandler.sendEmptyMessage(0);
@@ -695,34 +695,21 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
public StatusCode postLogFn(String log) {
try {
- final StatusCode status = cgBase.postLog(geocode, cacheid, viewstates, typeSelected,
+ final StatusCode status = GCParser.postLog(geocode, cacheid, viewstates, typeSelected,
date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE),
log, trackables);
if (status == StatusCode.NO_ERROR) {
- final cgLog logNow = new cgLog();
- logNow.author = Settings.getUsername();
- logNow.date = date.getTimeInMillis();
- logNow.type = typeSelected;
- logNow.log = log;
-
- if (cache != null) {
- cache.prependLog(logNow);
- }
- app.addLog(geocode, logNow);
+ final LogEntry logNow = new LogEntry(date, typeSelected, log);
+
+ cache.prependLog(logNow);
+ // app.saveLogs(cache);
if (typeSelected == LogType.LOG_FOUND_IT) {
- app.markFound(geocode);
- if (cache != null) {
- cache.setFound(true);
- }
+ cache.setFound(true);
}
- if (cache != null) {
- app.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE));
- } else {
- app.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE));
- }
+ app.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE));
}
if (status == StatusCode.NO_ERROR) {
@@ -741,7 +728,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
return status;
} catch (Exception e) {
- Log.e(Settings.tag, "cgeovisit.postLogFn: " + e.toString());
+ Log.e("cgeovisit.postLogFn: " + e.toString());
}
return StatusCode.LOG_POST_ERROR;
@@ -765,7 +752,7 @@ public class VisitCacheActivity extends AbstractActivity implements DateDialog.D
private class ActivityState {
private final String[] viewstates;
- private final List<cgTrackableLog> trackables;
+ private final List<TrackableLog> trackables;
private final int attempts;
private final List<LogType> possibleLogTypes;
private final LogType typeSelected;
diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java
index 8e8ad9d..8ddd21a 100644
--- a/main/src/cgeo/geocaching/activity/AbstractActivity.java
+++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java
@@ -2,11 +2,10 @@ package cgeo.geocaching.activity;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.compatibility.Compatibility;
-import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Cookies;
import android.app.Activity;
import android.content.Context;
@@ -85,10 +84,8 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi
res = this.getResources();
app = (cgeoapplication) this.getApplication();
- cgBase.initialize(app);
-
// Restore cookie store if needed
- Network.restoreCookieStore(Settings.getCookieStore());
+ Cookies.restoreCookieStore(Settings.getCookieStore());
ActivityMixin.keepScreenOn(this, keepScreenOn);
}
@@ -131,7 +128,7 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi
/**
* insert text into the EditText at the current cursor position
- *
+ *
* @param editText
* @param insertText
* @param moveCursor
diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java
index b3bbb3f..7af75b8 100644
--- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java
+++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java
@@ -1,6 +1,5 @@
package cgeo.geocaching.activity;
-import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.compatibility.Compatibility;
@@ -73,7 +72,6 @@ public abstract class AbstractListActivity extends ListActivity implements
// init
res = this.getResources();
app = (cgeoapplication) this.getApplication();
- cgBase.initialize(app);
ActivityMixin.keepScreenOn(this, keepScreenOn);
}
diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java
index 0e0041a..9b1bd2a 100644
--- a/main/src/cgeo/geocaching/activity/ActivityMixin.java
+++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java
@@ -40,7 +40,7 @@ public final class ActivityMixin {
fromActivity.finish();
}
- public final static void goManual(final Context context, final String helpTopic) {
+ public static void goManual(final Context context, final String helpTopic) {
if (StringUtils.isBlank(helpTopic)) {
return;
}
@@ -55,7 +55,7 @@ public final class ActivityMixin {
}
}
- public final static void setTitle(final Activity activity, final String text) {
+ public static void setTitle(final Activity activity, final String text) {
if (StringUtils.isBlank(text)) {
return;
}
@@ -66,7 +66,7 @@ public final class ActivityMixin {
}
}
- public final static void showProgress(final Activity activity, final boolean show) {
+ public static void showProgress(final Activity activity, final boolean show) {
if (activity == null) {
return;
}
@@ -79,7 +79,7 @@ public final class ActivityMixin {
}
}
- public final static void setTheme(final Activity activity) {
+ public static void setTheme(final Activity activity) {
if (Settings.isLightSkin()) {
activity.setTheme(R.style.light);
} else {
@@ -87,7 +87,7 @@ public final class ActivityMixin {
}
}
- public final static void showToast(final Activity activity, final String text) {
+ public static void showToast(final Activity activity, final String text) {
if (StringUtils.isNotBlank(text)) {
Toast toast = Toast.makeText(activity, text, Toast.LENGTH_LONG);
@@ -96,7 +96,7 @@ public final class ActivityMixin {
}
}
- public final static void showShortToast(final Activity activity, final String text) {
+ public static void showShortToast(final Activity activity, final String text) {
if (StringUtils.isNotBlank(text)) {
Toast toast = Toast.makeText(activity, text, Toast.LENGTH_SHORT);
@@ -105,7 +105,7 @@ public final class ActivityMixin {
}
}
- public static final void helpDialog(final Activity activity, final String title, final String message, final Drawable icon) {
+ public static void helpDialog(final Activity activity, final String title, final String message, final Drawable icon) {
if (StringUtils.isBlank(message)) {
return;
}
diff --git a/main/src/cgeo/geocaching/activity/IAbstractActivity.java b/main/src/cgeo/geocaching/activity/IAbstractActivity.java
index dd22cff..2503b99 100644
--- a/main/src/cgeo/geocaching/activity/IAbstractActivity.java
+++ b/main/src/cgeo/geocaching/activity/IAbstractActivity.java
@@ -1,8 +1,5 @@
package cgeo.geocaching.activity;
-import cgeo.geocaching.cgCache;
-
-import android.view.Menu;
import android.view.View;
public interface IAbstractActivity {
@@ -13,19 +10,11 @@ public interface IAbstractActivity {
public void goManual(View view);
- public void showProgress(final boolean show);
-
- public void setTheme();
-
public void showToast(String text);
public void showShortToast(String text);
public void helpDialog(String title, String message);
- public void setTitle(final String title);
-
- void addVisitMenu(Menu menu, cgCache cache);
-
public void invalidateOptionsMenuCompatible();
}
diff --git a/main/src/cgeo/geocaching/activity/Progress.java b/main/src/cgeo/geocaching/activity/Progress.java
index 70f829d..dbe4700 100644
--- a/main/src/cgeo/geocaching/activity/Progress.java
+++ b/main/src/cgeo/geocaching/activity/Progress.java
@@ -13,6 +13,7 @@ public class Progress {
private ProgressDialog dialog;
private int progress = 0;
+ private int progressDivider = 1;
public synchronized void dismiss() {
if (dialog != null && dialog.isShowing()) {
@@ -65,16 +66,19 @@ public class Progress {
public synchronized void setMaxProgressAndReset(final int max) {
if (dialog != null && dialog.isShowing()) {
- dialog.setMax(max);
+ final int modMax = max / this.progressDivider;
+ dialog.setMax(modMax);
dialog.setProgress(0);
}
+ this.progress = 0;
}
public synchronized void setProgress(final int progress) {
+ final int modProgress = progress / this.progressDivider;
if (dialog != null && dialog.isShowing()) {
- dialog.setProgress(progress);
+ dialog.setProgress(modProgress);
}
- this.progress = progress;
+ this.progress = modProgress;
}
public synchronized int getProgress() {
@@ -83,4 +87,8 @@ public class Progress {
}
return this.progress;
}
+
+ public synchronized void setProgressDivider(final int progressDivider) {
+ this.progressDivider = progressDivider;
+ }
}
diff --git a/main/src/cgeo/geocaching/apps/AbstractApp.java b/main/src/cgeo/geocaching/apps/AbstractApp.java
index 1161a05..f79afe0 100644
--- a/main/src/cgeo/geocaching/apps/AbstractApp.java
+++ b/main/src/cgeo/geocaching/apps/AbstractApp.java
@@ -33,8 +33,7 @@ public abstract class AbstractApp implements App {
try {
// This can throw an exception where the exception type is only defined on API Level > 3
// therefore surround with try-catch
- final Intent intent = packageManager.getLaunchIntentForPackage(packageName);
- return intent;
+ return packageManager.getLaunchIntentForPackage(packageName);
} catch (Exception e) {
return null;
}
diff --git a/main/src/cgeo/geocaching/apps/AbstractLocusApp.java b/main/src/cgeo/geocaching/apps/AbstractLocusApp.java
index 46105cd..6a239a6 100644
--- a/main/src/cgeo/geocaching/apps/AbstractLocusApp.java
+++ b/main/src/cgeo/geocaching/apps/AbstractLocusApp.java
@@ -1,7 +1,6 @@
package cgeo.geocaching.apps;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.enumerations.CacheSize;
@@ -37,6 +36,10 @@ public abstract class AbstractLocusApp extends AbstractApp {
super(getString(R.string.caches_map_locus), INTENT);
}
+ protected AbstractLocusApp(final String text, final String intent) {
+ super(text, intent);
+ }
+
@Override
public boolean isInstalled(Context context) {
return LocusUtils.isLocusAvailable(context);
@@ -52,7 +55,7 @@ public abstract class AbstractLocusApp extends AbstractApp {
* @param activity
* @author koem
*/
- protected static boolean showInLocus(final List<? extends Object> objectsToShow, final boolean withCacheWaypoints,
+ protected static boolean showInLocus(final List<?> objectsToShow, final boolean withCacheWaypoints, final boolean export,
final Activity activity) {
if (objectsToShow == null || objectsToShow.isEmpty()) {
return false;
@@ -78,13 +81,13 @@ public abstract class AbstractLocusApp extends AbstractApp {
}
if (pd.getPoints().size() <= 1000) {
- DisplayData.sendData(activity, pd, false);
+ DisplayData.sendData(activity, pd, export);
} else {
final ArrayList<PointsData> data = new ArrayList<PointsData>();
data.add(pd);
DisplayData.sendDataCursor(activity, data,
"content://" + LocusDataStorageProvider.class.getCanonicalName().toLowerCase(),
- false);
+ export);
}
return true;
@@ -108,7 +111,7 @@ public abstract class AbstractLocusApp extends AbstractApp {
}
// create one simple point with location
- final Location loc = new Location(Settings.tag);
+ final Location loc = new Location("cgeo");
loc.setLatitude(cache.getCoords().getLatitude());
loc.setLongitude(cache.getCoords().getLongitude());
@@ -124,7 +127,7 @@ public abstract class AbstractLocusApp extends AbstractApp {
pg.name = cache.getName();
pg.placedBy = cache.getOwner();
if (cache.getHiddenDate() != null) {
- pg.hidden = ISO8601DATE.format(Long.valueOf(cache.getHiddenDate().getTime()));
+ pg.hidden = ISO8601DATE.format(cache.getHiddenDate().getTime());
}
int locusId = toLocusType(cache.getType());
if (locusId != NO_LOCUS_ID) {
@@ -187,7 +190,7 @@ public abstract class AbstractLocusApp extends AbstractApp {
}
// create one simple point with location
- final Location loc = new Location(Settings.tag);
+ final Location loc = new Location("cgeo");
loc.setLatitude(waypoint.getCoords().getLatitude());
loc.setLongitude(waypoint.getCoords().getLongitude());
diff --git a/main/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java b/main/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java
index a845108..49db025 100644
--- a/main/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java
+++ b/main/src/cgeo/geocaching/apps/cache/GeneralAppsFactory.java
@@ -1,13 +1,12 @@
package cgeo.geocaching.apps.cache;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.apps.AbstractAppFactory;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.ArrayUtils;
import android.app.Activity;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -37,7 +36,7 @@ public final class GeneralAppsFactory extends AbstractAppFactory {
try {
return app.invoke(activity, cache);
} catch (Exception e) {
- Log.e(Settings.tag, "GeneralAppsFactory.onMenuItemSelected: " + e.toString());
+ Log.e("GeneralAppsFactory.onMenuItemSelected: " + e.toString());
}
}
return false;
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java b/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java
index bf7ebb1..16b641e 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.geopoint.Geopoint;
@@ -24,7 +24,7 @@ abstract class AbstractPointNavigationApp extends AbstractNavigationApp {
}
@Override
- public final boolean invoke(cgGeo geo, Activity activity, cgCache cache, cgWaypoint waypoint, Geopoint coords) {
+ public final boolean invoke(IGeoData geo, Activity activity, cgCache cache, cgWaypoint waypoint, Geopoint coords) {
if (cache == null && waypoint == null && coords == null) {
return false;
}
@@ -46,13 +46,24 @@ abstract class AbstractPointNavigationApp extends AbstractNavigationApp {
protected abstract void navigate(Activity activity, Geopoint point);
- private static Geopoint getCoordinates(cgCache cache, cgWaypoint waypoint, Geopoint coords) {
+ /**
+ * Return the first of the cache coordinates, the waypoint coordinates or the extra coordinates. <code>null</code>
+ * entities are skipped.
+ *
+ * @param cache a cache
+ * @param waypoint a waypoint
+ * @param coords extra coordinates
+ * @return the first non-null coordinates, or null if none are set
+ */
+ private static Geopoint getCoordinates(final cgCache cache, final cgWaypoint waypoint, final Geopoint coords) {
if (cache != null && cache.getCoords() != null) {
return cache.getCoords();
}
- else if (waypoint != null && waypoint.getCoords() != null) {
+
+ if (waypoint != null && waypoint.getCoords() != null) {
return waypoint.getCoords();
}
+
return coords;
}
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java b/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java
index 3d804d9..720b85a 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.cgeonavigate;
import cgeo.geocaching.geopoint.Geopoint;
@@ -22,7 +22,7 @@ class CompassApp extends AbstractNavigationApp {
}
@Override
- public boolean invoke(cgGeo geo, Activity activity, cgCache cache,
+ public boolean invoke(IGeoData geo, Activity activity, cgCache cache,
cgWaypoint waypoint, final Geopoint coords) {
if (cache != null && cache.getGeocode() != null) {
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java
index 649823a..24aa693 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/GoogleMapsApp.java
@@ -1,15 +1,14 @@
package cgeo.geocaching.apps.cache.navi;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.utils.Log;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.util.Log;
class GoogleMapsApp extends AbstractPointNavigationApp {
@@ -32,7 +31,7 @@ class GoogleMapsApp extends AbstractPointNavigationApp {
} catch (Exception e) {
// nothing
}
- Log.i(Settings.tag, "cgBase.runExternalMap: No maps application available.");
+ Log.i("cgBase.runExternalMap: No maps application available.");
ActivityMixin.showToast(activity, getString(R.string.err_application_no));
}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java b/main/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java
index f94a623..fb72157 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/GoogleNavigationApp.java
@@ -1,18 +1,18 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
+import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
-import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.utils.Log;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.util.Log;
class GoogleNavigationApp extends AbstractNavigationApp {
@@ -26,7 +26,7 @@ class GoogleNavigationApp extends AbstractNavigationApp {
}
@Override
- public boolean invoke(final cgGeo geo, final Activity activity, final cgCache cache, final cgWaypoint waypoint, final Geopoint coords) {
+ public boolean invoke(final IGeoData geo, final Activity activity, final cgCache cache, final cgWaypoint waypoint, final Geopoint coords) {
if (activity == null) {
return false;
}
@@ -50,8 +50,8 @@ class GoogleNavigationApp extends AbstractNavigationApp {
return true;
}
- private static boolean navigateToCoordinates(cgGeo geo, Activity activity, final Geopoint coords) {
- final Geopoint coordsNow = geo == null ? null : geo.coordsNow;
+ private static boolean navigateToCoordinates(IGeoData geo, Activity activity, final Geopoint coords) {
+ final Geopoint coordsNow = geo == null ? null : geo.getCoords();
// Google Navigation
if (Settings.isUseGoogleNavigation()) {
@@ -84,8 +84,7 @@ class GoogleNavigationApp extends AbstractNavigationApp {
// nothing
}
- Log.i(Settings.tag,
- "cgBase.runNavigation: No navigation application available.");
+ Log.i("cgBase.runNavigation: No navigation application available.");
return false;
}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java b/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java
index 44f151e..2f05459 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.geopoint.Geopoint;
@@ -18,7 +18,7 @@ class InternalMap extends AbstractNavigationApp {
}
@Override
- public boolean invoke(cgGeo geo, Activity activity, cgCache cache,
+ public boolean invoke(IGeoData geo, Activity activity, cgCache cache,
cgWaypoint waypoint, final Geopoint coords) {
if (cache != null) {
CGeoMap.startActivityGeoCode(activity, cache.getGeocode());
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java b/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java
index 260d933..60e3315 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java
@@ -1,9 +1,9 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
+import cgeo.geocaching.apps.AbstractLocusApp;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
-import cgeo.geocaching.apps.AbstractLocusApp;
import cgeo.geocaching.geopoint.Geopoint;
import android.app.Activity;
@@ -20,7 +20,7 @@ class LocusApp extends AbstractLocusApp implements NavigationApp {
* @author koem
*/
@Override
- public boolean invoke(cgGeo geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint coords) {
+ public boolean invoke(IGeoData geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint coords) {
final ArrayList<Object> points = new ArrayList<Object>();
@@ -34,7 +34,7 @@ class LocusApp extends AbstractLocusApp implements NavigationApp {
points.add(waypoint);
}
- return showInLocus(points, true, activity);
+ return showInLocus(points, true, false, activity);
}
}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java
index 119d27b..62629de 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigationApp.java
@@ -1,15 +1,15 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
+import cgeo.geocaching.apps.App;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
-import cgeo.geocaching.apps.App;
import cgeo.geocaching.geopoint.Geopoint;
import android.app.Activity;
public interface NavigationApp extends App {
- public boolean invoke(final cgGeo geo, final Activity activity,
+ public boolean invoke(final IGeoData geo, final Activity activity,
final cgCache cache, final cgWaypoint waypoint,
final Geopoint coords);
}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java
index e2a1fc1..6f179ab 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java
@@ -1,28 +1,24 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
-import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.StaticMapsProvider;
+import cgeo.geocaching.apps.AbstractAppFactory;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.cgeoapplication;
-import cgeo.geocaching.apps.AbstractAppFactory;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
import android.widget.ArrayAdapter;
-import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
@@ -66,6 +62,16 @@ public final class NavigationAppFactory extends AbstractAppFactory {
* The id - used in c:geo settings
*/
public final int id;
+
+ /*
+ * display app name in array adapter
+ *
+ * @see java.lang.Enum#toString()
+ */
+ @Override
+ public String toString() {
+ return app.getName();
+ }
}
/**
@@ -73,7 +79,7 @@ public final class NavigationAppFactory extends AbstractAppFactory {
* A dialog is created for tool selection and the selected tool is started afterwards.
* <p />
* Delegates to
- * {@link #showNavigationMenu(cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint, boolean, boolean)} with
+ * {@link #showNavigationMenu(IGeoData, Activity, cgCache, cgWaypoint, Geopoint, boolean, boolean)} with
* <code>showInternalMap = true</code> and <code>showDefaultNavigation = false</code>
*
* @param geo
@@ -82,7 +88,7 @@ public final class NavigationAppFactory extends AbstractAppFactory {
* @param waypoint
* @param destination
*/
- public static void showNavigationMenu(final cgGeo geo, final Activity activity,
+ public static void showNavigationMenu(final IGeoData geo, final Activity activity,
final cgCache cache, final cgWaypoint waypoint, final Geopoint destination) {
showNavigationMenu(geo, activity, cache, waypoint, destination, true, false);
}
@@ -104,9 +110,9 @@ public final class NavigationAppFactory extends AbstractAppFactory {
* @param showDefaultNavigation
* should be <code>false</code> by default
*
- * @see #showNavigationMenu(cgGeo, Activity, cgCache, cgWaypoint, Geopoint)
+ * @see #showNavigationMenu(IGeoData, Activity, cgCache, cgWaypoint, Geopoint)
*/
- public static void showNavigationMenu(final cgGeo geo, final Activity activity,
+ public static void showNavigationMenu(final IGeoData geo, final Activity activity,
final cgCache cache, final cgWaypoint waypoint, final Geopoint destination,
final boolean showInternalMap, final boolean showDefaultNavigation) {
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
@@ -127,24 +133,9 @@ public final class NavigationAppFactory extends AbstractAppFactory {
}
/*
* Using an ArrayAdapter with list of NavigationAppsEnum items avoids
- * handling between mapping list positions allows us to do dynamic filtering of the list based on usecase.
+ * handling between mapping list positions allows us to do dynamic filtering of the list based on use case.
*/
- final ArrayAdapter<NavigationAppsEnum> adapter = new ArrayAdapter<NavigationAppsEnum>(activity, android.R.layout.select_dialog_item, items) {
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- TextView textView = (TextView) super.getView(position, convertView, parent);
- textView.setText(getItem(position).app.getName());
- return textView;
- }
-
- @Override
- public View getDropDownView(int position, View convertView, ViewGroup parent) {
- TextView textView = (TextView) super.getDropDownView(position, convertView, parent);
- textView.setText(getItem(position).app.getName());
- return textView;
- }
- };
- adapter.setDropDownViewResource(android.R.layout.select_dialog_item);
+ final ArrayAdapter<NavigationAppsEnum> adapter = new ArrayAdapter<NavigationAppsEnum>(activity, android.R.layout.select_dialog_item, items);
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
@@ -196,10 +187,10 @@ public final class NavigationAppFactory extends AbstractAppFactory {
/**
* Adds the installed navigation tools to the given menu.
- * Use {@link #onMenuItemSelected(MenuItem, cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint)} on
+ * Use {@link #onMenuItemSelected(MenuItem, IGeoData, Activity, cgCache, cgWaypoint, Geopoint)} on
* selection event to start the selected navigation tool.
*
- * <b>Only use this way if {@link #showNavigationMenu(cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint)}
+ * <b>Only use this way if {@link #showNavigationMenu(IGeoData, Activity, cgCache, cgWaypoint, Geopoint)}
* is not suitable for the given usecase.</b>
*
* @param menu
@@ -211,11 +202,11 @@ public final class NavigationAppFactory extends AbstractAppFactory {
/**
* Adds the installed navigation tools to the given menu.
- * Use {@link #onMenuItemSelected(MenuItem, cgGeo, Activity, cgCache, cgWaypoint, Geopoint)} on
+ * Use {@link #onMenuItemSelected(MenuItem, IGeoData, Activity, cgCache, cgWaypoint, Geopoint)} on
* selection event to start the selected navigation tool.
*
* <b>Only use this way if
- * {@link #showNavigationMenu(cgGeo, Activity, cgCache, cgWaypoint, Geopoint, boolean, boolean)} is
+ * {@link #showNavigationMenu(IGeoData, Activity, cgCache, cgWaypoint, Geopoint, boolean, boolean)} is
* not suitable for the given usecase.</b>
*
* @param menu
@@ -247,7 +238,7 @@ public final class NavigationAppFactory extends AbstractAppFactory {
* @return
*/
public static boolean onMenuItemSelected(final MenuItem item,
- final cgGeo geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint destination) {
+ final IGeoData geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint destination) {
if (cache == null && waypoint == null && destination == null) {
return false;
}
@@ -257,7 +248,7 @@ public final class NavigationAppFactory extends AbstractAppFactory {
try {
return app.invoke(geo, activity, cache, waypoint, destination);
} catch (Exception e) {
- Log.e(Settings.tag, "NavigationAppFactory.onMenuItemSelected: " + e.toString());
+ Log.e("NavigationAppFactory.onMenuItemSelected: " + e.toString());
}
}
return false;
@@ -279,11 +270,10 @@ public final class NavigationAppFactory extends AbstractAppFactory {
* @param geo
* @param activity
* @param cache
- * @param search
* @param waypoint
* @param destination
*/
- public static void startDefaultNavigationApplication(final cgGeo geo, Activity activity, cgCache cache,
+ public static void startDefaultNavigationApplication(final IGeoData geo, Activity activity, cgCache cache,
cgWaypoint waypoint, final Geopoint destination) {
final NavigationApp app = getDefaultNavigationApplication(activity);
@@ -291,22 +281,21 @@ public final class NavigationAppFactory extends AbstractAppFactory {
try {
app.invoke(geo, activity, cache, waypoint, destination);
} catch (Exception e) {
- Log.e(Settings.tag, "NavigationAppFactory.startDefaultNavigationApplication: " + e.toString());
+ Log.e("NavigationAppFactory.startDefaultNavigationApplication: " + e.toString());
}
}
}
/**
* Starts the second default navigation tool if correctly set and installed or the compass app as default fallback.
- *
+ *
* @param geo
* @param activity
* @param cache
- * @param search
* @param waypoint
* @param destination
*/
- public static void startDefaultNavigationApplication2(final cgGeo geo, Activity activity, cgCache cache,
+ public static void startDefaultNavigationApplication2(final IGeoData geo, Activity activity, cgCache cache,
cgWaypoint waypoint, final Geopoint destination) {
final NavigationApp app = getDefaultNavigationApplication2(activity);
@@ -314,14 +303,14 @@ public final class NavigationAppFactory extends AbstractAppFactory {
try {
app.invoke(geo, activity, cache, waypoint, destination);
} catch (Exception e) {
- Log.e(Settings.tag, "NavigationAppFactory.startDefaultNavigationApplication2: " + e.toString());
+ Log.e("NavigationAppFactory.startDefaultNavigationApplication2: " + e.toString());
}
}
}
/**
* Returns the default navigation tool if correctly set and installed or the compass app as default fallback
- *
+ *
* @param activity
* @return never <code>null</code>
*/
@@ -341,7 +330,7 @@ public final class NavigationAppFactory extends AbstractAppFactory {
/**
* Returns the second default navigation tool if correctly set and installed or the compass app as default fallback
- *
+ *
* @param activity
* @return never <code>null</code>
*/
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java
index a87e61b..9af90ac 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter.Format;
@@ -21,7 +21,7 @@ class RMapsApp extends AbstractNavigationApp {
}
@Override
- public boolean invoke(cgGeo geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint coords) {
+ public boolean invoke(IGeoData geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint coords) {
try {
final ArrayList<String> locations = new ArrayList<String>();
if (cache != null && cache.getCoords() != null) {
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java
index a0eb5a1..d8b66c2 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java
@@ -1,11 +1,12 @@
package cgeo.geocaching.apps.cache.navi;
+import cgeo.geocaching.IGeoData;
+import cgeo.geocaching.ILogable;
import cgeo.geocaching.R;
import cgeo.geocaching.StaticMapsActivity;
+import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
-import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.geopoint.Geopoint;
import android.app.Activity;
@@ -24,26 +25,21 @@ class StaticMapApp extends AbstractNavigationApp {
}
@Override
- public boolean invoke(cgGeo geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint coords) {
-
- String geocode = null;
- if (cache != null && cache.getListId() != 0) {
- geocode = cache.getGeocode().toUpperCase();
- }
- if (waypoint != null) {
- geocode = waypoint.getGeocode().toUpperCase();
- }
+ public boolean invoke(IGeoData geo, Activity activity, cgCache cache, cgWaypoint waypoint, final Geopoint coords) {
+ final ILogable logable = cache != null && cache.getListId() != 0 ? cache : waypoint;
+ final String geocode = logable.getGeocode().toUpperCase();
if (geocode == null) {
ActivityMixin.showToast(activity, getString(R.string.err_detail_no_map_static));
return true;
- } else {
- final Intent intent = new Intent(activity, StaticMapsActivity.class);
- intent.putExtra("geocode", geocode);
- if (waypoint != null) {
- intent.putExtra("waypoint", waypoint.getId());
- }
- activity.startActivity(intent);
- return true;
}
+
+ final Intent intent = new Intent(activity, StaticMapsActivity.class);
+ intent.putExtra("geocode", geocode);
+ if (waypoint != null) {
+ intent.putExtra("waypoint", waypoint.getId());
+ }
+ activity.startActivity(intent);
+
+ return true;
}
}
diff --git a/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java b/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java
index 621aea4..45ebaff 100644
--- a/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java
+++ b/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java
@@ -1,9 +1,9 @@
package cgeo.geocaching.apps.cachelist;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.apps.App;
+import cgeo.geocaching.cgCache;
import android.app.Activity;
@@ -11,7 +11,7 @@ import java.util.List;
interface CacheListApp extends App {
- boolean invoke(final cgGeo geo, final List<cgCache> caches,
+ boolean invoke(final IGeoData geo, final List<cgCache> caches,
final Activity activity, final SearchResult search);
}
diff --git a/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java b/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java
index fd19353..fef9d2d 100644
--- a/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java
+++ b/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java
@@ -1,18 +1,15 @@
package cgeo.geocaching.apps.cachelist;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.apps.AbstractAppFactory;
-
-import org.apache.commons.lang3.ArrayUtils;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.utils.Log;
import android.app.Activity;
import android.content.res.Resources;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
@@ -21,15 +18,12 @@ import java.util.ArrayList;
import java.util.List;
public final class CacheListAppFactory extends AbstractAppFactory {
- private static CacheListApp[] apps = new CacheListApp[] {};
-
- private static CacheListApp[] getMultiPointNavigationApps() {
- if (ArrayUtils.isEmpty(apps)) {
- apps = new CacheListApp[] {
- new InternalCacheListMap(),
- new LocusCacheListApp() };
- }
- return apps;
+ private static class LazyHolder {
+ public static final CacheListApp[] apps = {
+ new InternalCacheListMap(),
+ new LocusCacheListApp(false),
+ new LocusCacheListApp(true)
+ };
}
/**
@@ -38,41 +32,41 @@ public final class CacheListAppFactory extends AbstractAppFactory {
* @param res
* @return the added menu item (also for a sub menu, then the menu item in the parent menu is returned)
*/
- public static MenuItem addMenuItems(Menu menu,
- Activity activity, Resources res) {
- List<CacheListApp> activeApps = new ArrayList<CacheListApp>();
- for (CacheListApp app : getMultiPointNavigationApps()) {
+ public static MenuItem addMenuItems(final Menu menu, final Activity activity, final Resources res) {
+ final List<CacheListApp> activeApps = new ArrayList<CacheListApp>(LazyHolder.apps.length);
+ for (final CacheListApp app : LazyHolder.apps) {
if (app.isInstalled(activity)) {
activeApps.add(app);
}
}
// use a new sub menu, if more than one app is available
- if (activeApps.size() > 1) {
- SubMenu subMenu = menu.addSubMenu(0, 101, 0,
- res.getString(R.string.caches_on_map)).setIcon(
- android.R.drawable.ic_menu_mapmode);
- for (CacheListApp app : activeApps) {
- subMenu.add(0, app.getId(), 0, app.getName());
- }
- return subMenu.getItem();
- } else if (activeApps.size() == 1) {
- return menu.add(0, activeApps.get(0).getId(), 0,
- activeApps.get(0).getName()).setIcon(android.R.drawable.ic_menu_mapmode);
+ switch (activeApps.size()) {
+ case 0:
+ return null;
+ case 1:
+ return menu.add(0, activeApps.get(0).getId(), 0,
+ activeApps.get(0).getName()).setIcon(android.R.drawable.ic_menu_mapmode);
+ default:
+ final SubMenu subMenu = menu.addSubMenu(0, 101, 0,
+ res.getString(R.string.caches_on_map)).setIcon(android.R.drawable.ic_menu_mapmode);
+ for (final CacheListApp app : activeApps) {
+ subMenu.add(0, app.getId(), 0, app.getName());
+ }
+ return subMenu.getItem();
}
- return null;
}
public static boolean onMenuItemSelected(final MenuItem item,
- final cgGeo geo, final List<cgCache> caches, final IAbstractActivity activity,
+ final IGeoData geo, final List<cgCache> caches, final IAbstractActivity activity,
final SearchResult search) {
- CacheListApp app = (CacheListApp) getAppFromMenuItem(item, apps);
+ final CacheListApp app = (CacheListApp) getAppFromMenuItem(item, LazyHolder.apps);
if (app != null) {
try {
boolean result = app.invoke(geo, caches, (Activity) activity, search);
activity.invalidateOptionsMenuCompatible();
return result;
} catch (Exception e) {
- Log.e(Settings.tag, "CacheListAppFactory.onMenuItemSelected: " + e.toString());
+ Log.e("CacheListAppFactory.onMenuItemSelected: " + e.toString());
}
}
return false;
diff --git a/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java b/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java
index 5eaefc9..f450bbc 100644
--- a/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java
+++ b/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java
@@ -1,10 +1,10 @@
package cgeo.geocaching.apps.cachelist;
+import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.apps.AbstractApp;
+import cgeo.geocaching.cgCache;
import cgeo.geocaching.maps.CGeoMap;
import android.app.Activity;
@@ -24,7 +24,7 @@ class InternalCacheListMap extends AbstractApp implements CacheListApp {
}
@Override
- public boolean invoke(cgGeo geo, List<cgCache> caches, Activity activity, final SearchResult search) {
+ public boolean invoke(IGeoData geo, List<cgCache> caches, Activity activity, final SearchResult search) {
CGeoMap.startActivitySearch(activity, search, null);
return true;
}
diff --git a/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java b/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java
index 0c5455c..b7557c3 100644
--- a/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java
+++ b/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java
@@ -1,18 +1,27 @@
package cgeo.geocaching.apps.cachelist;
+import cgeo.geocaching.IGeoData;
+import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.apps.AbstractLocusApp;
+import cgeo.geocaching.cgCache;
import org.apache.commons.collections.CollectionUtils;
import android.app.Activity;
+import android.content.Intent;
import java.util.List;
class LocusCacheListApp extends AbstractLocusApp implements CacheListApp {
+ private boolean export;
+
+ public LocusCacheListApp(boolean export) {
+ super(getString(export ? R.string.caches_map_locus_export : R.string.caches_map_locus), Intent.ACTION_VIEW);
+ this.export = export;
+ }
+
/**
* show caches in Locus
*
@@ -20,12 +29,12 @@ class LocusCacheListApp extends AbstractLocusApp implements CacheListApp {
* @author koem
*/
@Override
- public boolean invoke(cgGeo geo, List<cgCache> cacheList, Activity activity, final SearchResult search) {
+ public boolean invoke(IGeoData geo, List<cgCache> cacheList, Activity activity, final SearchResult search) {
if (CollectionUtils.isEmpty(cacheList)) {
return false;
}
- showInLocus(cacheList, false, activity);
+ showInLocus(cacheList, false, export, activity);
return true;
}
diff --git a/main/src/cgeo/geocaching/backup/CentralBackupAgent.java b/main/src/cgeo/geocaching/backup/CentralBackupAgent.java
index 28b9e4b..aef2b7b 100644
--- a/main/src/cgeo/geocaching/backup/CentralBackupAgent.java
+++ b/main/src/cgeo/geocaching/backup/CentralBackupAgent.java
@@ -7,11 +7,11 @@ import android.app.backup.SharedPreferencesBackupHelper;
public class CentralBackupAgent extends BackupAgentHelper {
- static final String PREFS_BACKUP_KEY = "prefs";
+ private static final String PREFS_BACKUP_KEY = "prefs";
@Override
public void onCreate() {
- SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, Settings.preferences);
+ final SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, Settings.getPreferencesName());
addHelper(PREFS_BACKUP_KEY, helper);
}
diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/cgCache.java
index b7f49e1..a426614 100644
--- a/main/src/cgeo/geocaching/cgCache.java
+++ b/main/src/cgeo/geocaching/cgCache.java
@@ -9,13 +9,15 @@ import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.gc.Tile;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
+import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag;
+import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.geopoint.GeopointParser;
+import cgeo.geocaching.network.HtmlImage;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.LogTemplateProvider;
import org.apache.commons.collections.CollectionUtils;
@@ -26,8 +28,9 @@ import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Handler;
+import android.os.Message;
+import android.text.Html;
import android.text.Spannable;
-import android.util.Log;
import java.util.ArrayList;
import java.util.Calendar;
@@ -43,7 +46,7 @@ import java.util.regex.Pattern;
/**
* Internal c:geo representation of a "cache"
*/
-public class cgCache implements ICache {
+public class cgCache implements ICache, IWaypoint {
private long updated = 0;
private long detailedUpdate = 0;
@@ -88,7 +91,7 @@ public class cgCache implements ICache {
private List<String> attributes = null;
private List<cgWaypoint> waypoints = null;
private ArrayList<cgImage> spoilers = null;
- private List<cgLog> logs = null;
+ private List<LogEntry> logs = null;
private List<cgTrackable> inventory = null;
private Map<LogType, Integer> logCounts = new HashMap<LogType, Integer>();
private boolean logOffline = false;
@@ -100,7 +103,7 @@ public class cgCache implements ICache {
private String nameForSorting;
private final EnumSet<StorageLocation> storageLocation = EnumSet.of(StorageLocation.HEAP);
private boolean finalDefined = false;
- private int zoomlevel = Tile.ZOOMLEVEL_MAX;
+ private int zoomlevel = Tile.ZOOMLEVEL_MAX + 1;
private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");
@@ -295,7 +298,7 @@ public class cgCache implements ICache {
/**
* Compare two caches quickly. For map and list fields only the references are compared !
*
- * @param other
+ * @param other the other cache to compare this one to
* @return true if both caches have the same content
*/
private boolean isEqualTo(final cgCache other) {
@@ -309,7 +312,7 @@ public class cgCache implements ICache {
premiumMembersOnly == other.premiumMembersOnly &&
difficulty == other.difficulty &&
terrain == other.terrain &&
- (coords != null ? coords.isEqualTo(other.coords) : null == other.coords) &&
+ (coords != null ? coords.equals(other.coords) : null == other.coords) &&
reliableLatLon == other.reliableLatLon &&
disabled == other.disabled &&
archived == other.archived &&
@@ -366,50 +369,33 @@ public class cgCache implements ICache {
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
- if (hidden.compareTo(cal.getTime()) < 0) {
- return false;
- }
- return true;
+ return hidden.compareTo(cal.getTime()) >= 0;
}
/**
- * checks if a page contains the guid of a cache
+ * Checks if a page contains the guid of a cache
*
- * @param cache
- * the cache to look for
* @param page
- * the page to search in
- *
- * @return true: page contains guid of cache, false: otherwise
+ * the page to search in, may be null
+ * @return true if the page contains the guid of the cache, false otherwise
*/
- boolean isGuidContainedInPage(final String page) {
- if (StringUtils.isBlank(page)) {
- return false;
- }
- // check if the guid of the cache is anywhere in the page
- if (StringUtils.isBlank(guid)) {
- return false;
- }
- Pattern patternOk = Pattern.compile(guid, Pattern.CASE_INSENSITIVE);
- Matcher matcherOk = patternOk.matcher(page);
- if (matcherOk.find()) {
- Log.i(Settings.tag, "cgCache.isGuidContainedInPage: guid '" + guid + "' found");
- return true;
- } else {
- Log.i(Settings.tag, "cgCache.isGuidContainedInPage: guid '" + guid + "' not found");
+ public boolean isGuidContainedInPage(final String page) {
+ if (StringUtils.isBlank(page) || StringUtils.isBlank(guid)) {
return false;
}
+ final Boolean found = Pattern.compile(guid, Pattern.CASE_INSENSITIVE).matcher(page).find();
+ Log.i("cgCache.isGuidContainedInPage: guid '" + guid + "' " + (found ? "" : "not ") + "found");
+ return found;
}
public boolean isEventCache() {
- return CacheType.EVENT == cacheType || CacheType.MEGA_EVENT == cacheType
- || CacheType.CITO == cacheType || CacheType.LOSTANDFOUND == cacheType;
+ return cacheType.isEvent();
}
- public boolean logVisit(IAbstractActivity fromActivity) {
+ public void logVisit(final IAbstractActivity fromActivity) {
if (StringUtils.isBlank(cacheId)) {
fromActivity.showToast(((Activity) fromActivity).getResources().getString(R.string.err_cannot_log_visit));
- return true;
+ return;
}
Intent logVisitIntent = new Intent((Activity) fromActivity, VisitCacheActivity.class);
logVisitIntent.putExtra(VisitCacheActivity.EXTRAS_ID, cacheId);
@@ -417,18 +403,12 @@ public class cgCache implements ICache {
logVisitIntent.putExtra(VisitCacheActivity.EXTRAS_FOUND, found);
((Activity) fromActivity).startActivity(logVisitIntent);
-
- return true;
}
- public boolean logOffline(final IAbstractActivity fromActivity, final LogType logType) {
- String log = "";
- if (StringUtils.isNotBlank(Settings.getSignature())
- && Settings.isAutoInsertSignature()) {
- log = LogTemplateProvider.applyTemplates(Settings.getSignature(), true);
- }
- logOffline(fromActivity, log, Calendar.getInstance(), logType);
- return true;
+ public void logOffline(final IAbstractActivity fromActivity, final LogType logType) {
+ final boolean mustIncludeSignature = StringUtils.isNotBlank(Settings.getSignature()) && Settings.isAutoInsertSignature();
+ final String initial = mustIncludeSignature ? LogTemplateProvider.applyTemplates(Settings.getSignature(), true) : "";
+ logOffline(fromActivity, initial, Calendar.getInstance(), logType);
}
void logOffline(final IAbstractActivity fromActivity, final String log, Calendar date, final LogType logType) {
@@ -523,16 +503,6 @@ public class cgCache implements ICache {
}
@Override
- public String getLatitude() {
- return coords != null ? coords.format(GeopointFormatter.Format.LAT_DECMINUTE) : null;
- }
-
- @Override
- public String getLongitude() {
- return coords != null ? coords.format(GeopointFormatter.Format.LON_DECMINUTE) : null;
- }
-
- @Override
public String getOwner() {
return owner;
}
@@ -938,14 +908,10 @@ public class cgCache implements ICache {
}
}
- if (saveToDatabase) {
- return cgeoapplication.getInstance().saveWaypoints(geocode, waypoints, false);
- }
-
- return false;
+ return saveToDatabase && cgeoapplication.getInstance().saveWaypoints(this);
}
- public List<cgLog> getLogs() {
+ public List<LogEntry> getLogs() {
return getLogs(true);
}
@@ -954,15 +920,15 @@ public class cgCache implements ICache {
* true for all logs, false for friend logs only
* @return the logs with all entries or just the entries of the friends, never <code>null</code>
*/
- public List<cgLog> getLogs(boolean allLogs) {
+ public List<LogEntry> getLogs(boolean allLogs) {
if (logs == null) {
return Collections.emptyList();
}
if (allLogs) {
return logs;
}
- ArrayList<cgLog> friendLogs = new ArrayList<cgLog>();
- for (cgLog log : logs) {
+ ArrayList<LogEntry> friendLogs = new ArrayList<LogEntry>();
+ for (LogEntry log : logs) {
if (log.friend) {
friendLogs.add(log);
}
@@ -974,7 +940,7 @@ public class cgCache implements ICache {
* @param logs
* the log entries
*/
- public void setLogs(List<cgLog> logs) {
+ public void setLogs(List<LogEntry> logs) {
this.logs = logs;
}
@@ -1133,8 +1099,8 @@ public class cgCache implements ICache {
* @param storageLocation
* the storageLocation to set
*/
- public void addStorageLocation(StorageLocation sl) {
- this.storageLocation.add(sl);
+ public void addStorageLocation(final StorageLocation storageLocation) {
+ this.storageLocation.add(storageLocation);
}
/**
@@ -1167,11 +1133,7 @@ public class cgCache implements ICache {
resetFinalDefined();
}
- if (saveToDatabase) {
- return cgeoapplication.getInstance().saveOwnWaypoint(waypoint.getId(), geocode, waypoint);
- }
-
- return false;
+ return saveToDatabase && cgeoapplication.getInstance().saveOwnWaypoint(waypoint.getId(), geocode, waypoint);
}
public boolean hasWaypoints() {
@@ -1209,30 +1171,23 @@ public class cgCache implements ICache {
}
/**
- * @param index
- * @return <code>true</code>, if the waypoint was duplicated
+ * Duplicate a waypoint.
+ *
+ * @param index the waypoint to duplicate
+ * @return <code>true</code> if the waypoint was duplicated, <code>false</code> otherwise (invalid index)
*/
- public boolean duplicateWaypoint(int index) {
- if (!isValidWaypointIndex(index)) {
+ public boolean duplicateWaypoint(final int index) {
+ final cgWaypoint original = getWaypoint(index);
+ if (original == null) {
return false;
}
- final cgWaypoint copy = new cgWaypoint(waypoints.get(index));
+ final cgWaypoint copy = new cgWaypoint(original);
copy.setUserDefined();
copy.setName(cgeoapplication.getInstance().getString(R.string.waypoint_copy_of) + " " + copy.getName());
waypoints.add(index + 1, copy);
return cgeoapplication.getInstance().saveOwnWaypoint(-1, geocode, copy);
}
- private boolean isValidWaypointIndex(int index) {
- if (!hasWaypoints()) {
- return false;
- }
- if (index < 0 || index >= waypoints.size()) {
- return false;
- }
- return true;
- }
-
/**
* delete a user defined waypoint
*
@@ -1240,11 +1195,11 @@ public class cgCache implements ICache {
* of the waypoint in cache's waypoint list
* @return <code>true</code>, if the waypoint was deleted
*/
- public boolean deleteWaypoint(int index) {
- if (!isValidWaypointIndex(index)) {
+ public boolean deleteWaypoint(final int index) {
+ final cgWaypoint waypoint = getWaypoint(index);
+ if (waypoint == null) {
return false;
}
- final cgWaypoint waypoint = waypoints.get(index);
if (waypoint.isUserDefined()) {
waypoints.remove(index);
cgeoapplication.getInstance().deleteWaypoint(waypoint.getId());
@@ -1265,17 +1220,13 @@ public class cgCache implements ICache {
* to be removed from cache
* @return <code>true</code>, if the waypoint was deleted
*/
- public boolean deleteWaypoint(cgWaypoint waypoint) {
+ public boolean deleteWaypoint(final cgWaypoint waypoint) {
if (waypoint.getId() <= 0) {
return false;
}
final int index = getWaypointIndex(waypoint);
- if (index >= 0) {
- return deleteWaypoint(index);
- }
-
- return false;
+ return index >= 0 && deleteWaypoint(index);
}
/**
@@ -1283,38 +1234,36 @@ public class cgCache implements ICache {
*
* @param waypoint
* to find index for
- * @return index in <code>waypoints</code> if found, else -1
+ * @return index in <code>waypoints</code> if found, -1 otherwise
*/
- private int getWaypointIndex(cgWaypoint waypoint) {
- int index = 0;
-
- for (cgWaypoint wp : waypoints) {
- if (wp.getId() == waypoint.getId()) {
+ private int getWaypointIndex(final cgWaypoint waypoint) {
+ final int id = waypoint.getId();
+ for (int index = 0; index < waypoints.size(); index++) {
+ if (waypoints.get(index).getId() == id) {
return index;
}
- index++;
}
-
return -1;
}
/**
- * @param index
- * @return waypoint or <code>null</code>
+ * Retrieve a given waypoint.
+ *
+ * @param index the index of the waypoint
+ * @return waypoint or <code>null</code> if index is out of range
*/
- public cgWaypoint getWaypoint(int index) {
- if (!isValidWaypointIndex(index)) {
- return null;
- }
- return waypoints.get(index);
+ public cgWaypoint getWaypoint(final int index) {
+ return waypoints != null && index >= 0 && index < waypoints.size() ? waypoints.get(index) : null;
}
/**
- * @param index
+ * Lookup a waypoint by its id.
+ *
+ * @param id the id of the waypoint to look for
* @return waypoint or <code>null</code>
*/
- public cgWaypoint getWaypointById(int id) {
- for (cgWaypoint waypoint : waypoints) {
+ public cgWaypoint getWaypointById(final int id) {
+ for (final cgWaypoint waypoint : waypoints) {
if (waypoint.getId() == id) {
return waypoint;
}
@@ -1333,16 +1282,16 @@ public class cgCache implements ICache {
Matcher matcher = coordPattern.matcher(note);
while (matcher.find()) {
try {
- final Geopoint point = GeopointParser.parse(note.substring(matcher.start()));
+ final Geopoint point = new Geopoint(note.substring(matcher.start()));
// coords must have non zero latitude and longitude and at least one part shall have fractional degrees
- if (point != null && point.getLatitudeE6() != 0 && point.getLongitudeE6() != 0 && ((point.getLatitudeE6() % 1000) != 0 || (point.getLongitudeE6() % 1000) != 0)) {
+ if (point.getLatitudeE6() != 0 && point.getLongitudeE6() != 0 && ((point.getLatitudeE6() % 1000) != 0 || (point.getLongitudeE6() % 1000) != 0)) {
final String name = cgeoapplication.getInstance().getString(R.string.cache_personal_note) + " " + count;
final cgWaypoint waypoint = new cgWaypoint(name, WaypointType.WAYPOINT, false);
waypoint.setCoords(point);
addWaypoint(waypoint, false);
count++;
}
- } catch (GeopointParser.ParseException e) {
+ } catch (Geopoint.ParseException e) {
// ignore
}
@@ -1350,7 +1299,7 @@ public class cgCache implements ICache {
matcher = coordPattern.matcher(note);
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgCache.parseWaypointsFromNote: " + e.toString());
+ Log.e("cgCache.parseWaypointsFromNote: " + e.toString());
}
}
@@ -1365,16 +1314,16 @@ public class cgCache implements ICache {
return attributes != null && attributes.size() > 0;
}
- public void prependLog(final cgLog log) {
+ public void prependLog(final LogEntry log) {
if (logs == null) {
- logs = new ArrayList<cgLog>();
+ logs = new ArrayList<LogEntry>();
}
logs.add(0, log);
}
- public void appendLog(final cgLog log) {
+ public void appendLog(final LogEntry log) {
if (logs == null) {
- logs = new ArrayList<cgLog>();
+ logs = new ArrayList<LogEntry>();
}
logs.add(log);
}
@@ -1403,20 +1352,198 @@ public class cgCache implements ICache {
if (!(obj instanceof cgCache)) {
return false;
}
- // just compare the geocode even if that is not what "equals" normaly does
- return geocode != null ? geocode.compareTo(((cgCache) obj).geocode) == 0 : false;
+ // just compare the geocode even if that is not what "equals" normally does
+ return StringUtils.isNotBlank(geocode) && geocode.equals(((cgCache) obj).geocode);
}
public void store(Activity activity, CancellableHandler handler) {
final int listId = Math.max(getListId(), StoredList.STANDARD_LIST_ID);
- cgBase.storeCache(activity, this, null, listId, handler);
- }
-
- public int getZoomlevel() {
- return this.zoomlevel;
+ storeCache(activity, this, null, listId, false, handler);
}
public void setZoomlevel(int zoomlevel) {
this.zoomlevel = zoomlevel;
}
+
+ @Override
+ public int getId() {
+ return 0;
+ }
+
+ @Override
+ public WaypointType getWaypointType() {
+ return null;
+ }
+
+ @Override
+ public String getCoordType() {
+ return "cache";
+ }
+
+ public void drop(Handler handler) {
+ try {
+ cgeoapplication.getInstance().markDropped(Collections.singletonList(this));
+ cgeoapplication.getInstance().removeCache(getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE));
+
+ handler.sendMessage(Message.obtain());
+ } catch (Exception e) {
+ Log.e("cache.drop: ", e);
+ }
+ }
+
+ public void checkFields() {
+ if (StringUtils.isBlank(getGeocode())) {
+ Log.e("cgBase.loadLogsFromDetails: geo code not parsed correctly");
+ }
+ if (StringUtils.isBlank(getName())) {
+ Log.e("name not parsed correctly");
+ }
+ if (StringUtils.isBlank(getGuid())) {
+ Log.e("guid not parsed correctly");
+ }
+ if (getTerrain() == 0.0) {
+ Log.e("terrain not parsed correctly");
+ }
+ if (getDifficulty() == 0.0) {
+ Log.e("difficulty not parsed correctly");
+ }
+ if (StringUtils.isBlank(getOwner())) {
+ Log.e("owner not parsed correctly");
+ }
+ if (StringUtils.isBlank(getOwnerReal())) {
+ Log.e("owner real not parsed correctly");
+ }
+ if (getHiddenDate() == null) {
+ Log.e("hidden not parsed correctly");
+ }
+ if (getFavoritePoints() < 0) {
+ Log.e("favoriteCount not parsed correctly");
+ }
+ if (getSize() == null) {
+ Log.e("size not parsed correctly");
+ }
+ if (getType() == null || getType() == CacheType.UNKNOWN) {
+ Log.e("type not parsed correctly");
+ }
+ if (getCoords() == null) {
+ Log.e("coordinates not parsed correctly");
+ }
+ if (StringUtils.isBlank(getLocation())) {
+ Log.e("location not parsed correctly");
+ }
+ }
+
+ public void refresh(Activity activity, int newListId, CancellableHandler handler) {
+ cgeoapplication.getInstance().removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE));
+ storeCache(activity, null, geocode, newListId, true, handler);
+ }
+
+ public static void storeCache(Activity activity, cgCache origCache, String geocode, int listId, boolean forceRedownload, CancellableHandler handler) {
+ try {
+ cgCache cache;
+ // get cache details, they may not yet be complete
+ if (origCache != null) {
+ // only reload the cache if it was already stored or doesn't have full details (by checking the description)
+ if (origCache.getListId() >= StoredList.STANDARD_LIST_ID || StringUtils.isBlank(origCache.getDescription())) {
+ final SearchResult search = searchByGeocode(origCache.getGeocode(), null, listId, false, handler);
+ cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
+ } else {
+ cache = origCache;
+ }
+ } else if (StringUtils.isNotBlank(geocode)) {
+ final SearchResult search = searchByGeocode(geocode, null, listId, forceRedownload, handler);
+ cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
+ } else {
+ cache = null;
+ }
+
+ if (cache == null) {
+ if (handler != null) {
+ handler.sendMessage(Message.obtain());
+ }
+
+ return;
+ }
+
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
+ final HtmlImage imgGetter = new HtmlImage(activity, cache.getGeocode(), false, listId, true);
+
+ // store images from description
+ if (StringUtils.isNotBlank(cache.getDescription())) {
+ Html.fromHtml(cache.getDescription(), imgGetter, null);
+ }
+
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
+ // store spoilers
+ if (CollectionUtils.isNotEmpty(cache.getSpoilers())) {
+ for (cgImage oneSpoiler : cache.getSpoilers()) {
+ imgGetter.getDrawable(oneSpoiler.getUrl());
+ }
+ }
+
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
+ // store images from logs
+ if (Settings.isStoreLogImages()) {
+ for (LogEntry log : cache.getLogs(true)) {
+ if (log.hasLogImages()) {
+ for (cgImage oneLogImg : log.getLogImages()) {
+ imgGetter.getDrawable(oneLogImg.getUrl());
+ }
+ }
+ }
+ }
+
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
+ // store map previews
+ StaticMapsProvider.downloadMaps(cache, activity);
+
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
+ cache.setListId(listId);
+ cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
+
+ if (handler != null) {
+ handler.sendMessage(Message.obtain());
+ }
+ } catch (Exception e) {
+ Log.e("cgBase.storeCache");
+ }
+ }
+
+ public static SearchResult searchByGeocode(final String geocode, final String guid, final int listId, final boolean forceReload, final CancellableHandler handler) {
+ if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) {
+ Log.e("cgeoBase.searchByGeocode: No geocode nor guid given");
+ return null;
+ }
+
+ cgeoapplication app = cgeoapplication.getInstance();
+ if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) {
+ final SearchResult search = new SearchResult();
+ final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : app.getGeocode(guid);
+ search.addGeocode(realGeocode);
+ return search;
+ }
+
+ // if we have no geocode, we can't dynamically select the handler, but must explicitly use GC
+ if (geocode == null && guid != null) {
+ return GCConnector.getInstance().searchByGeocode(null, guid, app, handler);
+ }
+
+ return ConnectorFactory.getConnector(geocode).searchByGeocode(geocode, guid, app, handler);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/cgCoord.java b/main/src/cgeo/geocaching/cgCoord.java
deleted file mode 100644
index 236b8f5..0000000
--- a/main/src/cgeo/geocaching/cgCoord.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package cgeo.geocaching;
-
-import cgeo.geocaching.enumerations.CacheSize;
-import cgeo.geocaching.enumerations.CacheType;
-import cgeo.geocaching.enumerations.WaypointType;
-import cgeo.geocaching.geopoint.Geopoint;
-
-public class cgCoord implements IBasicCache, IWaypoint {
-
- private int id = 0; // only valid if constructed with a waypoint
- private WaypointType waypointType = null; // only valid if constructed with a waypoint
- private String guid = null; // only valid if constructed with a cache
- private CacheType cacheType = null; // only valid if constructed with a cache
- private String geocode = "";
- private String coordType = "cache"; // used values: { cache, waypoint }
- private String typeSpec = CacheType.TRADITIONAL.id;
- private String name = "";
- private boolean found = false;
- private boolean disabled = false;
- private Geopoint coords = new Geopoint(0, 0);
- private float difficulty = 0;
- private float terrain = 0;
- private CacheSize size = CacheSize.UNKNOWN;
-
- public cgCoord() {
- }
-
- public cgCoord(cgCache cache) {
- guid = cache.getGuid();
- disabled = cache.isDisabled();
- found = cache.isFound();
- geocode = cache.getGeocode();
- coords = cache.getCoords();
- name = cache.getName();
- coordType = "cache";
- typeSpec = cache.getType().id;
- difficulty = cache.getDifficulty();
- terrain = cache.getTerrain();
- size = cache.getSize();
- cacheType = cache.getType();
- }
-
- public cgCoord(cgWaypoint waypoint) {
- id = waypoint.getId();
- disabled = false;
- found = false;
- geocode = waypoint.getGeocode();
- coords = waypoint.getCoords();
- name = waypoint.getName();
- coordType = "waypoint";
- typeSpec = waypoint.getWaypointType() != null ? waypoint.getWaypointType().id : null;
- waypointType = waypoint.getWaypointType();
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- @Override
- public String getGeocode() {
- return geocode;
- }
-
- public void setGeocode(String geocode) {
- this.geocode = geocode;
- }
-
- public String getCoordType() {
- return coordType;
- }
-
- public void setCoordType(String type) {
- this.coordType = type;
- }
-
- public String getTypeSpec() {
- return typeSpec;
- }
-
- public void setTypeSpec(String typeSpec) {
- this.typeSpec = typeSpec;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- @Override
- public boolean isFound() {
- return found;
- }
-
- public void setFound(boolean found) {
- this.found = found;
- }
-
- @Override
- public boolean isDisabled() {
- return disabled;
- }
-
- public void setDisabled(boolean disabled) {
- this.disabled = disabled;
- }
-
- public Geopoint getCoords() {
- return coords;
- }
-
- public void setCoords(Geopoint coords) {
- this.coords = coords;
- }
-
- @Override
- public float getDifficulty() {
- return difficulty;
- }
-
- public void setDifficulty(float difficulty) {
- this.difficulty = difficulty;
- }
-
- @Override
- public float getTerrain() {
- return terrain;
- }
-
- public void setTerrain(float terrain) {
- this.terrain = terrain;
- }
-
- @Override
- public CacheSize getSize() {
- return size;
- }
-
- public void setSize(CacheSize size) {
- this.size = size;
- }
-
- public void setGuid(String guid) {
- this.guid = guid;
- }
-
- @Override
- public String getGuid() {
- return guid;
- }
-
- @Override
- public WaypointType getWaypointType() {
- return waypointType;
- }
-
- @Override
- public CacheType getType() {
- return cacheType;
- }
-}
diff --git a/main/src/cgeo/geocaching/cgData.java b/main/src/cgeo/geocaching/cgData.java
index 3f48b07..fd90a02 100644
--- a/main/src/cgeo/geocaching/cgData.java
+++ b/main/src/cgeo/geocaching/cgData.java
@@ -10,6 +10,8 @@ import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.files.LocalStorage;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
@@ -24,7 +26,6 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDoneException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
-import android.util.Log;
import java.io.File;
import java.util.ArrayList;
@@ -57,6 +58,8 @@ public class cgData {
"inventoryunknown", "onWatchlist", "personal_note", "reliable_latlon", "coordsChanged", "finalDefined"
// reason is replaced by listId in cgCache
};
+ /** The list of fields needed for mapping. */
+ private static final String[] WAYPOINT_COLUMNS = new String[] { "_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude", "longitude", "note", "own" };
/** Number of days (as ms) after temporarily saved caches are deleted */
private static long DAYS_AFTER_CACHE_IS_DELETED = 3 * 24 * 60 * 60 * 1000;
@@ -68,11 +71,11 @@ public class cgData {
private Context context = null;
private CacheCache cacheCache = null;
private String path = null;
- private cgDbHelper dbHelper = null;
+ private DbHelper dbHelper = null;
private SQLiteDatabase databaseRO = null;
private SQLiteDatabase databaseRW = null;
private static final int dbVersion = 62;
- private static final int customListIdOffset = 10;
+ public static final int customListIdOffset = 10;
private static final String dbName = "data";
private static final String dbTableCaches = "cg_caches";
private static final String dbTableLists = "cg_lists";
@@ -260,28 +263,28 @@ public class cgData {
if (databaseRW == null || !databaseRW.isOpen()) {
try {
if (dbHelper == null) {
- dbHelper = new cgDbHelper(context);
+ dbHelper = new DbHelper(context);
}
databaseRW = dbHelper.getWritableDatabase();
if (databaseRW != null && databaseRW.isOpen()) {
- Log.i(Settings.tag, "Connection to RW database established.");
+ Log.i("Connection to RW database established.");
} else {
- Log.e(Settings.tag, "Failed to open connection to RW database.");
+ Log.e("Failed to open connection to RW database.");
}
if (databaseRW != null && databaseRW.inTransaction()) {
databaseRW.endTransaction();
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.openDb.RW: " + e.toString());
+ Log.e("cgData.openDb.RW: " + e.toString());
}
}
if (databaseRO == null || !databaseRO.isOpen()) {
try {
if (dbHelper == null) {
- dbHelper = new cgDbHelper(context);
+ dbHelper = new DbHelper(context);
}
databaseRO = dbHelper.getReadableDatabase();
@@ -290,16 +293,16 @@ public class cgData {
}
if (databaseRO != null && databaseRO.isOpen()) {
- Log.i(Settings.tag, "Connection to RO database established.");
+ Log.i("Connection to RO database established.");
} else {
- Log.e(Settings.tag, "Failed to open connection to RO database.");
+ Log.e("Failed to open connection to RO database.");
}
if (databaseRO != null && databaseRO.inTransaction()) {
databaseRO.endTransaction();
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.openDb.RO: " + e.toString());
+ Log.e("cgData.openDb.RO: " + e.toString());
}
}
@@ -324,7 +327,7 @@ public class cgData {
databaseRO = null;
SQLiteDatabase.releaseMemory();
- Log.d(Settings.tag, "Closing RO database");
+ Log.d("Closing RO database");
}
if (databaseRW != null) {
@@ -338,7 +341,7 @@ public class cgData {
databaseRW = null;
SQLiteDatabase.releaseMemory();
- Log.d(Settings.tag, "Closing RW database");
+ Log.d("Closing RW database");
}
if (dbHelper != null) {
@@ -359,7 +362,7 @@ public class cgData {
public String backupDatabase() {
if (!LocalStorage.isExternalStorageAvailable()) {
- Log.w(Settings.tag, "Database wasn't backed up: no external memory");
+ Log.w("Database wasn't backed up: no external memory");
return null;
}
@@ -368,27 +371,23 @@ public class cgData {
final boolean backupDone = LocalStorage.copy(new File(path), target);
init();
- if (backupDone) {
- Log.i(Settings.tag, "Database was copied to " + target);
- return target.getPath();
- } else {
- Log.e(Settings.tag, "Database could not be copied to " + target);
+ if (!backupDone) {
+ Log.e("Database could not be copied to " + target);
return null;
}
+
+ Log.i("Database was copied to " + target);
+ return target.getPath();
}
public static File isRestoreFile() {
final File fileSourceFile = backupFile();
- if (fileSourceFile.exists()) {
- return fileSourceFile;
- } else {
- return null;
- }
+ return fileSourceFile.exists() ? fileSourceFile : null;
}
public boolean restoreDatabase() {
if (!LocalStorage.isExternalStorageAvailable()) {
- Log.w(Settings.tag, "Database wasn't restored: no external memory");
+ Log.w("Database wasn't restored: no external memory");
return false;
}
@@ -398,17 +397,17 @@ public class cgData {
init();
if (restoreDone) {
- Log.i(Settings.tag, "Database succesfully restored from " + sourceFile.getPath());
+ Log.i("Database succesfully restored from " + sourceFile.getPath());
} else {
- Log.e(Settings.tag, "Could not restore database from " + sourceFile.getPath());
+ Log.e("Could not restore database from " + sourceFile.getPath());
}
return restoreDone;
}
- private static class cgDbHelper extends SQLiteOpenHelper {
+ private static class DbHelper extends SQLiteOpenHelper {
- cgDbHelper(Context context) {
+ DbHelper(Context context) {
super(context, dbName, null, dbVersion);
}
@@ -451,7 +450,7 @@ public class cgData {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.i(Settings.tag, "Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": start");
+ Log.i("Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": start");
try {
if (db.isReadOnly()) {
@@ -464,284 +463,19 @@ public class cgData {
dropDatabase(db);
onCreate(db);
- Log.i(Settings.tag, "Database structure created.");
+ Log.i("Database structure created.");
}
if (oldVersion > 0) {
db.execSQL("delete from " + dbTableCaches + " where reason = 0");
- if (oldVersion < 34) { // upgrade to 34
- try {
- db.execSQL("create index if not exists in_a on " + dbTableCaches + " (geocode)");
- db.execSQL("create index if not exists in_b on " + dbTableCaches + " (guid)");
- db.execSQL("create index if not exists in_c on " + dbTableCaches + " (reason)");
- db.execSQL("create index if not exists in_d on " + dbTableCaches + " (detailed)");
- db.execSQL("create index if not exists in_e on " + dbTableCaches + " (type)");
- db.execSQL("create index if not exists in_a on " + dbTableAttributes + " (geocode)");
- db.execSQL("create index if not exists in_a on " + dbTableWaypoints + " (geocode)");
- db.execSQL("create index if not exists in_b on " + dbTableWaypoints + " (geocode, type)");
- db.execSQL("create index if not exists in_a on " + dbTableSpoilers + " (geocode)");
- db.execSQL("create index if not exists in_a on " + dbTableLogs + " (geocode)");
- db.execSQL("create index if not exists in_a on " + dbTableTrackables + " (geocode)");
-
- Log.i(Settings.tag, "Indexes added.");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 34: " + e.toString());
- }
- }
-
- if (oldVersion < 37) { // upgrade to 37
- try {
- db.execSQL("alter table " + dbTableCaches + " add column direction text");
- db.execSQL("alter table " + dbTableCaches + " add column distance double");
-
- Log.i(Settings.tag, "Columns direction and distance added to " + dbTableCaches + ".");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 37: " + e.toString());
- }
- }
-
- if (oldVersion < 38) { // upgrade to 38
- try {
- db.execSQL("drop table " + dbTableLogs);
- db.execSQL(dbCreateLogs);
-
- Log.i(Settings.tag, "Changed type column in " + dbTableLogs + " to integer.");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 38: " + e.toString());
- }
- }
-
- if (oldVersion < 39) { // upgrade to 39
- try {
- db.execSQL(dbCreateLists);
-
- Log.i(Settings.tag, "Created lists table.");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 39: " + e.toString());
- }
- }
-
- if (oldVersion < 40) { // upgrade to 40
- try {
- db.execSQL("drop table " + dbTableTrackables);
- db.execSQL(dbCreateTrackables);
-
- Log.i(Settings.tag, "Changed type of geocode column in trackables table.");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 40: " + e.toString());
- }
- }
-
- if (oldVersion < 41) { // upgrade to 41
- try {
- db.execSQL("alter table " + dbTableCaches + " add column rating float");
- db.execSQL("alter table " + dbTableCaches + " add column votes integer");
- db.execSQL("alter table " + dbTableCaches + " add column vote integer");
-
- Log.i(Settings.tag, "Added columns for GCvote.");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 41: " + e.toString());
- }
- }
-
- if (oldVersion < 42) { // upgrade to 42
- try {
- db.execSQL(dbCreateLogsOffline);
-
- Log.i(Settings.tag, "Added table for offline logs");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 42: " + e.toString());
- }
- }
-
- if (oldVersion < 43) { // upgrade to 43
- try {
- final String dbTableCachesTemp = dbTableCaches + "_temp";
- final String dbCreateCachesTemp = ""
- + "create temporary table " + dbTableCachesTemp + " ("
- + "_id integer primary key autoincrement, "
- + "updated long not null, "
- + "detailed integer not null default 0, "
- + "detailedupdate long, "
- + "geocode text unique not null, "
- + "reason integer not null default 0, " // cached, favourite...
- + "cacheid text, "
- + "guid text, "
- + "type text, "
- + "name text, "
- + "owner text, "
- + "hidden long, "
- + "hint text, "
- + "size text, "
- + "difficulty float, "
- + "terrain float, "
- + "latlon text, "
- + "latitude_string text, "
- + "longitude_string text, "
- + "location text, "
- + "distance double, "
- + "latitude double, "
- + "longitude double, "
- + "shortdesc text, "
- + "description text, "
- + "rating float, "
- + "votes integer, "
- + "vote integer, "
- + "disabled integer not null default 0, "
- + "archived integer not null default 0, "
- + "members integer not null default 0, "
- + "found integer not null default 0, "
- + "favourite integer not null default 0, "
- + "inventorycoins integer default 0, "
- + "inventorytags integer default 0, "
- + "inventoryunknown integer default 0 "
- + "); ";
- final String dbCreateCachesNew = ""
- + "create table " + dbTableCaches + " ("
- + "_id integer primary key autoincrement, "
- + "updated long not null, "
- + "detailed integer not null default 0, "
- + "detailedupdate long, "
- + "geocode text unique not null, "
- + "reason integer not null default 0, " // cached, favourite...
- + "cacheid text, "
- + "guid text, "
- + "type text, "
- + "name text, "
- + "owner text, "
- + "hidden long, "
- + "hint text, "
- + "size text, "
- + "difficulty float, "
- + "terrain float, "
- + "latlon text, "
- + "latitude_string text, "
- + "longitude_string text, "
- + "location text, "
- + "direction double, "
- + "distance double, "
- + "latitude double, "
- + "longitude double, "
- + "shortdesc text, "
- + "description text, "
- + "rating float, "
- + "votes integer, "
- + "vote integer, "
- + "disabled integer not null default 0, "
- + "archived integer not null default 0, "
- + "members integer not null default 0, "
- + "found integer not null default 0, "
- + "favourite integer not null default 0, "
- + "inventorycoins integer default 0, "
- + "inventorytags integer default 0, "
- + "inventoryunknown integer default 0 "
- + "); ";
-
- db.beginTransaction();
- db.execSQL(dbCreateCachesTemp);
- db.execSQL("insert into " + dbTableCachesTemp + " select _id, updated, detailed, detailedupdate, geocode, reason, cacheid, guid, type, name, owner, hidden, hint, size, difficulty, terrain, latlon, latitude_string, longitude_string, location, distance, latitude, longitude, shortdesc, description, rating, votes, vote, disabled, archived, members, found, favourite, inventorycoins, inventorytags, inventoryunknown from " + dbTableCaches);
- db.execSQL("drop table " + dbTableCaches);
- db.execSQL(dbCreateCachesNew);
- db.execSQL("insert into " + dbTableCaches + " select _id, updated, detailed, detailedupdate, geocode, reason, cacheid, guid, type, name, owner, hidden, hint, size, difficulty, terrain, latlon, latitude_string, longitude_string, location, null, distance, latitude, longitude, shortdesc, description, rating, votes, vote, disabled, archived, members, found, favourite, inventorycoins, inventorytags, inventoryunknown from " + dbTableCachesTemp);
- db.execSQL("drop table " + dbTableCachesTemp);
- db.setTransactionSuccessful();
-
- Log.i(Settings.tag, "Changed direction column");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 43: " + e.toString());
- } finally {
- db.endTransaction();
- }
- }
-
- if (oldVersion < 44) { // upgrade to 44
- try {
- db.execSQL("alter table " + dbTableCaches + " add column favourite_cnt integer");
-
- Log.i(Settings.tag, "Column favourite_cnt added to " + dbTableCaches + ".");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 44: " + e.toString());
- }
- }
-
- if (oldVersion < 45) { // upgrade to 45
- try {
- db.execSQL("alter table " + dbTableCaches + " add column owner_real text");
-
- Log.i(Settings.tag, "Column owner_real added to " + dbTableCaches + ".");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 45: " + e.toString());
- }
- }
-
- if (oldVersion < 46) { // upgrade to 46
- try {
- db.execSQL("alter table " + dbTableCaches + " add column visiteddate long");
- db.execSQL("create index if not exists in_f on " + dbTableCaches + " (visiteddate, detailedupdate)");
-
- Log.i(Settings.tag, "Added column for date of visit.");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 46: " + e.toString());
- }
- }
- if (oldVersion < 47) { // upgrade to 47
- try {
- db.execSQL("alter table " + dbTableCaches + " add column own integer not null default 0");
-
- Log.i(Settings.tag, "Added column own.");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 47: " + e.toString());
- }
- }
-
- if (oldVersion < 48) { // upgrade to 48
- try {
- db.execSQL("alter table " + dbTableCaches + " add column elevation double");
-
- Log.i(Settings.tag, "Column elevation added to " + dbTableCaches + ".");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 48: " + e.toString());
- }
- }
-
- if (oldVersion < 49) { // upgrade to 49
- try {
- db.execSQL(dbCreateLogCount);
-
- Log.i(Settings.tag, "Created table " + dbTableLogCount + ".");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 49: " + e.toString());
- }
- }
-
- if (oldVersion < 50) { // upgrade to 50
- try {
- db.execSQL("alter table " + dbTableCaches + " add column myvote float");
-
- Log.i(Settings.tag, "Added float column for votes to " + dbTableCaches + ".");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 50: " + e.toString());
- }
- }
-
- if (oldVersion < 51) { // upgrade to 51
- try {
- db.execSQL("alter table " + dbTableCaches + " add column reliable_latlon integer");
-
- Log.i(Settings.tag, "Column reliable_latlon added to " + dbTableCaches + ".");
- } catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 51: " + e.toString());
- }
- }
-
if (oldVersion < 52) { // upgrade to 52
try {
db.execSQL(dbCreateSearchDestinationHistory);
- Log.i(Settings.tag, "Added table " + dbTableSearchDestionationHistory + ".");
+ Log.i("Added table " + dbTableSearchDestionationHistory + ".");
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 52", e);
+ Log.e("Failed to upgrade to ver. 52", e);
}
}
@@ -749,9 +483,9 @@ public class cgData {
try {
db.execSQL("alter table " + dbTableCaches + " add column onWatchlist integer");
- Log.i(Settings.tag, "Column onWatchlist added to " + dbTableCaches + ".");
+ Log.i("Column onWatchlist added to " + dbTableCaches + ".");
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 53", e);
+ Log.e("Failed to upgrade to ver. 53", e);
}
}
@@ -759,7 +493,7 @@ public class cgData {
try {
db.execSQL(dbCreateLogImages);
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 54: " + e.toString());
+ Log.e("Failed to upgrade to ver. 54: " + e.toString());
}
}
@@ -768,7 +502,7 @@ public class cgData {
try {
db.execSQL("alter table " + dbTableCaches + " add column personal_note text");
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 55: " + e.toString());
+ Log.e("Failed to upgrade to ver. 55: " + e.toString());
}
}
@@ -780,7 +514,7 @@ public class cgData {
"lower(attribute) where attribute like \"%_yes\" " +
"or attribute like \"%_no\"");
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 56: " + e.toString());
+ Log.e("Failed to upgrade to ver. 56: " + e.toString());
}
}
@@ -795,7 +529,7 @@ public class cgData {
db.execSQL("drop index in_f");
createIndices(db);
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 57: " + e.toString());
+ Log.e("Failed to upgrade to ver. 57: " + e.toString());
}
}
@@ -883,9 +617,9 @@ public class cgData {
db.setTransactionSuccessful();
- Log.i(Settings.tag, "Removed latitude_string and longitude_string columns");
+ Log.i("Removed latitude_string and longitude_string columns");
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 58", e);
+ Log.e("Failed to upgrade to ver. 58", e);
} finally {
db.endTransaction();
}
@@ -897,7 +631,7 @@ public class cgData {
createIndices(db);
removeObsoleteCacheDirectories(db);
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 59", e);
+ Log.e("Failed to upgrade to ver. 59", e);
}
}
@@ -905,7 +639,7 @@ public class cgData {
try {
removeSecEmptyDirs();
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 60", e);
+ Log.e("Failed to upgrade to ver. 60", e);
}
}
if (oldVersion < 61) {
@@ -913,7 +647,7 @@ public class cgData {
db.execSQL("alter table " + dbTableLogs + " add column friend integer");
db.execSQL("alter table " + dbTableCaches + " add column coordsChanged integer default 0");
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 61: " + e.toString());
+ Log.e("Failed to upgrade to ver. 61: " + e.toString());
}
}
@@ -924,7 +658,7 @@ public class cgData {
db.execSQL("alter table " + dbTableWaypoints + " add column own integer default 0");
db.execSQL("update " + dbTableWaypoints + " set own = 1 where type = 'own'");
} catch (Exception e) {
- Log.e(Settings.tag, "Failed to upgrade to ver. 62: " + e.toString());
+ Log.e("Failed to upgrade to ver. 62: " + e.toString());
}
}
@@ -935,7 +669,7 @@ public class cgData {
db.endTransaction();
}
- Log.i(Settings.tag, "Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": completed");
+ Log.i("Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": completed");
}
}
@@ -968,7 +702,7 @@ public class cgData {
@Override
public void run() {
for (final File dir : toRemove) {
- Log.i(Settings.tag, "Removing obsolete cache directory for " + dir.getName());
+ Log.i("Removing obsolete cache directory for " + dir.getName());
LocalStorage.deleteDirectory(dir);
}
}
@@ -1017,7 +751,7 @@ public class cgData {
"100");
if (cursor != null) {
- int index = 0;
+ int index;
if (cursor.getCount() > 0) {
cursor.moveToFirst();
@@ -1032,7 +766,7 @@ public class cgData {
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.allDetailedThere: " + e.toString());
+ Log.e("cgData.allDetailedThere: " + e.toString());
}
if (cursor != null) {
@@ -1078,7 +812,7 @@ public class cgData {
}
if (cursor != null) {
- int index = 0;
+ int index;
cnt = cursor.getCount();
if (cnt > 0) {
@@ -1093,7 +827,7 @@ public class cgData {
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.isThere: " + e.toString());
+ Log.e("cgData.isThere: " + e.toString());
}
if (cursor != null) {
@@ -1129,7 +863,7 @@ public class cgData {
public boolean isOffline(String geocode, String guid) {
init();
- Cursor cursor = null;
+ Cursor cursor;
long listId = StoredList.TEMPORARY_LIST_ID;
try {
@@ -1159,7 +893,7 @@ public class cgData {
if (cursor != null) {
final int cnt = cursor.getCount();
- int index = 0;
+ int index;
if (cnt > 0) {
cursor.moveToFirst();
@@ -1171,7 +905,7 @@ public class cgData {
cursor.close();
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.isOffline: " + e.toString());
+ Log.e("cgData.isOffline: " + e.toString());
}
return listId >= StoredList.STANDARD_LIST_ID;
@@ -1192,7 +926,7 @@ public class cgData {
} catch (SQLiteDoneException e) {
// Do nothing, it only means we have no information on the cache
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.getGeocodeForGuid", e);
+ Log.e("cgData.getGeocodeForGuid", e);
}
return null;
@@ -1213,7 +947,7 @@ public class cgData {
} catch (SQLiteDoneException e) {
// Do nothing, it only means we have no information on the cache
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.getCacheidForGeocode", e);
+ Log.e("cgData.getCacheidForGeocode", e);
}
return null;
@@ -1254,7 +988,7 @@ public class cgData {
cache.addStorageLocation(StorageLocation.DATABASE);
cacheCache.putCacheInCache(cache);
- Log.d(Settings.tag, "Saving " + cache.toString() + " (" + cache.getListId() + ") to DB");
+ Log.d("Saving " + cache.toString() + " (" + cache.getListId() + ") to DB");
ContentValues values = new ContentValues();
@@ -1308,55 +1042,20 @@ public class cgData {
values.put("coordsChanged", cache.hasUserModifiedCoords() ? 1 : 0);
values.put("finalDefined", cache.hasFinalDefined() ? 1 : 0);
- boolean statusOk = true;
-
- if (cache.hasAttributes()) {
- if (!saveAttributes(cache.getGeocode(), cache.getAttributes())) {
- statusOk = false;
- }
- }
-
- if (cache.hasWaypoints()) {
- if (!saveWaypoints(cache.getGeocode(), cache.getWaypoints(), true)) {
- statusOk = false;
- }
- }
-
- if (cache.getSpoilers() != null) {
- if (!saveSpoilers(cache.getGeocode(), cache.getSpoilers())) {
- statusOk = false;
- }
- }
-
- if (CollectionUtils.isNotEmpty(cache.getLogs())) {
- if (!saveLogs(cache.getGeocode(), cache.getLogs())) {
- statusOk = false;
- }
- }
-
- if (MapUtils.isNotEmpty(cache.getLogCounts())) {
- if (!saveLogCount(cache.getGeocode(), cache.getLogCounts())) {
- statusOk = false;
- }
- }
-
- if (cache.getInventory() != null) {
- if (!saveInventory(cache.getGeocode(), cache.getInventory())) {
- statusOk = false;
- }
- }
-
- if (!statusOk) {
- cache.setDetailed(false);
- cache.setDetailedUpdate(0L);
- }
-
+ boolean result = false;
init();
//try to update record else insert fresh..
- boolean result = false;
databaseRW.beginTransaction();
+
try {
+ saveAttributesWithoutTransaction(cache);
+ saveWaypointsWithoutTransaction(cache);
+ saveSpoilersWithoutTransaction(cache);
+ saveLogsWithoutTransaction(cache.getGeocode(), cache.getLogs());
+ saveLogCountsWithoutTransaction(cache);
+ saveInventoryWithoutTransaction(cache.getGeocode(), cache.getInventory());
+
int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { cache.getGeocode() });
if (rows == 0) {
// cache is not in the DB, insert it
@@ -1370,129 +1069,102 @@ public class cgData {
databaseRW.endTransaction();
}
- values = null;
return result;
}
- public boolean saveAttributes(String geocode, List<String> attributes) {
- if (StringUtils.isBlank(geocode) || attributes == null) {
- return false;
- }
+ private void saveAttributesWithoutTransaction(final cgCache cache) {
+ String geocode = cache.getGeocode();
+ databaseRW.delete(dbTableAttributes, "geocode = ?", new String[] { geocode });
- init();
+ final List<String> attributes = cache.getAttributes();
+ if (CollectionUtils.isNotEmpty(attributes)) {
- databaseRW.beginTransaction();
- try {
- databaseRW.delete(dbTableAttributes, "geocode = ?", new String[] { geocode });
-
- if (!attributes.isEmpty()) {
-
- InsertHelper helper = new InsertHelper(databaseRW, dbTableAttributes);
- long timeStamp = System.currentTimeMillis();
+ InsertHelper helper = new InsertHelper(databaseRW, dbTableAttributes);
+ long timeStamp = System.currentTimeMillis();
- for (String attribute : attributes) {
- helper.prepareForInsert();
+ for (String attribute : attributes) {
+ helper.prepareForInsert();
- helper.bind(ATTRIBUTES_GEOCODE, geocode);
- helper.bind(ATTRIBUTES_UPDATED, timeStamp);
- helper.bind(ATTRIBUTES_ATTRIBUTE, attribute);
+ helper.bind(ATTRIBUTES_GEOCODE, geocode);
+ helper.bind(ATTRIBUTES_UPDATED, timeStamp);
+ helper.bind(ATTRIBUTES_ATTRIBUTE, attribute);
- helper.execute();
- }
- helper.close();
+ helper.execute();
}
- databaseRW.setTransactionSuccessful();
- } finally {
- databaseRW.endTransaction();
+ helper.close();
}
-
- return true;
}
/**
* Persists the given <code>destination</code> into the database.
*
- * @param destinations
- * @return <code>true</code> if the given destination was successfully
- * persisted <code>false</code> otherwise.
+ * @param destination
+ * a destination to save
*/
- public boolean saveSearchedDestination(cgDestination destination) {
- boolean success = true;
-
- if (destination == null) {
- success = false;
- } else {
- init();
-
- databaseRW.beginTransaction();
+ public void saveSearchedDestination(final Destination destination) {
+ init();
- try {
- ContentValues values = new ContentValues();
- values.put("date", destination.getDate());
- putCoords(values, destination.getCoords());
+ databaseRW.beginTransaction();
- long id = databaseRW.insert(dbTableSearchDestionationHistory, null, values);
- destination.setId(id);
- databaseRW.setTransactionSuccessful();
- } catch (Exception e) {
- success = false;
- Log.e(Settings.tag, "Updating searchedDestinations db failed", e);
- } finally {
- databaseRW.endTransaction();
- }
+ try {
+ ContentValues values = new ContentValues();
+ values.put("date", destination.getDate());
+ putCoords(values, destination.getCoords());
+ databaseRW.insert(dbTableSearchDestionationHistory, null, values);
+ databaseRW.setTransactionSuccessful();
+ } catch (Exception e) {
+ Log.e("Updating searchedDestinations db failed", e);
+ } finally {
+ databaseRW.endTransaction();
}
-
- return success;
}
- public boolean saveWaypoints(String geocode, List<cgWaypoint> waypoints, boolean drop) {
- if (StringUtils.isBlank(geocode) || waypoints == null) {
- return false;
- }
-
+ public boolean saveWaypoints(final cgCache cache) {
+ boolean result = false;
init();
-
- Log.d(Settings.tag, "cgData.saveWaypoints(drop=" + drop + ")");
-
- boolean ok = false;
databaseRW.beginTransaction();
- try {
- if (drop) {
- databaseRW.delete(dbTableWaypoints, "geocode = ? and type <> ? and own = 0", new String[] { geocode, "own" });
- }
-
- if (!waypoints.isEmpty()) {
- ContentValues values = new ContentValues();
- long timeStamp = System.currentTimeMillis();
- for (cgWaypoint oneWaypoint : waypoints) {
- if (oneWaypoint.isUserDefined()) {
- continue;
- }
-
- values.clear();
- values.put("geocode", geocode);
- values.put("updated", timeStamp);
- values.put("type", oneWaypoint.getWaypointType() != null ? oneWaypoint.getWaypointType().id : null);
- values.put("prefix", oneWaypoint.getPrefix());
- values.put("lookup", oneWaypoint.getLookup());
- values.put("name", oneWaypoint.getName());
- values.put("latlon", oneWaypoint.getLatlon());
- putCoords(values, oneWaypoint.getCoords());
- values.put("note", oneWaypoint.getNote());
- values.put("own", oneWaypoint.isUserDefined() ? 1 : 0);
-
- final long rowId = databaseRW.insert(dbTableWaypoints, null, values);
- oneWaypoint.setId((int) rowId);
- }
- }
+ try {
+ saveWaypointsWithoutTransaction(cache);
databaseRW.setTransactionSuccessful();
- ok = true;
+ result = true;
+ } catch (Exception e) {
+ Log.e("saveWaypoints", e);
} finally {
databaseRW.endTransaction();
}
+ return result;
+ }
- return ok;
+ private void saveWaypointsWithoutTransaction(final cgCache cache) {
+ String geocode = cache.getGeocode();
+ databaseRW.delete(dbTableWaypoints, "geocode = ? and type <> ? and own = 0", new String[] { geocode, "own" });
+
+ List<cgWaypoint> waypoints = cache.getWaypoints();
+ if (CollectionUtils.isNotEmpty(waypoints)) {
+ ContentValues values = new ContentValues();
+ long timeStamp = System.currentTimeMillis();
+ for (cgWaypoint oneWaypoint : waypoints) {
+ if (oneWaypoint.isUserDefined()) {
+ continue;
+ }
+
+ values.clear();
+ values.put("geocode", geocode);
+ values.put("updated", timeStamp);
+ values.put("type", oneWaypoint.getWaypointType() != null ? oneWaypoint.getWaypointType().id : null);
+ values.put("prefix", oneWaypoint.getPrefix());
+ values.put("lookup", oneWaypoint.getLookup());
+ values.put("name", oneWaypoint.getName());
+ values.put("latlon", oneWaypoint.getLatlon());
+ putCoords(values, oneWaypoint.getCoords());
+ values.put("note", oneWaypoint.getNote());
+ values.put("own", oneWaypoint.isUserDefined() ? 1 : 0);
+
+ final long rowId = databaseRW.insert(dbTableWaypoints, null, values);
+ oneWaypoint.setId((int) rowId);
+ }
+ }
}
/**
@@ -1555,11 +1227,7 @@ public class cgData {
ok = true;
} else {
final int rows = databaseRW.update(dbTableWaypoints, values, "_id = " + id, null);
- if (rows > 0) {
- ok = true;
- } else {
- ok = false;
- }
+ ok = rows > 0;
}
databaseRW.setTransactionSuccessful();
} finally {
@@ -1576,121 +1244,72 @@ public class cgData {
init();
- int deleted = databaseRW.delete(dbTableWaypoints, "_id = " + id, null);
-
- if (deleted > 0) {
- return true;
- }
-
- return false;
+ return databaseRW.delete(dbTableWaypoints, "_id = " + id, null) > 0;
}
- public boolean saveSpoilers(String geocode, List<cgImage> spoilers) {
- if (StringUtils.isBlank(geocode) || spoilers == null) {
- return false;
- }
-
- init();
-
- databaseRW.beginTransaction();
- try {
- databaseRW.delete(dbTableSpoilers, "geocode = ?", new String[] { geocode });
+ private void saveSpoilersWithoutTransaction(final cgCache cache) {
+ String geocode = cache.getGeocode();
+ databaseRW.delete(dbTableSpoilers, "geocode = ?", new String[] { geocode });
- if (!spoilers.isEmpty()) {
- ContentValues values = new ContentValues();
- long timeStamp = System.currentTimeMillis();
- for (cgImage oneSpoiler : spoilers) {
- values.clear();
- values.put("geocode", geocode);
- values.put("updated", timeStamp);
- values.put("url", oneSpoiler.getUrl());
- values.put("title", oneSpoiler.getTitle());
- values.put("description", oneSpoiler.getDescription());
+ List<cgImage> spoilers = cache.getSpoilers();
+ if (CollectionUtils.isNotEmpty(spoilers)) {
+ ContentValues values = new ContentValues();
+ long timeStamp = System.currentTimeMillis();
+ for (cgImage spoiler : spoilers) {
+ values.clear();
+ values.put("geocode", geocode);
+ values.put("updated", timeStamp);
+ values.put("url", spoiler.getUrl());
+ values.put("title", spoiler.getTitle());
+ values.put("description", spoiler.getDescription());
- databaseRW.insert(dbTableSpoilers, null, values);
- }
+ databaseRW.insert(dbTableSpoilers, null, values);
}
- databaseRW.setTransactionSuccessful();
- } finally {
- databaseRW.endTransaction();
}
-
- return true;
}
- public boolean saveLogs(String geocode, List<cgLog> logs) {
- return saveLogs(geocode, logs, true);
- }
+ private void saveLogsWithoutTransaction(final String geocode, final List<LogEntry> logs) {
+ // TODO delete logimages referring these logs
+ databaseRW.delete(dbTableLogs, "geocode = ?", new String[] { geocode });
- public boolean saveLogs(String geocode, List<cgLog> logs, boolean drop) {
- if (StringUtils.isBlank(geocode) || logs == null) {
- return false;
- }
-
- init();
-
- databaseRW.beginTransaction();
- try {
- if (drop) {
- // TODO delete logimages referring these logs
- databaseRW.delete(dbTableLogs, "geocode = ?", new String[] { geocode });
- }
-
- if (!logs.isEmpty()) {
- InsertHelper helper = new InsertHelper(databaseRW, dbTableLogs);
- long timeStamp = System.currentTimeMillis();
- for (cgLog log : logs) {
- helper.prepareForInsert();
-
- helper.bind(LOGS_GEOCODE, geocode);
- helper.bind(LOGS_UPDATED, timeStamp);
- helper.bind(LOGS_TYPE, log.type.id);
- helper.bind(LOGS_AUTHOR, log.author);
- helper.bind(LOGS_LOG, log.log);
- helper.bind(LOGS_DATE, log.date);
- helper.bind(LOGS_FOUND, log.found);
- helper.bind(LOGS_FRIEND, log.friend);
-
- long log_id = helper.execute();
-
- if (CollectionUtils.isNotEmpty(log.logImages)) {
- ContentValues values = new ContentValues();
- for (cgImage img : log.logImages) {
- values.clear();
- values.put("log_id", log_id);
- values.put("title", img.getTitle());
- values.put("url", img.getUrl());
- databaseRW.insert(dbTableLogImages, null, values);
- }
+ if (CollectionUtils.isNotEmpty(logs)) {
+ InsertHelper helper = new InsertHelper(databaseRW, dbTableLogs);
+ long timeStamp = System.currentTimeMillis();
+ for (LogEntry log : logs) {
+ helper.prepareForInsert();
+
+ helper.bind(LOGS_GEOCODE, geocode);
+ helper.bind(LOGS_UPDATED, timeStamp);
+ helper.bind(LOGS_TYPE, log.type.id);
+ helper.bind(LOGS_AUTHOR, log.author);
+ helper.bind(LOGS_LOG, log.log);
+ helper.bind(LOGS_DATE, log.date);
+ helper.bind(LOGS_FOUND, log.found);
+ helper.bind(LOGS_FRIEND, log.friend);
+
+ long log_id = helper.execute();
+
+ if (log.hasLogImages()) {
+ ContentValues values = new ContentValues();
+ for (cgImage img : log.getLogImages()) {
+ values.clear();
+ values.put("log_id", log_id);
+ values.put("title", img.getTitle());
+ values.put("url", img.getUrl());
+ databaseRW.insert(dbTableLogImages, null, values);
}
}
- helper.close();
}
- databaseRW.setTransactionSuccessful();
- } finally {
- databaseRW.endTransaction();
+ helper.close();
}
-
- return true;
- }
-
- public boolean saveLogCount(String geocode, Map<LogType, Integer> logCounts) {
- return saveLogCount(geocode, logCounts, true);
}
- public boolean saveLogCount(String geocode, Map<LogType, Integer> logCounts, boolean drop) {
- if (StringUtils.isBlank(geocode) || MapUtils.isEmpty(logCounts)) {
- return false;
- }
-
- init();
-
- databaseRW.beginTransaction();
- try {
- if (drop) {
- databaseRW.delete(dbTableLogCount, "geocode = ?", new String[] { geocode });
- }
+ private void saveLogCountsWithoutTransaction(final cgCache cache) {
+ String geocode = cache.getGeocode();
+ databaseRW.delete(dbTableLogCount, "geocode = ?", new String[] { geocode });
+ Map<LogType, Integer> logCounts = cache.getLogCounts();
+ if (MapUtils.isNotEmpty(logCounts)) {
ContentValues values = new ContentValues();
Set<Entry<LogType, Integer>> logCountsItems = logCounts.entrySet();
@@ -1704,6 +1323,15 @@ public class cgData {
databaseRW.insert(dbTableLogCount, null, values);
}
+ }
+ }
+
+ public boolean saveTrackable(final cgTrackable trackable) {
+ init();
+
+ databaseRW.beginTransaction();
+ try {
+ saveInventoryWithoutTransaction(null, Collections.singletonList(trackable));
databaseRW.setTransactionSuccessful();
} finally {
databaseRW.endTransaction();
@@ -1712,81 +1340,46 @@ public class cgData {
return true;
}
- public boolean saveInventory(String geocode, List<cgTrackable> trackables) {
- if (trackables == null) {
- return false;
+ private void saveInventoryWithoutTransaction(final String geocode, final List<cgTrackable> trackables) {
+ if (geocode != null) {
+ databaseRW.delete(dbTableTrackables, "geocode = ?", new String[] { geocode });
}
- init();
-
- databaseRW.beginTransaction();
- try {
- if (geocode != null) {
- databaseRW.delete(dbTableTrackables, "geocode = ?", new String[] { geocode });
- }
-
- if (!trackables.isEmpty()) {
- ContentValues values = new ContentValues();
- long timeStamp = System.currentTimeMillis();
- for (cgTrackable oneTrackable : trackables) {
- values.clear();
- if (geocode != null) {
- values.put("geocode", geocode);
- }
- values.put("updated", timeStamp);
- values.put("tbcode", oneTrackable.getGeocode());
- values.put("guid", oneTrackable.getGuid());
- values.put("title", oneTrackable.getName());
- values.put("owner", oneTrackable.getOwner());
- if (oneTrackable.getReleased() != null) {
- values.put("released", oneTrackable.getReleased().getTime());
- } else {
- values.put("released", 0L);
- }
- values.put("goal", oneTrackable.getGoal());
- values.put("description", oneTrackable.getDetails());
+ if (CollectionUtils.isNotEmpty(trackables)) {
+ ContentValues values = new ContentValues();
+ long timeStamp = System.currentTimeMillis();
+ for (cgTrackable trackable : trackables) {
+ values.clear();
+ if (geocode != null) {
+ values.put("geocode", geocode);
+ }
+ values.put("updated", timeStamp);
+ values.put("tbcode", trackable.getGeocode());
+ values.put("guid", trackable.getGuid());
+ values.put("title", trackable.getName());
+ values.put("owner", trackable.getOwner());
+ if (trackable.getReleased() != null) {
+ values.put("released", trackable.getReleased().getTime());
+ } else {
+ values.put("released", 0L);
+ }
+ values.put("goal", trackable.getGoal());
+ values.put("description", trackable.getDetails());
- databaseRW.insert(dbTableTrackables, null, values);
+ databaseRW.insert(dbTableTrackables, null, values);
- saveLogs(oneTrackable.getGeocode(), oneTrackable.getLogs());
- }
+ saveLogsWithoutTransaction(trackable.getGeocode(), trackable.getLogs());
}
- databaseRW.setTransactionSuccessful();
- } finally {
- databaseRW.endTransaction();
}
-
- return true;
}
- public List<Number> getBounds(Set<String> geocodes) {
+ public Viewport getBounds(final Set<String> geocodes) {
if (CollectionUtils.isEmpty(geocodes)) {
return null;
}
final Set<cgCache> caches = loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB);
-
- double latMin = 360.0;
- double latMax = -360.0;
- double lonMin = 360.0;
- double lonMax = -360.0;
- for (cgCache cache : caches) {
- final Geopoint coords = cache.getCoords();
- double latitude = coords.getLatitude();
- latMin = Math.min(latitude, latMin);
- latMax = Math.max(latitude, latMax);
- double longitude = coords.getLongitude();
- lonMin = Math.min(longitude, lonMin);
- lonMax = Math.max(longitude, lonMax);
- }
-
- final List<Number> viewport = new ArrayList<Number>();
- viewport.add(caches.size());
- viewport.add(latMin);
- viewport.add(latMax);
- viewport.add(lonMin);
- viewport.add(lonMax);
- return viewport;
+ return Viewport.containing(caches);
}
/**
@@ -1837,12 +1430,10 @@ public class cgData {
loadFlags.contains(LoadFlag.LOAD_INVENTORY) ||
loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) {
- Set<cgCache> cachesFromDB = loadCaches(remaining, null, null, null, null, loadFlags);
- if (cachesFromDB != null) {
- result.addAll(cachesFromDB);
- for (cgCache cache : cachesFromDB) {
- remaining.remove(cache.getGeocode());
- }
+ final Set<cgCache> cachesFromDB = loadCachesFromGeocodes(remaining, loadFlags);
+ result.addAll(cachesFromDB);
+ for (final cgCache cache : cachesFromDB) {
+ remaining.remove(cache.getGeocode());
}
}
@@ -1857,7 +1448,7 @@ public class cgData {
}
if (remaining.size() >= 1) {
- Log.e(Settings.tag, "cgData.loadCaches(" + remaining.toString() + ") failed");
+ Log.e("cgData.loadCaches(" + remaining.toString() + ") failed");
}
return result;
}
@@ -1866,150 +1457,107 @@ public class cgData {
* Load caches.
*
* @param geocodes
- * OR
- * @param centerLat
- * @param centerLon
- * @param spanLat
- * @param spanLon
* @param loadFlags
* @return Set of loaded caches. Never null.
*/
- public Set<cgCache> loadCaches(final Set<String> geocodes, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final EnumSet<LoadFlag> loadFlags) {
- final Set<cgCache> caches = new HashSet<cgCache>();
+ private Set<cgCache> loadCachesFromGeocodes(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) {
if (CollectionUtils.isEmpty(geocodes)) {
- return caches;
- }
- // Using more than one of the parametersets results in overly comlex wheres
- if (CollectionUtils.isNotEmpty(geocodes)
- && centerLat != null
- && centerLon != null
- && spanLat != null
- && spanLon != null) {
- throw new IllegalArgumentException("Please use only one parameter");
+ return Collections.emptySet();
}
- Log.d(Settings.tag, "cgData.loadCaches(" + geocodes.toString() + ") from DB");
+
+ Log.d("cgData.loadCachesFromGeocodes(" + geocodes.toString() + ") from DB");
init();
- Cursor cursor = null;
+ final Cursor cursor = databaseRO.query(
+ dbTableCaches,
+ CACHE_COLUMNS,
+ cgData.whereGeocodeIn(geocodes),
+ null,
+ null,
+ null,
+ null,
+ null);
try {
- StringBuilder where = cgData.whereGeocodeIn(geocodes);
-
- // viewport limitation
- if (centerLat != null && centerLon != null && spanLat != null && spanLon != null) {
- double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4);
- double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4);
- double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4);
- double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4);
- double llCache;
-
- if (latMin > latMax) {
- llCache = latMax;
- latMax = latMin;
- latMin = llCache;
- }
- if (lonMin > lonMax) {
- llCache = lonMax;
- lonMax = lonMin;
- lonMin = llCache;
- }
-
- if (where.length() > 0) {
- where.append(" and ");
- }
- where.append("(latitude >= ");
- where.append(String.format((Locale) null, "%.6f", latMin));
- where.append(" and latitude <= ");
- where.append(String.format((Locale) null, "%.6f", latMax));
- where.append(" and longitude >= ");
- where.append(String.format((Locale) null, "%.6f", lonMin));
- where.append(" and longitude <= ");
- where.append(String.format((Locale) null, "%.6f", lonMax));
- where.append(')');
+ if (!cursor.moveToFirst()) {
+ return Collections.emptySet();
}
- cursor = databaseRO.query(
- dbTableCaches,
- CACHE_COLUMNS,
- where.toString(),
- null,
- null,
- null,
- null,
- null);
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- cursor.moveToFirst();
-
- do {
- //Extracted Method = LOADDBMINIMAL
- cgCache cache = cgData.createCacheFromDatabaseContent(cursor);
-
- if (loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES)) {
- cache.setAttributes(loadAttributes(cache.getGeocode()));
- }
+ final Set<cgCache> caches = new HashSet<cgCache>();
+ do {
+ //Extracted Method = LOADDBMINIMAL
+ cgCache cache = cgData.createCacheFromDatabaseContent(cursor);
- if (loadFlags.contains(LoadFlag.LOAD_WAYPOINTS)) {
- final List<cgWaypoint> waypoints = loadWaypoints(cache.getGeocode());
- if (CollectionUtils.isNotEmpty(waypoints)) {
- cache.setWaypoints(waypoints, false);
- }
- }
+ if (loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES)) {
+ cache.setAttributes(loadAttributes(cache.getGeocode()));
+ }
- if (loadFlags.contains(LoadFlag.LOAD_SPOILERS)) {
- final List<cgImage> spoilers = loadSpoilers(cache.getGeocode());
- if (CollectionUtils.isNotEmpty(spoilers)) {
- if (cache.getSpoilers() == null) {
- cache.setSpoilers(new ArrayList<cgImage>());
- } else {
- cache.getSpoilers().clear();
- }
- cache.getSpoilers().addAll(spoilers);
- }
- }
+ if (loadFlags.contains(LoadFlag.LOAD_WAYPOINTS)) {
+ final List<cgWaypoint> waypoints = loadWaypoints(cache.getGeocode());
+ if (CollectionUtils.isNotEmpty(waypoints)) {
+ cache.setWaypoints(waypoints, false);
+ }
+ }
- if (loadFlags.contains(LoadFlag.LOAD_LOGS)) {
- cache.setLogs(loadLogs(cache.getGeocode()));
- final Map<LogType, Integer> logCounts = loadLogCounts(cache.getGeocode());
- if (MapUtils.isNotEmpty(logCounts)) {
- cache.getLogCounts().clear();
- cache.getLogCounts().putAll(logCounts);
- }
+ if (loadFlags.contains(LoadFlag.LOAD_SPOILERS)) {
+ final List<cgImage> spoilers = loadSpoilers(cache.getGeocode());
+ if (CollectionUtils.isNotEmpty(spoilers)) {
+ if (cache.getSpoilers() == null) {
+ cache.setSpoilers(new ArrayList<cgImage>());
+ } else {
+ cache.getSpoilers().clear();
}
+ cache.getSpoilers().addAll(spoilers);
+ }
+ }
- if (loadFlags.contains(LoadFlag.LOAD_INVENTORY)) {
- final List<cgTrackable> inventory = loadInventory(cache.getGeocode());
- if (CollectionUtils.isNotEmpty(inventory)) {
- if (cache.getInventory() == null) {
- cache.setInventory(new ArrayList<cgTrackable>());
- } else {
- cache.getInventory().clear();
- }
- cache.getInventory().addAll(inventory);
- }
- }
+ if (loadFlags.contains(LoadFlag.LOAD_LOGS)) {
+ cache.setLogs(loadLogs(cache.getGeocode()));
+ final Map<LogType, Integer> logCounts = loadLogCounts(cache.getGeocode());
+ if (MapUtils.isNotEmpty(logCounts)) {
+ cache.getLogCounts().clear();
+ cache.getLogCounts().putAll(logCounts);
+ }
+ }
- if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) {
- cache.setLogOffline(hasLogOffline(cache.getGeocode()));
+ if (loadFlags.contains(LoadFlag.LOAD_INVENTORY)) {
+ final List<cgTrackable> inventory = loadInventory(cache.getGeocode());
+ if (CollectionUtils.isNotEmpty(inventory)) {
+ if (cache.getInventory() == null) {
+ cache.setInventory(new ArrayList<cgTrackable>());
+ } else {
+ cache.getInventory().clear();
}
- cache.addStorageLocation(StorageLocation.DATABASE);
- cacheCache.putCacheInCache(cache);
+ cache.getInventory().addAll(inventory);
+ }
+ }
- caches.add(cache);
- } while (cursor.moveToNext());
+ if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) {
+ cache.setLogOffline(hasLogOffline(cache.getGeocode()));
}
- }
- } catch (Exception e) {
- Log.e(Settings.tag, "cgData.getCaches: " + e.toString());
- }
+ cache.addStorageLocation(StorageLocation.DATABASE);
+ cacheCache.putCacheInCache(cache);
- if (cursor != null) {
+ caches.add(cache);
+ } while (cursor.moveToNext());
+ return caches;
+ } finally {
cursor.close();
}
+ }
- return caches;
+ /**
+ * Builds a where for a viewport with the size enhanced by 50%.
+ *
+ * @param dbTable
+ * @param viewport
+ * @return
+ */
+
+ private static String buildCoordinateWhere(final String dbTable, final Viewport viewport) {
+ return viewport.resize(1.5).sqlWhere(dbTable);
}
/**
@@ -2128,7 +1676,7 @@ public class cgData {
cache.setUserModifiedCoords(cursor.getInt(cacheColumnIndex[37]) > 0);
cache.setFinalDefined(cursor.getInt(cacheColumnIndex[40]) > 0);
- Log.d(Settings.tag, "Loading " + cache.toString() + " (" + cache.getListId() + ") from DB");
+ Log.d("Loading " + cache.toString() + " (" + cache.getListId() + ") from DB");
return cache;
}
@@ -2179,7 +1727,7 @@ public class cgData {
Cursor cursor = databaseRO.query(
dbTableWaypoints,
- new String[] { "_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude", "longitude", "note", "own" },
+ WAYPOINT_COLUMNS,
"_id = ?",
new String[] { Integer.toString(id) },
null,
@@ -2187,7 +1735,7 @@ public class cgData {
null,
"1");
- Log.d(Settings.tag, "cgData.loadWaypoint(" + id + ")");
+ Log.d("cgData.loadWaypoint(" + id + ")");
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
@@ -2213,7 +1761,7 @@ public class cgData {
Cursor cursor = databaseRO.query(
dbTableWaypoints,
- new String[] { "_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude", "longitude", "note", "own" },
+ WAYPOINT_COLUMNS,
"geocode = ?",
new String[] { geocode },
null,
@@ -2256,7 +1804,7 @@ public class cgData {
return waypoint;
}
- public List<cgImage> loadSpoilers(String geocode) {
+ private List<cgImage> loadSpoilers(String geocode) {
if (StringUtils.isBlank(geocode)) {
return null;
}
@@ -2301,7 +1849,7 @@ public class cgData {
*
* @return A list of previously entered destinations or an empty list.
*/
- public List<cgDestination> loadHistoryOfSearchedLocations() {
+ public List<Destination> loadHistoryOfSearchedLocations() {
init();
Cursor cursor = databaseRO.query(dbTableSearchDestionationHistory,
@@ -2313,7 +1861,7 @@ public class cgData {
"date desc",
"100");
- final List<cgDestination> destinations = new LinkedList<cgDestination>();
+ final List<Destination> destinations = new LinkedList<Destination>();
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
@@ -2323,10 +1871,7 @@ public class cgData {
int indexLongitude = cursor.getColumnIndex("longitude");
do {
- final cgDestination dest = new cgDestination();
- dest.setId(cursor.getLong(indexId));
- dest.setDate(cursor.getLong(indexDate));
- dest.setCoords(getCoords(cursor, indexLatitude, indexLongitude));
+ final Destination dest = new Destination(cursor.getLong(indexId), cursor.getLong(indexDate), getCoords(cursor, indexLatitude, indexLongitude));
// If coordinates are non-existent or invalid, do not consider
// this point.
@@ -2353,7 +1898,7 @@ public class cgData {
databaseRW.setTransactionSuccessful();
} catch (Exception e) {
success = false;
- Log.e(Settings.tag, "Unable to clear searched destinations", e);
+ Log.e("Unable to clear searched destinations", e);
} finally {
databaseRW.endTransaction();
}
@@ -2361,14 +1906,14 @@ public class cgData {
return success;
}
- public List<cgLog> loadLogs(String geocode) {
+ public List<LogEntry> loadLogs(String geocode) {
if (StringUtils.isBlank(geocode)) {
return null;
}
init();
- List<cgLog> logs = new ArrayList<cgLog>();
+ List<LogEntry> logs = new ArrayList<LogEntry>();
Cursor cursor = databaseRO.rawQuery(
"SELECT cg_logs._id as cg_logs_id, type, author, log, date, found, friend, " + dbTableLogImages + "._id as cg_logImages_id, log_id, title, url FROM "
@@ -2376,7 +1921,7 @@ public class cgData {
+ " ON ( cg_logs._id = log_id ) WHERE geocode = ? ORDER BY date desc, cg_logs._id asc", new String[] { geocode });
if (cursor != null && cursor.getCount() > 0) {
- cgLog log = null;
+ LogEntry log = null;
int indexLogsId = cursor.getColumnIndex("cg_logs_id");
int indexType = cursor.getColumnIndex("type");
int indexAuthor = cursor.getColumnIndex("author");
@@ -2389,24 +1934,20 @@ public class cgData {
int indexUrl = cursor.getColumnIndex("url");
while (cursor.moveToNext() && logs.size() < 100) {
if (log == null || log.id != cursor.getInt(indexLogsId)) {
- log = new cgLog();
+ log = new LogEntry(
+ cursor.getString(indexAuthor),
+ cursor.getLong(indexDate),
+ LogType.getById(cursor.getInt(indexType)),
+ cursor.getString(indexLog));
log.id = cursor.getInt(indexLogsId);
- log.type = LogType.getById(cursor.getInt(indexType));
- log.author = cursor.getString(indexAuthor);
- log.log = cursor.getString(indexLog);
- log.date = cursor.getLong(indexDate);
log.found = cursor.getInt(indexFound);
- log.friend = cursor.getInt(indexFriend) == 1 ? true : false;
+ log.friend = cursor.getInt(indexFriend) == 1;
logs.add(log);
}
if (!cursor.isNull(indexLogImagesId)) {
String title = cursor.getString(indexTitle);
String url = cursor.getString(indexUrl);
- if (log.logImages == null) {
- log.logImages = new ArrayList<cgImage>();
- }
- final cgImage log_img = new cgImage(url, title);
- log.logImages.add(log_img);
+ log.addLogImage(new cgImage(url, title));
}
}
}
@@ -2457,7 +1998,7 @@ public class cgData {
return logCounts;
}
- public List<cgTrackable> loadInventory(String geocode) {
+ private List<cgTrackable> loadInventory(String geocode) {
if (StringUtils.isBlank(geocode)) {
return null;
}
@@ -2530,11 +2071,14 @@ public class cgData {
trackable.setGuid(cursor.getString(cursor.getColumnIndex("guid")));
trackable.setName(cursor.getString(cursor.getColumnIndex("title")));
trackable.setOwner(cursor.getString(cursor.getColumnIndex("owner")));
- String releasedPre = cursor.getString(cursor.getColumnIndex("released"));
- if (releasedPre != null && Long.getLong(releasedPre) != null) {
- trackable.setReleased(new Date(Long.getLong(releasedPre)));
- } else {
- trackable.setReleased(null);
+ String released = cursor.getString(cursor.getColumnIndex("released"));
+ if (released != null) {
+ try {
+ long releaseMilliSeconds = Long.parseLong(released);
+ trackable.setReleased(new Date(releaseMilliSeconds));
+ } catch (NumberFormatException e) {
+ Log.e("createTrackableFromDatabaseContent", e);
+ }
}
trackable.setGoal(cursor.getString(cursor.getColumnIndex("goal")));
trackable.setDetails(cursor.getString(cursor.getColumnIndex("description")));
@@ -2543,22 +2087,22 @@ public class cgData {
}
/**
- * Number of caches stored. The number is shown on the starting activitiy of c:geo
+ * Number of caches stored. The number is shown on the starting activity of c:geo
*
* @param detailedOnly
* @param cacheType
* @param list
* @return
*/
- public int getAllStoredCachesCount(final boolean detailedOnly, final CacheType cacheType, final Integer list) {
+ public int getAllStoredCachesCount(final boolean detailedOnly, final CacheType cacheType, final int list) {
if (cacheType == null) {
throw new IllegalArgumentException("cacheType must not be null");
}
init();
- String listSql = null;
- String listSqlW = null;
- if (list == null) {
+ String listSql;
+ String listSqlW;
+ if (list == 0) {
listSql = " where reason >= 1";
listSqlW = " and reason >= 1";
} else if (list >= 1) {
@@ -2570,7 +2114,7 @@ public class cgData {
int count = 0;
try {
- String sql = "select count(_id) from " + dbTableCaches; // this default is not used, but we like to have variables initialized
+ String sql; // this default is not used, but we like to have variables initialized
if (!detailedOnly) {
if (cacheType == CacheType.ALL) {
sql = "select count(_id) from " + dbTableCaches + listSql;
@@ -2588,7 +2132,7 @@ public class cgData {
count = (int) compiledStmnt.simpleQueryForLong();
compiledStmnt.close();
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.loadAllStoredCachesCount: " + e.toString());
+ Log.e("cgData.loadAllStoredCachesCount: " + e.toString());
}
return count;
@@ -2604,16 +2148,23 @@ public class cgData {
count = (int) sqlCount.simpleQueryForLong();
sqlCount.close();
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.getAllHistoricCachesCount: " + e.toString());
+ Log.e("cgData.getAllHistoricCachesCount: " + e.toString());
}
return count;
}
+ /**
+ * Return a batch of stored geocodes.
+ *
+ * @param detailedOnly
+ * @param coords
+ * the current coordinates to sort by distance, or null to sort by geocode
+ * @param cacheType
+ * @param listId
+ * @return
+ */
public Set<String> loadBatchOfStoredGeocodes(final boolean detailedOnly, final Geopoint coords, final CacheType cacheType, final int listId) {
- if (coords == null) {
- throw new IllegalArgumentException("coords must not be null");
- }
if (cacheType == null) {
throw new IllegalArgumentException("cacheType must not be null");
}
@@ -2637,7 +2188,9 @@ public class cgData {
}
try {
- Cursor cursor = databaseRO.query(
+ Cursor cursor;
+ if (coords != null) {
+ cursor = databaseRO.query(
dbTableCaches,
new String[] { "geocode", "(abs(latitude-" + String.format((Locale) null, "%.6f", coords.getLatitude()) +
") + abs(longitude-" + String.format((Locale) null, "%.6f", coords.getLongitude()) + ")) as dif" },
@@ -2647,22 +2200,29 @@ public class cgData {
null,
"dif",
null);
+ } else {
+ cursor = databaseRO.query(
+ dbTableCaches,
+ new String[] { "geocode" },
+ specifySql.toString(),
+ null,
+ null,
+ null,
+ "geocode");
+ }
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- cursor.moveToFirst();
- int index = cursor.getColumnIndex("geocode");
-
- do {
- geocodes.add(cursor.getString(index));
- } while (cursor.moveToNext());
- }
+ if (cursor.moveToFirst()) {
+ final int index = cursor.getColumnIndex("geocode");
- cursor.close();
+ do {
+ geocodes.add(cursor.getString(index));
+ } while (cursor.moveToNext());
}
+ cursor.close();
+
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.loadBatchOfStoredGeocodes: " + e.toString());
+ Log.e("cgData.loadBatchOfStoredGeocodes: " + e.toString());
}
return geocodes;
@@ -2712,58 +2272,46 @@ public class cgData {
cursor.close();
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.loadBatchOfHistoricGeocodes: " + e.toString());
+ Log.e("cgData.loadBatchOfHistoricGeocodes: " + e.toString());
}
return geocodes;
}
/** Retrieve all stored caches from DB */
- public Set<String> loadCachedInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) {
- return loadInViewport(false, centerLat, centerLon, spanLat, spanLon, cacheType);
+ public Set<String> loadCachedInViewport(final Viewport viewport, final CacheType cacheType) {
+ return loadInViewport(false, viewport, cacheType);
}
/** Retrieve stored caches from DB with listId >= 1 */
- public Set<String> loadStoredInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) {
- return loadInViewport(true, centerLat, centerLon, spanLat, spanLon, cacheType);
+ public Set<String> loadStoredInViewport(final Viewport viewport, final CacheType cacheType) {
+ return loadInViewport(true, viewport, cacheType);
}
- public Set<String> loadInViewport(final boolean stored, final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) {
- if (centerLat == null || centerLon == null || spanLat == null || spanLon == null) {
- return null;
- }
-
+ /**
+ * Loads the geocodes of caches in a viewport from CacheCache and/or Database
+ *
+ * @param stored
+ * True - query only stored caches, False - query cached ones as well
+ * @param centerLat
+ * @param centerLon
+ * @param spanLat
+ * @param spanLon
+ * @param cacheType
+ * @return Set with geocodes
+ */
+ private Set<String> loadInViewport(final boolean stored, final Viewport viewport, final CacheType cacheType) {
init();
- Set<String> geocodes = new HashSet<String>();
+ final Set<String> geocodes = new HashSet<String>();
+
+ // if not stored only, get codes from CacheCache as well
+ if (!stored) {
+ geocodes.addAll(CacheCache.getInstance().getInViewport(viewport, cacheType));
+ }
// viewport limitation
- double latMin = (centerLat / 1e6) - ((spanLat / 1e6) / 2) - ((spanLat / 1e6) / 4);
- double latMax = (centerLat / 1e6) + ((spanLat / 1e6) / 2) + ((spanLat / 1e6) / 4);
- double lonMin = (centerLon / 1e6) - ((spanLon / 1e6) / 2) - ((spanLon / 1e6) / 4);
- double lonMax = (centerLon / 1e6) + ((spanLon / 1e6) / 2) + ((spanLon / 1e6) / 4);
- double llCache;
-
- if (latMin > latMax) {
- llCache = latMax;
- latMax = latMin;
- latMin = llCache;
- }
- if (lonMin > lonMax) {
- llCache = lonMax;
- lonMax = lonMin;
- lonMin = llCache;
- }
-
- StringBuilder where = new StringBuilder();
- where.append("latitude >= ");
- where.append(String.format((Locale) null, "%.6f", latMin));
- where.append(" and latitude <= ");
- where.append(String.format((Locale) null, "%.6f", latMax));
- where.append(" and longitude >= ");
- where.append(String.format((Locale) null, "%.6f", lonMin));
- where.append(" and longitude <= ");
- where.append(String.format((Locale) null, "%.6f", lonMax));
+ final StringBuilder where = new StringBuilder(buildCoordinateWhere(dbTableCaches, viewport));
// cacheType limitation
if (cacheType != CacheType.ALL) {
@@ -2778,7 +2326,7 @@ public class cgData {
}
try {
- Cursor cursor = databaseRO.query(
+ final Cursor cursor = databaseRO.query(
dbTableCaches,
new String[] { "geocode" },
where.toString(),
@@ -2788,110 +2336,21 @@ public class cgData {
null,
"500");
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- cursor.moveToFirst();
- int index = cursor.getColumnIndex("geocode");
-
- do {
- geocodes.add(cursor.getString(index));
- } while (cursor.moveToNext());
- } else {
- cursor.close();
- return null;
- }
-
- cursor.close();
- }
- } catch (Exception e) {
- Log.e(Settings.tag, "cgData.loadInViewport: " + e.toString());
- }
-
- return geocodes;
- }
-
- public List<String> getOfflineAll(CacheType cacheType) {
- init();
-
- List<String> geocodes = new ArrayList<String>();
-
- StringBuilder where = new StringBuilder();
-
- // cacheType limitation
- if (cacheType != CacheType.ALL) {
- where.append(cacheType);
- where.append('"');
- }
-
- // offline caches only
- if (where.length() > 0) {
- where.append(" and ");
- }
- where.append("reason >= 1");
-
- try {
- Cursor cursor = databaseRO.query(
- dbTableCaches,
- new String[] { "geocode" },
- where.toString(),
- null,
- null,
- null,
- null,
- "5000");
-
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- cursor.moveToFirst();
- int index = cursor.getColumnIndex("geocode");
-
- do {
- geocodes.add(cursor.getString(index));
- } while (cursor.moveToNext());
- } else {
- cursor.close();
- return null;
- }
+ if (cursor.moveToFirst()) {
+ final int index = cursor.getColumnIndex("geocode");
- cursor.close();
+ do {
+ geocodes.add(cursor.getString(index));
+ } while (cursor.moveToNext());
}
+ cursor.close();
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.getOfflineAll: " + e.toString());
+ Log.e("cgData.loadInViewport: " + e.toString());
}
return geocodes;
}
- public boolean markFound(String geocode) {
- if (StringUtils.isBlank(geocode)) {
- return false;
- }
-
- init();
-
- boolean result = false;
- databaseRW.beginTransaction();
- try {
- ContentValues values = new ContentValues();
- values.put("found", 1);
- int rows = databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode });
- if (rows > 0) {
- // update CacheCache
- cgCache cache = cacheCache.getCacheFromCache(geocode);
- if (cache != null) {
- cache.setFound(true);
- cacheCache.putCacheInCache(cache);
- }
- result = true;
- }
- databaseRW.setTransactionSuccessful();
- } finally {
- databaseRW.endTransaction();
- }
-
- return result;
- }
-
/** delete caches from the DB store 3 days or more before */
public void clean() {
clean(false);
@@ -2906,9 +2365,9 @@ public class cgData {
public void clean(boolean more) {
init();
- Log.d(Settings.tag, "Database clean: started");
+ Log.d("Database clean: started");
- Cursor cursor = null;
+ Cursor cursor;
Set<String> geocodes = new HashSet<String>();
try {
@@ -2951,7 +2410,7 @@ public class cgData {
final int size = geocodes.size();
if (size > 0) {
- Log.d(Settings.tag, "Database clean: removing " + size + " geocaches from listId=0");
+ Log.d("Database clean: removing " + size + " geocaches from listId=0");
removeCaches(geocodes, LoadFlags.REMOVE_ALL);
}
@@ -2959,13 +2418,13 @@ public class cgData {
final SQLiteStatement countSql = databaseRO.compileStatement("select count(_id) from " + dbTableCaches + " where reason = 0");
final int count = (int) countSql.simpleQueryForLong();
countSql.close();
- Log.d(Settings.tag, "Database clean: " + count + " geocaches remaining for listId=0");
+ Log.d("Database clean: " + count + " geocaches remaining for listId=0");
} catch (Exception e) {
- Log.w(Settings.tag, "cgData.clean: " + e.toString());
+ Log.w("cgData.clean: " + e.toString());
}
- Log.d(Settings.tag, "Database clean: finished");
+ Log.d("Database clean: finished");
}
/**
@@ -2981,7 +2440,7 @@ public class cgData {
values.put("reason", StoredList.TEMPORARY_LIST_ID);
databaseRW.update(dbTableCaches, values, "reason = ?", new String[] { Integer.toString(listId) });
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.dropList: error when updating reason", e);
+ Log.e("cgData.dropList: error when updating reason", e);
}
}
@@ -3078,20 +2537,20 @@ public class cgData {
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.saveLogOffline: " + e.toString());
+ Log.e("cgData.saveLogOffline: " + e.toString());
}
return status;
}
- public cgLog loadLogOffline(String geocode) {
+ public LogEntry loadLogOffline(String geocode) {
if (StringUtils.isBlank(geocode)) {
return null;
}
init();
- cgLog log = null;
+ LogEntry log = null;
Cursor cursor = databaseRO.query(
dbTableLogsOffline,
@@ -3106,11 +2565,11 @@ public class cgData {
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
- log = new cgLog();
+ log = new LogEntry(
+ cursor.getLong(cursor.getColumnIndex("date")),
+ LogType.getById(cursor.getInt(cursor.getColumnIndex("type"))),
+ cursor.getString(cursor.getColumnIndex("log")));
log.id = cursor.getInt(cursor.getColumnIndex("_id"));
- log.type = LogType.getById(cursor.getInt(cursor.getColumnIndex("type")));
- log.log = cursor.getString(cursor.getColumnIndex("log"));
- log.date = cursor.getLong(cursor.getColumnIndex("date"));
}
if (cursor != null) {
@@ -3160,7 +2619,7 @@ public class cgData {
return logCount.simpleQueryForLong() > 0;
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.hasLogOffline", e);
+ Log.e("cgData.hasLogOffline", e);
}
return false;
@@ -3203,7 +2662,7 @@ public class cgData {
lists.addAll(storedLists);
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.readLists: " + e.toString());
+ Log.e("cgData.readLists: " + e.toString());
}
return lists;
}
@@ -3282,11 +2741,7 @@ public class cgData {
databaseRW.endTransaction();
}
- if (id < 0) {
- return -1;
- } else {
- return (id + customListIdOffset);
- }
+ return id >= 0 ? id + customListIdOffset : -1;
}
/**
@@ -3347,40 +2802,33 @@ public class cgData {
return status;
}
- public void moveToList(String geocode, int listId) {
- if (StringUtils.isBlank(geocode)) {
+ public void moveToList(final List<cgCache> caches, final int listId) {
+ if (caches.isEmpty()) {
return;
}
-
init();
- ContentValues values = new ContentValues();
+ final ContentValues values = new ContentValues();
values.put("reason", listId);
+
databaseRW.beginTransaction();
try {
- databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { geocode });
+ for (cgCache cache : caches) {
+ databaseRW.update(dbTableCaches, values, "geocode = ?", new String[] { cache.getGeocode() });
+ cache.setListId(listId);
+ }
databaseRW.setTransactionSuccessful();
} finally {
databaseRW.endTransaction();
}
-
- // update CacheCache
- cgCache cache = cacheCache.getCacheFromCache(geocode);
- if (cache != null) {
- cache.setListId(listId);
- cacheCache.putCacheInCache(cache);
- }
}
public synchronized boolean status() {
- if (databaseRO == null || databaseRW == null || !initialized) {
- return false;
- }
+ return databaseRO != null && databaseRW != null && initialized;
- return true;
}
- public boolean removeSearchedDestination(cgDestination destination) {
+ public boolean removeSearchedDestination(Destination destination) {
boolean success = true;
if (destination == null) {
success = false;
@@ -3392,7 +2840,7 @@ public class cgData {
databaseRW.delete(dbTableSearchDestionationHistory, "_id = " + destination.getId(), null);
databaseRW.setTransactionSuccessful();
} catch (Exception e) {
- Log.e(Settings.tag, "Unable to remove searched destination", e);
+ Log.e("Unable to remove searched destination", e);
success = false;
} finally {
databaseRW.endTransaction();
@@ -3429,7 +2877,7 @@ public class cgData {
} catch (SQLiteDoneException e) {
// Do nothing, it only means we have no information on the cache
} catch (Exception e) {
- Log.e(Settings.tag, "cgData.getCacheDescription", e);
+ Log.e("cgData.getCacheDescription", e);
}
return null;
@@ -3451,7 +2899,7 @@ public class cgData {
newlyCreatedDatabase = false;
}
- private static StringBuilder whereGeocodeIn(Set<String> geocodes) {
+ private static String whereGeocodeIn(Set<String> geocodes) {
final StringBuilder where = new StringBuilder();
if (geocodes != null && geocodes.size() > 0) {
@@ -3470,7 +2918,51 @@ public class cgData {
where.append(')');
}
- return where;
+ return where.toString();
+ }
+
+ /**
+ * Loads all Waypoints in the coordinate rectangle.
+ *
+ * @param centerLat
+ * @param centerLon
+ * @param spanLat
+ * @param spanLon
+ * @param excludeDisabled
+ * @param excludeMine
+ * @return
+ */
+
+ public Set<cgWaypoint> loadWaypoints(final Viewport viewport, boolean excludeMine, boolean excludeDisabled) {
+ final StringBuilder where = new StringBuilder(buildCoordinateWhere(dbTableWaypoints, viewport));
+ if (excludeMine) {
+ where.append(" and ").append(dbTableCaches).append(".own == 0 and ").append(dbTableCaches).append(".found == 0");
+ }
+ if (excludeDisabled) {
+ where.append(" and ").append(dbTableCaches).append(".disabled == 0");
+ }
+ init();
+
+ final StringBuilder query = new StringBuilder("SELECT ");
+ for (int i = 0; i < WAYPOINT_COLUMNS.length; i++) {
+ query.append(i > 0 ? ", " : "").append(dbTableWaypoints).append('.').append(WAYPOINT_COLUMNS[i]).append(' ');
+ }
+ query.append(" FROM ").append(dbTableWaypoints).append(", ").append(dbTableCaches).append(" WHERE ").append(dbTableWaypoints).append("._id == ").append(dbTableCaches).append("._id and ").append(where);
+
+ final Cursor cursor = databaseRO.rawQuery(query.toString(), null);
+ try {
+ if (!cursor.moveToFirst()) {
+ return Collections.emptySet();
+ }
+
+ final Set<cgWaypoint> waypoints = new HashSet<cgWaypoint>();
+ do {
+ waypoints.add(createWaypointFromDatabaseContent(cursor));
+ } while (cursor.moveToNext());
+ return waypoints;
+ } finally {
+ cursor.close();
+ }
}
}
diff --git a/main/src/cgeo/geocaching/cgDestination.java b/main/src/cgeo/geocaching/cgDestination.java
deleted file mode 100644
index cf9a8ef..0000000
--- a/main/src/cgeo/geocaching/cgDestination.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package cgeo.geocaching;
-
-import cgeo.geocaching.geopoint.Geopoint;
-
-public class cgDestination {
-
- private long id;
-
- private long date;
-
- private Geopoint coords;
-
- public cgDestination() {
- }
-
- public cgDestination(long id, long date, final Geopoint coords) {
- super();
- this.id = id;
- this.date = date;
- this.coords = coords;
- }
-
- public long getDate() {
- return date;
- }
-
- public void setDate(long date) {
- this.date = date;
- }
-
- public Geopoint getCoords() {
- return coords;
- }
-
- public void setCoords(final Geopoint coords) {
- this.coords = coords;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- long temp;
- temp = Double.doubleToLongBits(coords.getLatitude());
- result = prime * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(coords.getLongitude());
- result = prime * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof cgDestination)) {
- return false;
- }
- cgDestination other = (cgDestination) obj;
- return coords.isEqualTo(other.coords);
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
-}
diff --git a/main/src/cgeo/geocaching/cgGeo.java b/main/src/cgeo/geocaching/cgGeo.java
deleted file mode 100644
index dcad1ba..0000000
--- a/main/src/cgeo/geocaching/cgGeo.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package cgeo.geocaching;
-
-import cgeo.geocaching.enumerations.LocationProviderType;
-import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.go4cache.Go4Cache;
-
-import android.content.Context;
-import android.location.GpsSatellite;
-import android.location.GpsStatus;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.util.Iterator;
-
-public class cgGeo {
-
- private static final String LAST_LOCATION_PSEUDO_PROVIDER = "last";
- private final LocationManager geoManager = (LocationManager) cgeoapplication.getInstance().getSystemService(Context.LOCATION_SERVICE);
- private UpdateLocationCallback updateLocationCallback = null;
- private final AbstractLocationListener networkListener = new NetworkLocationListener();
- private final AbstractLocationListener gpsListener = new GpsLocationListener();
- private final GpsStatusListener gpsStatusListener = new GpsStatusListener();
- private Location locGps = null;
- private Location locNet = null;
- private long locGpsLast = 0L;
- public Location location = null;
- public LocationProviderType locationProvider = LocationProviderType.LAST;
- public Geopoint coordsNow = null;
- public Double altitudeNow = null;
- public float bearingNow = 0;
- public float speedNow = 0;
- public float accuracyNow = -1f;
- public int satellitesVisible = 0;
- public int satellitesFixed = 0;
-
- public cgGeo() {
- restoreLastLocation();
-
- geoManager.addGpsStatusListener(gpsStatusListener);
-
- for (AbstractLocationListener listener : new AbstractLocationListener[] { networkListener, gpsListener }) {
- try {
- geoManager.requestLocationUpdates(listener.locationProvider, 0, 0, listener);
- } catch (Exception e) {
- Log.w(Settings.tag, "There is no location provider " + listener.locationProvider);
- }
- }
- }
-
- public void closeGeo() {
- geoManager.removeUpdates(networkListener);
- geoManager.removeUpdates(gpsListener);
- geoManager.removeGpsStatusListener(gpsStatusListener);
- }
-
- public void replaceUpdate(UpdateLocationCallback callback) {
- updateLocationCallback = callback;
- fireLocationCallback();
- }
-
- private void fireLocationCallback() {
- if (updateLocationCallback != null) {
- updateLocationCallback.updateLocation(this);
- }
- }
-
- private static abstract class AbstractLocationListener implements LocationListener {
- private final String locationProvider;
-
- protected AbstractLocationListener(String provider) {
- this.locationProvider = provider;
- }
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- // nothing
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- // nothing
- }
-
- @Override
- public void onProviderEnabled(String provider) {
- // nothing
- }
- }
-
- private final class GpsLocationListener extends AbstractLocationListener {
-
- public GpsLocationListener() {
- super(LocationManager.GPS_PROVIDER);
- }
-
- @Override
- public void onLocationChanged(Location location) {
- locGps = location;
- locGpsLast = System.currentTimeMillis();
- selectBest(location.getProvider());
- }
- }
-
- private final class NetworkLocationListener extends AbstractLocationListener {
-
- protected NetworkLocationListener() {
- super(LocationManager.NETWORK_PROVIDER);
- }
-
- @Override
- public void onLocationChanged(Location location) {
- locNet = location;
- selectBest(location.getProvider());
- }
-
- }
-
- private final class GpsStatusListener implements GpsStatus.Listener {
-
- @Override
- public void onGpsStatusChanged(int event) {
- if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) {
- final GpsStatus status = geoManager.getGpsStatus(null);
- final Iterator<GpsSatellite> statusIterator = status.getSatellites().iterator();
-
- int satellites = 0;
- int fixed = 0;
-
- while (statusIterator.hasNext()) {
- GpsSatellite sat = statusIterator.next();
- if (sat.usedInFix()) {
- fixed++;
- }
- satellites++;
- }
-
- boolean changed = false;
- if (satellites != satellitesVisible) {
- satellitesVisible = satellites;
- changed = true;
- }
- if (fixed != satellitesFixed) {
- satellitesFixed = fixed;
- changed = true;
- }
-
- if (changed) {
- selectBest(null);
- }
- }
- }
- }
-
- private void selectBest(final String signallingProvider) {
- if (locNet != null && locGps == null) { // we have only NET
- assign(locNet);
- }
- else if ((locNet == null && locGps != null) // we have only GPS
- || (satellitesFixed > 0) // GPS seems to be fixed
- || (signallingProvider != null && signallingProvider.equals(LocationManager.GPS_PROVIDER)) // we have new location from GPS
- || locGpsLast > (System.currentTimeMillis() - 30 * 1000) // GPS was working in last 30 seconds
- ) {
- assign(locGps);
- }
- else {
- assign(locNet); // nothing else, using NET
- }
- }
-
- private void assignLastLocation(final Geopoint coords) {
- if (coords == null) {
- return;
- }
-
- locationProvider = LocationProviderType.LAST;
- coordsNow = coords;
- altitudeNow = null;
- bearingNow = 0f;
- speedNow = 0f;
- accuracyNow = 999f;
-
- fireLocationCallback();
- }
-
- private void assign(final Location loc) {
- if (loc == null) {
- locationProvider = LocationProviderType.LAST;
- return;
- }
-
- location = loc;
-
- final String provider = location.getProvider();
- if (provider.equals(LocationManager.GPS_PROVIDER)) {
- locationProvider = LocationProviderType.GPS;
- } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) {
- locationProvider = LocationProviderType.NETWORK;
- } else if (provider.equalsIgnoreCase(LAST_LOCATION_PSEUDO_PROVIDER)) {
- locationProvider = LocationProviderType.LAST;
- }
-
- coordsNow = new Geopoint(location.getLatitude(), location.getLongitude());
- cgeoapplication.getInstance().setLastCoords(coordsNow);
-
- if (location.hasAltitude() && locationProvider != LocationProviderType.LAST) {
- altitudeNow = location.getAltitude() + Settings.getAltCorrection();
- } else {
- altitudeNow = null;
- }
- if (location.hasBearing() && locationProvider != LocationProviderType.LAST) {
- bearingNow = location.getBearing();
- } else {
- bearingNow = 0f;
- }
- if (location.hasSpeed() && locationProvider != LocationProviderType.LAST) {
- speedNow = location.getSpeed();
- } else {
- speedNow = 0f;
- }
- if (location.hasAccuracy() && locationProvider != LocationProviderType.LAST) {
- accuracyNow = location.getAccuracy();
- } else {
- accuracyNow = 999f;
- }
-
- fireLocationCallback();
-
- if (locationProvider == LocationProviderType.GPS || locationProvider == LocationProviderType.NETWORK) {
- Go4Cache.signalCoordinates(coordsNow);
- }
- }
-
- private void restoreLastLocation() {
- // restore from last location (stored by app)
- assignLastLocation(cgeoapplication.getInstance().getLastCoords());
-
- // restore from last location (stored by device sensors)
- for (String provider : new String[] { LocationManager.GPS_PROVIDER, LocationManager.NETWORK_PROVIDER }) {
- final Location lastLocation = geoManager.getLastKnownLocation(provider);
- if (lastLocation != null) {
- lastLocation.setProvider(LAST_LOCATION_PSEUDO_PROVIDER);
- assign(lastLocation);
-
- Log.i(Settings.tag, "Using last location from " + provider);
- break;
- }
- }
- }
-}
diff --git a/main/src/cgeo/geocaching/cgLog.java b/main/src/cgeo/geocaching/cgLog.java
deleted file mode 100644
index 2b3568d..0000000
--- a/main/src/cgeo/geocaching/cgLog.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package cgeo.geocaching;
-
-import cgeo.geocaching.enumerations.LogType;
-
-import java.util.List;
-
-public class cgLog {
- public int id = 0;
- public LogType type = LogType.LOG_NOTE; // note
- public String author = "";
- public String log = "";
- public long date = 0;
- public int found = -1;
- /** Friend's logentry */
- public boolean friend = false;
- public List<cgImage> logImages = null;
- public String cacheName = ""; // used for trackables
- public String cacheGuid = ""; // used for trackables
-
- @Override
- public int hashCode() {
- return (int) date * type.hashCode() * author.hashCode() * log.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof cgLog)) {
- return false;
- }
- final cgLog otherLog = (cgLog) obj;
- return date == otherLog.date &&
- type == otherLog.type &&
- author.compareTo(otherLog.author) == 0 &&
- log.compareTo(otherLog.log) == 0 ? true : false;
- }
-}
diff --git a/main/src/cgeo/geocaching/cgSearchHandler.java b/main/src/cgeo/geocaching/cgSearchHandler.java
index 8e8dffd..6d38ea1 100644
--- a/main/src/cgeo/geocaching/cgSearchHandler.java
+++ b/main/src/cgeo/geocaching/cgSearchHandler.java
@@ -1,5 +1,7 @@
package cgeo.geocaching;
+import cgeo.geocaching.utils.Log;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
@@ -8,7 +10,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
@@ -98,7 +99,7 @@ public class cgSearchHandler extends Handler {
imgHandler.sendEmptyMessage(0);
} catch (IOException e) {
- Log.e(Settings.tag, "Failed to download reCAPTCHA image");
+ Log.e("Failed to download reCAPTCHA image");
}
}
}
diff --git a/main/src/cgeo/geocaching/cgSearchThread.java b/main/src/cgeo/geocaching/cgSearchThread.java
index 3daddc5..ff73a66 100644
--- a/main/src/cgeo/geocaching/cgSearchThread.java
+++ b/main/src/cgeo/geocaching/cgSearchThread.java
@@ -1,7 +1,8 @@
package cgeo.geocaching;
+import cgeo.geocaching.utils.Log;
+
import android.os.Handler;
-import android.util.Log;
abstract public class cgSearchThread extends Thread {
private Handler recaptchaHandler = null;
@@ -22,7 +23,7 @@ abstract public class cgSearchThread extends Thread {
try {
wait();
} catch (InterruptedException e) {
- Log.w(Settings.tag, "searchThread is not waiting for user...");
+ Log.w("searchThread is not waiting for user...");
}
}
diff --git a/main/src/cgeo/geocaching/cgTrackable.java b/main/src/cgeo/geocaching/cgTrackable.java
index b5fc215..ff84833 100644
--- a/main/src/cgeo/geocaching/cgTrackable.java
+++ b/main/src/cgeo/geocaching/cgTrackable.java
@@ -1,9 +1,10 @@
package cgeo.geocaching;
+import cgeo.geocaching.utils.Log;
+
import org.apache.commons.lang3.StringUtils;
import android.text.Html;
-import android.util.Log;
import java.util.ArrayList;
import java.util.Date;
@@ -16,7 +17,6 @@ public class cgTrackable implements ILogable {
static final public int SPOTTED_UNKNOWN = 3;
static final public int SPOTTED_OWNER = 4;
- private String error = "";
private String guid = "";
private String geocode = "";
private String iconUrl = "";
@@ -33,7 +33,7 @@ public class cgTrackable implements ILogable {
private String goal = null;
private String details = null;
private String image = null;
- private List<cgLog> logs = new ArrayList<cgLog>();
+ private List<LogEntry> logs = new ArrayList<LogEntry>();
private String trackingcode = null;
public String getUrl() {
@@ -43,17 +43,13 @@ public class cgTrackable implements ILogable {
int id = Integer.parseInt(hex, 16);
return "http://geokrety.org/konkret.php?id=" + id;
} catch (NumberFormatException e) {
- Log.e(Settings.tag, "cgTrackable.getUrl", e);
+ Log.e("cgTrackable.getUrl", e);
return null;
}
}
return "http://coord.info/" + geocode.toUpperCase();
}
- public String getError() {
- return error;
- }
-
public String getGuid() {
return guid;
}
@@ -187,11 +183,11 @@ public class cgTrackable implements ILogable {
this.image = image;
}
- public List<cgLog> getLogs() {
+ public List<LogEntry> getLogs() {
return logs;
}
- public void setLogs(List<cgLog> logs) {
+ public void setLogs(List<LogEntry> logs) {
this.logs = logs;
}
@@ -209,10 +205,7 @@ public class cgTrackable implements ILogable {
}
public boolean isLoggable() {
- if (StringUtils.startsWithIgnoreCase(geocode, "GK")) {
- return false;
- }
- return true;
+ return !StringUtils.startsWithIgnoreCase(geocode, "GK");
}
public String getTrackingcode() {
diff --git a/main/src/cgeo/geocaching/cgTrackableLog.java b/main/src/cgeo/geocaching/cgTrackableLog.java
deleted file mode 100644
index ee134da..0000000
--- a/main/src/cgeo/geocaching/cgTrackableLog.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package cgeo.geocaching;
-
-import cgeo.geocaching.enumerations.LogTypeTrackable;
-
-public class cgTrackableLog {
- public int ctl = -1;
- public int id = -1;
- public String trackCode = null;
- public String name = null;
- public LogTypeTrackable action = LogTypeTrackable.DO_NOTHING; // base.logTrackablesAction - no action
-}
diff --git a/main/src/cgeo/geocaching/cgWaypoint.java b/main/src/cgeo/geocaching/cgWaypoint.java
index b13c141..ee865ee 100644
--- a/main/src/cgeo/geocaching/cgWaypoint.java
+++ b/main/src/cgeo/geocaching/cgWaypoint.java
@@ -179,10 +179,6 @@ public class cgWaypoint implements IWaypoint, Comparable<cgWaypoint> {
return waypointType;
}
- public void setWaypointType(WaypointType type) {
- this.waypointType = type;
- }
-
public String getLookup() {
return lookup;
}
@@ -223,14 +219,6 @@ public class cgWaypoint implements IWaypoint, Comparable<cgWaypoint> {
this.note = note;
}
- public int getCachedOrder() {
- return cachedOrder;
- }
-
- public void setCachedOrder(int cachedOrder) {
- this.cachedOrder = cachedOrder;
- }
-
@Override
public String toString() {
return name + " " + waypointType.getL10n();
@@ -244,4 +232,9 @@ public class cgWaypoint implements IWaypoint, Comparable<cgWaypoint> {
public boolean isFinalWithCoords() {
return WaypointType.FINAL == waypointType && null != coords;
}
+
+ @Override
+ public String getCoordType() {
+ return "waypoint";
+ }
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/cgeo.java b/main/src/cgeo/geocaching/cgeo.java
index 7367d82..019d217 100644
--- a/main/src/cgeo/geocaching/cgeo.java
+++ b/main/src/cgeo/geocaching/cgeo.java
@@ -2,18 +2,16 @@ package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.activity.ActivityMixin;
-import cgeo.geocaching.enumerations.CacheSize;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.enumerations.CacheType;
-import cgeo.geocaching.enumerations.LiveMapStrategy.Strategy;
-import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.StatusCode;
-import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.HumanDistance;
import cgeo.geocaching.geopoint.IConversion;
import cgeo.geocaching.maps.CGeoMap;
-import cgeo.geocaching.network.Login;
import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.utils.IObserver;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -25,6 +23,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.location.Address;
@@ -32,7 +31,6 @@ import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
@@ -60,8 +58,6 @@ public class cgeo extends AbstractActivity {
public static final int SEARCH_REQUEST_CODE = 2;
private int version = 0;
- private cgGeo geo = null;
- private UpdateLocationCallback geoUpdate = null;
private TextView filterTitle = null;
private boolean cleanupRunning = false;
private int countBubbleCnt = 0;
@@ -70,6 +66,8 @@ public class cgeo extends AbstractActivity {
private boolean addressObtaining = false;
private boolean initialized = false;
+ final private UpdateLocation locationUpdater = new UpdateLocation();
+
private Handler updateUserInfoHandler = new Handler() {
@Override
@@ -115,9 +113,7 @@ public class cgeo extends AbstractActivity {
addText.append(address.getAdminArea());
}
- if (geo != null) {
- addCoords = geo.coordsNow;
- }
+ addCoords = app.currentGeo().getCoords();
TextView navLocation = (TextView) findViewById(R.id.nav_location);
navLocation.setText(addText.toString());
@@ -130,6 +126,44 @@ public class cgeo extends AbstractActivity {
}
};
+ private class SatellitesHandler extends Handler implements IObserver<IGeoData> {
+
+ private boolean gpsEnabled = false;
+ private int satellitesFixed = 0;
+ private int satellitesVisible = 0;
+
+ @Override
+ public void handleMessage(final Message msg) {
+ final IGeoData data = (IGeoData) msg.obj;
+ if (data.getGpsEnabled() == gpsEnabled &&
+ data.getSatellitesFixed() == satellitesFixed &&
+ data.getSatellitesVisible() == satellitesVisible) {
+ return;
+ }
+ gpsEnabled = data.getGpsEnabled();
+ satellitesFixed = data.getSatellitesFixed();
+ satellitesVisible = data.getSatellitesVisible();
+
+ final TextView navSatellites = (TextView) findViewById(R.id.nav_satellites);
+ if (gpsEnabled) {
+ if (satellitesFixed > 0) {
+ navSatellites.setText(res.getString(R.string.loc_sat) + ": " + satellitesFixed + '/' + satellitesVisible);
+ } else if (satellitesVisible >= 0) {
+ navSatellites.setText(res.getString(R.string.loc_sat) + ": 0/" + satellitesVisible);
+ }
+ } else {
+ navSatellites.setText(res.getString(R.string.loc_gps_disabled));
+ }
+ }
+
+ @Override
+ public void update(final IGeoData data) {
+ obtainMessage(0, data).sendToTarget();
+ }
+ }
+
+ private SatellitesHandler satellitesHandler = new SatellitesHandler();
+
private Handler firstLoginHandler = new Handler() {
@Override
@@ -141,7 +175,7 @@ public class cgeo extends AbstractActivity {
showToast(res.getString(reason == StatusCode.MAINTENANCE ? reason.getErrorString() : R.string.err_login_failed_toast));
}
} catch (Exception e) {
- Log.w(Settings.tag, "cgeo.fisrtLoginHander: " + e.toString());
+ Log.w("cgeo.firstLoginHander: " + e.toString());
}
}
};
@@ -156,29 +190,22 @@ public class cgeo extends AbstractActivity {
app.setAction(null);
- app.cleanGeo();
app.cleanDir();
setContentView(R.layout.main);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); // type to search
try {
- PackageManager manager = this.getPackageManager();
- PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);
-
+ final PackageInfo info = getPackageManager().getPackageInfo(this.getPackageName(), 0);
version = info.versionCode;
-
- Log.i(Settings.tag, "Starting " + info.packageName + " " + info.versionCode + " a.k.a " + info.versionName + "...");
-
- info = null;
- manager = null;
- } catch (Exception e) {
- Log.i(Settings.tag, "No info.");
+ Log.i("Starting " + info.packageName + " " + info.versionCode + " a.k.a " + info.versionName + "…");
+ } catch (final NameNotFoundException e) {
+ Log.i("No info.");
}
try {
if (!Settings.isHelpShown()) {
- RelativeLayout helper = (RelativeLayout) findViewById(R.id.helper);
+ final RelativeLayout helper = (RelativeLayout) findViewById(R.id.helper);
if (helper != null) {
helper.setVisibility(View.VISIBLE);
helper.setClickable(true);
@@ -209,9 +236,9 @@ public class cgeo extends AbstractActivity {
@Override
public void onResume() {
super.onResume();
-
+ app.addGeoObserver(locationUpdater);
+ app.addGeoObserver(satellitesHandler);
updateUserInfoHandler.sendEmptyMessage(-1);
-
init();
}
@@ -220,32 +247,20 @@ public class cgeo extends AbstractActivity {
initialized = false;
app.showLoginToast = true;
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onDestroy();
}
@Override
public void onStop() {
initialized = false;
-
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onStop();
}
@Override
public void onPause() {
initialized = false;
-
- if (geo != null) {
- geo = app.removeGeo();
- }
-
+ app.deleteGeoObserver(locationUpdater);
+ app.deleteGeoObserver(satellitesHandler);
super.onPause();
}
@@ -345,11 +360,8 @@ public class cgeo extends AbstractActivity {
// context menu for offline button
if (v.getId() == R.id.search_offline) {
- List<StoredList> cacheLists = app.getLists();
- int listCount = cacheLists.size();
menu.setHeaderTitle(res.getString(R.string.list_title));
- for (int i = 0; i < listCount; i++) {
- StoredList list = cacheLists.get(i);
+ for (final StoredList list : app.getLists()) {
menu.add(Menu.NONE, MENU_OPEN_LIST + list.id, Menu.NONE, list.getTitleAndCount());
}
return;
@@ -398,23 +410,22 @@ public class cgeo extends AbstractActivity {
}
@Override
- public boolean onContextItemSelected(MenuItem item) {
+ public boolean onContextItemSelected(final MenuItem item) {
final int id = item.getItemId();
+ if (id < 0) {
+ return false;
+ }
if (id == 0) {
Settings.setCacheType(CacheType.ALL);
setFilterTitle();
-
- return true;
} else if (id > MENU_OPEN_LIST) {
- int listId = id - MENU_OPEN_LIST;
- Settings.saveLastList(listId);
+ Settings.saveLastList(id - MENU_OPEN_LIST);
cgeocaches.startActivityOffline(this);
- return true;
- } else if (id > 0) {
+ } else {
final String itemTitle = item.getTitle().toString();
CacheType cacheType = CacheType.ALL;
- for (CacheType ct : CacheType.values()) {
+ for (final CacheType ct : CacheType.values()) {
if (ct.getL10n().equalsIgnoreCase(itemTitle)) {
cacheType = ct;
break;
@@ -422,11 +433,9 @@ public class cgeo extends AbstractActivity {
}
Settings.setCacheType(cacheType);
setFilterTitle();
-
- return true;
}
- return false;
+ return true;
}
private void setFilterTitle() {
@@ -452,40 +461,12 @@ public class cgeo extends AbstractActivity {
initialized = true;
Settings.setLanguage(Settings.isUseEnglish());
-
- /*
- * "update" the cache size/type. For a better performance
- * the resource strings are stored in the enum's. In case of a
- * locale change the resource strings don't get updated automatically.
- * That's why we have to do it on our own.
- */
- for (CacheSize cacheSize : CacheSize.values()) {
- cacheSize.setL10n();
- }
- for (CacheType cacheType : CacheType.values()) {
- cacheType.setL10n();
- }
- for (LogType logType : LogType.values()) {
- logType.setL10n();
- }
- for (WaypointType waypointType : WaypointType.values()) {
- waypointType.setL10n();
- }
- for (Strategy strategy : Strategy.values()) {
- strategy.setL10n();
- }
-
Settings.getLogin();
if (app.firstRun) {
(new firstLogin()).start();
}
- if (geo == null) {
- geoUpdate = new UpdateLocation();
- geo = app.startGeo(geoUpdate);
- }
-
final View findOnMap = findViewById(R.id.map);
findOnMap.setClickable(true);
findOnMap.setOnClickListener(new OnClickListener() {
@@ -565,22 +546,16 @@ public class cgeo extends AbstractActivity {
.show();
}
- private class UpdateLocation implements UpdateLocationCallback {
-
- private final View nearestView = findViewById(R.id.nearest);
- private final TextView navType = (TextView) findViewById(R.id.nav_type);
- private final TextView navAccuracy = (TextView) findViewById(R.id.nav_accuracy);
- private final TextView navSatellites = (TextView) findViewById(R.id.nav_satellites);
- private final TextView navLocation = (TextView) findViewById(R.id.nav_location);
+ private class UpdateLocation extends GeoObserver {
@Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
- }
-
+ public void updateLocation(final IGeoData geo) {
+ final View nearestView = findViewById(R.id.nearest);
+ final TextView navType = (TextView) findViewById(R.id.nav_type);
+ final TextView navAccuracy = (TextView) findViewById(R.id.nav_accuracy);
+ final TextView navLocation = (TextView) findViewById(R.id.nav_location);
try {
- if (geo.coordsNow != null) {
+ if (geo.getCoords() != null) {
if (!nearestView.isClickable()) {
nearestView.setFocusable(true);
nearestView.setClickable(true);
@@ -592,23 +567,14 @@ public class cgeo extends AbstractActivity {
nearestView.setBackgroundResource(R.drawable.main_nearby);
}
- String satellites = null;
- if (geo.satellitesFixed > 0) {
- satellites = res.getString(R.string.loc_sat) + ": " + geo.satellitesFixed + "/" + geo.satellitesVisible;
- } else if (geo.satellitesVisible >= 0) {
- satellites = res.getString(R.string.loc_sat) + ": 0/" + geo.satellitesVisible;
- } else {
- satellites = "";
- }
- navSatellites.setText(satellites);
- navType.setText(res.getString(geo.locationProvider.resourceId));
+ navType.setText(res.getString(geo.getLocationProvider().resourceId));
- if (geo.accuracyNow >= 0) {
- int speed = Math.round(geo.speedNow) * 60 * 60 / 1000;
+ if (geo.getAccuracy() >= 0) {
+ int speed = Math.round(geo.getSpeed()) * 60 * 60 / 1000;
if (Settings.isUseMetricUnits()) {
- navAccuracy.setText("±" + Math.round(geo.accuracyNow) + " m" + Formatter.SEPARATOR + speed + " km/h");
+ navAccuracy.setText("±" + Math.round(geo.getAccuracy()) + " m" + Formatter.SEPARATOR + speed + " km/h");
} else {
- navAccuracy.setText("±" + Math.round(geo.accuracyNow * IConversion.METERS_TO_FEET) + " ft" + Formatter.SEPARATOR + speed / IConversion.MILES_TO_KILOMETER + " mph");
+ navAccuracy.setText("±" + Math.round(geo.getAccuracy() * IConversion.METERS_TO_FEET) + " ft" + Formatter.SEPARATOR + speed / IConversion.MILES_TO_KILOMETER + " mph");
}
} else {
navAccuracy.setText(null);
@@ -618,15 +584,15 @@ public class cgeo extends AbstractActivity {
if (addCoords == null) {
navLocation.setText(res.getString(R.string.loc_no_addr));
}
- if (addCoords == null || (geo.coordsNow.distanceTo(addCoords) > 0.5 && !addressObtaining)) {
+ if (addCoords == null || (geo.getCoords().distanceTo(addCoords) > 0.5 && !addressObtaining)) {
(new ObtainAddressThread()).start();
}
} else {
- if (geo.altitudeNow != null) {
- final String humanAlt = HumanDistance.getHumanDistance(geo.altitudeNow.floatValue() / 1000);
- navLocation.setText(geo.coordsNow + " | " + humanAlt);
+ if (geo.getAltitude() != 0.0) {
+ final String humanAlt = HumanDistance.getHumanDistance((float) geo.getAltitude() / 1000);
+ navLocation.setText(geo.getCoords() + " | " + humanAlt);
} else {
- navLocation.setText(geo.coordsNow.toString());
+ navLocation.setText(geo.getCoords().toString());
}
}
} else {
@@ -641,7 +607,7 @@ public class cgeo extends AbstractActivity {
navLocation.setText(res.getString(R.string.loc_trying));
}
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
+ Log.w("Failed to update location.");
}
}
}
@@ -660,12 +626,12 @@ public class cgeo extends AbstractActivity {
* unused here but needed since this method is referenced from XML layout
*/
public void cgeoFindNearest(View v) {
- if (geo == null || geo.coordsNow == null) {
+ if (app.currentGeo().getCoords() == null) {
return;
}
findViewById(R.id.nearest).setPressed(true);
- cgeocaches.startActivityNearest(this, geo.coordsNow);
+ cgeocaches.startActivityNearest(this, app.currentGeo().getCoords());
}
/**
@@ -704,6 +670,14 @@ public class cgeo extends AbstractActivity {
findViewById(R.id.filter_button).performClick();
}
+ /**
+ * @param v
+ * unused here but needed since this method is referenced from XML layout
+ */
+ public void cgeoNavSettings(View v) {
+ startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
+ }
+
private class CountBubbleUpdateThread extends Thread {
private Handler countBubbleHandler = new Handler() {
private TextView countBubble = null;
@@ -723,7 +697,7 @@ public class cgeo extends AbstractActivity {
countBubble.setVisibility(View.VISIBLE);
}
} catch (Exception e) {
- Log.w(Settings.tag, "cgeo.countBubbleHander: " + e.toString());
+ Log.w("cgeo.countBubbleHander: " + e.toString());
}
}
};
@@ -748,7 +722,7 @@ public class cgeo extends AbstractActivity {
}
}
- countBubbleCnt = app.getAllStoredCachesCount(true, CacheType.ALL, null);
+ countBubbleCnt = app.getAllStoredCachesCount(true, CacheType.ALL);
countBubbleHandler.sendEmptyMessage(0);
}
@@ -767,7 +741,7 @@ public class cgeo extends AbstractActivity {
boolean more = false;
if (version != Settings.getVersion()) {
- Log.i(Settings.tag, "Initializing hard cleanup - version changed from " + Settings.getVersion() + " to " + version + ".");
+ Log.i("Initializing hard cleanup - version changed from " + Settings.getVersion() + " to " + version + ".");
more = true;
}
@@ -805,9 +779,7 @@ public class cgeo extends AbstractActivity {
// invoke settings activity to insert login details
if (status == StatusCode.NO_LOGIN_INFO_STORED) {
- final Context context = cgeo.this;
- final Intent initIntent = new Intent(context, cgeoinit.class);
- context.startActivity(initIntent);
+ cgeoinit.startActivity(cgeo.this);
}
}
}
@@ -821,9 +793,6 @@ public class cgeo extends AbstractActivity {
@Override
public void run() {
- if (geo == null) {
- return;
- }
if (addressObtaining) {
return;
}
@@ -831,10 +800,10 @@ public class cgeo extends AbstractActivity {
try {
final Geocoder geocoder = new Geocoder(cgeo.this, Locale.getDefault());
-
- addresses = geocoder.getFromLocation(geo.coordsNow.getLatitude(), geo.coordsNow.getLongitude(), 1);
+ final Geopoint coords = app.currentGeo().getCoords();
+ addresses = geocoder.getFromLocation(coords.getLatitude(), coords.getLongitude(), 1);
} catch (Exception e) {
- Log.i(Settings.tag, "Failed to obtain address");
+ Log.i("Failed to obtain address");
}
obtainAddressHandler.sendEmptyMessage(0);
diff --git a/main/src/cgeo/geocaching/cgeoabout.java b/main/src/cgeo/geocaching/cgeoabout.java
index 1fc6605..f112539 100644
--- a/main/src/cgeo/geocaching/cgeoabout.java
+++ b/main/src/cgeo/geocaching/cgeoabout.java
@@ -1,14 +1,13 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.utils.Log;
import android.content.Intent;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
-import android.util.Log;
import android.view.View;
import android.widget.TextView;
@@ -27,17 +26,13 @@ public class cgeoabout extends AbstractActivity {
private void init() {
try {
- PackageManager manager = this.getPackageManager();
- PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);
+ final PackageInfo info = getPackageManager().getPackageInfo(this.getPackageName(), 0);
setTitle(res.getString(R.string.about) + " (ver. " + info.versionName + ")");
-
- manager = null;
-
((TextView) findViewById(R.id.contributors)).setMovementMethod(LinkMovementMethod.getInstance());
((TextView) findViewById(R.id.changelog)).setMovementMethod(LinkMovementMethod.getInstance());
} catch (Exception e) {
- Log.e(Settings.tag, "cgeoabout.init: Failed to obtain package version.");
+ Log.e("cgeoabout.init: Failed to obtain package version.");
}
}
diff --git a/main/src/cgeo/geocaching/cgeoadvsearch.java b/main/src/cgeo/geocaching/cgeoadvsearch.java
index db0088c..4fac391 100644
--- a/main/src/cgeo/geocaching/cgeoadvsearch.java
+++ b/main/src/cgeo/geocaching/cgeoadvsearch.java
@@ -4,9 +4,10 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.connector.gc.GCConstants;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.geopoint.GeopointParser;
import cgeo.geocaching.utils.BaseUtils;
import cgeo.geocaching.utils.EditUtils;
+import cgeo.geocaching.utils.IObserver;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
@@ -14,7 +15,6 @@ import android.app.SearchManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -24,16 +24,13 @@ import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
-public class cgeoadvsearch extends AbstractActivity {
+public class cgeoadvsearch extends AbstractActivity implements IObserver<IGeoData> {
public static final String EXTRAS_KEYWORDSEARCH = "keywordsearch";
private static final int MENU_SEARCH_OWN_CACHES = 1;
- private cgGeo geo = null;
- private UpdateLocationCallback geoUpdate = new update();
private EditText latEdit = null;
private EditText lonEdit = null;
- private String[] geocodesInCache = null;
public cgeoadvsearch() {
super("c:geo-search");
@@ -80,34 +77,13 @@ public class cgeoadvsearch extends AbstractActivity {
@Override
public void onResume() {
super.onResume();
-
+ app.addGeoObserver(this);
init();
}
@Override
- public void onDestroy() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
- super.onDestroy();
- }
-
- @Override
- public void onStop() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
- super.onStop();
- }
-
- @Override
public void onPause() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
+ app.deleteGeoObserver(this);
super.onPause();
}
@@ -121,32 +97,25 @@ public class cgeoadvsearch extends AbstractActivity {
* @return true if a search was performed, else false
*/
private boolean instantSearch(final String query, final boolean keywordSearch) {
- try {
- String result = BaseUtils.getMatch(query, GCConstants.PATTERN_GC_CODE, true, 0, "", false);
- if (StringUtils.isNotBlank(result)) {
- final Intent cachesIntent = new Intent(this, CacheDetailActivity.class);
- cachesIntent.putExtra("geocode", result.toUpperCase());
- startActivity(cachesIntent);
+ final String geocode = BaseUtils.getMatch(query, GCConstants.PATTERN_GC_CODE, true, 0, "", false);
+ if (StringUtils.isNotBlank(geocode)) {
+ final Intent cachesIntent = new Intent(this, CacheDetailActivity.class);
+ cachesIntent.putExtra("geocode", geocode.toUpperCase());
+ startActivity(cachesIntent);
+ return true;
+ }
- return true;
- } else {
- result = BaseUtils.getMatch(query, GCConstants.PATTERN_TB_CODE, true, 0, "", false);
- if (StringUtils.isNotBlank(result)) {
- final Intent trackablesIntent = new Intent(this, cgeotrackable.class);
- trackablesIntent.putExtra("geocode", result.toUpperCase());
- startActivity(trackablesIntent);
-
- return true;
- } else if (keywordSearch) { // keyword fallback, if desired by caller
- cgeocaches.startActivityKeyword(this, query.trim());
- return true;
- } else {
- return false;
- }
+ final String trackable = BaseUtils.getMatch(query, GCConstants.PATTERN_TB_CODE, true, 0, "", false);
+ if (StringUtils.isNotBlank(trackable)) {
+ final Intent trackablesIntent = new Intent(this, cgeotrackable.class);
+ trackablesIntent.putExtra("geocode", trackable.toUpperCase());
+ startActivity(trackablesIntent);
+ return true;
+ }
- }
- } catch (Exception e) {
- Log.w(Settings.tag, "cgeoadvsearch.instantSearch: " + e.toString());
+ if (keywordSearch) { // keyword fallback, if desired by caller
+ cgeocaches.startActivityKeyword(this, query.trim());
+ return true;
}
return false;
@@ -155,10 +124,6 @@ public class cgeoadvsearch extends AbstractActivity {
private void init() {
Settings.getLogin();
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
-
((Button) findViewById(R.id.buttonLatitude)).setOnClickListener(new findByCoordsAction());
((Button) findViewById(R.id.buttonLongitude)).setOnClickListener(new findByCoordsAction());
@@ -184,7 +149,7 @@ public class cgeoadvsearch extends AbstractActivity {
findByGeocodeFn();
}
});
- geocodesInCache = app.geocodesInCache();
+ final String[] geocodesInCache = app.geocodesInCache();
if (geocodesInCache != null) {
final ArrayAdapter<String> geocodesAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, geocodesInCache);
geocodeEdit.setAdapter(geocodesAdapter);
@@ -246,33 +211,26 @@ public class cgeoadvsearch extends AbstractActivity {
displayTrackable.setOnClickListener(new findTrackableListener());
}
- private class update implements UpdateLocationCallback {
-
- @Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
+ @Override
+ public void update(final IGeoData geo) {
+ try {
+ if (latEdit == null) {
+ latEdit = (EditText) findViewById(R.id.latitude);
+ }
+ if (lonEdit == null) {
+ lonEdit = (EditText) findViewById(R.id.longitude);
}
- try {
- if (latEdit == null) {
- latEdit = (EditText) findViewById(R.id.latitude);
- }
- if (lonEdit == null) {
- lonEdit = (EditText) findViewById(R.id.longitude);
+ if (geo.getCoords() != null) {
+ if (latEdit != null) {
+ latEdit.setHint(geo.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
}
-
- if (geo.coordsNow != null) {
- if (latEdit != null) {
- latEdit.setHint(geo.coordsNow.format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
- }
- if (lonEdit != null) {
- lonEdit.setHint(geo.coordsNow.format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
- }
+ if (lonEdit != null) {
+ lonEdit.setHint(geo.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
}
- } catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
}
+ } catch (Exception e) {
+ Log.w("Failed to update location.");
}
}
@@ -280,7 +238,7 @@ public class cgeoadvsearch extends AbstractActivity {
@Override
public void onClick(View arg0) {
- cgeocoords coordsDialog = new cgeocoords(cgeoadvsearch.this, null, null, geo);
+ cgeocoords coordsDialog = new cgeocoords(cgeoadvsearch.this, null, null, app.currentGeo());
coordsDialog.setCancelable(true);
coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() {
@Override
@@ -307,14 +265,15 @@ public class cgeoadvsearch extends AbstractActivity {
final String lonText = lonView.getText().toString();
if (StringUtils.isEmpty(latText) || StringUtils.isEmpty(lonText)) {
- if (geo.coordsNow != null) {
- latView.setText(geo.coordsNow.format(GeopointFormatter.Format.LAT_DECMINUTE));
- lonView.setText(geo.coordsNow.format(GeopointFormatter.Format.LON_DECMINUTE));
+ final IGeoData geo = app.currentGeo();
+ if (geo.getCoords() != null) {
+ latView.setText(geo.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE));
+ lonView.setText(geo.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE));
}
} else {
try {
- cgeocaches.startActivityCoordinates(this, GeopointParser.parseLatitude(latText), GeopointParser.parseLongitude(lonText));
- } catch (GeopointParser.ParseException e) {
+ cgeocaches.startActivityCoordinates(this, new Geopoint(latText, lonText));
+ } catch (Geopoint.ParseException e) {
showToast(res.getString(e.resource));
}
}
diff --git a/main/src/cgeo/geocaching/cgeoapplication.java b/main/src/cgeo/geocaching/cgeoapplication.java
index e2b39d8..d0ee5c3 100644
--- a/main/src/cgeo/geocaching/cgeoapplication.java
+++ b/main/src/cgeo/geocaching/cgeoapplication.java
@@ -7,6 +7,9 @@ import cgeo.geocaching.enumerations.LoadFlags.LoadFlag;
import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
+import cgeo.geocaching.utils.IObserver;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
@@ -17,13 +20,11 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import java.io.File;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -33,9 +34,7 @@ public class cgeoapplication extends Application {
private cgData storage = null;
private String action = null;
- private Geopoint lastCoords = null;
- private cgGeo geo = null;
- private boolean geoInUse = false;
+ private volatile GeoDataProvider geo;
private cgDirection dir = null;
private boolean dirInUse = false;
public boolean firstRun = true; // c:geo is just launched
@@ -54,16 +53,15 @@ public class cgeoapplication extends Application {
@Override
public void onLowMemory() {
- Log.i(Settings.tag, "Cleaning applications cache.");
+ Log.i("Cleaning applications cache.");
storage.removeAllFromCache();
}
@Override
public void onTerminate() {
- Log.d(Settings.tag, "Terminating c:geo...");
+ Log.d("Terminating c:geo...");
- cleanGeo();
cleanDir();
if (storage != null) {
@@ -114,73 +112,45 @@ public class cgeoapplication extends Application {
restoreThread.start();
}
- public void cleanGeo() {
- if (geo != null) {
- geo.closeGeo();
- geo = null;
- }
- }
-
- public void cleanDir() {
- if (dir != null) {
- dir.closeDir();
- dir = null;
- }
+ public void addGeoObserver(final IObserver<? super IGeoData> observer) {
+ currentGeoObject().addObserver(observer);
}
- public boolean storageStatus() {
- return storage.status();
+ public void deleteGeoObserver(final IObserver<? super IGeoData> observer) {
+ currentGeoObject().deleteObserver(observer);
}
- public cgGeo startGeo(UpdateLocationCallback geoUpdate) {
+ private GeoDataProvider currentGeoObject() {
if (geo == null) {
- geo = new cgGeo();
- Log.i(Settings.tag, "Location service started");
+ synchronized(this) {
+ if (geo == null) {
+ geo = new GeoDataProvider(this);
+ }
+ }
}
-
- geo.replaceUpdate(geoUpdate);
- geoInUse = true;
-
return geo;
}
- public float getSpeedFromGeo() {
- return geo != null ? geo.speedNow : 0f;
+ public IGeoData currentGeo() {
+ return currentGeoObject().getMemory();
}
- public cgGeo removeGeo() {
- if (geo != null) {
- geo.replaceUpdate(null);
+ public void cleanDir() {
+ if (dir != null) {
+ dir.closeDir();
+ dir = null;
}
- geoInUse = false;
-
- (new removeGeoThread()).start();
-
- return null;
}
- private class removeGeoThread extends Thread {
-
- @Override
- public void run() {
- try {
- sleep(2500);
- } catch (Exception e) {
- // nothing
- }
-
- if (!geoInUse && geo != null) {
- cleanGeo();
- Log.i(Settings.tag, "Location service stopped");
- }
- }
+ public boolean storageStatus() {
+ return storage.status();
}
public cgDirection startDir(Context context, UpdateDirectionCallback dirUpdate) {
if (dir == null) {
dir = new cgDirection(context, dirUpdate);
- Log.i(Settings.tag, "Direction service started");
+ Log.i("Direction service started");
}
dir.replaceUpdate(dirUpdate);
@@ -212,7 +182,7 @@ public class cgeoapplication extends Application {
if (!dirInUse && dir != null) {
cleanDir();
- Log.i(Settings.tag, "Direction service stopped");
+ Log.i("Direction service stopped");
}
}
}
@@ -264,10 +234,7 @@ public class cgeoapplication extends Application {
return null;
}
- cgTrackable trackable = null;
- trackable = storage.loadTrackable(geocode);
-
- return trackable;
+ return storage.loadTrackable(geocode);
}
/** {@link cgData#allDetailedThere()} */
@@ -275,56 +242,53 @@ public class cgeoapplication extends Application {
return storage.allDetailedThere();
}
- public List<Number> getBounds(String geocode) {
+ public Viewport getBounds(String geocode) {
if (geocode == null) {
return null;
}
- Set<String> geocodeList = new HashSet<String>();
- geocodeList.add(geocode);
-
- return getBounds(geocodeList);
+ return getBounds(Collections.singleton(geocode));
}
/** {@link cgData#getBounds(Set)} */
- public List<Number> getBounds(final Set<String> geocodes) {
+ public Viewport getBounds(final Set<String> geocodes) {
return storage.getBounds(geocodes);
}
/** {@link cgData#loadBatchOfStoredGeocodes(boolean, Geopoint, CacheType, int)} */
public SearchResult getBatchOfStoredCaches(final boolean detailedOnly, final Geopoint coords, final CacheType cacheType, final int listId) {
final Set<String> geocodes = storage.loadBatchOfStoredGeocodes(detailedOnly, coords, cacheType, listId);
- final SearchResult search = new SearchResult(geocodes);
- search.totalCnt = getAllStoredCachesCount(true, cacheType, listId);
- return search;
+ return new SearchResult(geocodes, getAllStoredCachesCount(true, cacheType, listId));
}
/** {@link cgData#loadHistoryOfSearchedLocations()} */
- public List<cgDestination> getHistoryOfSearchedLocations() {
+ public List<Destination> getHistoryOfSearchedLocations() {
return storage.loadHistoryOfSearchedLocations();
}
public SearchResult getHistoryOfCaches(final boolean detailedOnly, final CacheType cacheType) {
final Set<String> geocodes = storage.loadBatchOfHistoricGeocodes(detailedOnly, cacheType);
- final SearchResult search = new SearchResult(geocodes);
-
- search.totalCnt = getAllHistoricCachesCount();
- return search;
+ return new SearchResult(geocodes, getAllHistoricCachesCount());
}
- /** {@link cgData#loadCachedInViewport(Long, Long, Long, Long, CacheType)} */
- public SearchResult getCachedInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) {
- final Set<String> geocodes = storage.loadCachedInViewport(centerLat, centerLon, spanLat, spanLon, cacheType);
+ /** {@link cgData#loadCachedInViewport(Viewport, CacheType)} */
+ public SearchResult getCachedInViewport(final Viewport viewport, final CacheType cacheType) {
+ final Set<String> geocodes = storage.loadCachedInViewport(viewport, cacheType);
return new SearchResult(geocodes);
}
- /** {@link cgData#loadStoredInViewport(Long, Long, Long, Long, CacheType)} */
- public SearchResult getStoredInViewport(final Long centerLat, final Long centerLon, final Long spanLat, final Long spanLon, final CacheType cacheType) {
- final Set<String> geocodes = storage.loadStoredInViewport(centerLat, centerLon, spanLat, spanLon, cacheType);
+ /** {@link cgData#loadStoredInViewport(Viewport, CacheType)} */
+ public SearchResult getStoredInViewport(final Viewport viewport, final CacheType cacheType) {
+ final Set<String> geocodes = storage.loadStoredInViewport(viewport, cacheType);
return new SearchResult(geocodes);
}
- /** {@link cgData#getAllStoredCachesCount(boolean, CacheType, Integer)} */
+ /** {@link cgData#getAllStoredCachesCount(boolean, CacheType, int)} */
+ public int getAllStoredCachesCount(final boolean detailedOnly, final CacheType cacheType) {
+ return storage.getAllStoredCachesCount(detailedOnly, cacheType, 0);
+ }
+
+ /** {@link cgData#getAllStoredCachesCount(boolean, CacheType, int)} */
public int getAllStoredCachesCount(final boolean detailedOnly, final CacheType cacheType, final Integer list) {
return storage.getAllStoredCachesCount(detailedOnly, cacheType, list);
}
@@ -335,18 +299,13 @@ public class cgeoapplication extends Application {
}
/** {@link cgData#moveToList(String, int)} */
- public void markStored(String geocode, int listId) {
- storage.moveToList(geocode, listId);
+ public void markStored(List<cgCache> caches, int listId) {
+ storage.moveToList(caches, listId);
}
/** {@link cgData#moveToList(String, int)} */
- public void markDropped(String geocode) {
- storage.moveToList(geocode, StoredList.TEMPORARY_LIST_ID);
- }
-
- /** {@link cgData#markFound(String)} */
- public boolean markFound(String geocode) {
- return storage.markFound(geocode);
+ public void markDropped(List<cgCache> caches) {
+ storage.moveToList(caches, StoredList.TEMPORARY_LIST_ID);
}
/** {@link cgData#clearSearchedDestinations()} */
@@ -354,14 +313,14 @@ public class cgeoapplication extends Application {
return storage.clearSearchedDestinations();
}
- /** {@link cgData#saveSearchedDestination(cgDestination)} */
- public boolean saveSearchedDestination(cgDestination destination) {
- return storage.saveSearchedDestination(destination);
+ /** {@link cgData#saveSearchedDestination(Destination)} */
+ public void saveSearchedDestination(Destination destination) {
+ storage.saveSearchedDestination(destination);
}
/** {@link cgData#saveWaypoints(String, List, boolean)} */
- public boolean saveWaypoints(String geocode, List<cgWaypoint> waypoints, boolean drop) {
- return storage.saveWaypoints(geocode, waypoints, drop);
+ public boolean saveWaypoints(final cgCache cache) {
+ return storage.saveWaypoints(cache);
}
public boolean saveOwnWaypoint(int id, String geocode, cgWaypoint waypoint) {
@@ -378,10 +337,7 @@ public class cgeoapplication extends Application {
}
public boolean saveTrackable(cgTrackable trackable) {
- final List<cgTrackable> list = new ArrayList<cgTrackable>();
- list.add(trackable);
-
- return storage.saveInventory("---", list);
+ return storage.saveTrackable(trackable);
}
/** {@link cgData#dropList(int)} **/
@@ -389,21 +345,11 @@ public class cgeoapplication extends Application {
storage.dropList(listId);
}
- /** {@link cgData#loadInventory(String)} */
- public List<cgTrackable> loadInventory(String geocode) {
- return storage.loadInventory(geocode);
- }
-
/** {@link cgData#loadLogCounts(String)} */
public Map<LogType, Integer> loadLogCounts(String geocode) {
return storage.loadLogCounts(geocode);
}
- /** {@link cgData#loadSpoilers(String)} */
- public List<cgImage> loadSpoilers(String geocode) {
- return storage.loadSpoilers(geocode);
- }
-
/** {@link cgData#loadWaypoint(int)} */
public cgWaypoint loadWaypoint(int id) {
return storage.loadWaypoint(id);
@@ -428,35 +374,13 @@ public class cgeoapplication extends Application {
return StringUtils.defaultString(action);
}
- public boolean addLog(String geocode, cgLog log) {
- if (StringUtils.isBlank(geocode)) {
- return false;
- }
- if (log == null) {
- return false;
- }
-
- List<cgLog> list = new ArrayList<cgLog>();
- list.add(log);
-
- return storage.saveLogs(geocode, list, false);
- }
-
- public void setLastCoords(final Geopoint coords) {
- lastCoords = coords;
- }
-
- public Geopoint getLastCoords() {
- return lastCoords;
- }
-
/** {@link cgData#saveLogOffline(String, Date, LogType, String)} */
public boolean saveLogOffline(String geocode, Date date, LogType logtype, String log) {
return storage.saveLogOffline(geocode, date, logtype, log);
}
/** {@link cgData#loadLogOffline(String)} */
- public cgLog loadLogOffline(String geocode) {
+ public LogEntry loadLogOffline(String geocode) {
return storage.loadLogOffline(geocode);
}
@@ -500,14 +424,14 @@ public class cgeoapplication extends Application {
return storage.removeList(id);
}
- /** {@link cgData#removeSearchedDestination(cgDestination)} */
- public boolean removeSearchedDestinations(cgDestination destination) {
+ /** {@link cgData#removeSearchedDestination(Destination)} */
+ public boolean removeSearchedDestinations(Destination destination) {
return storage.removeSearchedDestination(destination);
}
/** {@link cgData#moveToList(String, int)} */
- public void moveToList(String geocode, int listId) {
- storage.moveToList(geocode, listId);
+ public void moveToList(List<cgCache> caches, int listId) {
+ storage.moveToList(caches, listId);
}
/** {@link cgData#getCacheDescription(String)} */
@@ -525,11 +449,6 @@ public class cgeoapplication extends Application {
return storage.loadCaches(geocodes, loadFlags);
}
- /** {@link cgData#loadCaches} */
- public Set<cgCache> loadCaches(Long centerLat, Long centerLon, Long spanLat, Long spanLon, final EnumSet<LoadFlag> loadFlags) {
- return storage.loadCaches(null, centerLat, centerLon, spanLat, spanLon, loadFlags);
- }
-
/** {@link cgData#saveCache} */
public boolean saveCache(cgCache cache, EnumSet<LoadFlags.SaveFlag> saveFlags) {
return storage.saveCache(cache, saveFlags);
@@ -545,4 +464,8 @@ public class cgeoapplication extends Application {
storage.removeCaches(geocodes, removeFlags);
}
+ public Set<cgWaypoint> getWaypointsInViewport(final Viewport viewport, boolean excludeMine, boolean excludeDisabled) {
+ return storage.loadWaypoints(viewport, excludeMine, excludeDisabled);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java
index 21ecb5e..db44e16 100644
--- a/main/src/cgeo/geocaching/cgeocaches.java
+++ b/main/src/cgeo/geocaching/cgeocaches.java
@@ -6,21 +6,19 @@ import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.activity.Progress;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.apps.cachelist.CacheListAppFactory;
+import cgeo.geocaching.connector.gc.GCParser;
import cgeo.geocaching.enumerations.CacheListType;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.export.ExportFactory;
import cgeo.geocaching.files.GPXImporter;
-import cgeo.geocaching.filter.AttributeFilter;
+import cgeo.geocaching.filter.FilterUserInterface;
import cgeo.geocaching.filter.IFilter;
-import cgeo.geocaching.filter.ModifiedFilter;
-import cgeo.geocaching.filter.SizeFilter;
-import cgeo.geocaching.filter.StateFilter;
-import cgeo.geocaching.filter.TrackablesFilter;
-import cgeo.geocaching.filter.TypeFilter;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.maps.CGeoMap;
+import cgeo.geocaching.network.Cookies;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.sorting.CacheComparator;
@@ -39,6 +37,8 @@ import cgeo.geocaching.sorting.TerrainComparator;
import cgeo.geocaching.sorting.VisitComparator;
import cgeo.geocaching.sorting.VoteComparator;
import cgeo.geocaching.ui.CacheListAdapter;
+import cgeo.geocaching.utils.IObserver;
+import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.RunnableWithArgument;
import org.apache.commons.collections.CollectionUtils;
@@ -50,13 +50,10 @@ import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Environment;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
@@ -66,31 +63,22 @@ import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.EditText;
import android.widget.ListView;
-import android.widget.RelativeLayout;
import android.widget.TextView;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-public class cgeocaches extends AbstractListActivity {
+public class cgeocaches extends AbstractListActivity implements IObserver<IGeoData> {
private static final int MAX_LIST_ITEMS = 1000;
private static final String EXTRAS_LIST_TYPE = "type";
+ private static final String EXTRAS_COORDS = "coords";
private static final int MENU_REFRESH_STORED = 2;
private static final int MENU_CACHE_DETAILS = 4;
private static final int MENU_DROP_CACHES = 5;
@@ -110,21 +98,15 @@ public class cgeocaches extends AbstractListActivity {
private static final int MENU_SORT_VOTE = 19;
private static final int MENU_SORT_INVENTORY = 20;
private static final int MENU_IMPORT_WEB = 21;
- private static final int MENU_EXPORT_NOTES = 22;
+ private static final int MENU_EXPORT = 22;
private static final int MENU_REMOVE_FROM_HISTORY = 23;
private static final int MENU_DROP_CACHE = 24;
private static final int MENU_MOVE_TO_LIST = 25;
- private static final int MENU_FILTER_CLEAR = 26;
- private static final int MENU_FILTER_TRACKABLES = 27;
- private static final int SUBMENU_FILTER_SIZE = 28;
- private static final int SUBMENU_FILTER_TYPE = 29;
private static final int MENU_SWITCH_SELECT_MODE = 52;
private static final int SUBMENU_SHOW_MAP = 54;
private static final int SUBMENU_MANAGE_LISTS = 55;
private static final int SUBMENU_MANAGE_OFFLINE = 56;
private static final int SUBMENU_SORT = 57;
- private static final int SUBMENU_FILTER = 58;
- private static final int SUBMENU_IMPORT = 59;
private static final int SUBMENU_MANAGE_HISTORY = 60;
private static final int MENU_SORT_DATE = 61;
private static final int MENU_SORT_FINDS = 62;
@@ -132,12 +114,12 @@ public class cgeocaches extends AbstractListActivity {
private static final int MENU_RENAME_LIST = 64;
private static final int MENU_DROP_CACHES_AND_LIST = 65;
private static final int MENU_DEFAULT_NAVIGATION = 66;
- private static final int SUBMENU_FILTER_ATTRIBUTES = 67;
- private static final int SUBMENU_FILTER_STATE = 68;
private static final int MENU_NAVIGATION = 69;
- private static final int MENU_FILTER_MODIFIED = 70;
+ private static final int MENU_STORE_CACHE = 73;
+ private static final int MENU_FILTER = 74;
private static final int MSG_DONE = -1;
+ private static final int MSG_RESTART_GEO_AND_DIR = -2;
private static final int MSG_CANCEL = -99;
private String action = null;
@@ -155,9 +137,7 @@ public class cgeocaches extends AbstractListActivity {
private TextView listFooterText = null;
private Progress progress = new Progress();
private Float northHeading = 0f;
- private cgGeo geo = null;
private cgDirection dir = null;
- private UpdateLocationCallback geoUpdate = new UpdateLocation();
private UpdateDirectionCallback dirUpdate = new UpdateDirection();
private String title = "";
private int detailTotal = 0;
@@ -165,11 +145,8 @@ public class cgeocaches extends AbstractListActivity {
private long detailProgressTime = 0L;
private LoadDetailsThread threadDetails = null;
private LoadFromWebThread threadWeb = null;
- private DropDetailsThread threadR = null;
- private ExportFieldNotesThread threadF = null;
private RemoveFromHistoryThread threadH = null;
private int listId = StoredList.TEMPORARY_LIST_ID;
- private List<StoredList> lists = null;
private GeocodeComparator gcComparator = new GeocodeComparator();
private Handler loadCachesHandler = new Handler() {
@@ -177,7 +154,7 @@ public class cgeocaches extends AbstractListActivity {
public void handleMessage(Message msg) {
try {
if (search != null) {
- setTitle(title + " [" + search.getCount() + "]");
+ setTitle(title + " [" + search.getCount() + ']');
cacheList.clear();
final Set<cgCache> caches = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB);
@@ -206,14 +183,14 @@ public class cgeocaches extends AbstractListActivity {
dialog.setNegativeButton(res.getString(R.string.license_dismiss), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- Network.clearCookies();
+ Cookies.clearCookies();
dialog.cancel();
}
});
dialog.setPositiveButton(res.getString(R.string.license_show), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- Network.clearCookies();
+ Cookies.clearCookies();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/software/agreement.aspx?ID=0")));
}
});
@@ -221,7 +198,7 @@ public class cgeocaches extends AbstractListActivity {
AlertDialog alert = dialog.create();
alert.show();
} else if (app != null && search != null && search.getError() != null) {
- showToast(res.getString(R.string.err_download_fail) + " " + search.getError().getErrorString(res) + ".");
+ showToast(res.getString(R.string.err_download_fail) + ' ' + search.getError().getErrorString(res) + '.');
hideLoading();
showProgress(false);
@@ -230,13 +207,14 @@ public class cgeocaches extends AbstractListActivity {
return;
}
- if (geo != null && geo.coordsNow != null) {
- adapter.setActualCoordinates(geo.coordsNow);
+ final Geopoint coordsNow = app.currentGeo().getCoords();
+ if (coordsNow != null) {
+ adapter.setActualCoordinates(coordsNow);
adapter.setActualHeading(northHeading);
}
} catch (Exception e) {
showToast(res.getString(R.string.err_detail_cache_find_any));
- Log.e(Settings.tag, "cgeocaches.loadCachesHandler: " + e.toString());
+ Log.e("cgeocaches.loadCachesHandler: " + e.toString());
hideLoading();
showProgress(false);
@@ -249,7 +227,7 @@ public class cgeocaches extends AbstractListActivity {
hideLoading();
showProgress(false);
} catch (Exception e2) {
- Log.e(Settings.tag, "cgeocaches.loadCachesHandler.2: " + e2.toString());
+ Log.e("cgeocaches.loadCachesHandler.2: " + e2.toString());
}
if (adapter != null) {
@@ -297,13 +275,14 @@ public class cgeocaches extends AbstractListActivity {
return;
}
- if (geo != null && geo.coordsNow != null) {
- adapter.setActualCoordinates(geo.coordsNow);
+ final Geopoint coordsNow = app.currentGeo().getCoords();
+ if (coordsNow != null) {
+ adapter.setActualCoordinates(coordsNow);
adapter.setActualHeading(northHeading);
}
} catch (Exception e) {
showToast(res.getString(R.string.err_detail_cache_find_next));
- Log.e(Settings.tag, "cgeocaches.loadNextPageHandler: " + e.toString());
+ Log.e("cgeocaches.loadNextPageHandler: " + e.toString());
}
hideLoading();
@@ -342,6 +321,8 @@ public class cgeocaches extends AbstractListActivity {
if (threadDetails != null) {
threadDetails.kill();
}
+ } else if (msg.what == MSG_RESTART_GEO_AND_DIR) {
+ startGeoAndDir();
} else {
if (cacheList != null && search != null) {
final Set<cgCache> cacheListTmp = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB);
@@ -353,8 +334,9 @@ public class cgeocaches extends AbstractListActivity {
}
}
- if (geo != null && geo.coordsNow != null) {
- adapter.setActualCoordinates(geo.coordsNow);
+ final Geopoint coordsNow = app.currentGeo().getCoords();
+ if (coordsNow != null) {
+ adapter.setActualCoordinates(coordsNow);
adapter.setActualHeading(northHeading);
}
@@ -383,12 +365,10 @@ public class cgeocaches extends AbstractListActivity {
refreshCurrentList();
} else if (msg.what == -2) {
progress.dismiss();
- startGeoAndDir();
showToast(res.getString(R.string.sendToCgeo_download_fail));
finish();
} else if (msg.what == -3) {
progress.dismiss();
- startGeoAndDir();
showToast(res.getString(R.string.sendToCgeo_no_registration));
finish();
} else if (msg.what == MSG_CANCEL) {
@@ -410,7 +390,6 @@ public class cgeocaches extends AbstractListActivity {
Collections.sort(cacheList, gcComparator);
}
- startGeoAndDir();
progress.dismiss();
}
}
@@ -419,11 +398,7 @@ public class cgeocaches extends AbstractListActivity {
@Override
public void handleMessage(Message msg) {
- if (msg.what == MSG_CANCEL) {
- if (threadR != null) {
- threadR.kill();
- }
- } else {
+ if (msg.what != MSG_CANCEL) {
if (adapter != null) {
adapter.setSelectMode(false, true);
}
@@ -469,39 +444,6 @@ public class cgeocaches extends AbstractListActivity {
}
}
};
- private Handler exportFieldNotesHandler = new Handler() {
-
- @Override
- public void handleMessage(Message msg)
- {
- setAdapter();
-
- if (msg.what > -1)
- {
- cacheList.get(msg.what).setStatusChecked(false);
- progress.setProgress(detailProgress);
- }
- else if (-2 == msg.what)
- {
- showToast(res.getString(R.string.info_fieldnotes_exported_to) + ": " + msg.obj.toString());
- }
- else if (-3 == msg.what)
- {
- showToast(res.getString(R.string.err_fieldnotes_export_failed));
- } else if (msg.what == MSG_CANCEL) {
- if (threadF != null) {
- threadF.kill();
- }
- } else {
- if (adapter != null)
- {
- adapter.setSelectMode(false, true);
- }
-
- progress.dismiss();
- }
- }
- };
private Handler importGpxAttachementFinishedHandler = new Handler() {
@Override
@@ -526,6 +468,13 @@ public class cgeocaches extends AbstractListActivity {
super.onCreate(savedInstanceState);
// init
+ if (CollectionUtils.isNotEmpty(cacheList)) {
+ setMoreCaches();
+ }
+
+ setTitle(title);
+ setAdapter();
+
app.setAction(action);
setTheme();
@@ -537,7 +486,7 @@ public class cgeocaches extends AbstractListActivity {
if (extras != null) {
Object typeObject = extras.get(EXTRAS_LIST_TYPE);
type = (typeObject instanceof CacheListType) ? (CacheListType) typeObject : CacheListType.OFFLINE;
- coords = new Geopoint(extras.getDouble("latitude"), extras.getDouble("longitude"));
+ coords = (Geopoint) extras.getParcelable(EXTRAS_COORDS);
cacheType = Settings.getCacheType();
keyword = extras.getString("keyword");
address = extras.getString("address");
@@ -546,12 +495,10 @@ public class cgeocaches extends AbstractListActivity {
if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
type = CacheListType.OFFLINE;
if (coords == null) {
- coords = new Geopoint(0, 0);
+ coords = new Geopoint(0.0, 0.0);
}
}
- init();
-
Thread threadPure;
cgSearchThread thread;
@@ -666,7 +613,7 @@ public class cgeocaches extends AbstractListActivity {
default:
title = "caches";
setTitle(title);
- Log.e(Settings.tag, "cgeocaches.onCreate: No action or unknown action specified");
+ Log.e("cgeocaches.onCreate: No action or unknown action specified");
break;
}
prepareFilterBar();
@@ -696,27 +643,18 @@ public class cgeocaches extends AbstractListActivity {
}
@Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
-
- init();
- }
-
- @Override
public void onResume() {
super.onResume();
init();
- if (adapter != null && geo != null && geo.coordsNow != null) {
- adapter.setActualCoordinates(geo.coordsNow);
- adapter.setActualHeading(northHeading);
- }
-
if (adapter != null) {
adapter.setSelectMode(false, true);
- if (geo != null && geo.coordsNow != null) {
- adapter.forceSort(geo.coordsNow);
+ final Geopoint coordsNow = app.currentGeo().getCoords();
+ if (coordsNow != null) {
+ adapter.setActualCoordinates(coordsNow);
+ adapter.setActualHeading(northHeading);
+ adapter.forceSort(coordsNow);
}
}
@@ -726,8 +664,8 @@ public class cgeocaches extends AbstractListActivity {
// refresh standard list if it has changed (new caches downloaded)
if (type == CacheListType.OFFLINE && listId >= StoredList.STANDARD_LIST_ID && search != null) {
- SearchResult newSearch = cgBase.searchByStored(coords, cacheType, listId);
- if (newSearch != null && newSearch.totalCnt != search.totalCnt) {
+ SearchResult newSearch = cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, cacheType, listId);
+ if (newSearch != null && newSearch.getTotal() != search.getTotal()) {
refreshCurrentList();
}
}
@@ -739,15 +677,11 @@ public class cgeocaches extends AbstractListActivity {
adapter = null;
}
- removeGeoAndDir();
-
super.onDestroy();
}
@Override
public void onStop() {
- removeGeoAndDir();
-
super.onStop();
}
@@ -760,17 +694,7 @@ public class cgeocaches extends AbstractListActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
- SubMenu subMenuFilter = menu.addSubMenu(0, SUBMENU_FILTER, 0, res.getString(R.string.caches_filter)).setIcon(R.drawable.ic_menu_filter);
- subMenuFilter.setHeaderTitle(res.getString(R.string.caches_filter_title));
- if (Settings.getCacheType() == CacheType.ALL) {
- subMenuFilter.add(0, SUBMENU_FILTER_TYPE, 0, res.getString(R.string.caches_filter_type));
- }
- subMenuFilter.add(0, SUBMENU_FILTER_SIZE, 0, res.getString(R.string.caches_filter_size));
- subMenuFilter.add(0, SUBMENU_FILTER_ATTRIBUTES, 0, res.getString(R.string.cache_attributes));
- subMenuFilter.add(0, SUBMENU_FILTER_STATE, 0, res.getString(R.string.cache_status));
- subMenuFilter.add(0, MENU_FILTER_TRACKABLES, 0, res.getString(R.string.caches_filter_track));
- subMenuFilter.add(0, MENU_FILTER_MODIFIED, 0, res.getString(R.string.caches_filter_modified));
- subMenuFilter.add(0, MENU_FILTER_CLEAR, 0, res.getString(R.string.caches_filter_clear));
+ menu.add(0, MENU_FILTER, 0, res.getString(R.string.caches_filter)).setIcon(R.drawable.ic_menu_filter);
SubMenu subMenuSort = menu.addSubMenu(0, SUBMENU_SORT, 0, res.getString(R.string.caches_sort)).setIcon(android.R.drawable.ic_menu_sort_alphabetically);
subMenuSort.setHeaderTitle(res.getString(R.string.caches_sort_title));
@@ -795,7 +719,7 @@ public class cgeocaches extends AbstractListActivity {
Collections.sort(sortedLabels);
for (String label : sortedLabels) {
Integer id = comparators.get(label);
- subMenuSort.add(1, id.intValue(), 0, label).setCheckable(true).setChecked(id.intValue() == MENU_SORT_DISTANCE);
+ subMenuSort.add(1, id, 0, label).setCheckable(true).setChecked(id == MENU_SORT_DISTANCE);
}
subMenuSort.setGroupCheckable(1, true, true);
@@ -808,21 +732,19 @@ public class cgeocaches extends AbstractListActivity {
subMenu.add(0, MENU_DROP_CACHES_AND_LIST, 0, res.getString(R.string.caches_drop_all_and_list));
subMenu.add(0, MENU_REFRESH_STORED, 0, res.getString(R.string.cache_offline_refresh)); // download details for all caches
subMenu.add(0, MENU_MOVE_TO_LIST, 0, res.getString(R.string.cache_menu_move_list));
- subMenu.add(0, MENU_EXPORT_NOTES, 0, res.getString(R.string.cache_export_fieldnote)); // export field notes
- if (Settings.getWebDeviceCode() == null)
- {
- menu.add(0, MENU_IMPORT_GPX, 0, res.getString(R.string.gpx_import_title)).setIcon(android.R.drawable.ic_menu_upload); // import gpx file
- } else {
- SubMenu subMenuImport = menu.addSubMenu(0, SUBMENU_IMPORT, 0, res.getString(R.string.import_title)).setIcon(android.R.drawable.ic_menu_upload); // import
- subMenuImport.add(1, MENU_IMPORT_GPX, 0, res.getString(R.string.gpx_import_title)).setCheckable(false).setChecked(false);
- subMenuImport.add(1, MENU_IMPORT_WEB, 0, res.getString(R.string.web_import_title)).setCheckable(false).setChecked(false);
+
+ //TODO: add submenu/AlertDialog and use R.string.gpx_import_title
+ subMenu.add(0, MENU_IMPORT_GPX, 0, res.getString(R.string.gpx_import_title));
+ if (Settings.getWebDeviceCode() != null) {
+ subMenu.add(0, MENU_IMPORT_WEB, 0, res.getString(R.string.web_import_title));
}
+
+ subMenu.add(0, MENU_EXPORT, 0, res.getString(R.string.export)); // export caches
} else {
- if (type == CacheListType.HISTORY)
- {
+ if (type == CacheListType.HISTORY) {
SubMenu subMenu = menu.addSubMenu(0, SUBMENU_MANAGE_HISTORY, 0, res.getString(R.string.caches_manage)).setIcon(android.R.drawable.ic_menu_save);
subMenu.add(0, MENU_REMOVE_FROM_HISTORY, 0, res.getString(R.string.cache_clear_history)); // remove from history
- subMenu.add(0, MENU_EXPORT_NOTES, 0, res.getString(R.string.cache_export_fieldnote)); // export field notes
+ subMenu.add(0, MENU_EXPORT, 0, res.getString(R.string.export)); // export caches
}
menu.add(0, MENU_REFRESH_STORED, 0, res.getString(R.string.caches_store_offline)).setIcon(android.R.drawable.ic_menu_set_as); // download details for all caches
}
@@ -859,40 +781,27 @@ public class cgeocaches extends AbstractListActivity {
boolean isNonDefaultList = listId != StoredList.STANDARD_LIST_ID;
if (type == CacheListType.OFFLINE) { // only offline list
- if (hasSelection) {
- menu.findItem(MENU_DROP_CACHES).setTitle(res.getString(R.string.caches_drop_selected) + " (" + adapter.getChecked() + ")");
- } else {
- menu.findItem(MENU_DROP_CACHES).setTitle(res.getString(R.string.caches_drop_all));
- }
+ setMenuItemLabel(menu, MENU_DROP_CACHES, R.string.caches_drop_selected, R.string.caches_drop_all);
menu.findItem(MENU_DROP_CACHES_AND_LIST).setVisible(!hasSelection && isNonDefaultList);
-
- if (hasSelection) {
- menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_refresh_selected) + " (" + adapter.getChecked() + ")");
- } else {
- menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_refresh_all));
- }
-
- if (hasSelection) {
- menu.findItem(MENU_MOVE_TO_LIST).setTitle(res.getString(R.string.caches_move_selected) + " (" + adapter.getChecked() + ")");
- } else {
- menu.findItem(MENU_MOVE_TO_LIST).setTitle(res.getString(R.string.caches_move_all));
- }
+ setMenuItemLabel(menu, MENU_REFRESH_STORED, R.string.caches_refresh_selected, R.string.caches_refresh_all);
+ setMenuItemLabel(menu, MENU_MOVE_TO_LIST, R.string.caches_move_selected, R.string.caches_move_all);
} else { // search and history list (all other than offline)
- if (hasSelection) {
- menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_store_selected) + " (" + adapter.getChecked() + ")");
- } else {
- menu.findItem(MENU_REFRESH_STORED).setTitle(res.getString(R.string.caches_store_offline));
- }
+ setMenuItemLabel(menu, MENU_REFRESH_STORED, R.string.caches_store_selected, R.string.caches_store_offline);
}
// Hide menus if cache-list is empty
int[] hideIfEmptyList = new int[] {
MENU_SWITCH_SELECT_MODE,
- SUBMENU_MANAGE_OFFLINE,
SUBMENU_MANAGE_HISTORY,
SUBMENU_SHOW_MAP,
SUBMENU_SORT,
- MENU_REFRESH_STORED };
+ MENU_REFRESH_STORED,
+ MENU_DROP_CACHES,
+ MENU_DROP_CACHES_AND_LIST,
+ MENU_MOVE_TO_LIST,
+ MENU_EXPORT,
+ MENU_REMOVE_FROM_HISTORY
+ };
boolean menuVisible = cacheList.size() > 0;
for (int itemId : hideIfEmptyList) {
@@ -922,42 +831,31 @@ public class cgeocaches extends AbstractListActivity {
}
item = menu.findItem(MENU_MOVE_TO_LIST);
if (item != null) {
- item.setVisible(multipleLists);
- }
-
- item = menu.findItem(MENU_REMOVE_FROM_HISTORY);
- if (null != item) {
- if (hasSelection) {
- item.setTitle(res.getString(R.string.cache_remove_from_history) + " (" + adapter.getChecked() + ")");
- } else {
- item.setTitle(res.getString(R.string.cache_clear_history));
- }
- }
-
- item = menu.findItem(MENU_EXPORT_NOTES);
- if (null != item) {
- // Hide Field Notes export if there are no caches with logs
- item.setVisible(false);
- for (cgCache cache : cacheList) {
- if (cache.isLogOffline()) {
- item.setVisible(true);
- if (hasSelection) {
- item.setTitle(res.getString(R.string.cache_export_fieldnote) + " (" + adapter.getChecked() + ")");
- } else {
- item.setTitle(res.getString(R.string.cache_export_fieldnote));
- }
- break;
- }
- }
+ item.setVisible(multipleLists && cacheList.size() > 0);
}
+ setMenuItemLabel(menu, MENU_REMOVE_FROM_HISTORY, R.string.cache_remove_from_history, R.string.cache_clear_history);
+ setMenuItemLabel(menu, MENU_EXPORT, R.string.export, R.string.export);
} catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.onPrepareOptionsMenu: " + e.toString());
+ Log.e("cgeocaches.onPrepareOptionsMenu", e);
}
return true;
}
+ private void setMenuItemLabel(final Menu menu, final int menuId, final int resIdSelection, final int resId) {
+ final MenuItem menuItem = menu.findItem(menuId);
+ if (menuItem == null) {
+ return;
+ }
+ boolean hasSelection = adapter != null && adapter.getChecked() > 0;
+ if (hasSelection) {
+ menuItem.setTitle(res.getString(resIdSelection) + " (" + adapter.getChecked() + ")");
+ } else {
+ menuItem.setTitle(res.getString(resId));
+ }
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
@@ -985,7 +883,7 @@ public class cgeocaches extends AbstractListActivity {
invalidateOptionsMenuCompatible();
return false;
case MENU_CREATE_LIST:
- createList(null);
+ new StoredList.UserInterface(this).promptForListCreation(null);
invalidateOptionsMenuCompatible();
return false;
case MENU_DROP_LIST:
@@ -1044,34 +942,27 @@ public class cgeocaches extends AbstractListActivity {
case MENU_SORT_STATE:
setComparator(item, new StateComparator());
return true;
- case SUBMENU_FILTER_TYPE:
- showFilterMenu(TypeFilter.getAllFilters(), res.getString(R.string.caches_filter_type_title));
- return true;
- case SUBMENU_FILTER_SIZE:
- showFilterMenu(SizeFilter.getAllFilters(), res.getString(R.string.caches_filter_size_title));
- return true;
- case SUBMENU_FILTER_ATTRIBUTES:
- showFilterMenu(AttributeFilter.getAllFilters(), res.getString(R.string.cache_attributes));
- return true;
- case SUBMENU_FILTER_STATE:
- showFilterMenu(StateFilter.getAllFilters(), res.getString(R.string.cache_status));
- return true;
- case MENU_FILTER_TRACKABLES:
- setFilter(new TrackablesFilter(res.getString(R.string.caches_filter_track)));
- return true;
- case MENU_FILTER_MODIFIED:
- setFilter(new ModifiedFilter(res.getString(R.string.caches_filter_modified)));
+ case MENU_FILTER:
+ new FilterUserInterface(this).selectFilter(new RunnableWithArgument<IFilter>() {
+ @Override
+ public void run(IFilter selectedFilter) {
+ if (selectedFilter != null) {
+ setFilter(selectedFilter);
+ }
+ else {
+ // clear filter
+ if (adapter != null) {
+ setFilter(null);
+ }
+ }
+ }
+ });
return true;
- case MENU_FILTER_CLEAR:
- if (adapter != null) {
- setFilter(null);
- }
- return false;
case MENU_IMPORT_WEB:
importWeb();
return false;
- case MENU_EXPORT_NOTES:
- exportFieldNotes();
+ case MENU_EXPORT:
+ exportCaches();
return false;
case MENU_REMOVE_FROM_HISTORY:
removeFromHistoryCheck();
@@ -1083,24 +974,7 @@ public class cgeocaches extends AbstractListActivity {
return true;
}
- return CacheListAppFactory.onMenuItemSelected(item, geo, cacheList, this, search);
- }
-
- private void showFilterMenu(final IFilter[] filters, final String menuTitle) {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(menuTitle);
-
- final String[] names = new String[filters.length];
- for (int i = 0; i < filters.length; i++) {
- names[i] = filters[i].getName();
- }
- builder.setItems(names, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- setFilter(filters[item]);
- }
- });
-
- builder.create().show();
+ return CacheListAppFactory.onMenuItemSelected(item, app.currentGeo(), cacheList, this, search);
}
private void setComparator(MenuItem item,
@@ -1123,7 +997,7 @@ public class cgeocaches extends AbstractListActivity {
try {
adapterInfo = (AdapterContextMenuInfo) info;
} catch (Exception e) {
- Log.w(Settings.tag, "cgeocaches.onCreateContextMenu: " + e.toString());
+ Log.w("cgeocaches.onCreateContextMenu: " + e.toString());
}
if (adapterInfo == null || adapterInfo.position >= adapter.getCount()) {
@@ -1153,41 +1027,33 @@ public class cgeocaches extends AbstractListActivity {
menu.add(0, MENU_MOVE_TO_LIST, 0, res.getString(R.string.cache_menu_move_list));
}
}
+ else {
+ menu.add(0, MENU_STORE_CACHE, 0, res.getString(R.string.cache_offline_store));
+ }
}
private void moveCachesToOtherList() {
- final List<StoredList> cacheLists = app.getLists();
- ArrayList<String> listNames = new ArrayList<String>();
- for (StoredList list : cacheLists) {
- listNames.add(list.getTitleAndCount());
- }
+ new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new RunnableWithArgument<Integer>() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(res.getString(R.string.cache_menu_move_list));
- builder.setItems(listNames.toArray(new String[listNames.size()]), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- moveCachesToList(cacheLists.get(item));
- }
- });
- builder.create().show();
- }
+ @Override
+ public void run(Integer newListId) {
+ List<cgCache> selected;
+ final boolean moveAll = adapter.getChecked() == 0;
+ if (moveAll) {
+ selected = new ArrayList<cgCache>(cacheList);
+ } else {
+ selected = adapter.getCheckedCaches();
+ }
+ app.moveToList(selected, newListId);
+ adapter.resetChecks();
- private void moveCachesToList(final StoredList list) {
- int newListId = list.id;
- final boolean moveAll = adapter.getChecked() == 0;
- for (final cgCache c : Collections.unmodifiableList(cacheList)) {
- if (moveAll || c.isStatusChecked()) {
- app.moveToList(c.getGeocode(), newListId);
+ refreshCurrentList();
}
- }
- adapter.resetChecks();
-
- refreshCurrentList();
+ });
}
@Override
public boolean onContextItemSelected(MenuItem item) {
- final int id = item.getItemId();
ContextMenu.ContextMenuInfo info = item.getMenuInfo();
// restore menu info for sub menu items, see
@@ -1201,69 +1067,62 @@ public class cgeocaches extends AbstractListActivity {
try {
adapterInfo = (AdapterContextMenuInfo) info;
} catch (Exception e) {
- Log.w(Settings.tag, "cgeocaches.onContextItemSelected: " + e.toString());
+ Log.w("cgeocaches.onContextItemSelected: " + e.toString());
}
- if (id == MENU_DEFAULT_NAVIGATION) {
- final cgCache cache = getCacheFromAdapter(adapterInfo);
- NavigationAppFactory.startDefaultNavigationApplication(geo, this, cache, null, null);
- return true;
- } else if (id == MENU_NAVIGATION) {
- final cgCache cache = getCacheFromAdapter(adapterInfo);
- NavigationAppFactory.showNavigationMenu(geo, this, cache, null, null);
- return true;
- } else if (id == MENU_LOG_VISIT) {
- return getCacheFromAdapter(adapterInfo).logVisit(this);
- } else if (id == MENU_CACHE_DETAILS) {
- final Intent cachesIntent = new Intent(this, CacheDetailActivity.class);
- final cgCache cache = getCacheFromAdapter(adapterInfo);
- cachesIntent.putExtra("geocode", cache.getGeocode().toUpperCase());
- cachesIntent.putExtra("name", cache.getName());
- startActivity(cachesIntent);
+ final cgCache cache = adapterInfo != null ? getCacheFromAdapter(adapterInfo) : null;
- return true;
- } else if (id == MENU_DROP_CACHE) {
- cgBase.dropCache(getCacheFromAdapter(adapterInfo), new Handler() {
- @Override
- public void handleMessage(Message msg) {
- refreshCurrentList();
- }
- });
- return true;
- } else if (id == MENU_MOVE_TO_LIST) {
- final String geocode = getCacheFromAdapter(adapterInfo).getGeocode();
- final List<StoredList> cacheLists = app.getLists();
- ArrayList<String> listNames = new ArrayList<String>();
- for (StoredList list : cacheLists) {
- listNames.add(list.getTitleAndCount());
- }
+ final int id = item.getItemId();
+ switch (id) {
+ case MENU_DEFAULT_NAVIGATION:
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), this, cache, null, null);
+ break;
+ case MENU_NAVIGATION:
+ NavigationAppFactory.showNavigationMenu(app.currentGeo(), this, cache, null, null);
+ break;
+ case MENU_LOG_VISIT:
+ cache.logVisit(this);
+ break;
+ case MENU_CACHE_DETAILS:
+ final Intent cachesIntent = new Intent(this, CacheDetailActivity.class);
+ cachesIntent.putExtra("geocode", cache.getGeocode().toUpperCase());
+ cachesIntent.putExtra("name", cache.getName());
+ startActivity(cachesIntent);
+ break;
+ case MENU_DROP_CACHE:
+ cache.drop(new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ refreshCurrentList();
+ }
+ });
+ break;
+ case MENU_MOVE_TO_LIST:
+ new StoredList.UserInterface(this).promptForListSelection(R.string.cache_menu_move_list, new RunnableWithArgument<Integer>() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(res.getString(R.string.cache_menu_move_list));
- builder.setItems(listNames.toArray(new String[listNames.size()]), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- final int newListId = cacheLists.get(item).id;
- app.moveToList(geocode, newListId);
- adapter.resetChecks();
- refreshCurrentList();
+ @Override
+ public void run(Integer newListId) {
+ app.moveToList(Collections.singletonList(cache), newListId);
+ adapter.resetChecks();
+ refreshCurrentList();
+ }
+ });
+ break;
+ case MENU_STORE_CACHE:
+ //FIXME: this must use the same handler like in the CacheDetailActivity. Will be done by moving the handler into the store method.
+ cache.store(this, null);
+ break;
+ default:
+ // we must remember the menu info for the sub menu, there is a bug
+ // in Android:
+ // https://code.google.com/p/android/issues/detail?id=7139
+ lastMenuInfo = info;
+ if (cache != null) {
+ // create a search for a single cache (as if in details view)
+ cache.logOffline(this, LogType.getById(id - MENU_LOG_VISIT_OFFLINE));
}
- });
- builder.create().show();
- return true;
}
- // we must remember the menu info for the sub menu, there is a bug
- // in Android:
- // https://code.google.com/p/android/issues/detail?id=7139
- lastMenuInfo = info;
-
- if (adapterInfo != null) {
- // create a search for a single cache (as if in details view)
- final cgCache cache = getCacheFromAdapter(adapterInfo);
-
- int logType = id - MENU_LOG_VISIT_OFFLINE;
- cache.logOffline(this, LogType.getById(logType));
- }
return true;
}
@@ -1336,9 +1195,8 @@ public class cgeocaches extends AbstractListActivity {
}
adapter.reFilter();
- if (geo != null) {
- adapter.setActualCoordinates(geo.coordsNow);
- }
+ adapter.setActualCoordinates(app.currentGeo().getCoords());
+
if (dir != null) {
adapter.setActualHeading(dir.directionNow);
}
@@ -1388,38 +1246,22 @@ public class cgeocaches extends AbstractListActivity {
private void init() {
startGeoAndDir();
- if (CollectionUtils.isNotEmpty(cacheList)) {
- setMoreCaches();
- }
-
- setTitle(title);
- setAdapter();
-
- if (geo != null) {
- geoUpdate.updateLocation(geo);
- }
if (dir != null) {
dirUpdate.updateDirection(dir);
}
}
- // sensor & geolocation manager
+ // Sensor & geolocation manager. This must be called from the UI thread as it may
+ // cause the system listeners to start if nobody else required them before.
private void startGeoAndDir() {
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
+ app.addGeoObserver(this);
if (Settings.isLiveList() && Settings.isUseCompass() && dir == null) {
dir = app.startDir(this, dirUpdate);
}
}
private void removeGeoAndDir() {
- if (dir != null) {
- dir = app.removeDir();
- }
- if (geo != null) {
- geo = app.removeGeo();
- }
+ app.deleteGeoObserver(this);
}
private void importGpx() {
@@ -1463,8 +1305,7 @@ public class cgeocaches extends AbstractListActivity {
threadDetails.start();
}
- public void removeFromHistoryCheck()
- {
+ public void removeFromHistoryCheck() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setCancelable(true);
dialog.setTitle(res.getString(R.string.caches_removing_from_history));
@@ -1486,8 +1327,7 @@ public class cgeocaches extends AbstractListActivity {
alert.show();
}
- public void removeFromHistory()
- {
+ public void removeFromHistory() {
if (adapter != null && adapter.getChecked() > 0)
{
// there are some checked caches
@@ -1508,27 +1348,17 @@ public class cgeocaches extends AbstractListActivity {
threadH.start();
}
- public void exportFieldNotes()
- {
- if (adapter != null && adapter.getChecked() > 0)
- {
- // there are some checked caches
- detailTotal = adapter.getChecked();
- }
- else
- {
- // no checked caches, export all
- detailTotal = cacheList.size();
+ public void exportCaches() {
+ List<cgCache> caches;
+ if (adapter != null && adapter.getChecked() > 0) {
+ // there are some caches checked
+ caches = adapter.getCheckedCaches();
+ } else {
+ // no caches checked, export all
+ caches = cacheList;
}
- detailProgress = 0;
-
- showProgress(false);
-
- progress.show(this, null, res.getString(R.string.caches_exporting_fieldnote), ProgressDialog.STYLE_HORIZONTAL, exportFieldNotesHandler.obtainMessage(MSG_CANCEL));
- progress.setMaxProgressAndReset(detailTotal);
- threadF = new ExportFieldNotesThread(exportFieldNotesHandler);
- threadF.start();
+ ExportFactory.showExportMenu(caches, this);
}
public void importWeb() {
@@ -1574,38 +1404,30 @@ public class cgeocaches extends AbstractListActivity {
public void dropSelected() {
progress.show(this, null, res.getString(R.string.caches_drop_progress), true, dropDetailsHandler.obtainMessage(MSG_CANCEL));
-
- threadR = new DropDetailsThread(dropDetailsHandler);
- threadR.start();
+ new DropDetailsThread(dropDetailsHandler).start();
}
- private class UpdateLocation implements UpdateLocationCallback {
+ @Override
+ public void update(final IGeoData geo) {
+ if (adapter == null) {
+ return;
+ }
- @Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
- }
- if (adapter == null) {
- return;
+ try {
+ if (cacheList != null && geo.getCoords() != null) {
+ adapter.setActualCoordinates(geo.getCoords());
}
- try {
- if (cacheList != null && geo.coordsNow != null) {
- adapter.setActualCoordinates(geo.coordsNow);
+ if (!Settings.isUseCompass() || geo.getSpeed() > 5) { // use GPS when speed is higher than 18 km/h
+ if (!Settings.isUseCompass()) {
+ adapter.setActualHeading(geo.getBearing());
}
-
- if (!Settings.isUseCompass() || geo.speedNow > 5) { // use GPS when speed is higher than 18 km/h
- if (!Settings.isUseCompass()) {
- adapter.setActualHeading(geo.bearingNow);
- }
- if (northHeading != null) {
- adapter.setActualHeading(northHeading);
- }
+ if (northHeading != null) {
+ adapter.setActualHeading(northHeading);
}
- } catch (Exception e) {
- Log.w(Settings.tag, "Failed to UpdateLocation location.");
}
+ } catch (Exception e) {
+ Log.w("Failed to UpdateLocation location.");
}
}
@@ -1621,7 +1443,7 @@ public class cgeocaches extends AbstractListActivity {
}
northHeading = dir.directionNow;
- if (northHeading != null && adapter != null && (geo == null || geo.speedNow <= 5)) { // use compass when speed is lower than 18 km/h) {
+ if (northHeading != null && adapter != null && (app.currentGeo().getSpeed() <= 5)) { // use compass when speed is lower than 18 km/h) {
adapter.setActualHeading(northHeading);
}
}
@@ -1641,7 +1463,7 @@ public class cgeocaches extends AbstractListActivity {
@Override
public void run() {
- search = cgBase.searchByStored(coords, Settings.getCacheType(), listId);
+ search = cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, Settings.getCacheType(), listId);
handler.sendMessage(Message.obtain());
}
}
@@ -1671,7 +1493,7 @@ public class cgeocaches extends AbstractListActivity {
@Override
public void run() {
- search = cgBase.searchByNextPage(this, search, Settings.isShowCaptcha());
+ search = GCParser.searchByNextPage(this, search, Settings.isShowCaptcha());
handler.sendMessage(Message.obtain());
}
@@ -1692,13 +1514,12 @@ public class cgeocaches extends AbstractListActivity {
showToast(res.getString(R.string.warn_no_coordinates));
finish();
- return;
}
}
@Override
public void run() {
- search = cgBase.searchByCoords(this, coords, cacheType, Settings.isShowCaptcha());
+ search = GCParser.searchByCoords(this, coords, cacheType, Settings.isShowCaptcha());
handler.sendMessage(Message.obtain());
}
@@ -1719,13 +1540,12 @@ public class cgeocaches extends AbstractListActivity {
showToast(res.getString(R.string.warn_no_keyword));
finish();
- return;
}
}
@Override
public void run() {
- search = cgBase.searchByKeyword(this, keyword, cacheType, Settings.isShowCaptcha());
+ search = GCParser.searchByKeyword(this, keyword, cacheType, Settings.isShowCaptcha());
handler.sendMessage(Message.obtain());
}
}
@@ -1745,13 +1565,12 @@ public class cgeocaches extends AbstractListActivity {
showToast(res.getString(R.string.warn_no_username));
finish();
- return;
}
}
@Override
public void run() {
- search = cgBase.searchByUsername(this, username, cacheType, Settings.isShowCaptcha());
+ search = GCParser.searchByUsername(this, username, cacheType, Settings.isShowCaptcha());
handler.sendMessage(Message.obtain());
}
}
@@ -1771,20 +1590,12 @@ public class cgeocaches extends AbstractListActivity {
showToast(res.getString(R.string.warn_no_username));
finish();
- return;
}
}
@Override
public void run() {
- Map<String, String> params = new HashMap<String, String>();
- params.put("username", username);
- if (cacheType != null) {
- params.put("cacheType", cacheType.id);
- }
-
- search = cgBase.searchByOwner(this, username, cacheType, Settings.isShowCaptcha());
-
+ search = GCParser.searchByOwner(this, username, cacheType, Settings.isShowCaptcha());
handler.sendMessage(Message.obtain());
}
}
@@ -1829,7 +1640,7 @@ public class cgeocaches extends AbstractListActivity {
try {
if (needToStop) {
- Log.i(Settings.tag, "Stopped storing process.");
+ Log.i("Stopped storing process.");
break;
}
@@ -1840,32 +1651,33 @@ public class cgeocaches extends AbstractListActivity {
delay = 500;
}
- Log.i(Settings.tag, "Waiting for next cache " + delay + " ms");
+ Log.i("Waiting for next cache " + delay + " ms");
sleep(delay);
} catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.LoadDetailsThread.sleep: " + e.toString());
+ Log.e("cgeocaches.LoadDetailsThread.sleep: " + e.toString());
}
}
if (needToStop) {
- Log.i(Settings.tag, "Stopped storing process.");
+ Log.i("Stopped storing process.");
break;
}
detailProgress++;
- cgBase.storeCache(cgeocaches.this, cache, null, listIdLD, null);
+ cache.refresh(cgeocaches.this, listIdLD, null);
handler.sendEmptyMessage(cacheList.indexOf(cache));
yield();
} catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.LoadDetailsThread: " + e.toString());
+ Log.e("cgeocaches.LoadDetailsThread: " + e.toString());
}
last = System.currentTimeMillis();
}
cacheListTemp.clear();
+ handler.sendEmptyMessage(MSG_RESTART_GEO_AND_DIR);
handler.sendEmptyMessage(MSG_DONE);
}
}
@@ -1904,21 +1716,18 @@ public class cgeocaches extends AbstractListActivity {
deviceCode = "";
}
final Parameters params = new Parameters("code", deviceCode);
- HttpResponse responseFromWeb = Network.request("http://send2.cgeo.org/read.html", params, true);
+ HttpResponse responseFromWeb = Network.getRequest("http://send2.cgeo.org/read.html", params);
if (responseFromWeb != null && responseFromWeb.getStatusLine().getStatusCode() == 200) {
final String response = Network.getResponseData(responseFromWeb);
if (response.length() > 2) {
-
- String GCcode = response;
-
delay = 1;
- handler.sendMessage(handler.obtainMessage(1, GCcode));
+ handler.sendMessage(handler.obtainMessage(1, response));
yield();
- cgBase.storeCache(cgeocaches.this, null, GCcode, listIdLFW, null);
+ cgCache.storeCache(cgeocaches.this, null, response, listIdLFW, false, null);
- handler.sendMessage(handler.obtainMessage(2, GCcode));
+ handler.sendMessage(handler.obtainMessage(2, response));
yield();
} else if ("RG".equals(response)) {
//Server returned RG (registration) and this device no longer registered.
@@ -1949,58 +1758,42 @@ public class cgeocaches extends AbstractListActivity {
times = 0;
}
} catch (InterruptedException e) {
- Log.e(Settings.tag, "cgeocaches.LoadFromWebThread.sleep: " + e.toString());
+ Log.e("cgeocaches.LoadFromWebThread.sleep: " + e.toString());
}
}
handler.sendEmptyMessage(ret);
+
+ startGeoAndDir();
}
}
private class DropDetailsThread extends Thread {
final private Handler handler;
- private volatile boolean needToStop = false;
- private int checked = 0;
+ private List<cgCache> selected = new ArrayList<cgCache>();
public DropDetailsThread(Handler handlerIn) {
setPriority(Thread.MIN_PRIORITY);
handler = handlerIn;
- if (adapter != null) {
- checked = adapter.getChecked();
+ int checked = adapter.getChecked();
+ if (checked == 0) {
+ selected = new ArrayList<cgCache>(cacheList);
+ }
+ else {
+ selected = adapter.getCheckedCaches();
}
- }
-
- public void kill() {
- needToStop = true;
}
@Override
public void run() {
removeGeoAndDir();
-
- final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList);
- for (cgCache cache : cacheListTemp) {
- if (checked > 0 && !cache.isStatusChecked()) {
- continue;
- }
-
- try {
- if (needToStop) {
- Log.i(Settings.tag, "Stopped dropping process.");
- break;
- }
-
- app.markDropped(cache.getGeocode());
- } catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.DropDetailsThread: " + e.toString());
- }
- }
- cacheListTemp.clear();
-
+ app.markDropped(selected);
handler.sendEmptyMessage(MSG_DONE);
+
+ startGeoAndDir();
}
}
@@ -2036,7 +1829,7 @@ public class cgeocaches extends AbstractListActivity {
try {
if (needToStop) {
- Log.i(Settings.tag, "Stopped removing process.");
+ Log.i("Stopped removing process.");
break;
}
@@ -2047,128 +1840,7 @@ public class cgeocaches extends AbstractListActivity {
yield();
} catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.RemoveFromHistoryThread: " + e.toString());
- }
- }
-
- handler.sendEmptyMessage(MSG_DONE);
- }
- }
-
- private class ExportFieldNotesThread extends Thread
- {
- private final Handler handler;
- private volatile boolean needToStop = false;
- private int checked = 0;
-
- public ExportFieldNotesThread(Handler handlerIn)
- {
- setPriority(Thread.MIN_PRIORITY);
-
- handler = handlerIn;
-
- if (adapter != null)
- {
- checked = adapter.getChecked();
- }
- }
-
- public void kill()
- {
- needToStop = true;
- }
-
- @Override
- public void run()
- {
- SimpleDateFormat fieldNoteDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
- StringBuilder fieldNoteBuffer = new StringBuilder(500);
-
- // We need our own HashMap because LogType will give us localized and maybe
- // different strings than gc.com expects in the field note
- // We only need such logtypes that are possible to log via c:geo
- Map<LogType, String> logTypes = new HashMap<LogType, String>();
- logTypes.put(LogType.LOG_FOUND_IT, "Found it");
- logTypes.put(LogType.LOG_DIDNT_FIND_IT, "Didn't find it");
- logTypes.put(LogType.LOG_NOTE, "Write Note");
- logTypes.put(LogType.LOG_NEEDS_ARCHIVE, "Needs archived");
- logTypes.put(LogType.LOG_NEEDS_MAINTENANCE, "Needs Maintenance");
- logTypes.put(LogType.LOG_WILL_ATTEND, "Will Attend");
- logTypes.put(LogType.LOG_ATTENDED, "Attended");
- logTypes.put(LogType.LOG_WEBCAM_PHOTO_TAKEN, "Webcam Photo Taken");
-
- for (cgCache cache : cacheList) {
- if (checked > 0 && !cache.isStatusChecked()) {
- handler.sendEmptyMessage(0);
-
- yield();
- continue;
- }
-
- try {
- if (needToStop)
- {
- Log.i(Settings.tag, "Stopped exporting process.");
- break;
- }
-
- if (cache.isLogOffline())
- {
- cgLog log = app.loadLogOffline(cache.getGeocode());
-
- if (null != logTypes.get(log.type))
- {
- fieldNoteBuffer.append(cache.getGeocode())
- .append(',')
- .append(fieldNoteDateFormat.format(new Date(log.date)))
- .append(',')
- .append(logTypes.get(log.type))
- .append(",\"")
- .append(StringUtils.replaceChars(log.log, '"', '\''))
- .append("\"\n");
- }
- }
-
- detailProgress++;
-
- handler.sendEmptyMessage(cacheList.indexOf(cache));
-
- yield();
- } catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.ExportFieldNotesThread: " + e.toString());
- }
- }
-
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
- {
- File exportLocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/field-notes");
- exportLocation.mkdirs();
-
- SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
- File exportFile = new File(exportLocation + "/" + fileNameDateFormat.format(new Date()) + ".txt");
-
- OutputStream os = null;
- Writer fw = null;
- try
- {
- os = new FileOutputStream(exportFile);
- fw = new OutputStreamWriter(os, "ISO-8859-1"); // TODO: gc.com doesn't support UTF-8
- fw.write(fieldNoteBuffer.toString());
-
- Message.obtain(handler, -2, exportFile).sendToTarget();
- } catch (IOException e) {
- Log.e(Settings.tag, "cgeocaches.ExportFieldNotesThread: " + e.toString());
- handler.sendEmptyMessage(-3);
- } finally
- {
- if (fw != null)
- {
- try {
- fw.close();
- } catch (IOException e) {
- Log.e(Settings.tag, "cgeocaches.ExportFieldNotesThread: " + e.toString());
- }
- }
+ Log.e("cgeocaches.RemoveFromHistoryThread: " + e.toString());
}
}
@@ -2193,7 +1865,7 @@ public class cgeocaches extends AbstractListActivity {
private void hideLoading() {
final ListView list = getListView();
- final RelativeLayout loading = (RelativeLayout) findViewById(R.id.loading);
+ final View loading = findViewById(R.id.loading);
if (list.getVisibility() == View.GONE) {
list.setVisibility(View.VISIBLE);
@@ -2209,41 +1881,13 @@ public class cgeocaches extends AbstractListActivity {
if (type != CacheListType.OFFLINE) {
return;
}
+ new StoredList.UserInterface(this).promptForListSelection(R.string.list_title, new RunnableWithArgument<Integer>() {
- lists = app.getLists();
-
- if (lists == null) {
- return;
- }
-
- final List<CharSequence> listsTitle = new ArrayList<CharSequence>();
- for (StoredList list : lists) {
- listsTitle.add(list.getTitleAndCount());
- }
- listsTitle.add("<" + res.getString(R.string.list_menu_create) + ">");
-
- final CharSequence[] items = new CharSequence[listsTitle.size()];
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(res.getString(R.string.list_title));
- builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialogInterface, int itemId) {
- if (itemId >= lists.size()) {
- // create new list on the fly
- createList(new RunnableWithArgument<Integer>() {
-
- @Override
- public void run(final Integer arg) {
- switchListById(arg.intValue());
- }
- });
- }
- else {
- switchListById(lists.get(itemId).id);
- }
+ @Override
+ public void run(final Integer selectedListId) {
+ switchListById(selectedListId);
}
});
- builder.create().show();
}
public void switchListById(int id) {
@@ -2287,72 +1931,17 @@ public class cgeocaches extends AbstractListActivity {
@Override
public void run() {
- int checked = adapter.getChecked();
- if (checked > 0) {
- final List<cgCache> cacheListTemp = new ArrayList<cgCache>(cacheList);
- for (cgCache cache : cacheListTemp) {
- if (cache.isStatusChecked()) {
- app.moveToList(cache.getGeocode(), listId);
- }
- }
- }
-
+ final List<cgCache> caches = adapter.getCheckedCaches();
+ app.moveToList(caches, listId);
handler.sendEmptyMessage(listId);
}
}
- private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final RunnableWithArgument<String> runnable) {
- final AlertDialog.Builder alert = new AlertDialog.Builder(this);
- final View view = inflater.inflate(R.layout.list_create_dialog, null);
- final EditText input = (EditText) view.findViewById(R.id.text);
- input.setText(defaultValue);
-
- alert.setTitle(dialogTitle);
- alert.setView(view);
- alert.setPositiveButton(buttonTitle, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- // remove whitespaces added by autocompletion of Android keyboard
- String listName = StringUtils.trim(input.getText().toString());
- if (StringUtils.isNotBlank(listName)) {
- runnable.run(listName);
- }
- }
- });
- alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- dialog.dismiss();
- }
- });
-
- alert.show();
- }
-
- private void createList(final RunnableWithArgument<Integer> runAfterwards) {
- handleListNameInput("", R.string.list_dialog_create_title, R.string.list_dialog_create, new RunnableWithArgument<String>() {
-
- @Override
- public void run(final String listName) {
- final int newId = app.createList(listName);
-
- if (newId >= 10) {
- showToast(res.getString(R.string.list_dialog_create_ok));
- if (runAfterwards != null) {
- runAfterwards.run(newId);
- }
- } else {
- showToast(res.getString(R.string.list_dialog_create_err));
- }
- }
- });
- }
-
private void renameList() {
- final StoredList list = app.getList(listId);
- handleListNameInput(list.title, R.string.list_dialog_rename_title, R.string.list_dialog_rename, new RunnableWithArgument<String>() {
+ new StoredList.UserInterface(this).promptForListRename(listId, new Runnable() {
@Override
- public void run(final String listName) {
- app.renameList(listId, listName);
+ public void run() {
refreshCurrentList();
}
});
@@ -2461,8 +2050,7 @@ public class cgeocaches extends AbstractListActivity {
Intent cachesIntent = new Intent(context, cachesActivity.getClass());
cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.COORDINATE);
- cachesIntent.putExtra("latitude", coords.getLatitude());
- cachesIntent.putExtra("longitude", coords.getLongitude());
+ cachesIntent.putExtra(EXTRAS_COORDS, coords);
context.startActivity(cachesIntent);
}
@@ -2529,8 +2117,7 @@ public class cgeocaches extends AbstractListActivity {
public static void startActivityNearest(final Context context, final Geopoint coordsNow) {
final Intent cachesIntent = new Intent(context, cgeocaches.class);
cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.NEAREST);
- cachesIntent.putExtra("latitude", coordsNow.getLatitude());
- cachesIntent.putExtra("longitude", coordsNow.getLongitude());
+ cachesIntent.putExtra(EXTRAS_COORDS, coordsNow);
context.startActivity(cachesIntent);
}
@@ -2540,20 +2127,18 @@ public class cgeocaches extends AbstractListActivity {
context.startActivity(cachesIntent);
}
- public static void startActivityAddress(Context context, double latitude, double longitude, String address) {
+ public static void startActivityAddress(final Context context, final Geopoint coords, final String address) {
Intent addressIntent = new Intent(context, cgeocaches.class);
addressIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.ADDRESS);
- addressIntent.putExtra("latitude", latitude);
- addressIntent.putExtra("longitude", longitude);
+ addressIntent.putExtra(EXTRAS_COORDS, coords);
addressIntent.putExtra("address", address);
context.startActivity(addressIntent);
}
- public static void startActivityCoordinates(final Context context, double latitude, double longitude) {
+ public static void startActivityCoordinates(final Context context, final Geopoint coords) {
final Intent cachesIntent = new Intent(context, cgeocaches.class);
cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.COORDINATE);
- cachesIntent.putExtra("latitude", latitude);
- cachesIntent.putExtra("longitude", longitude);
+ cachesIntent.putExtra(EXTRAS_COORDS, coords);
context.startActivity(cachesIntent);
}
diff --git a/main/src/cgeo/geocaching/cgeocoords.java b/main/src/cgeo/geocaching/cgeocoords.java
index b4868ce..0ad2e81 100644
--- a/main/src/cgeo/geocaching/cgeocoords.java
+++ b/main/src/cgeo/geocaching/cgeocoords.java
@@ -5,12 +5,11 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.compatibility.Compatibility;
import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.geopoint.Geopoint.DDD;
-import cgeo.geocaching.geopoint.Geopoint.DMM;
-import cgeo.geocaching.geopoint.Geopoint.DMS;
-import cgeo.geocaching.geopoint.Geopoint.Direction;
import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.geopoint.GeopointParser.ParseException;
+import cgeo.geocaching.geopoint.direction.DDD;
+import cgeo.geocaching.geopoint.direction.DMM;
+import cgeo.geocaching.geopoint.direction.DMS;
+import cgeo.geocaching.geopoint.direction.Direction;
import org.apache.commons.lang3.StringUtils;
@@ -32,7 +31,7 @@ import android.widget.TextView;
public class cgeocoords extends Dialog {
final private AbstractActivity context;
- final private cgGeo geo;
+ final private IGeoData geo;
final private cgCache cache;
private Geopoint gp;
@@ -43,13 +42,11 @@ public class cgeocoords extends Dialog {
private TextView tLatSep1, tLatSep2, tLatSep3;
private TextView tLonSep1, tLonSep2, tLonSep3;
- private Spinner spinner;
-
private CoordinateUpdate cuListener;
private coordInputFormatEnum currentFormat = null;
- public cgeocoords(final AbstractActivity context, final cgCache cache, final Geopoint gp, final cgGeo geo) {
+ public cgeocoords(final AbstractActivity context, final cgCache cache, final Geopoint gp, final IGeoData geo) {
super(context);
this.context = context;
this.geo = geo;
@@ -57,8 +54,8 @@ public class cgeocoords extends Dialog {
if (gp != null) {
this.gp = gp;
- } else if (geo != null && geo.coordsNow != null) {
- this.gp = geo.coordsNow;
+ } else if (geo != null && geo.getCoords() != null) {
+ this.gp = geo.getCoords();
} else {
this.gp = new Geopoint(0.0, 0.0);
}
@@ -84,7 +81,7 @@ public class cgeocoords extends Dialog {
}
});
- spinner = (Spinner) findViewById(R.id.spinnerCoordinateFormats);
+ final Spinner spinner = (Spinner) findViewById(R.id.spinnerCoordinateFormats);
final ArrayAdapter<CharSequence> adapter =
ArrayAdapter.createFromResource(context,
R.array.waypoint_coordinate_formats,
@@ -352,7 +349,7 @@ public class cgeocoords extends Dialog {
if (currentFormat == coordInputFormatEnum.Plain) {
try {
gp = new Geopoint(eLat.getText().toString(), eLon.getText().toString());
- } catch (ParseException e) {
+ } catch (Geopoint.ParseException e) {
if (signalError) {
context.showToast(context.getResources().getString(R.string.err_parse_lat_lon));
}
@@ -416,10 +413,10 @@ public class cgeocoords extends Dialog {
// Start new format with an acceptable value: either the current one
// entered by the user, else our current coordinates, else (0,0).
if (!calc(false)) {
- if (geo != null && geo.coordsNow != null) {
- gp = geo.coordsNow;
+ if (geo != null && geo.getCoords() != null) {
+ gp = geo.getCoords();
} else {
- gp = new Geopoint(0, 0);
+ gp = new Geopoint(0.0, 0.0);
}
}
}
@@ -439,12 +436,12 @@ public class cgeocoords extends Dialog {
@Override
public void onClick(View v) {
- if (geo == null || geo.coordsNow == null) {
+ if (geo == null || geo.getCoords() == null) {
context.showToast(context.getResources().getString(R.string.err_point_unknown_position));
return;
}
- gp = geo.coordsNow;
+ gp = geo.getCoords();
updateGUI();
}
}
diff --git a/main/src/cgeo/geocaching/cgeoimages.java b/main/src/cgeo/geocaching/cgeoimages.java
index 79c0e24..7145d59 100644
--- a/main/src/cgeo/geocaching/cgeoimages.java
+++ b/main/src/cgeo/geocaching/cgeoimages.java
@@ -3,6 +3,7 @@ package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.files.LocalStorage;
import cgeo.geocaching.network.HtmlImage;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -18,7 +19,7 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
-import android.util.Log;
+import android.util.SparseArray;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
@@ -34,7 +35,6 @@ import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
public class cgeoimages extends AbstractActivity {
@@ -51,7 +51,7 @@ public class cgeoimages extends AbstractActivity {
private LinearLayout imagesView = null;
private int count = 0;
private int countDone = 0;
- private final HashMap<Integer, cgImage> images = new HashMap<Integer, cgImage>();
+ private final SparseArray<cgImage> images = new SparseArray<cgImage>();
private BitmapDrawable currentDrawable;
private cgImage currentImage;
@@ -60,14 +60,14 @@ public class cgeoimages extends AbstractActivity {
private void loadImages(final List<cgImage> images, final int progressMessage, final boolean offline) {
count = images.size();
- progressDialog = new ProgressDialog(cgeoimages.this);
+ progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage(res.getString(progressMessage));
progressDialog.setCancelable(true);
progressDialog.setMax(count);
progressDialog.show();
- LinearLayout rowView = null;
+ LinearLayout rowView;
for (final cgImage img : images) {
rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null);
@@ -207,7 +207,7 @@ public class cgeoimages extends AbstractActivity {
image.getBitmap().compress(CompressFormat.JPEG, 100, fos);
fos.close();
} catch (Exception e) {
- Log.e(Settings.tag, "cgeoimages.handleMessage.onClick: " + e.toString());
+ Log.e("cgeoimages.handleMessage.onClick: " + e.toString());
return;
}
diff --git a/main/src/cgeo/geocaching/cgeoinit.java b/main/src/cgeo/geocaching/cgeoinit.java
index a8e660a..0aeed10 100644
--- a/main/src/cgeo/geocaching/cgeoinit.java
+++ b/main/src/cgeo/geocaching/cgeoinit.java
@@ -4,13 +4,16 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory.NavigationAppsEnum;
import cgeo.geocaching.compatibility.Compatibility;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.maps.MapProviderFactory;
-import cgeo.geocaching.network.Login;
+import cgeo.geocaching.network.Cookies;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.twitter.TwitterAuthorizationActivity;
+import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.LogTemplateProvider;
import cgeo.geocaching.utils.LogTemplateProvider.LogTemplate;
@@ -19,6 +22,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.http.HttpResponse;
import android.app.ProgressDialog;
+import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
@@ -26,7 +30,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
@@ -45,7 +48,6 @@ import android.widget.TextView;
import java.io.File;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
public class cgeoinit extends AbstractActivity {
@@ -73,7 +75,7 @@ public class cgeoinit extends AbstractActivity {
} catch (Exception e) {
showToast(res.getString(R.string.err_login_failed));
- Log.e(Settings.tag, "cgeoinit.logInHandler: " + e.toString());
+ Log.e("cgeoinit.logInHandler: " + e.toString());
}
if (loginDialog != null && loginDialog.isShowing()) {
@@ -101,7 +103,7 @@ public class cgeoinit extends AbstractActivity {
} catch (Exception e) {
showToast(res.getString(R.string.init_sendToCgeo_register_fail));
- Log.e(Settings.tag, "cgeoinit.webHandler: " + e.toString());
+ Log.e("cgeoinit.webHandler: " + e.toString());
}
if (webDialog != null && webDialog.isShowing()) {
@@ -173,7 +175,7 @@ public class cgeoinit extends AbstractActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 0) {
- boolean status = false;
+ boolean status;
((EditText) findViewById(R.id.username)).setText("");
((EditText) findViewById(R.id.password)).setText("");
@@ -669,6 +671,17 @@ public class cgeoinit extends AbstractActivity {
refreshBackupLabel();
+ // Debug settings
+ final CheckBox debugButton = (CheckBox) findViewById(R.id.debug);
+ debugButton.setChecked(Settings.isDebug());
+ debugButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ Settings.setDebug(!Settings.isDebug());
+ debugButton.setChecked(Settings.isDebug());
+ }
+ });
}
private void initMapfileEdittext(boolean setFocus) {
@@ -685,42 +698,34 @@ public class cgeoinit extends AbstractActivity {
*/
public void backup(View view) {
// avoid overwriting an existing backup with an empty database (can happen directly after reinstalling the app)
- if (app.getAllStoredCachesCount(true, CacheType.ALL, null) == 0) {
+ if (app.getAllStoredCachesCount(true, CacheType.ALL) == 0) {
helpDialog(res.getString(R.string.init_backup), res.getString(R.string.init_backup_unnecessary));
return;
}
- final AtomicReference<String> fileRef = new AtomicReference<String>(null);
final ProgressDialog dialog = ProgressDialog.show(this, res.getString(R.string.init_backup), res.getString(R.string.init_backup_running), true, false);
- Thread backupThread = new Thread() {
- final Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- dialog.dismiss();
- final String file = fileRef.get();
- if (file != null) {
- helpDialog(res.getString(R.string.init_backup_backup), res.getString(R.string.init_backup_success) + "\n" + file);
- } else {
- helpDialog(res.getString(R.string.init_backup_backup), res.getString(R.string.init_backup_failed));
- }
- refreshBackupLabel();
- }
- };
-
+ new Thread() {
@Override
public void run() {
- fileRef.set(app.backupDatabase());
- handler.sendMessage(handler.obtainMessage());
+ final String backupFileName = app.backupDatabase();
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ dialog.dismiss();
+ helpDialog(res.getString(R.string.init_backup_backup),
+ backupFileName != null ? res.getString(R.string.init_backup_success) + "\n" + backupFileName : res.getString(R.string.init_backup_failed));
+ refreshBackupLabel();
+ }
+ });
}
- };
- backupThread.start();
+ }.start();
}
private void refreshBackupLabel() {
TextView lastBackup = (TextView) findViewById(R.id.backup_last);
File lastBackupFile = cgeoapplication.isRestoreFile();
if (lastBackupFile != null) {
- lastBackup.setText(res.getString(R.string.init_backup_last) + " " + cgBase.formatTime(lastBackupFile.lastModified()) + ", " + cgBase.formatDate(lastBackupFile.lastModified()));
+ lastBackup.setText(res.getString(R.string.init_backup_last) + " " + Formatter.formatTime(lastBackupFile.lastModified()) + ", " + Formatter.formatDate(lastBackupFile.lastModified()));
} else {
lastBackup.setText(res.getString(R.string.init_backup_last_no));
}
@@ -810,7 +815,7 @@ public class cgeoinit extends AbstractActivity {
loginDialog.setCancelable(false);
Settings.setLogin(username, password);
- Network.clearCookies();
+ Cookies.clearCookies();
(new Thread() {
@@ -852,7 +857,7 @@ public class cgeoinit extends AbstractActivity {
final String cod = StringUtils.defaultString(deviceCode);
final Parameters params = new Parameters("name", nam, "code", cod);
- HttpResponse response = Network.request("http://send2.cgeo.org/auth.html", params, true);
+ HttpResponse response = Network.getRequest("http://send2.cgeo.org/auth.html", params);
if (response != null && response.getStatusLine().getStatusCode() == 200)
{
@@ -861,7 +866,7 @@ public class cgeoinit extends AbstractActivity {
try {
pin = Integer.parseInt(strings[1].trim());
} catch (Exception e) {
- Log.e(Settings.tag, "webDialog: " + e.toString());
+ Log.e("webDialog: " + e.toString());
}
String code = strings[0];
Settings.setWebNameCode(nam, code);
@@ -881,9 +886,18 @@ public class cgeoinit extends AbstractActivity {
if (resultCode == RESULT_OK) {
if (data.hasExtra("mapfile")) {
Settings.setMapFile(data.getStringExtra("mapfile"));
+ if (!Settings.isValidMapFile(Settings.getMapFile())) {
+ showToast(res.getString(R.string.warn_invalid_mapfile));
+ }
}
}
initMapfileEdittext(true);
}
}
+
+ public static void startActivity(Context fromActivity) {
+ final Intent initIntent = new Intent(fromActivity, cgeoinit.class);
+ fromActivity.startActivity(initIntent);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/cgeonavigate.java b/main/src/cgeo/geocaching/cgeonavigate.java
index 01a9e74..9e903b6 100644
--- a/main/src/cgeo/geocaching/cgeonavigate.java
+++ b/main/src/cgeo/geocaching/cgeonavigate.java
@@ -6,16 +6,16 @@ import cgeo.geocaching.geopoint.HumanDistance;
import cgeo.geocaching.geopoint.IConversion;
import cgeo.geocaching.maps.CGeoMap;
import cgeo.geocaching.ui.CompassView;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.IObserver;
+import cgeo.geocaching.utils.PeriodicHandler;
import org.apache.commons.lang3.StringUtils;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.os.PowerManager;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
@@ -25,19 +25,16 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-public class cgeonavigate extends AbstractActivity {
+public class cgeonavigate extends AbstractActivity implements IObserver<IGeoData> {
- private static final String EXTRAS_LONGITUDE = "longitude";
- private static final String EXTRAS_LATITUDE = "latitude";
+ private static final String EXTRAS_COORDS = "coords";
private static final String EXTRAS_NAME = "name";
private static final String EXTRAS_GEOCODE = "geocode";
- private static final List<cgCoord> coordinates = new ArrayList<cgCoord>();
+ private static final List<IWaypoint> coordinates = new ArrayList<IWaypoint>();
private static final int MENU_MAP = 0;
private static final int MENU_SWITCH_COMPASS_GPS = 1;
private PowerManager pm = null;
- private cgGeo geo = null;
private cgDirection dir = null;
- private UpdateLocationCallback geoUpdate = new update();
private UpdateDirectionCallback dirUpdate = new UpdateDirection();
private Geopoint dstCoords = null;
private float cacheHeading = 0;
@@ -51,19 +48,15 @@ public class cgeonavigate extends AbstractActivity {
private TextView distanceView = null;
private TextView headingView = null;
private CompassView compassView = null;
- private updaterThread updater = null;
- private Handler updaterHandler = new Handler() {
+ private PeriodicHandler updaterHandler = new PeriodicHandler(20) {
@Override
- public void handleMessage(Message msg) {
- try {
- if (compassView != null && northHeading != null) {
- compassView.updateNorth(northHeading, cacheHeading);
- }
- } catch (Exception e) {
- Log.e(Settings.tag, "cgeonavigate.updaterHandler: " + e.toString());
+ public void act() {
+ if (compassView != null && northHeading != null) {
+ compassView.updateNorth(northHeading, cacheHeading);
}
}
+
};
private String geocode;
@@ -80,9 +73,6 @@ public class cgeonavigate extends AbstractActivity {
setTitle(res.getString(R.string.compass_title));
// sensor & geolocation manager
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
if (Settings.isUseCompass() && dir == null) {
dir = app.startDir(this, dirUpdate);
}
@@ -93,7 +83,7 @@ public class cgeonavigate extends AbstractActivity {
geocode = extras.getString(EXTRAS_GEOCODE);
title = geocode;
name = extras.getString(EXTRAS_NAME);
- dstCoords = new Geopoint(extras.getDouble(EXTRAS_LATITUDE), extras.getDouble(EXTRAS_LONGITUDE));
+ dstCoords = (Geopoint) extras.getParcelable(EXTRAS_COORDS);
if (StringUtils.isNotBlank(name)) {
if (StringUtils.isNotBlank(title)) {
@@ -116,19 +106,18 @@ public class cgeonavigate extends AbstractActivity {
setTitle();
setDestCoords();
- if (geo != null) {
- geoUpdate.updateLocation(geo);
- }
if (dir != null) {
dirUpdate.updateDirection(dir);
}
// get textviews once
compassView = (CompassView) findViewById(R.id.rose);
+ }
- // start updater thread
- updater = new updaterThread(updaterHandler);
- updater.start();
+ @Override
+ public void onStart() {
+ super.onStart();
+ updaterHandler.start();
}
@Override
@@ -138,9 +127,7 @@ public class cgeonavigate extends AbstractActivity {
setGo4CacheAction();
// sensor & geolocation manager
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
+ app.addGeoObserver(this);
if (Settings.isUseCompass() && dir == null) {
dir = app.startDir(this, dirUpdate);
}
@@ -149,12 +136,6 @@ public class cgeonavigate extends AbstractActivity {
if (pm == null) {
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
}
-
- // updater thread
- if (updater == null) {
- updater = new updaterThread(updaterHandler);
- updater.start();
- }
}
private void setGo4CacheAction() {
@@ -167,21 +148,18 @@ public class cgeonavigate extends AbstractActivity {
@Override
public void onStop() {
- if (geo != null) {
- geo = app.removeGeo();
- }
if (dir != null) {
dir = app.removeDir();
}
+ updaterHandler.stop();
+
super.onStop();
}
@Override
public void onPause() {
- if (geo != null) {
- geo = app.removeGeo();
- }
+ app.deleteGeoObserver(this);
if (dir != null) {
dir = app.removeDir();
}
@@ -191,9 +169,6 @@ public class cgeonavigate extends AbstractActivity {
@Override
public void onDestroy() {
- if (geo != null) {
- geo = app.removeGeo();
- }
if (dir != null) {
dir = app.removeDir();
}
@@ -205,42 +180,27 @@ public class cgeonavigate extends AbstractActivity {
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (Settings.isUseCompass()) {
- menu.add(0, MENU_SWITCH_COMPASS_GPS, 0, res.getString(R.string.use_gps)).setIcon(android.R.drawable.ic_menu_compass);
- } else {
- menu.add(0, MENU_SWITCH_COMPASS_GPS, 0, res.getString(R.string.use_compass)).setIcon(android.R.drawable.ic_menu_compass);
- }
+ public boolean onCreateOptionsMenu(final Menu menu) {
+ menu.add(0, MENU_SWITCH_COMPASS_GPS, 0, res.getString(Settings.isUseCompass() ? R.string.use_gps : R.string.use_compass)).setIcon(android.R.drawable.ic_menu_compass);
menu.add(0, MENU_MAP, 0, res.getString(R.string.caches_on_map)).setIcon(android.R.drawable.ic_menu_mapmode);
menu.add(0, 2, 0, res.getString(R.string.destination_set)).setIcon(android.R.drawable.ic_menu_edit);
if (coordinates.size() > 1) {
- SubMenu subMenu = menu.addSubMenu(0, 3, 0, res.getString(R.string.destination_select)).setIcon(android.R.drawable.ic_menu_myplaces);
-
+ final SubMenu subMenu = menu.addSubMenu(0, 3, 0, res.getString(R.string.destination_select)).setIcon(android.R.drawable.ic_menu_myplaces);
int cnt = 4;
- for (cgCoord coordinate : coordinates) {
+ for (final IWaypoint coordinate : coordinates) {
subMenu.add(0, cnt, 0, coordinate.getName() + " (" + coordinate.getCoordType() + ")");
cnt++;
}
-
- return true;
} else {
menu.add(0, 3, 0, res.getString(R.string.destination_select)).setIcon(android.R.drawable.ic_menu_myplaces).setEnabled(false);
-
- return true;
}
+ return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
-
- MenuItem item = menu.findItem(MENU_SWITCH_COMPASS_GPS);
- if (Settings.isUseCompass()) {
- item.setTitle(res.getString(R.string.use_gps));
- } else {
- item.setTitle(res.getString(R.string.use_compass));
- }
-
+ menu.findItem(MENU_SWITCH_COMPASS_GPS).setTitle(res.getString(Settings.isUseCompass() ? R.string.use_gps : R.string.use_compass));
return true;
}
@@ -270,15 +230,15 @@ public class cgeonavigate extends AbstractActivity {
finish();
return true;
} else if (id > 3 && coordinates.get(id - 4) != null) {
- cgCoord coordinate = coordinates.get(id - 4);
+ final IWaypoint coordinate = coordinates.get(id - 4);
title = coordinate.getName();
dstCoords = coordinate.getCoords();
setTitle();
setDestCoords();
- updateDistanceInfo();
+ updateDistanceInfo(app.currentGeo());
- Log.d(Settings.tag, "destination set: " + title + " (" + dstCoords + ")");
+ Log.d("destination set: " + title + " (" + dstCoords + ")");
return true;
}
@@ -301,25 +261,8 @@ public class cgeonavigate extends AbstractActivity {
((TextView) findViewById(R.id.destination)).setText(dstCoords.toString());
}
- public void setDest(final Geopoint coords) {
- if (coords == null) {
- return;
- }
-
- title = "some place";
- setTitle();
- setDestCoords();
-
- dstCoords = coords;
- updateDistanceInfo();
- }
-
- public Geopoint getCoordinatesNow() {
- return geo.coordsNow;
- }
-
- private void updateDistanceInfo() {
- if (geo == null || geo.coordsNow == null || dstCoords == null) {
+ private void updateDistanceInfo(final IGeoData geo) {
+ if (geo.getCoords() == null || dstCoords == null) {
return;
}
@@ -330,69 +273,62 @@ public class cgeonavigate extends AbstractActivity {
headingView = (TextView) findViewById(R.id.heading);
}
- cacheHeading = geo.coordsNow.bearingTo(dstCoords);
- distanceView.setText(HumanDistance.getHumanDistance(geo.coordsNow.distanceTo(dstCoords)));
+ cacheHeading = geo.getCoords().bearingTo(dstCoords);
+ distanceView.setText(HumanDistance.getHumanDistance(geo.getCoords().distanceTo(dstCoords)));
headingView.setText(Math.round(cacheHeading) + "°");
}
- private class update implements UpdateLocationCallback {
-
- @Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
+ @Override
+ public void update(final IGeoData geo) {
+ try {
+ if (navType == null || navLocation == null || navAccuracy == null) {
+ navType = (TextView) findViewById(R.id.nav_type);
+ navAccuracy = (TextView) findViewById(R.id.nav_accuracy);
+ navSatellites = (TextView) findViewById(R.id.nav_satellites);
+ navLocation = (TextView) findViewById(R.id.nav_location);
}
- try {
- if (navType == null || navLocation == null || navAccuracy == null) {
- navType = (TextView) findViewById(R.id.nav_type);
- navAccuracy = (TextView) findViewById(R.id.nav_accuracy);
- navSatellites = (TextView) findViewById(R.id.nav_satellites);
- navLocation = (TextView) findViewById(R.id.nav_location);
+ if (geo.getCoords() != null) {
+ String satellites;
+ if (geo.getSatellitesFixed() > 0) {
+ satellites = res.getString(R.string.loc_sat) + ": " + geo.getSatellitesFixed() + "/" + geo.getSatellitesVisible();
+ } else if (geo.getSatellitesVisible() >= 0) {
+ satellites = res.getString(R.string.loc_sat) + ": 0/" + geo.getSatellitesVisible();
+ } else {
+ satellites = "";
}
+ navSatellites.setText(satellites);
+ navType.setText(res.getString(geo.getLocationProvider().resourceId));
- if (geo.coordsNow != null) {
- String satellites = null;
- if (geo.satellitesFixed > 0) {
- satellites = res.getString(R.string.loc_sat) + ": " + geo.satellitesFixed + "/" + geo.satellitesVisible;
- } else if (geo.satellitesVisible >= 0) {
- satellites = res.getString(R.string.loc_sat) + ": 0/" + geo.satellitesVisible;
+ if (geo.getAccuracy() >= 0) {
+ if (Settings.isUseMetricUnits()) {
+ navAccuracy.setText("±" + Math.round(geo.getAccuracy()) + " m");
} else {
- satellites = "";
+ navAccuracy.setText("±" + Math.round(geo.getAccuracy() * IConversion.METERS_TO_FEET) + " ft");
}
- navSatellites.setText(satellites);
- navType.setText(res.getString(geo.locationProvider.resourceId));
-
- if (geo.accuracyNow >= 0) {
- if (Settings.isUseMetricUnits()) {
- navAccuracy.setText("±" + Math.round(geo.accuracyNow) + " m");
- } else {
- navAccuracy.setText("±" + Math.round(geo.accuracyNow * IConversion.METERS_TO_FEET) + " ft");
- }
- } else {
- navAccuracy.setText(null);
- }
-
- if (geo.altitudeNow != null) {
- final String humanAlt = HumanDistance.getHumanDistance(geo.altitudeNow.floatValue() / 1000);
- navLocation.setText(geo.coordsNow + " | " + humanAlt);
- } else {
- navLocation.setText(geo.coordsNow.toString());
- }
-
- updateDistanceInfo();
} else {
- navType.setText(null);
navAccuracy.setText(null);
- navLocation.setText(res.getString(R.string.loc_trying));
}
- if (!Settings.isUseCompass() || geo.speedNow > 5) { // use GPS when speed is higher than 18 km/h
- northHeading = geo.bearingNow;
+ if (geo.getAltitude() != 0.0f) {
+ final String humanAlt = HumanDistance.getHumanDistance((float) geo.getAltitude() / 1000);
+ navLocation.setText(geo.getCoords() + " | " + humanAlt);
+ } else {
+ navLocation.setText(geo.getCoords().toString());
}
- } catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
+
+ updateDistanceInfo(geo);
+ } else {
+ navType.setText(null);
+ navAccuracy.setText(null);
+ navLocation.setText(res.getString(R.string.loc_trying));
+ }
+
+ if (!Settings.isUseCompass() || geo.getSpeed() > 5) { // use GPS when speed is higher than 18 km/h
+ northHeading = geo.getBearing();
}
+ } catch (Exception e) {
+ Log.w("Failed to LocationUpdater location.");
}
}
@@ -404,45 +340,20 @@ public class cgeonavigate extends AbstractActivity {
return;
}
- if (geo == null || geo.speedNow <= 5) { // use compass when speed is lower than 18 km/h
+ if (app.currentGeo().getSpeed() <= 5) { // use compass when speed is lower than 18 km/h
northHeading = dir.directionNow;
}
}
}
- private static class updaterThread extends Thread {
-
- private Handler handler = null;
-
- public updaterThread(Handler handlerIn) {
- handler = handlerIn;
- }
-
- @Override
- public void run() {
- while (!Thread.currentThread().isInterrupted()) {
- if (handler != null) {
- handler.sendMessage(Message.obtain());
- }
-
- try {
- Thread.sleep(20);
- } catch (Exception e) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
-
- public static void startActivity(final Context context, final String geocode, final String displayedName, final Geopoint coords, final Collection<cgCoord> coordinatesWithType) {
+ public static void startActivity(final Context context, final String geocode, final String displayedName, final Geopoint coords, final Collection<IWaypoint> coordinatesWithType) {
coordinates.clear();
if (coordinatesWithType != null) { // avoid possible NPE
coordinates.addAll(coordinatesWithType);
}
final Intent navigateIntent = new Intent(context, cgeonavigate.class);
- navigateIntent.putExtra(EXTRAS_LATITUDE, coords.getLatitude());
- navigateIntent.putExtra(EXTRAS_LONGITUDE, coords.getLongitude());
+ navigateIntent.putExtra(EXTRAS_COORDS, coords);
navigateIntent.putExtra(EXTRAS_GEOCODE, geocode.toUpperCase());
if (null != displayedName) {
navigateIntent.putExtra(EXTRAS_NAME, displayedName);
diff --git a/main/src/cgeo/geocaching/cgeopoint.java b/main/src/cgeo/geocaching/cgeopoint.java
index 890f396..e85b27d 100644
--- a/main/src/cgeo/geocaching/cgeopoint.java
+++ b/main/src/cgeo/geocaching/cgeopoint.java
@@ -5,7 +5,9 @@ import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.geopoint.DistanceParser;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.geopoint.GeopointParser;
+import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.IObserver;
import org.apache.commons.lang3.StringUtils;
@@ -13,7 +15,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
@@ -34,24 +35,24 @@ import android.widget.TextView;
import java.util.List;
-public class cgeopoint extends AbstractActivity {
+public class cgeopoint extends AbstractActivity implements IObserver<IGeoData> {
private static final int MENU_DEFAULT_NAVIGATION = 2;
private static final int MENU_NAVIGATE = 0;
private static final int MENU_CACHES_AROUND = 5;
private static final int MENU_CLEAR_HISTORY = 6;
- private static class DestinationHistoryAdapter extends ArrayAdapter<cgDestination> {
+ private static class DestinationHistoryAdapter extends ArrayAdapter<Destination> {
private LayoutInflater inflater = null;
public DestinationHistoryAdapter(Context context,
- List<cgDestination> objects) {
+ List<Destination> objects) {
super(context, 0, objects);
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
- cgDestination loc = getItem(position);
+ Destination loc = getItem(position);
View v = convertView;
@@ -70,7 +71,7 @@ public class cgeopoint extends AbstractActivity {
longitude.setText(lonString);
latitude.setText(latString);
- date.setText(cgBase.formatShortDateTime(getContext(), loc.getDate()));
+ date.setText(Formatter.formatShortDateTime(getContext(), loc.getDate()));
return v;
}
@@ -84,12 +85,10 @@ public class cgeopoint extends AbstractActivity {
}
}
- private cgGeo geo = null;
- private UpdateLocationCallback geoUpdate = new update();
private Button latButton = null;
private Button lonButton = null;
private boolean changed = false;
- private List<cgDestination> historyOfSearchedLocations;
+ private List<Destination> historyOfSearchedLocations;
private DestinationHistoryAdapter destionationHistoryAdapter;
private ListView historyListView;
private TextView historyFooter;
@@ -137,8 +136,8 @@ public class cgeopoint extends AbstractActivity {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
final Object selection = arg0.getItemAtPosition(arg2);
- if (selection instanceof cgDestination) {
- navigateTo(((cgDestination) selection).getCoords());
+ if (selection instanceof Destination) {
+ navigateTo(((Destination) selection).getCoords());
}
}
});
@@ -146,7 +145,7 @@ public class cgeopoint extends AbstractActivity {
historyListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
+ ContextMenuInfo menuInfo) {
menu.add(Menu.NONE, CONTEXT_MENU_NAVIGATE, Menu.NONE, res.getString(R.string.cache_menu_navigate));
menu.add(Menu.NONE, CONTEXT_MENU_EDIT_WAYPOINT, Menu.NONE, R.string.waypoint_edit);
menu.add(Menu.NONE, CONTEXT_MENU_DELETE_WAYPOINT, Menu.NONE, R.string.waypoint_delete);
@@ -163,21 +162,21 @@ public class cgeopoint extends AbstractActivity {
switch (item.getItemId()) {
case CONTEXT_MENU_NAVIGATE:
contextMenuItemPosition = position;
- if (destination instanceof cgDestination) {
- NavigationAppFactory.showNavigationMenu(geo, this, null, null, ((cgDestination) destination).getCoords());
+ if (destination instanceof Destination) {
+ NavigationAppFactory.showNavigationMenu(app.currentGeo(), this, null, null, ((Destination) destination).getCoords());
return true;
}
break;
case CONTEXT_MENU_DELETE_WAYPOINT:
- if (destination instanceof cgDestination) {
- removeFromHistory((cgDestination) destination);
+ if (destination instanceof Destination) {
+ removeFromHistory((Destination) destination);
}
return true;
case CONTEXT_MENU_EDIT_WAYPOINT:
- if (destination instanceof cgDestination) {
- final Geopoint gp = ((cgDestination) destination).getCoords();
+ if (destination instanceof Destination) {
+ final Geopoint gp = ((Destination) destination).getCoords();
latButton.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE));
lonButton.setText(gp.format(GeopointFormatter.Format.LON_DECMINUTE));
}
@@ -205,7 +204,7 @@ public class cgeopoint extends AbstractActivity {
return destionationHistoryAdapter;
}
- private List<cgDestination> getHistoryOfSearchedLocations() {
+ private List<Destination> getHistoryOfSearchedLocations() {
if (historyOfSearchedLocations == null) {
// Load from database
historyOfSearchedLocations = app.getHistoryOfSearchedLocations();
@@ -224,42 +223,27 @@ public class cgeopoint extends AbstractActivity {
@Override
public void onResume() {
super.onResume();
-
+ app.addGeoObserver(this);
init();
}
@Override
public void onDestroy() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onDestroy();
}
@Override
public void onStop() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onStop();
}
@Override
public void onPause() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
+ app.deleteGeoObserver(this);
super.onPause();
}
private void init() {
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
-
latButton = (Button) findViewById(R.id.buttonLatitude);
lonButton = (Button) findViewById(R.id.buttonLongitude);
@@ -305,7 +289,7 @@ public class cgeopoint extends AbstractActivity {
if (latButton.getText().length() > 0 && lonButton.getText().length() > 0) {
gp = new Geopoint(latButton.getText().toString() + " " + lonButton.getText().toString());
}
- cgeocoords coordsDialog = new cgeocoords(cgeopoint.this, null, gp, geo);
+ cgeocoords coordsDialog = new cgeocoords(cgeopoint.this, null, gp, app.currentGeo());
coordsDialog.setCancelable(true);
coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() {
@Override
@@ -382,8 +366,7 @@ public class cgeopoint extends AbstractActivity {
final Geopoint coords = getDestination();
- if (coords != null)
- {
+ if (coords != null) {
addToHistory(coords);
}
@@ -401,7 +384,7 @@ public class cgeopoint extends AbstractActivity {
return true;
case MENU_NAVIGATE:
- NavigationAppFactory.showNavigationMenu(geo, this, null, null, coords);
+ NavigationAppFactory.showNavigationMenu(app.currentGeo(), this, null, null, coords);
return true;
default:
return false;
@@ -410,12 +393,9 @@ public class cgeopoint extends AbstractActivity {
private void addToHistory(final Geopoint coords) {
// Add locations to history
- cgDestination loc = new cgDestination();
- loc.setCoords(coords);
+ final Destination loc = new Destination(coords);
- if (!getHistoryOfSearchedLocations().contains(loc))
- {
- loc.setDate(System.currentTimeMillis());
+ if (!getHistoryOfSearchedLocations().contains(loc)) {
getHistoryOfSearchedLocations().add(0, loc);
// Save location
@@ -426,7 +406,7 @@ public class cgeopoint extends AbstractActivity {
}
}
- private void removeFromHistory(cgDestination destination) {
+ private void removeFromHistory(Destination destination) {
if (getHistoryOfSearchedLocations().contains(destination)) {
getHistoryOfSearchedLocations().remove(destination);
@@ -472,7 +452,7 @@ public class cgeopoint extends AbstractActivity {
return;
}
- NavigationAppFactory.startDefaultNavigationApplication(geo, this, null, null, geopoint);
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), this, null, null, geopoint);
}
private void cachesAround() {
@@ -483,46 +463,40 @@ public class cgeopoint extends AbstractActivity {
return;
}
- cgeocaches.startActivityCoordinates(this, coords.getLatitude(), coords.getLongitude());
+ cgeocaches.startActivityCoordinates(this, coords);
finish();
}
- private class update implements UpdateLocationCallback {
-
- @Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
- }
-
- try {
- latButton.setHint(geo.coordsNow.format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
- lonButton.setHint(geo.coordsNow.format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
- } catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
- }
+ @Override
+ public void update(final IGeoData geo) {
+ try {
+ latButton.setHint(geo.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
+ lonButton.setHint(geo.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
+ } catch (final Exception e) {
+ Log.w("Failed to update location.");
}
}
private class currentListener implements View.OnClickListener {
public void onClick(View arg0) {
- if (geo == null || geo.coordsNow == null) {
+ final Geopoint coords = app.currentGeo().getCoords();
+ if (coords == null) {
showToast(res.getString(R.string.err_point_unknown_position));
return;
}
- latButton.setText(geo.coordsNow.format(GeopointFormatter.Format.LAT_DECMINUTE));
- lonButton.setText(geo.coordsNow.format(GeopointFormatter.Format.LON_DECMINUTE));
+ latButton.setText(coords.format(GeopointFormatter.Format.LAT_DECMINUTE));
+ lonButton.setText(coords.format(GeopointFormatter.Format.LON_DECMINUTE));
changed = false;
}
}
private Geopoint getDestination() {
- Geopoint result = null;
- Geopoint coords = null;
+ Geopoint result;
+ Geopoint coords;
String bearingText = ((EditText) findViewById(R.id.bearing)).getText().toString();
// combine distance from EditText and distanceUnit saved from Spinner
@@ -538,23 +512,23 @@ public class cgeopoint extends AbstractActivity {
if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) {
try {
- coords = GeopointParser.parse(latText, lonText);
- } catch (GeopointParser.ParseException e) {
+ coords = new Geopoint(latText, lonText);
+ } catch (Geopoint.ParseException e) {
showToast(res.getString(e.resource));
return null;
}
} else {
- if (geo == null || geo.coordsNow == null) {
+ if (app.currentGeo().getCoords() == null) {
showToast(res.getString(R.string.err_point_curr_position_unavailable));
return null;
}
- coords = geo.coordsNow;
+ coords = app.currentGeo().getCoords();
}
if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) {
// bearing & distance
- double bearing = 0;
+ double bearing;
try {
bearing = Double.parseDouble(bearingText);
} catch (NumberFormatException e) {
diff --git a/main/src/cgeo/geocaching/cgeopopup.java b/main/src/cgeo/geocaching/cgeopopup.java
index afc7df6..dc98928 100644
--- a/main/src/cgeo/geocaching/cgeopopup.java
+++ b/main/src/cgeo/geocaching/cgeopopup.java
@@ -11,20 +11,23 @@ import cgeo.geocaching.gcvote.GCVote;
import cgeo.geocaching.gcvote.GCVoteRating;
import cgeo.geocaching.geopoint.HumanDistance;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import android.app.ProgressDialog;
+import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
@@ -42,8 +45,7 @@ public class cgeopopup extends AbstractActivity {
private LayoutInflater inflater = null;
private String geocode = null;
private cgCache cache = null;
- private cgGeo geo = null;
- private UpdateLocationCallback geoUpdate = new update();
+ private GeoObserver geoUpdate = new UpdateLocation();
private ProgressDialog storeDialog = null;
private ProgressDialog dropDialog = null;
private TextView cacheDistance = null;
@@ -74,7 +76,7 @@ public class cgeopopup extends AbstractActivity {
} catch (Exception e) {
showToast(res.getString(R.string.err_store));
- Log.e(Settings.tag, "cgeopopup.storeCacheHandler: " + e.toString());
+ Log.e("cgeopopup.storeCacheHandler: " + e.toString());
}
if (storeDialog != null) {
@@ -97,7 +99,7 @@ public class cgeopopup extends AbstractActivity {
} catch (Exception e) {
showToast(res.getString(R.string.err_drop));
- Log.e(Settings.tag, "cgeopopup.dropCacheHandler: " + e.toString());
+ Log.e("cgeopopup.dropCacheHandler: " + e.toString());
}
if (dropDialog != null) {
@@ -145,6 +147,19 @@ public class cgeopopup extends AbstractActivity {
}
@Override
+ public boolean onTouchEvent(final MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ final Rect r = new Rect(0, 0, 0, 0);
+ getWindow().getDecorView().getHitRect(r);
+ if (!r.contains((int) event.getX(), (int) event.getY())) {
+ finish();
+ return true;
+ }
+ }
+ return super.onTouchEvent(event);
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 2, 0, NavigationAppFactory.getDefaultNavigationApplication(this).getName()).setIcon(android.R.drawable.ic_menu_compass); // default navigation tool
menu.add(0, 3, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_mapmode);
@@ -182,34 +197,31 @@ public class cgeopopup extends AbstractActivity {
public boolean onOptionsItemSelected(MenuItem item) {
final int menuItem = item.getItemId();
- if (menuItem == 2) {
- navigateTo();
- return true;
- } else if (menuItem == 3) {
- NavigationAppFactory.showNavigationMenu(geo, this, cache, null, null);
- return true;
- } else if (menuItem == 5) {
- cachesAround();
- return true;
- } else if (menuItem == MENU_LOG_VISIT) {
- cache.logVisit(this);
- finish();
- return true;
- } else if (menuItem == 7) {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.getGeocode())));
- return true;
+ switch (menuItem) {
+ case 2:
+ navigateTo();
+ break;
+ case 3:
+ NavigationAppFactory.showNavigationMenu(app.currentGeo(), this, cache, null, null);
+ break;
+ case 5:
+ cachesAround();
+ break;
+ case MENU_LOG_VISIT:
+ cache.logVisit(this);
+ finish();
+ break;
+ case 7:
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.getGeocode())));
+ break;
+ default:
+ cache.logOffline(this, LogType.getById(menuItem - MENU_LOG_VISIT_OFFLINE));
}
- int logType = menuItem - MENU_LOG_VISIT_OFFLINE;
- cache.logOffline(this, LogType.getById(logType));
return true;
}
private void init() {
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
-
app.setAction(geocode);
cache = app.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
@@ -278,7 +290,7 @@ public class cgeopopup extends AbstractActivity {
itemName.setText(res.getString(R.string.cache_status));
- StringBuilder state = new StringBuilder();
+ final StringBuilder state = new StringBuilder();
if (cache.isFound()) {
if (state.length() > 0) {
state.append(", ");
@@ -306,8 +318,6 @@ public class cgeopopup extends AbstractActivity {
itemValue.setText(state.toString());
detailsList.addView(itemLayout);
-
- state = null;
}
// distance
@@ -403,7 +413,6 @@ public class cgeopopup extends AbstractActivity {
startActivity(cachesIntent);
finish();
- return;
}
});
@@ -417,7 +426,7 @@ public class cgeopopup extends AbstractActivity {
if (cache.getListId() > 0) {
long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.getDetailedUpdate() / (60 * 1000)); // minutes
- String ago = "";
+ String ago;
if (diff < 15) {
ago = res.getString(R.string.cache_offline_time_mins_few);
} else if (diff < 50) {
@@ -452,11 +461,7 @@ public class cgeopopup extends AbstractActivity {
offlineStore.setOnClickListener(new storeCache());
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeopopup.init: " + e.toString());
- }
-
- if (geo != null) {
- geoUpdate.updateLocation(geo);
+ Log.e("cgeopopup.init: " + e.toString());
}
}
@@ -470,52 +475,37 @@ public class cgeopopup extends AbstractActivity {
@Override
public void onResume() {
super.onResume();
-
+ app.addGeoObserver(geoUpdate);
init();
}
@Override
public void onDestroy() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onDestroy();
}
@Override
public void onStop() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onStop();
}
@Override
public void onPause() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
+ app.deleteGeoObserver(geoUpdate);
super.onPause();
}
- private class update implements UpdateLocationCallback {
+ private class UpdateLocation extends GeoObserver {
@Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
- }
-
+ protected void updateLocation(final IGeoData geo) {
try {
- if (geo.coordsNow != null && cache != null && cache.getCoords() != null) {
- cacheDistance.setText(HumanDistance.getHumanDistance(geo.coordsNow.distanceTo(cache.getCoords())));
+ if (geo.getCoords() != null && cache != null && cache.getCoords() != null) {
+ cacheDistance.setText(HumanDistance.getHumanDistance(geo.getCoords().distanceTo(cache.getCoords())));
cacheDistance.bringToFront();
}
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
+ Log.w("Failed to UpdateLocation location.");
}
}
}
@@ -526,7 +516,7 @@ public class cgeopopup extends AbstractActivity {
return;
}
- NavigationAppFactory.startDefaultNavigationApplication(geo, this, cache, null, null);
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), this, cache, null, null);
}
private void cachesAround() {
@@ -595,7 +585,7 @@ public class cgeopopup extends AbstractActivity {
@Override
public void run() {
- cgBase.dropCache(cache, handler);
+ cache.drop(handler);
}
}
@@ -636,7 +626,7 @@ public class cgeopopup extends AbstractActivity {
showToast(res.getString(R.string.cache_coordinates_no));
return;
}
- NavigationAppFactory.startDefaultNavigationApplication(geo, this, cache, null, null);
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), this, cache, null, null);
finish();
}
@@ -648,7 +638,7 @@ public class cgeopopup extends AbstractActivity {
showToast(res.getString(R.string.cache_coordinates_no));
return;
}
- NavigationAppFactory.startDefaultNavigationApplication2(geo, this, cache, null, null);
+ NavigationAppFactory.startDefaultNavigationApplication2(app.currentGeo(), this, cache, null, null);
finish();
}
@@ -657,4 +647,10 @@ public class cgeopopup extends AbstractActivity {
super.goManual(view);
finish();
}
+
+ public static void startActivity(final Context context, final String geocode) {
+ final Intent popupIntent = new Intent(context, cgeopopup.class);
+ popupIntent.putExtra("geocode", geocode);
+ context.startActivity(popupIntent);
+ }
}
diff --git a/main/src/cgeo/geocaching/cgeotouch.java b/main/src/cgeo/geocaching/cgeotouch.java
index e5af4d3..5a3ed7b 100644
--- a/main/src/cgeo/geocaching/cgeotouch.java
+++ b/main/src/cgeo/geocaching/cgeotouch.java
@@ -1,13 +1,16 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.StatusCode;
-import cgeo.geocaching.network.Login;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.twitter.Twitter;
import cgeo.geocaching.ui.DateDialog;
+import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
@@ -17,7 +20,6 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
@@ -34,7 +36,6 @@ import java.util.Calendar;
import java.util.List;
public class cgeotouch extends AbstractActivity implements DateDialog.DateDialogParent {
- private cgTrackable trackable = null;
private List<LogType> logTypes = new ArrayList<LogType>();
private ProgressDialog waitDialog = null;
private String guid = null;
@@ -58,33 +59,28 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
private Handler loadDataHandler = new Handler() {
@Override
- public void handleMessage(Message msg) {
- if (MSG_UPDATE_TYPE == msg.what) {
+ public void handleMessage(final Message msg) {
+ if (msg.what == MSG_UPDATE_TYPE) {
setType((LogType) msg.obj);
showToast(res.getString(R.string.info_log_type_changed));
} else {
- if (cgBase.isEmpty(viewstates) && attempts < 2) {
- showToast(res.getString(R.string.err_log_load_data_again));
+ if (Login.isEmpty(viewstates)) {
+ if (attempts < 2) {
+ showToast(res.getString(R.string.err_log_load_data_again));
+ new loadData(guid).start();
+ } else {
+ showToast(res.getString(R.string.err_log_load_data));
+ showProgress(false);
+ }
+ } else {
+ gettingViewstate = false; // we're done, user can post log
- loadData thread;
- thread = new loadData(guid);
- thread.start();
+ final Button buttonPost = (Button) findViewById(R.id.post);
+ buttonPost.setEnabled(true);
+ buttonPost.setOnClickListener(new postListener());
- return;
- } else if (cgBase.isEmpty(viewstates) && attempts >= 2) {
- showToast(res.getString(R.string.err_log_load_data));
showProgress(false);
-
- return;
}
-
- gettingViewstate = false; // we're done, user can post log
-
- Button buttonPost = (Button) findViewById(R.id.post);
- buttonPost.setEnabled(true);
- buttonPost.setOnClickListener(new postListener());
-
- showProgress(false);
}
}
};
@@ -129,7 +125,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
}
}
- trackable = app.getTrackableByGeocode("logging trackable");
+ final cgTrackable trackable = app.getTrackableByGeocode("logging trackable");
if (StringUtils.isNotBlank(trackable.getName())) {
setTitle(res.getString(R.string.trackable_touch) + trackable.getName());
@@ -139,7 +135,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
app.setAction("logging trackable");
- if (trackable == null || guid == null) {
+ if (guid == null) {
showToast(res.getString(R.string.err_tb_forgot_saw));
finish();
@@ -192,10 +188,10 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
- EditText text = null;
- String textContent = null;
- String dateString = null;
- String timeString = null;
+ EditText text;
+ String textContent;
+ String dateString;
+ String timeString;
String addText = "";
if ((id >= 0x1 && id <= 0x7)) {
@@ -203,8 +199,8 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
textContent = text.getText().toString();
final long now = System.currentTimeMillis();
- dateString = cgBase.formatDate(now);
- timeString = cgBase.formatTime(now);
+ dateString = Formatter.formatDate(now);
+ timeString = Formatter.formatTime(now);
if ((id & 0x4) == 0x4) {
addText += dateString;
@@ -287,7 +283,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
});
Button dateButton = (Button) findViewById(R.id.date);
- dateButton.setText(cgBase.formatShortDate(date.getTime().getTime()));
+ dateButton.setText(Formatter.formatShortDate(date.getTime().getTime()));
dateButton.setOnClickListener(new cgeotouchDateListener());
if (tweetBox == null) {
@@ -299,7 +295,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
tweetCheck.setChecked(true);
Button buttonPost = (Button) findViewById(R.id.post);
- if (cgBase.isEmpty(viewstates)) {
+ if (Login.isEmpty(viewstates)) {
buttonPost.setEnabled(false);
buttonPost.setOnTouchListener(null);
buttonPost.setOnClickListener(null);
@@ -319,7 +315,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
date = dateIn;
final Button dateButton = (Button) findViewById(R.id.date);
- dateButton.setText(cgBase.formatShortDate(date.getTime().getTime()));
+ dateButton.setText(Formatter.formatShortDate(date.getTime().getTime()));
}
public void setType(LogType type) {
@@ -372,7 +368,6 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
showToast(res.getString(R.string.err_tb_forgot_saw));
finish();
- return;
}
}
@@ -392,11 +387,11 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
return;
}
- final String page = Network.getResponseData(Network.request("http://www.geocaching.com/track/log.aspx", params, false, false, false));
+ final String page = Network.getResponseData(Network.getRequest("http://www.geocaching.com/track/log.aspx", params));
viewstates = Login.getViewstates(page);
- final List<LogType> typesPre = cgBase.parseTypes(page);
+ final List<LogType> typesPre = GCParser.parseTypes(page);
if (typesPre.size() > 0) {
logTypes.clear();
logTypes.addAll(typesPre);
@@ -408,7 +403,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
loadDataHandler.obtainMessage(MSG_UPDATE_TYPE, typeSelected).sendToTarget();
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeotouch.loadData.run: " + e.toString());
+ Log.e("cgeotouch.loadData.run: " + e.toString());
}
loadDataHandler.sendEmptyMessage(0);
@@ -442,7 +437,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
tweetCheck = (CheckBox) findViewById(R.id.tweet);
}
- final StatusCode status = cgBase.postLogTrackable(guid, tracking, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log);
+ final StatusCode status = GCParser.postLogTrackable(guid, tracking, viewstates, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log);
if (status == StatusCode.NO_ERROR && Settings.isUseTwitter() &&
Settings.isTwitterLoginValid() &&
@@ -452,7 +447,7 @@ public class cgeotouch extends AbstractActivity implements DateDialog.DateDialog
return status;
} catch (Exception e) {
- Log.e(Settings.tag, "cgeotouch.postLogFn: " + e.toString());
+ Log.e("cgeotouch.postLogFn: " + e.toString());
}
return StatusCode.LOG_POST_ERROR;
diff --git a/main/src/cgeo/geocaching/cgeotrackable.java b/main/src/cgeo/geocaching/cgeotrackable.java
index 1d5b5db..2a0a017 100644
--- a/main/src/cgeo/geocaching/cgeotrackable.java
+++ b/main/src/cgeo/geocaching/cgeotrackable.java
@@ -1,10 +1,12 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.connector.gc.GCParser;
import cgeo.geocaching.geopoint.HumanDistance;
import cgeo.geocaching.network.HtmlImage;
+import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.utils.Log;
-import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import android.app.ProgressDialog;
@@ -16,7 +18,6 @@ import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.text.method.LinkMovementMethod;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -48,13 +49,6 @@ public class cgeotrackable extends AbstractActivity {
@Override
public void handleMessage(Message msg) {
- if (trackable != null && StringUtils.isNotBlank(trackable.getError())) {
- showToast(res.getString(R.string.err_tb_details_download) + " " + trackable.getError() + ".");
-
- finish();
- return;
- }
-
if (trackable == null) {
if (waitDialog != null) {
waitDialog.dismiss();
@@ -94,7 +88,7 @@ public class cgeotrackable extends AbstractActivity {
addDetail(R.string.trackable_name, StringUtils.isNotBlank(trackable.getName()) ? Html.fromHtml(trackable.getName()).toString() : res.getString(R.string.trackable_unknown));
// trackable type
- String tbType = null;
+ String tbType;
if (StringUtils.isNotBlank(trackable.getType())) {
tbType = Html.fromHtml(trackable.getType()).toString();
} else {
@@ -117,7 +111,7 @@ public class cgeotrackable extends AbstractActivity {
trackable.getSpottedType() == cgTrackable.SPOTTED_UNKNOWN ||
trackable.getSpottedType() == cgTrackable.SPOTTED_OWNER
) {
- String text = null;
+ String text;
if (trackable.getSpottedType() == cgTrackable.SPOTTED_CACHE) {
text = res.getString(R.string.trackable_spotted_in_cache) + " " + Html.fromHtml(trackable.getSpottedName()).toString();
@@ -155,7 +149,7 @@ public class cgeotrackable extends AbstractActivity {
// trackable released
if (trackable.getReleased() != null) {
- addDetail(R.string.trackable_released, cgBase.formatDate(trackable.getReleased().getTime()));
+ addDetail(R.string.trackable_released, Formatter.formatDate(trackable.getReleased().getTime()));
}
// trackable distance
@@ -213,7 +207,7 @@ public class cgeotrackable extends AbstractActivity {
@Override
public void run() {
- BitmapDrawable image = null;
+ BitmapDrawable image;
try {
HtmlImage imgGetter = new HtmlImage(cgeotrackable.this, geocode, true, 0, false);
@@ -221,7 +215,7 @@ public class cgeotrackable extends AbstractActivity {
Message message = handler.obtainMessage(0, image);
handler.sendMessage(message);
} catch (Exception e) {
- Log.e(Settings.tag, "cgeospoilers.onCreate.onClick.run: " + e.toString());
+ Log.e("cgeospoilers.onCreate.onClick.run: " + e.toString());
}
}
}.start();
@@ -229,7 +223,7 @@ public class cgeotrackable extends AbstractActivity {
imgView.addView(trackableImage);
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeotrackable.loadTrackableHandler: " + e.toString() + Arrays.toString(e.getStackTrace()));
+ Log.e("cgeotrackable.loadTrackableHandler: " + e.toString() + Arrays.toString(e.getStackTrace()));
}
displayLogs();
@@ -356,21 +350,20 @@ public class cgeotrackable extends AbstractActivity {
}
@Override
- public boolean onContextItemSelected(MenuItem item) {
- final int id = item.getItemId();
-
- if (id == 1) {
- cgeocaches.startActivityOwner(this, contextMenuUser);
- return true;
- } else if (id == 2) {
- cgeocaches.startActivityUserName(this, contextMenuUser);
- return true;
- } else if (id == 3) {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(contextMenuUser))));
-
- return true;
+ public boolean onContextItemSelected(final MenuItem item) {
+ switch (item.getItemId()) {
+ case 1:
+ cgeocaches.startActivityOwner(this, contextMenuUser);
+ return true;
+ case 2:
+ cgeocaches.startActivityUserName(this, contextMenuUser);
+ return true;
+ case 3:
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(contextMenuUser))));
+ return true;
+ default:
+ return false;
}
- return false;
}
@Override
@@ -418,7 +411,6 @@ public class cgeotrackable extends AbstractActivity {
stop();
finish();
- return;
}
}
@@ -428,7 +420,7 @@ public class cgeotrackable extends AbstractActivity {
trackable = cgeoapplication.getInstance().getTrackableByGeocode(geocode);
if ((trackable == null || trackable.isLoggable()) && !StringUtils.startsWithIgnoreCase(geocode, "GK")) {
- trackable = cgBase.searchTrackable(geocode, guid, id);
+ trackable = GCParser.searchTrackable(geocode, guid, id);
}
handler.sendMessage(Message.obtain());
}
@@ -442,11 +434,11 @@ public class cgeotrackable extends AbstractActivity {
RelativeLayout rowView;
if (trackable != null && trackable.getLogs() != null) {
- for (cgLog log : trackable.getLogs()) {
+ for (LogEntry log : trackable.getLogs()) {
rowView = (RelativeLayout) inflater.inflate(R.layout.trackable_logs_item, null);
if (log.date > 0) {
- ((TextView) rowView.findViewById(R.id.added)).setText(cgBase.formatShortDate(log.date));
+ ((TextView) rowView.findViewById(R.id.added)).setText(Formatter.formatShortDate(log.date));
}
((TextView) rowView.findViewById(R.id.type)).setText(log.type.getL10n());
@@ -460,24 +452,21 @@ public class cgeotrackable extends AbstractActivity {
final String cacheName = log.cacheName;
((TextView) rowView.findViewById(R.id.location)).setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
- Intent cacheIntent = new Intent(cgeotrackable.this, CacheDetailActivity.class);
- cacheIntent.putExtra("guid", cacheGuid);
- cacheIntent.putExtra("name", Html.fromHtml(cacheName).toString());
- startActivity(cacheIntent);
+ CacheDetailActivity.startActivityGuid(cgeotrackable.this, cacheGuid, Html.fromHtml(cacheName).toString());
}
});
}
TextView logView = (TextView) rowView.findViewById(R.id.log);
logView.setMovementMethod(LinkMovementMethod.getInstance());
- logView.setText(Html.fromHtml(log.log, new HtmlImage(cgeotrackable.this, null, false, StoredList.TEMPORARY_LIST_ID, false), null), TextView.BufferType.SPANNABLE);
+ logView.setText(Html.fromHtml(log.log, new HtmlImage(this, null, false, StoredList.TEMPORARY_LIST_ID, false), null), TextView.BufferType.SPANNABLE);
// add LogImages
LinearLayout logLayout = (LinearLayout) rowView.findViewById(R.id.log_layout);
- if (CollectionUtils.isNotEmpty(log.logImages)) {
+ if (log.hasLogImages()) {
- final ArrayList<cgImage> logImages = new ArrayList<cgImage>(log.logImages);
+ final ArrayList<cgImage> logImages = new ArrayList<cgImage>(log.getLogImages());
final View.OnClickListener listener = new View.OnClickListener() {
@Override
@@ -487,8 +476,8 @@ public class cgeotrackable extends AbstractActivity {
};
ArrayList<String> titles = new ArrayList<String>();
- for (int i_img_cnt = 0; i_img_cnt < log.logImages.size(); i_img_cnt++) {
- String img_title = log.logImages.get(i_img_cnt).getTitle();
+ for (cgImage image : log.getLogImages()) {
+ String img_title = image.getTitle();
if (!StringUtils.isBlank(img_title)) {
titles.add(img_title);
}
@@ -525,7 +514,7 @@ public class cgeotrackable extends AbstractActivity {
registerForContextMenu(view);
openContextMenu(view);
} catch (Exception e) {
- Log.e(Settings.tag, "cgeotrackable.userActions.onClick ", e);
+ Log.e("cgeotrackable.userActions.onClick ", e);
}
}
}
@@ -565,7 +554,7 @@ public class cgeotrackable extends AbstractActivity {
return;
}
- BitmapDrawable image = null;
+ BitmapDrawable image;
try {
HtmlImage imgGetter = new HtmlImage(cgeotrackable.this, trackable.getGeocode(), false, 0, false);
@@ -573,7 +562,7 @@ public class cgeotrackable extends AbstractActivity {
Message message = handler.obtainMessage(0, image);
handler.sendMessage(message);
} catch (Exception e) {
- Log.e(Settings.tag, "cgeotrackable.tbIconThread.run: " + e.toString());
+ Log.e("cgeotrackable.tbIconThread.run: " + e.toString());
}
}
}
diff --git a/main/src/cgeo/geocaching/cgeowaypoint.java b/main/src/cgeo/geocaching/cgeowaypoint.java
index 453308e..e8aa770 100644
--- a/main/src/cgeo/geocaching/cgeowaypoint.java
+++ b/main/src/cgeo/geocaching/cgeowaypoint.java
@@ -4,16 +4,18 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
+import cgeo.geocaching.utils.IObserver;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import android.app.ProgressDialog;
+import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
@@ -26,7 +28,7 @@ import android.widget.TextView;
import java.util.EnumSet;
-public class cgeowaypoint extends AbstractActivity {
+public class cgeowaypoint extends AbstractActivity implements IObserver<IGeoData> {
private static final int MENU_ID_NAVIGATION = 0;
private static final int MENU_ID_CACHES_AROUND = 5;
@@ -35,83 +37,67 @@ public class cgeowaypoint extends AbstractActivity {
private cgWaypoint waypoint = null;
private int id = -1;
private ProgressDialog waitDialog = null;
- private cgGeo geo = null;
- private UpdateLocationCallback geoUpdate = new update();
private Handler loadWaypointHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- try {
- if (waypoint == null) {
- if (waitDialog != null) {
- waitDialog.dismiss();
- waitDialog = null;
- }
+ if (waitDialog != null) {
+ waitDialog.dismiss();
+ waitDialog = null;
+ }
- showToast(res.getString(R.string.err_waypoint_load_failed));
+ if (waypoint == null) {
+ showToast(res.getString(R.string.err_waypoint_load_failed));
+ finish();
+ return;
+ }
- finish();
- return;
- } else {
- final TextView identification = (TextView) findViewById(R.id.identification);
- final TextView coords = (TextView) findViewById(R.id.coordinates);
- final ImageView defaultNavigation = (ImageView) findViewById(R.id.defaultNavigation);
- final View separator = findViewById(R.id.separator);
+ final TextView identification = (TextView) findViewById(R.id.identification);
+ final TextView coords = (TextView) findViewById(R.id.coordinates);
+ final ImageView defaultNavigation = (ImageView) findViewById(R.id.defaultNavigation);
+ final View separator = findViewById(R.id.separator);
- final View headline = findViewById(R.id.headline);
- registerNavigationMenu(headline);
+ final View headline = findViewById(R.id.headline);
+ registerNavigationMenu(headline);
- if (StringUtils.isNotBlank(waypoint.getName())) {
- setTitle(Html.fromHtml(waypoint.getName()).toString());
- } else {
- setTitle(res.getString(R.string.waypoint_title));
- }
+ if (StringUtils.isNotBlank(waypoint.getName())) {
+ setTitle(Html.fromHtml(waypoint.getName()).toString());
+ } else {
+ setTitle(res.getString(R.string.waypoint_title));
+ }
- if (!waypoint.getPrefix().equalsIgnoreCase("OWN")) {
- identification.setText(waypoint.getPrefix() + "/" + waypoint.getLookup());
- } else {
- identification.setText(res.getString(R.string.waypoint_custom));
- }
- registerNavigationMenu(identification);
- waypoint.setIcon(res, identification);
-
- if (waypoint.getCoords() != null) {
- coords.setText(Html.fromHtml(waypoint.getCoords().toString()), TextView.BufferType.SPANNABLE);
- defaultNavigation.setVisibility(View.VISIBLE);
- separator.setVisibility(View.VISIBLE);
- } else {
- coords.setText(res.getString(R.string.waypoint_unknown_coordinates));
- defaultNavigation.setVisibility(View.GONE);
- separator.setVisibility(View.GONE);
- }
- registerNavigationMenu(coords);
+ if (!waypoint.getPrefix().equalsIgnoreCase("OWN")) {
+ identification.setText(waypoint.getPrefix() + "/" + waypoint.getLookup());
+ } else {
+ identification.setText(res.getString(R.string.waypoint_custom));
+ }
+ registerNavigationMenu(identification);
+ waypoint.setIcon(res, identification);
- if (StringUtils.isNotBlank(waypoint.getNote())) {
- final TextView note = (TextView) findViewById(R.id.note);
- note.setText(Html.fromHtml(waypoint.getNote()), TextView.BufferType.SPANNABLE);
- registerNavigationMenu(note);
- }
+ if (waypoint.getCoords() != null) {
+ coords.setText(Html.fromHtml(waypoint.getCoords().toString()), TextView.BufferType.SPANNABLE);
+ defaultNavigation.setVisibility(View.VISIBLE);
+ separator.setVisibility(View.VISIBLE);
+ } else {
+ coords.setText(res.getString(R.string.waypoint_unknown_coordinates));
+ defaultNavigation.setVisibility(View.GONE);
+ separator.setVisibility(View.GONE);
+ }
+ registerNavigationMenu(coords);
- Button buttonEdit = (Button) findViewById(R.id.edit);
- buttonEdit.setOnClickListener(new editWaypointListener());
+ if (StringUtils.isNotBlank(waypoint.getNote())) {
+ final TextView note = (TextView) findViewById(R.id.note);
+ note.setText(Html.fromHtml(waypoint.getNote()), TextView.BufferType.SPANNABLE);
+ registerNavigationMenu(note);
+ }
- Button buttonDelete = (Button) findViewById(R.id.delete);
- if (waypoint.isUserDefined()) {
- buttonDelete.setOnClickListener(new deleteWaypointListener());
- buttonDelete.setVisibility(View.VISIBLE);
- }
+ final Button buttonEdit = (Button) findViewById(R.id.edit);
+ buttonEdit.setOnClickListener(new editWaypointListener());
- if (waitDialog != null) {
- waitDialog.dismiss();
- waitDialog = null;
- }
- }
- } catch (Exception e) {
- if (waitDialog != null) {
- waitDialog.dismiss();
- waitDialog = null;
- }
- Log.e(Settings.tag, "cgeowaypoint.loadWaypointHandler: " + e.toString());
+ if (waypoint.isUserDefined()) {
+ final Button buttonDelete = (Button) findViewById(R.id.delete);
+ buttonDelete.setOnClickListener(new deleteWaypointListener());
+ buttonDelete.setVisibility(View.VISIBLE);
}
}
@@ -155,10 +141,6 @@ public class cgeowaypoint extends AbstractActivity {
return;
}
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
-
waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true);
waitDialog.setCancelable(true);
@@ -178,10 +160,7 @@ public class cgeowaypoint extends AbstractActivity {
public void onResume() {
super.onResume();
-
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
+ app.addGeoObserver(this);
if (waitDialog == null) {
waitDialog = ProgressDialog.show(this, null, res.getString(R.string.waypoint_loading), true);
@@ -193,28 +172,17 @@ public class cgeowaypoint extends AbstractActivity {
@Override
public void onDestroy() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onDestroy();
}
@Override
public void onStop() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onStop();
}
@Override
public void onPause() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
+ app.deleteGeoObserver(this);
super.onPause();
}
@@ -249,21 +217,22 @@ public class cgeowaypoint extends AbstractActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- final int menuItem = item.getItemId();
- if (menuItem == MENU_ID_DEFAULT_NAVIGATION) {
- goDefaultNavigation(null);
- return true;
- } else if (menuItem == MENU_ID_CACHES_AROUND) {
- cachesAround();
- return true;
- } else if (menuItem == MENU_ID_OPEN_GEOCACHE) {
- goToGeocache();
- return true;
- } else if (menuItem == MENU_ID_NAVIGATION) {
- NavigationAppFactory.showNavigationMenu(geo, this, null, waypoint, null);
- return true;
+ switch (item.getItemId()) {
+ case MENU_ID_DEFAULT_NAVIGATION:
+ goDefaultNavigation(null);
+ return true;
+ case MENU_ID_CACHES_AROUND:
+ cachesAround();
+ return true;
+ case MENU_ID_OPEN_GEOCACHE:
+ goToGeocache();
+ return true;
+ case MENU_ID_NAVIGATION:
+ NavigationAppFactory.showNavigationMenu(app.currentGeo(), this, null, waypoint, null);
+ return true;
+ default:
+ return false;
}
- return false;
}
private void cachesAround() {
@@ -295,17 +264,14 @@ public class cgeowaypoint extends AbstractActivity {
loadWaypointHandler.sendMessage(Message.obtain());
} catch (Exception e) {
- Log.e(Settings.tag, "cgeowaypoint.loadWaypoint.run: " + e.toString());
+ Log.e("cgeowaypoint.loadWaypoint.run: " + e.toString());
}
}
}
- private static class update implements UpdateLocationCallback {
-
- @Override
- public void updateLocation(cgGeo geo) {
- // nothing
- }
+ @Override
+ public void update(final IGeoData geo) {
+ // nothing
}
private class editWaypointListener implements View.OnClickListener {
@@ -328,7 +294,6 @@ public class cgeowaypoint extends AbstractActivity {
StaticMapsProvider.removeWpStaticMaps(id, geocode);
finish();
- return;
} else {
showToast(res.getString(R.string.err_waypoint_delete_failed));
}
@@ -344,7 +309,7 @@ public class cgeowaypoint extends AbstractActivity {
return;
}
- NavigationAppFactory.startDefaultNavigationApplication(geo, this, null, waypoint, null);
+ NavigationAppFactory.startDefaultNavigationApplication(app.currentGeo(), this, null, waypoint, null);
}
/**
@@ -355,7 +320,7 @@ public class cgeowaypoint extends AbstractActivity {
return;
}
- NavigationAppFactory.startDefaultNavigationApplication2(geo, this, null, waypoint, null);
+ NavigationAppFactory.startDefaultNavigationApplication2(app.currentGeo(), this, null, waypoint, null);
}
private boolean navigationPossible() {
@@ -381,6 +346,12 @@ public class cgeowaypoint extends AbstractActivity {
if (handled) {
return true;
}
- return NavigationAppFactory.onMenuItemSelected(item, geo, this, null, waypoint, null);
+ return NavigationAppFactory.onMenuItemSelected(item, app.currentGeo(), this, null, waypoint, null);
+ }
+
+ public static void startActivity(final Context context, final int waypointId) {
+ Intent popupIntent = new Intent(context, cgeowaypoint.class);
+ popupIntent.putExtra("waypoint", waypointId);
+ context.startActivity(popupIntent);
}
}
diff --git a/main/src/cgeo/geocaching/cgeowaypointadd.java b/main/src/cgeo/geocaching/cgeowaypointadd.java
index 9c00241..9c02eef 100644
--- a/main/src/cgeo/geocaching/cgeowaypointadd.java
+++ b/main/src/cgeo/geocaching/cgeowaypointadd.java
@@ -8,7 +8,9 @@ import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.geopoint.DistanceParser;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.geopoint.GeopointParser;
+import cgeo.geocaching.utils.BaseUtils;
+import cgeo.geocaching.utils.IObserver;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
@@ -17,7 +19,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
-import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
@@ -31,12 +32,10 @@ import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
-public class cgeowaypointadd extends AbstractActivity {
+public class cgeowaypointadd extends AbstractActivity implements IObserver<IGeoData> {
private String geocode = null;
private int id = -1;
- private cgGeo geo = null;
- private UpdateLocationCallback geoUpdate = new update();
private ProgressDialog waitDialog = null;
private cgWaypoint waypoint = null;
private Geopoint gpTemp = null;
@@ -72,7 +71,12 @@ public class cgeowaypointadd extends AbstractActivity {
((Button) findViewById(R.id.buttonLongitude)).setText(waypoint.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE));
}
((EditText) findViewById(R.id.name)).setText(Html.fromHtml(StringUtils.trimToEmpty(waypoint.getName())).toString());
- ((EditText) findViewById(R.id.note)).setText(Html.fromHtml(StringUtils.trimToEmpty(waypoint.getNote())).toString());
+ if (BaseUtils.containsHtml(waypoint.getNote())) {
+ ((EditText) findViewById(R.id.note)).setText(Html.fromHtml(StringUtils.trimToEmpty(waypoint.getNote())).toString());
+ }
+ else {
+ ((EditText) findViewById(R.id.note)).setText(StringUtils.trimToEmpty(waypoint.getNote()));
+ }
}
if (own) {
@@ -81,7 +85,7 @@ public class cgeowaypointadd extends AbstractActivity {
initializeDistanceUnitSelector();
} catch (Exception e) {
- Log.e(Settings.tag, "cgeowaypointadd.loadWaypointHandler: " + e.toString());
+ Log.e("cgeowaypointadd.loadWaypointHandler: " + e.toString());
} finally {
if (waitDialog != null) {
waitDialog.dismiss();
@@ -99,10 +103,6 @@ public class cgeowaypointadd extends AbstractActivity {
setContentView(R.layout.waypoint_new);
setTitle("waypoint");
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
-
// get parameters
Bundle extras = getIntent().getExtras();
if (extras != null) {
@@ -136,7 +136,10 @@ public class cgeowaypointadd extends AbstractActivity {
Button addWaypoint = (Button) findViewById(R.id.add_waypoint);
addWaypoint.setOnClickListener(new coordsListener());
- List<String> wayPointNames = new ArrayList<String>(WaypointType.ALL_TYPES_EXCEPT_OWN.values());
+ List<String> wayPointNames = new ArrayList<String>();
+ for (WaypointType wpt : WaypointType.ALL_TYPES_EXCEPT_OWN) {
+ wayPointNames.add(wpt.getL10n());
+ }
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.name);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, wayPointNames);
textView.setAdapter(adapter);
@@ -162,10 +165,7 @@ public class cgeowaypointadd extends AbstractActivity {
public void onResume() {
super.onResume();
-
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
+ app.addGeoObserver(this);
if (id > 0) {
if (waitDialog == null) {
@@ -179,28 +179,17 @@ public class cgeowaypointadd extends AbstractActivity {
@Override
public void onDestroy() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onDestroy();
}
@Override
public void onStop() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
super.onStop();
}
@Override
public void onPause() {
- if (geo != null) {
- geo = app.removeGeo();
- }
-
+ app.deleteGeoObserver(this);
super.onPause();
}
@@ -208,7 +197,7 @@ public class cgeowaypointadd extends AbstractActivity {
Spinner waypointTypeSelector = (Spinner) findViewById(R.id.type);
- wpTypes = new ArrayList<WaypointType>(WaypointType.ALL_TYPES_EXCEPT_OWN.keySet());
+ wpTypes = new ArrayList<WaypointType>(WaypointType.ALL_TYPES_EXCEPT_OWN);
ArrayAdapter<WaypointType> wpAdapter = new ArrayAdapter<WaypointType>(this, android.R.layout.simple_spinner_item, wpTypes.toArray(new WaypointType[wpTypes.size()]));
wpAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
waypointTypeSelector.setAdapter(wpAdapter);
@@ -241,23 +230,20 @@ public class cgeowaypointadd extends AbstractActivity {
distanceUnitSelector.setOnItemSelectedListener(new changeDistanceUnit(this));
}
- private class update implements UpdateLocationCallback {
-
- @Override
- public void updateLocation(cgGeo geo) {
- Log.d(Settings.tag, "cgeowaypointadd.updateLocation called");
- if (geo == null || geo.coordsNow == null) {
- return;
- }
+ @Override
+ public void update(final IGeoData geo) {
+ Log.d("cgeowaypointadd.updateLocation called");
+ if (geo.getCoords() == null) {
+ return;
+ }
- try {
- Button bLat = (Button) findViewById(R.id.buttonLatitude);
- Button bLon = (Button) findViewById(R.id.buttonLongitude);
- bLat.setHint(geo.coordsNow.format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
- bLon.setHint(geo.coordsNow.format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
- } catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
- }
+ try {
+ Button bLat = (Button) findViewById(R.id.buttonLatitude);
+ Button bLon = (Button) findViewById(R.id.buttonLongitude);
+ bLat.setHint(geo.getCoords().format(GeopointFormatter.Format.LAT_DECMINUTE_RAW));
+ bLon.setHint(geo.getCoords().format(GeopointFormatter.Format.LON_DECMINUTE_RAW));
+ } catch (Exception e) {
+ Log.w("Failed to update location.");
}
}
@@ -270,7 +256,7 @@ public class cgeowaypointadd extends AbstractActivity {
loadWaypointHandler.sendMessage(Message.obtain());
} catch (Exception e) {
- Log.e(Settings.tag, "cgeowaypoint.loadWaypoint.run: " + e.toString());
+ Log.e("cgeowaypoint.loadWaypoint.run: " + e.toString());
}
}
}
@@ -285,7 +271,7 @@ public class cgeowaypointadd extends AbstractActivity {
gp = gpTemp;
}
cgCache cache = app.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS);
- cgeocoords coordsDialog = new cgeocoords(cgeowaypointadd.this, cache, gp, geo);
+ cgeocoords coordsDialog = new cgeocoords(cgeowaypointadd.this, cache, gp, app.currentGeo());
coordsDialog.setCancelable(true);
coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() {
@Override
@@ -361,31 +347,27 @@ public class cgeowaypointadd extends AbstractActivity {
return;
}
- double latitude;
- double longitude;
+ Geopoint coords;
if (StringUtils.isNotBlank(latText) && StringUtils.isNotBlank(lonText)) {
try {
- latitude = GeopointParser.parseLatitude(latText);
- longitude = GeopointParser.parseLongitude(lonText);
- } catch (GeopointParser.ParseException e) {
+ coords = new Geopoint(latText, lonText);
+ } catch (Geopoint.ParseException e) {
showToast(res.getString(e.resource));
return;
}
} else {
- if (geo == null || geo.coordsNow == null) {
+ final IGeoData geo = app.currentGeo();
+ if (geo.getCoords() == null) {
showToast(res.getString(R.string.err_point_curr_position_unavailable));
return;
}
-
- latitude = geo.coordsNow.getLatitude();
- longitude = geo.coordsNow.getLongitude();
+ coords = geo.getCoords();
}
- Geopoint coords = null;
if (StringUtils.isNotBlank(bearingText) && StringUtils.isNotBlank(distanceText)) {
// bearing & distance
- double bearing = 0;
+ double bearing;
try {
bearing = Double.parseDouble(bearingText);
} catch (NumberFormatException e) {
@@ -401,9 +383,7 @@ public class cgeowaypointadd extends AbstractActivity {
return;
}
- coords = new Geopoint(latitude, longitude).project(bearing, distance);
- } else {
- coords = new Geopoint(latitude, longitude);
+ coords = coords.project(bearing, distance);
}
String name = ((EditText) findViewById(R.id.name)).getText().toString().trim();
@@ -429,7 +409,6 @@ public class cgeowaypointadd extends AbstractActivity {
StaticMapsProvider.storeWaypointStaticMap(cache, cgeowaypointadd.this, waypoint, false);
}
finish();
- return;
} else {
showToast(res.getString(R.string.err_waypoint_add_failed));
}
diff --git a/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java b/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java
index 6d01e55..0fc9624 100644
--- a/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java
+++ b/main/src/cgeo/geocaching/compatibility/AndroidLevel8.java
@@ -1,10 +1,9 @@
package cgeo.geocaching.compatibility;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.utils.Log;
import android.app.Activity;
import android.app.backup.BackupManager;
-import android.util.Log;
import android.view.Display;
public class AndroidLevel8 implements AndroidLevel8Interface {
@@ -15,7 +14,7 @@ public class AndroidLevel8 implements AndroidLevel8Interface {
}
public void dataChanged(final String name) {
- Log.i(Settings.tag, "Requesting settings backup with settings manager");
+ Log.i("Requesting settings backup with settings manager");
BackupManager.dataChanged(name);
}
}
diff --git a/main/src/cgeo/geocaching/compatibility/Compatibility.java b/main/src/cgeo/geocaching/compatibility/Compatibility.java
index 344ff6a..6086604 100644
--- a/main/src/cgeo/geocaching/compatibility/Compatibility.java
+++ b/main/src/cgeo/geocaching/compatibility/Compatibility.java
@@ -1,7 +1,9 @@
package cgeo.geocaching.compatibility;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.utils.Log;
+
+import org.apache.commons.lang3.reflect.MethodUtils;
import android.app.Activity;
import android.content.Intent;
@@ -9,13 +11,10 @@ import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.text.InputType;
-import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.widget.EditText;
-import java.lang.reflect.Method;
-
public final class Compatibility {
private final static int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
@@ -25,16 +24,7 @@ public final class Compatibility {
private final static AndroidLevel8Interface level8;
private final static AndroidLevel11Interface level11;
- private static Method overridePendingTransitionMethod = null;
-
static {
- if (isLevel5) {
- try {
- overridePendingTransitionMethod = Activity.class.getMethod("overridePendingTransition", Integer.TYPE, Integer.TYPE);
- } catch (Exception e) {
- Log.e(Settings.tag, "cannot get overridePendingTransition", e);
- }
- }
if (isLevel8) {
level8 = new AndroidLevel8();
}
@@ -63,7 +53,7 @@ public final class Compatibility {
}
} catch (final Exception e) {
// This should never happen: IllegalArgumentException, IllegalAccessException or InvocationTargetException
- Log.e(Settings.tag, "Cannot call getRotation()", e);
+ Log.e("Cannot call getRotation()", e);
}
} else {
final Display display = activity.getWindowManager()
@@ -102,9 +92,9 @@ public final class Compatibility {
private static void overridePendingTransition(final Activity activity, int enterAnim, int exitAnim) {
try {
- overridePendingTransitionMethod.invoke(activity, enterAnim, exitAnim);
+ MethodUtils.invokeMethod(activity, "overridePendingTransition", enterAnim, exitAnim);
} catch (Exception e) {
- Log.e(Settings.tag, "cannot call overridePendingTransition", e);
+ Log.e("cannot call overridePendingTransition", e);
}
}
diff --git a/main/src/cgeo/geocaching/concurrent/Task.java b/main/src/cgeo/geocaching/concurrent/Task.java
deleted file mode 100644
index 2472538..0000000
--- a/main/src/cgeo/geocaching/concurrent/Task.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package cgeo.geocaching.concurrent;
-
-/**
- * Basic class for Runnables added to ThreadPool.
- */
-public abstract class Task implements Runnable {
- private String name = null;
-
- public Task(String name) {
- this.name = name;
- }
-
- public String getName() {
- return this.name;
- }
-}
diff --git a/main/src/cgeo/geocaching/connector/OXConnector.java b/main/src/cgeo/geocaching/connector/OXConnector.java
index 755dbaa..cfde92f 100644
--- a/main/src/cgeo/geocaching/connector/OXConnector.java
+++ b/main/src/cgeo/geocaching/connector/OXConnector.java
@@ -32,4 +32,10 @@ public class OXConnector extends AbstractConnector {
return "www.opencaching.com";
}
+ @Override
+ public String getLicenseText(cgCache cache) {
+ // NOT TO BE TRANSLATED
+ return "<a href=\"" + getCacheUrl(cache) + "\">" + getName() + "</a> data licensed under the Creative Commons BY-SA 3.0 License";
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCBase.java b/main/src/cgeo/geocaching/connector/gc/GCBase.java
index 7c56583..d7f6241 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCBase.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCBase.java
@@ -1,8 +1,8 @@
package cgeo.geocaching.connector.gc;
+import cgeo.geocaching.ICoordinates;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheSize;
@@ -13,11 +13,12 @@ import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.IConversion;
import cgeo.geocaching.geopoint.Viewport;
-import cgeo.geocaching.network.Login;
import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.utils.BaseUtils;
-import cgeo.geocaching.utils.LeastRecentlyUsedCache;
+import cgeo.geocaching.utils.LeastRecentlyUsedMap;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -27,10 +28,10 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.graphics.Bitmap;
-import android.util.Log;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -52,6 +53,9 @@ public class GCBase {
protected final static long GC_BASE31 = 31;
protected final static long GC_BASE16 = 16;
+ private final static LeastRecentlyUsedMap<Integer, Tile> tileCache = new LeastRecentlyUsedMap.LruCache<Integer, Tile>(64);
+ private static Viewport lastSearchViewport = null;
+
/**
* Searches the view port on the live map with Strategy.AUTO
*
@@ -64,7 +68,7 @@ public class GCBase {
public static SearchResult searchByViewport(final Viewport viewport, final String[] tokens) {
Strategy strategy = Settings.getLiveMapStrategy();
if (strategy == Strategy.AUTO) {
- float speedNow = cgeoapplication.getInstance().getSpeedFromGeo();
+ float speedNow = cgeoapplication.getInstance().currentGeo().getSpeed();
strategy = speedNow >= 8 ? Strategy.FAST : Strategy.DETAILED; // 8 m/s = 30 km/h
}
// return searchByViewport(viewport, tokens, strategy);
@@ -73,7 +77,7 @@ public class GCBase {
{
SearchResult result = searchByViewport(viewport, tokens, strategy);
String text = Formatter.SEPARATOR + strategy.getL10n() + Formatter.SEPARATOR;
- int speed = (int) cgeoapplication.getInstance().getSpeedFromGeo();
+ int speed = (int) cgeoapplication.getInstance().currentGeo().getSpeed();
if (Settings.isUseMetricUnits()) {
text += speed + " km/h";
} else {
@@ -84,6 +88,17 @@ public class GCBase {
}
}
+ public static void removeFromTileCache(final ICoordinates point) {
+ if (point != null) {
+ Collection<Tile> tiles = new ArrayList<Tile>(tileCache.values());
+ for (Tile tile : tiles) {
+ if (tile.containsPoint(point)) {
+ tileCache.remove(tile.hashCode());
+ }
+ }
+ }
+ }
+
/**
* Searches the view port on the live map for caches.
* The strategy dictates if only live map information is used or if an additional
@@ -98,7 +113,7 @@ public class GCBase {
* @return
*/
private static SearchResult searchByViewport(final Viewport viewport, final String[] tokens, Strategy strategy) {
- Log.d(Settings.tag, "GCBase.searchByViewport" + viewport.toString());
+ Log.d("GCBase.searchByViewport" + viewport.toString());
String referer = GCConstants.URL_LIVE_MAP;
@@ -110,58 +125,76 @@ public class GCBase {
for (Tile tile : tiles) {
- StringBuilder url = new StringBuilder();
- url.append("?x=").append(tile.getX()) // x tile
- .append("&y=").append(tile.getY()) // y tile
- .append("&z=").append(tile.getZoomlevel()); // zoom level
- if (tokens != null) {
- url.append("&k=").append(tokens[0]); // user session
- url.append("&st=").append(tokens[1]); // session token
- }
- url.append("&ep=1");
- if (Settings.isExcludeMyCaches()) {
- url.append("&hf=1").append("&hh=1"); // hide found, hide hidden
- }
- if (Settings.getCacheType() == CacheType.TRADITIONAL) {
- url.append("&ect=9,5,3,6,453,13,1304,137,11,4,8,1858"); // 2 = tradi 3 = multi 8 = mystery
- }
- if (Settings.getCacheType() == CacheType.MULTI) {
- url.append("&ect=9,5,2,6,453,13,1304,137,11,4,8,1858");
- }
- if (Settings.getCacheType() == CacheType.MYSTERY) {
- url.append("&ect=9,5,3,6,453,13,1304,137,11,4,2,1858");
- }
- if (tile.getZoomlevel() != 14) {
- url.append("&_=").append(String.valueOf(System.currentTimeMillis()));
- }
- // other types t.b.d
- final String urlString = url.toString();
+ if (!tileCache.containsKey(tile.hashCode())) {
+ final Parameters params = new Parameters(
+ "x", String.valueOf(tile.getX()),
+ "y", String.valueOf(tile.getY()),
+ "z", String.valueOf(tile.getZoomlevel()),
+ "ep", "1");
+ if (tokens != null) {
+ params.put("k", tokens[0], "st", tokens[1]);
+ }
+ if (Settings.isExcludeMyCaches()) {
+ params.put("hf", "1", "hh", "1"); // hide found, hide hidden
+ }
+ if (Settings.getCacheType() == CacheType.TRADITIONAL) {
+ params.put("ect", "9,5,3,6,453,13,1304,137,11,4,8,1858"); // 2 = tradi 3 = multi 8 = mystery
+ } else if (Settings.getCacheType() == CacheType.MULTI) {
+ params.put("ect", "9,5,2,6,453,13,1304,137,11,4,8,1858");
+ } else if (Settings.getCacheType() == CacheType.MYSTERY) {
+ params.put("ect", "9,5,3,6,453,13,1304,137,11,4,2,1858");
+ }
+ if (tile.getZoomlevel() != 14) {
+ params.put("_", String.valueOf(System.currentTimeMillis()));
+ }
+ // TODO: other types t.b.d
- // The PNG must be request before ! Else the following request would return with 204 - No Content
- Bitmap bitmap = Tile.requestMapTile(GCConstants.URL_MAP_TILE + urlString, referer);
+ // The PNG must be requested first, otherwise the following request would always return with 204 - No Content
+ Bitmap bitmap = Tile.requestMapTile(GCConstants.URL_MAP_TILE, params, referer);
- assert bitmap.getWidth() == Tile.TILE_SIZE : "Bitmap has wrong width";
- assert bitmap.getHeight() == Tile.TILE_SIZE : "Bitmap has wrong height";
+ // Check bitmap size
+ if (bitmap != null && (bitmap.getWidth() != Tile.TILE_SIZE ||
+ bitmap.getHeight() != Tile.TILE_SIZE)) {
+ bitmap.recycle();
+ bitmap = null;
+ }
- String data = Tile.requestMapInfo(GCConstants.URL_MAP_INFO + urlString, referer);
- if (StringUtils.isEmpty(data)) {
- Log.e(Settings.tag, "GCBase.searchByViewport: No data from server for tile (" + tile.getX() + "/" + tile.getY() + ")");
- } else {
- final SearchResult search = parseMapJSON(data, tile, bitmap, strategy);
- if (search == null || CollectionUtils.isEmpty(search.getGeocodes())) {
- Log.e(Settings.tag, "GCBase.searchByViewport: No cache parsed for viewport " + viewport);
+ String data = Tile.requestMapInfo(GCConstants.URL_MAP_INFO, params, referer);
+ if (StringUtils.isEmpty(data)) {
+ Log.e("GCBase.searchByViewport: No data from server for tile (" + tile.getX() + "/" + tile.getY() + ")");
+ } else {
+ final SearchResult search = parseMapJSON(data, tile, bitmap, strategy);
+ if (search == null || CollectionUtils.isEmpty(search.getGeocodes())) {
+ Log.e("GCBase.searchByViewport: No cache parsed for viewport " + viewport);
+ }
+ else {
+ searchResult.addGeocodes(search.getGeocodes());
+ }
+ tileCache.put(tile.hashCode(), tile);
}
- else {
- searchResult.addGeocodes(search.getGeocodes());
+
+ // release native bitmap memory
+ if (bitmap != null) {
+ bitmap.recycle();
}
+
}
}
}
if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY)) {
- SearchResult search = cgBase.searchByCoords(null, viewport.getCenter(), Settings.getCacheType(), false);
- if (search != null) {
- searchResult.addGeocodes(search.getGeocodes());
+ final Geopoint center = viewport.getCenter();
+ if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) {
+ SearchResult search = GCParser.searchByCoords(null, center, Settings.getCacheType(), false);
+ if (search != null && !search.isEmpty()) {
+ final Set<String> geocodes = search.getGeocodes();
+ if (Settings.isPremiumMember()) {
+ lastSearchViewport = cgeoapplication.getInstance().getBounds(geocodes);
+ } else {
+ lastSearchViewport = new Viewport(center, 0.01, 0.01);
+ }
+ searchResult.addGeocodes(geocodes);
+ }
}
}
@@ -180,7 +213,7 @@ public class GCBase {
try {
- final LeastRecentlyUsedCache<String, String> nameCache = new LeastRecentlyUsedCache<String, String>(2000); // JSON id, cache name
+ final LeastRecentlyUsedMap<String, String> nameCache = new LeastRecentlyUsedMap.LruCache<String, String>(2000); // JSON id, cache name
if (StringUtils.isEmpty(data)) {
throw new JSONException("No page given");
@@ -265,7 +298,7 @@ public class GCBase {
cache.setName(nameCache.get(id));
cache.setZoomlevel(tile.getZoomlevel());
cache.setCoords(tile.getCoord(xy));
- if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && positions.size() < 64) {
+ if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && positions.size() < 64 && bitmap != null) {
// don't parse if there are too many caches. The decoding would return too much wrong results
IconDecoder.parseMapPNG(cache, bitmap, xy, tile.getZoomlevel());
} else {
@@ -273,10 +306,10 @@ public class GCBase {
}
searchResult.addCache(cache);
}
- Log.d(Settings.tag, "Retrieved " + searchResult.getCount() + " caches for tile " + tile.toString());
+ Log.d("Retrieved " + searchResult.getCount() + " caches for tile " + tile.toString());
} catch (Exception e) {
- Log.e(Settings.tag, "GCBase.parseMapJSON", e);
+ Log.e("GCBase.parseMapJSON", e);
}
return searchResult;
@@ -325,65 +358,9 @@ public class GCBase {
return gcid;
}
- private static String modulo(final long value, final long base, final String sequence) {
- String result = "";
- long rest = 0;
- long divResult = value;
- do
- {
- rest = divResult % base;
- divResult = (int) Math.floor(divResult / base);
- result = sequence.charAt((int) rest) + result;
- } while (divResult != 0);
- return result;
- }
-
- /**
- * Convert (old) GCIds to GCCode (geocode)
- *
- * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
- */
- public static String gcidToGCCode(final long gcid) {
- String gccode = modulo(gcid + 411120, GC_BASE31, SEQUENCE_GCID);
- if ((gccode.length() < 4) || (gccode.length() == 4 && SEQUENCE_GCID.indexOf(gccode.charAt(0)) < 16)) {
- gccode = modulo(gcid, GC_BASE16, SEQUENCE_GCID);
- }
- return "GC" + gccode;
- }
-
- /**
- * Convert ids from the live map to (old) GCIds
- *
- * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
- */
- public static long newidToGCId(final String newid) {
- long gcid = 0;
- for (int p = 0; p < newid.length(); p++) {
- gcid = GC_BASE57 * gcid + SEQUENCE_NEWID.indexOf(newid.charAt(p));
- }
- return gcid;
- }
-
- /**
- * Convert (old) GCIds to ids used in the live map
- *
- * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
- */
- public static String gcidToNewId(final long gcid) {
- return modulo(gcid, GC_BASE57, SEQUENCE_NEWID);
- }
-
- /**
- * Convert ids from the live map into GCCode (geocode)
- */
- public static String newidToGeocode(final String newid) {
- long gcid = GCBase.newidToGCId(newid);
- return GCBase.gcidToGCCode(gcid);
- }
-
/** Get user session & session token from the Live Map. Needed for following requests */
public static String[] getTokens() {
- final HttpResponse response = Network.request(GCConstants.URL_LIVE_MAP, null, false);
+ final HttpResponse response = Network.getRequest(GCConstants.URL_LIVE_MAP);
final String data = Network.getResponseData(response);
String userSession = BaseUtils.getMatch(data, GCConstants.PATTERN_USERSESSION, "");
String sessionToken = BaseUtils.getMatch(data, GCConstants.PATTERN_SESSIONTOKEN, "");
@@ -392,18 +369,14 @@ public class GCBase {
public static SearchResult searchByGeocodes(final Set<String> geocodes) {
- SearchResult result = new SearchResult();
+ final SearchResult result = new SearchResult();
final String geocodeList = StringUtils.join(geocodes.toArray(), "|");
-
- String referer = GCConstants.URL_LIVE_MAP_DETAILS;
-
- StringBuilder url = new StringBuilder();
- url.append("?i=").append(geocodeList).append("&_=").append(String.valueOf(System.currentTimeMillis()));
- final String urlString = url.toString();
+ final String referer = GCConstants.URL_LIVE_MAP_DETAILS;
try {
- String data = Tile.requestMapInfo(referer + urlString, referer);
+ final Parameters params = new Parameters("i", geocodeList, "_", String.valueOf(System.currentTimeMillis()));
+ final String data = StringUtils.defaultString(Tile.requestMapInfo(referer, params, referer));
// Example JSON information
// {"status":"success",
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index 1c57508..b461cc2 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -3,21 +3,18 @@ package cgeo.geocaching.connector.gc;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.AbstractConnector;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.geopoint.Viewport;
-import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import android.util.Log;
-
import java.util.Set;
import java.util.regex.Pattern;
@@ -90,7 +87,7 @@ public class GCConnector extends AbstractConnector {
public SearchResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final CancellableHandler handler) {
if (app == null) {
- Log.e(Settings.tag, "cgeoBase.searchByGeocode: No application found");
+ Log.e("cgeoBase.searchByGeocode: No application found");
return null;
}
@@ -103,39 +100,37 @@ public class GCConnector extends AbstractConnector {
params.put("log", "y");
params.put("numlogs", String.valueOf(GCConstants.NUMBER_OF_LOGS));
- cgBase.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_loadpage);
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_loadpage);
- final String page = Network.requestLogged("http://www.geocaching.com/seek/cache_details.aspx", params, false, false, false);
+ final String page = Login.getRequestLogged("http://www.geocaching.com/seek/cache_details.aspx", params);
if (StringUtils.isEmpty(page)) {
final SearchResult search = new SearchResult();
if (app.isThere(geocode, guid, true, false)) {
if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) {
- Log.i(Settings.tag, "Loading old cache from cache.");
+ Log.i("Loading old cache from cache.");
search.addGeocode(app.getGeocode(guid));
} else {
search.addGeocode(geocode);
}
- search.error = StatusCode.NO_ERROR;
+ search.setError(StatusCode.NO_ERROR);
return search;
}
- Log.e(Settings.tag, "cgeoBase.searchByGeocode: No data from server");
- search.error = StatusCode.COMMUNICATION_ERROR;
+ Log.e("cgeoBase.searchByGeocode: No data from server");
+ search.setError(StatusCode.COMMUNICATION_ERROR);
return search;
}
- final SearchResult searchResult = cgBase.parseCache(page, handler);
+ final SearchResult searchResult = GCParser.parseCache(page, handler);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) {
- Log.e(Settings.tag, "cgeoBase.searchByGeocode: No cache parsed");
+ Log.e("cgeoBase.searchByGeocode: No cache parsed");
return searchResult;
}
- final SearchResult search = searchResult.filterSearchResults(false, false, Settings.getCacheType());
-
- return search;
+ return searchResult.filterSearchResults(false, false, Settings.getCacheType());
}
@Override
diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 0d39608..e0cb70f 100644
--- a/main/src/cgeo/geocaching/cgBase.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -1,14 +1,19 @@
-// $codepro.audit.disable logExceptions
-package cgeo.geocaching;
-
-import cgeo.geocaching.activity.ActivityMixin;
-import cgeo.geocaching.connector.ConnectorFactory;
-import cgeo.geocaching.connector.gc.GCConnector;
-import cgeo.geocaching.connector.gc.GCConstants;
+package cgeo.geocaching.connector.gc;
+
+import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.R;
+import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.Settings;
+import cgeo.geocaching.TrackableLog;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgImage;
+import cgeo.geocaching.cgSearchThread;
+import cgeo.geocaching.cgTrackable;
+import cgeo.geocaching.cgWaypoint;
+import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
-import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.LogTypeTrackable;
@@ -19,13 +24,12 @@ import cgeo.geocaching.gcvote.GCVote;
import cgeo.geocaching.gcvote.GCVoteRating;
import cgeo.geocaching.geopoint.DistanceParser;
import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.network.HtmlImage;
-import cgeo.geocaching.network.Login;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.ui.DirectionImage;
import cgeo.geocaching.utils.BaseUtils;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
@@ -35,101 +39,35 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
import android.text.Html;
import android.text.Spannable;
import android.text.Spanned;
-import android.text.format.DateUtils;
import android.text.style.StrikethroughSpan;
-import android.util.Log;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
-public class cgBase {
-
+public abstract class GCParser {
private final static SimpleDateFormat dateTbIn1 = new SimpleDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009
private final static SimpleDateFormat dateTbIn2 = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009
- public static String version = null;
-
- private static Context context;
- public static Resources res;
-
- public static final int UPDATE_LOAD_PROGRESS_DETAIL = 42186;
-
- private cgBase() {
- //initialize(app);
- throw new UnsupportedOperationException(); // static class, not to be instantiated
- }
-
- /**
- * Called from AbstractActivity.onCreate() and AbstractListActivity.onCreate()
- *
- * @param app
- */
- public static void initialize(final cgeoapplication app) {
- context = app.getBaseContext();
- res = app.getBaseContext().getResources();
-
- try {
- final PackageManager manager = app.getPackageManager();
- final PackageInfo info = manager.getPackageInfo(app.getPackageName(), 0);
- version = info.versionName;
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(Settings.tag, "unable to get version information", e);
- version = null;
- }
- }
-
- public static void sendLoadProgressDetail(final Handler handler, final int str) {
- if (null != handler) {
- handler.obtainMessage(UPDATE_LOAD_PROGRESS_DETAIL, cgeoapplication.getInstance().getString(str)).sendToTarget();
- }
- }
-
- /**
- * checks if an Array of Strings is empty or not. Empty means:
- * - Array is null
- * - or all elements are null or empty strings
- */
- public static boolean isEmpty(String[] a) {
- if (a == null) {
- return true;
- }
-
- for (String s : a) {
- if (StringUtils.isNotEmpty(s)) {
- return false;
- }
- }
- return true;
- }
private static SearchResult parseSearch(final cgSearchThread thread, final String url, final String pageContent, final boolean showCaptcha) {
if (StringUtils.isBlank(pageContent)) {
- Log.e(Settings.tag, "cgeoBase.parseSearch: No page given");
+ Log.e("cgeoBase.parseSearch: No page given");
return null;
}
final List<String> cids = new ArrayList<String>();
- final List<String> guids = new ArrayList<String>();
String recaptchaChallenge = null;
String recaptchaText = null;
String page = pageContent;
@@ -144,7 +82,7 @@ public class cgBase {
if (recaptchaJsParam != null) {
final Parameters params = new Parameters("k", recaptchaJsParam.trim());
- final String recaptchaJs = Network.getResponseData(Network.request("http://www.google.com/recaptcha/api/challenge", params, true));
+ final String recaptchaJs = Network.getResponseData(Network.getRequest("http://www.google.com/recaptcha/api/challenge", params));
if (StringUtils.isNotBlank(recaptchaJs)) {
recaptchaChallenge = BaseUtils.getMatch(recaptchaJs, GCConstants.PATTERN_SEARCH_RECAPTCHACHALLENGE, true, 1, null, true);
@@ -163,7 +101,7 @@ public class cgBase {
int startPos = page.indexOf("<div id=\"ctl00_ContentBody_ResultsPanel\"");
if (startPos == -1) {
- Log.e(Settings.tag, "cgeoBase.parseSearch: ID \"ctl00_ContentBody_dlResults\" not found on page");
+ Log.e("cgeoBase.parseSearch: ID \"ctl00_ContentBody_dlResults\" not found on page");
return null;
}
@@ -172,7 +110,7 @@ public class cgBase {
startPos = page.indexOf('>');
int endPos = page.indexOf("ctl00_ContentBody_UnitTxt");
if (startPos == -1 || endPos == -1) {
- Log.e(Settings.tag, "cgeoBase.parseSearch: ID \"ctl00_ContentBody_UnitTxt\" not found on page");
+ Log.e("cgeoBase.parseSearch: ID \"ctl00_ContentBody_UnitTxt\" not found on page");
return null;
}
@@ -195,8 +133,6 @@ public class cgBase {
while (matcherGuidAndDisabled.find()) {
if (matcherGuidAndDisabled.groupCount() > 0) {
- guids.add(matcherGuidAndDisabled.group(1));
-
cache.setGuid(matcherGuidAndDisabled.group(1));
if (matcherGuidAndDisabled.group(4) != null) {
cache.setName(Html.fromHtml(matcherGuidAndDisabled.group(4).trim()).toString());
@@ -215,7 +151,7 @@ public class cgBase {
}
} catch (Exception e) {
// failed to parse GUID and/or Disabled
- Log.w(Settings.tag, "cgeoBase.parseSearch: Failed to parse GUID and/or Disabled data");
+ Log.w("cgeoBase.parseSearch: Failed to parse GUID and/or Disabled data");
}
if (Settings.isExcludeDisabledCaches() && (cache.isDisabled() || cache.isArchived())) {
@@ -247,15 +183,11 @@ public class cgBase {
if (StringUtils.isNotBlank(inventoryPre)) {
final Matcher matcherTbsInside = GCConstants.PATTERN_SEARCH_TRACKABLESINSIDE.matcher(inventoryPre);
while (matcherTbsInside.find()) {
- if (matcherTbsInside.groupCount() == 2 && matcherTbsInside.group(2) != null) {
- final String inventoryItem = matcherTbsInside.group(2).toLowerCase();
- if (inventoryItem.equals("premium member only cache")) {
- continue;
- } else {
- if (cache.getInventoryItems() <= 0) {
- cache.setInventoryItems(1);
- }
- }
+ if (matcherTbsInside.groupCount() == 2 &&
+ matcherTbsInside.group(2) != null &&
+ !matcherTbsInside.group(2).equalsIgnoreCase("premium member only cache") &&
+ cache.getInventoryItems() <= 0) {
+ cache.setInventoryItems(1);
}
}
}
@@ -276,14 +208,14 @@ public class cgBase {
cids.add(cache.getCacheId());
}
- // favourite count
+ // favorite count
try {
result = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_FAVORITE, false, 1, null, true);
if (null != result) {
cache.setFavoritePoints(Integer.parseInt(result));
}
} catch (NumberFormatException e) {
- Log.w(Settings.tag, "cgeoBase.parseSearch: Failed to parse favourite count");
+ Log.w("cgeoBase.parseSearch: Failed to parse favourite count");
}
if (cache.getNameSp() == null) {
@@ -300,10 +232,10 @@ public class cgBase {
try {
String result = BaseUtils.getMatch(page, GCConstants.PATTERN_SEARCH_TOTALCOUNT, false, 1, null, true);
if (null != result) {
- searchResult.totalCnt = Integer.parseInt(result);
+ searchResult.setTotal(Integer.parseInt(result));
}
} catch (NumberFormatException e) {
- Log.w(Settings.tag, "cgeoBase.parseSearch: Failed to parse cache count");
+ Log.w("cgeoBase.parseSearch: Failed to parse cache count");
}
if (thread != null && recaptchaChallenge != null) {
@@ -315,7 +247,7 @@ public class cgBase {
}
if (cids.size() > 0 && (Settings.isPremiumMember() || showCaptcha) && (recaptchaChallenge == null || StringUtils.isNotBlank(recaptchaText))) {
- Log.i(Settings.tag, "Trying to get .loc for " + cids.size() + " caches");
+ Log.i("Trying to get .loc for " + cids.size() + " caches");
try {
// get coordinates for parsed caches
@@ -345,9 +277,9 @@ public class cgBase {
if (StringUtils.isNotBlank(coordinates)) {
if (coordinates.contains("You have not agreed to the license agreement. The license agreement is required before you can start downloading GPX or LOC files from Geocaching.com")) {
- Log.i(Settings.tag, "User has not agreed to the license agreement. Can\'t download .loc file.");
+ Log.i("User has not agreed to the license agreement. Can\'t download .loc file.");
- searchResult.error = StatusCode.UNAPPROVED_LICENSE;
+ searchResult.setError(StatusCode.UNAPPROVED_LICENSE);
return searchResult;
}
@@ -356,7 +288,7 @@ public class cgBase {
LocParser.parseLoc(searchResult, coordinates);
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.parseSearch.CIDs: " + e.toString());
+ Log.e("cgBase.parseSearch.CIDs: " + e.toString());
}
}
@@ -384,6 +316,9 @@ public class cgBase {
if (CancellableHandler.isCancelled(handler)) {
return null;
}
+ // update progress message so user knows we're still working. Otherwise it will remain on whatever was set
+ // in getExtraOnlineInfo (which could be logs, gcvote, or elevation)
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_render);
// save full detailed caches
cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
}
@@ -391,33 +326,33 @@ public class cgBase {
}
static SearchResult parseCacheFromText(final String page, final CancellableHandler handler) {
- sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details);
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details);
if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.parseCache: No page given");
+ Log.e("cgeoBase.parseCache: No page given");
return null;
}
final SearchResult searchResult = new SearchResult();
if (page.contains("Cache is Unpublished") || page.contains("you cannot view this cache listing until it has been published")) {
- searchResult.error = StatusCode.UNPUBLISHED_CACHE;
+ searchResult.setError(StatusCode.UNPUBLISHED_CACHE);
return searchResult;
}
if (page.contains("Sorry, the owner of this listing has made it viewable to Premium Members only.")) {
- searchResult.error = StatusCode.PREMIUM_ONLY;
+ searchResult.setError(StatusCode.PREMIUM_ONLY);
return searchResult;
}
if (page.contains("has chosen to make this cache listing visible to Premium Members only.")) {
- searchResult.error = StatusCode.PREMIUM_ONLY;
+ searchResult.setError(StatusCode.PREMIUM_ONLY);
return searchResult;
}
final String cacheName = Html.fromHtml(BaseUtils.getMatch(page, GCConstants.PATTERN_NAME, true, "")).toString();
if ("An Error Has Occurred".equalsIgnoreCase(cacheName)) {
- searchResult.error = StatusCode.UNKNOWN_ERROR;
+ searchResult.setError(StatusCode.UNKNOWN_ERROR);
return searchResult;
}
@@ -454,7 +389,7 @@ public class cgBase {
int pos = tableInside.indexOf("id=\"cacheDetails\"");
if (pos == -1) {
- Log.e(Settings.tag, "cgeoBase.parseCache: ID \"cacheDetails\" not found on page");
+ Log.e("cgeoBase.parseCache: ID \"cacheDetails\" not found on page");
return null;
}
@@ -462,7 +397,7 @@ public class cgBase {
pos = tableInside.indexOf("<div class=\"CacheInformationTable\"");
if (pos == -1) {
- Log.e(Settings.tag, "cgeoBase.parseCache: class \"CacheInformationTable\" not found on page");
+ Log.e("cgeoBase.parseCache: class \"CacheInformationTable\" not found on page");
return null;
}
@@ -499,7 +434,7 @@ public class cgBase {
}
} catch (ParseException e) {
// failed to parse cache hidden date
- Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache hidden (event) date");
+ Log.w("cgeoBase.parseCache: Failed to parse cache hidden (event) date");
}
// favourite
@@ -525,7 +460,7 @@ public class cgBase {
cache.setCoords(new Geopoint(cache.getLatlon()));
cache.setReliableLatLon(true);
} catch (Geopoint.GeopointException e) {
- Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache coordinates: " + e.toString());
+ Log.w("cgeoBase.parseCache: Failed to parse cache coordinates: " + e.toString());
}
}
@@ -542,7 +477,7 @@ public class cgBase {
}
}
- checkFields(cache);
+ cache.checkFields();
// cache personal note
cache.setPersonalNote(BaseUtils.getMatch(page, GCConstants.PATTERN_PERSONALNOTE, true, cache.getPersonalNote()));
@@ -579,7 +514,7 @@ public class cgBase {
}
} catch (Exception e) {
// failed to parse cache attributes
- Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache attributes");
+ Log.w("cgeoBase.parseCache: Failed to parse cache attributes");
}
// cache spoilers
@@ -589,7 +524,7 @@ public class cgBase {
if (CancellableHandler.isCancelled(handler)) {
return null;
}
- sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_spoilers);
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_spoilers);
final Matcher matcherSpoilersInside = GCConstants.PATTERN_SPOILERSINSIDE.matcher(spoilers);
@@ -616,7 +551,7 @@ public class cgBase {
}
} catch (Exception e) {
// failed to parse cache spoilers
- Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache spoilers");
+ Log.w("cgeoBase.parseCache: Failed to parse cache spoilers");
}
// cache inventory
@@ -650,7 +585,7 @@ public class cgBase {
}
} catch (Exception e) {
// failed to parse cache inventory
- Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache inventory (2)");
+ Log.w("cgeoBase.parseCache: Failed to parse cache inventory (2)");
}
// cache logs counts
@@ -675,7 +610,7 @@ public class cgBase {
} catch (Exception e)
{
// failed to parse logs
- Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache log count");
+ Log.w("cgeoBase.parseCache: Failed to parse cache log count");
}
// add waypoint for original coordinates in case of user-modified listing-coordinates
@@ -683,8 +618,7 @@ public class cgBase {
final String originalCoords = BaseUtils.getMatch(page, GCConstants.PATTERN_LATLON_ORIG, false, null);
if (null != originalCoords) {
- // res is null during the unit tests
- final cgWaypoint waypoint = new cgWaypoint(res != null ? res.getString(R.string.cache_coordinates_original) : "res = null", WaypointType.WAYPOINT, false);
+ final cgWaypoint waypoint = new cgWaypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.WAYPOINT, false);
waypoint.setCoords(new Geopoint(originalCoords));
cache.addWaypoint(waypoint, false);
cache.setUserModifiedCoords(true);
@@ -693,16 +627,15 @@ public class cgBase {
}
// waypoints
- int wpBegin = 0;
- int wpEnd = 0;
+ int wpBegin;
+ int wpEnd;
wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">");
if (wpBegin != -1) { // parse waypoints
if (CancellableHandler.isCancelled(handler)) {
return null;
}
- sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_waypoints);
-
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_waypoints);
String wpList = page.substring(wpBegin);
@@ -729,7 +662,7 @@ public class cgBase {
// waypoint name
// res is null during the unit tests
- final String name = BaseUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, res != null ? res.getString(R.string.waypoint) : "res = null", true);
+ final String name = BaseUtils.getMatch(wp[6], GCConstants.PATTERN_WPNAME, true, 1, cgeoapplication.getInstance().getString(R.string.waypoint), true);
// waypoint type
final String resulttype = BaseUtils.getMatch(wp[3], GCConstants.PATTERN_WPTYPE, null);
@@ -769,7 +702,7 @@ public class cgBase {
// last check for necessary cache conditions
if (StringUtils.isBlank(cache.getGeocode())) {
- searchResult.error = StatusCode.UNKNOWN_ERROR;
+ searchResult.setError(StatusCode.UNKNOWN_ERROR);
return searchResult;
}
@@ -777,485 +710,6 @@ public class cgBase {
return searchResult;
}
- private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) {
- if (CancellableHandler.isCancelled(handler)) {
- return;
- }
-
- //cache.setLogs(loadLogsFromDetails(page, cache, false));
- if (Settings.isFriendLogsWanted()) {
- sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs);
- List<cgLog> allLogs = cache.getLogs();
- List<cgLog> friendLogs = loadLogsFromDetails(page, cache, true, false);
- if (friendLogs != null) {
- for (cgLog log : friendLogs) {
- if (allLogs.contains(log)) {
- allLogs.get(allLogs.indexOf(log)).friend = true;
- } else {
- allLogs.add(log);
- }
- }
- }
- }
-
- if (Settings.isElevationWanted()) {
- if (CancellableHandler.isCancelled(handler)) {
- return;
- }
- sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_elevation);
- if (cache.getCoords() != null) {
- cache.setElevation(cache.getCoords().getElevation());
- }
- }
-
- if (Settings.isRatingWanted()) {
- if (CancellableHandler.isCancelled(handler)) {
- return;
- }
- sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_gcvote);
- final GCVoteRating rating = GCVote.getRating(cache.getGuid(), cache.getGeocode());
- if (rating != null) {
- cache.setRating(rating.getRating());
- cache.setVotes(rating.getVotes());
- cache.setMyVote(rating.getMyVote());
- }
- }
- }
-
- /**
- * Load logs from a cache details page.
- *
- * @param page
- * the text of the details page
- * @param cache
- * the cache object to put the logs in
- * @param friends
- * retrieve friend logs
- */
- private static List<cgLog> loadLogsFromDetails(final String page, final cgCache cache, final boolean friends, final boolean getDataFromPage) {
- String rawResponse = null;
-
- if (!getDataFromPage) {
- final Matcher userTokenMatcher = GCConstants.PATTERN_USERTOKEN2.matcher(page);
- if (!userTokenMatcher.find()) {
- Log.e(Settings.tag, "cgBase.loadLogsFromDetails: unable to extract userToken");
- return null;
- }
-
- final String userToken = userTokenMatcher.group(1);
- final Parameters params = new Parameters(
- "tkn", userToken,
- "idx", "1",
- "num", String.valueOf(GCConstants.NUMBER_OF_LOGS),
- "decrypt", "true",
- // "sp", Boolean.toString(personal), // personal logs
- "sf", Boolean.toString(friends));
-
- final HttpResponse response = Network.request("http://www.geocaching.com/seek/geocache.logbook", params, false, false, false);
- if (response == null) {
- Log.e(Settings.tag, "cgBase.loadLogsFromDetails: cannot log logs, response is null");
- return null;
- }
- final int statusCode = response.getStatusLine().getStatusCode();
- if (statusCode != 200) {
- Log.e(Settings.tag, "cgBase.loadLogsFromDetails: error " + statusCode + " when requesting log information");
- return null;
- }
- rawResponse = Network.getResponseData(response);
- if (rawResponse == null) {
- Log.e(Settings.tag, "cgBase.loadLogsFromDetails: unable to read whole response");
- return null;
- }
- } else {
- // extract embedded JSON data from page
- rawResponse = BaseUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, "");
- }
-
- List<cgLog> logs = new ArrayList<cgLog>();
-
- try {
- final JSONObject resp = new JSONObject(rawResponse);
- if (!resp.getString("status").equals("success")) {
- Log.e(Settings.tag, "cgBase.loadLogsFromDetails: status is " + resp.getString("status"));
- return null;
- }
-
- final JSONArray data = resp.getJSONArray("data");
-
- for (int index = 0; index < data.length(); index++) {
- final JSONObject entry = data.getJSONObject(index);
- final cgLog logDone = new cgLog();
- logDone.friend = friends;
-
- // FIXME: use the "LogType" field instead of the "LogTypeImage" one.
- final String logIconNameExt = entry.optString("LogTypeImage", ".gif");
- final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4);
- logDone.type = LogType.getByIconName(logIconName);
-
- try {
- logDone.date = Login.parseGcCustomDate(entry.getString("Visited")).getTime();
- } catch (ParseException e) {
- Log.e(Settings.tag, "cgBase.loadLogsFromDetails: failed to parse log date.");
- }
-
- logDone.author = entry.getString("UserName");
- logDone.found = entry.getInt("GeocacheFindCount");
- logDone.log = entry.getString("LogText");
-
- final JSONArray images = entry.getJSONArray("Images");
- for (int i = 0; i < images.length(); i++) {
- final JSONObject image = images.getJSONObject(i);
- String url = "http://img.geocaching.com/cache/log/" + image.getString("FileName");
- String title = image.getString("Name");
- final cgImage logImage = new cgImage(url, title);
- if (logDone.logImages == null) {
- logDone.logImages = new ArrayList<cgImage>();
- }
- logDone.logImages.add(logImage);
- }
-
- logs.add(logDone);
- }
- } catch (JSONException e) {
- // failed to parse logs
- Log.w(Settings.tag, "cgBase.loadLogsFromDetails: Failed to parse cache logs", e);
- }
-
- return logs;
- }
-
- private static void checkFields(cgCache cache) {
- if (StringUtils.isBlank(cache.getGeocode())) {
- Log.e(Settings.tag, "cgBase.loadLogsFromDetails: geo code not parsed correctly");
- }
- if (StringUtils.isBlank(cache.getName())) {
- Log.e(Settings.tag, "name not parsed correctly");
- }
- if (StringUtils.isBlank(cache.getGuid())) {
- Log.e(Settings.tag, "guid not parsed correctly");
- }
- if (cache.getTerrain() == 0.0) {
- Log.e(Settings.tag, "terrain not parsed correctly");
- }
- if (cache.getDifficulty() == 0.0) {
- Log.e(Settings.tag, "difficulty not parsed correctly");
- }
- if (StringUtils.isBlank(cache.getOwner())) {
- Log.e(Settings.tag, "owner not parsed correctly");
- }
- if (StringUtils.isBlank(cache.getOwnerReal())) {
- Log.e(Settings.tag, "owner real not parsed correctly");
- }
- if (cache.getHiddenDate() == null) {
- Log.e(Settings.tag, "hidden not parsed correctly");
- }
- if (cache.getFavoritePoints() < 0) {
- Log.e(Settings.tag, "favoriteCount not parsed correctly");
- }
- if (cache.getSize() == null) {
- Log.e(Settings.tag, "size not parsed correctly");
- }
- if (cache.getType() == null || cache.getType() == CacheType.UNKNOWN) {
- Log.e(Settings.tag, "type not parsed correctly");
- }
- if (cache.getCoords() == null) {
- Log.e(Settings.tag, "coordinates not parsed correctly");
- }
- if (StringUtils.isBlank(cache.getLocation())) {
- Log.e(Settings.tag, "location not parsed correctly");
- }
- }
-
- /**
- * Parse a trackable HTML description into a cgTrackable object
- *
- * @param page
- * the HTML page to parse, already processed through {@link BaseUtils#replaceWhitespace}
- * @param app
- * if not null, the application to use to save the trackable
- * @return the parsed trackable, or null if none could be parsed
- */
- public static cgTrackable parseTrackable(final String page, final cgeoapplication app, final String possibleTrackingcode) {
- if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.parseTrackable: No page given");
- return null;
- }
-
- final cgTrackable trackable = new cgTrackable();
-
- // trackable geocode
- trackable.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode()).toUpperCase());
-
- // trackable id
- trackable.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid()));
-
- // trackable icon
- trackable.setIconUrl(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ICON, true, trackable.getIconUrl()));
-
- // trackable name
- trackable.setName(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_NAME, true, trackable.getName()));
-
- // trackable type
- if (StringUtils.isNotBlank(trackable.getName())) {
- trackable.setType(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_TYPE, true, trackable.getType()));
- }
-
- // trackable owner name
- try {
- final Matcher matcherOwner = GCConstants.PATTERN_TRACKABLE_OWNER.matcher(page);
- if (matcherOwner.find() && matcherOwner.groupCount() > 0) {
- trackable.setOwnerGuid(matcherOwner.group(1));
- trackable.setOwner(matcherOwner.group(2).trim());
- }
- } catch (Exception e) {
- // failed to parse trackable owner name
- Log.w(Settings.tag, "cgeoBase.parseTrackable: Failed to parse trackable owner name");
- }
-
- // trackable origin
- trackable.setOrigin(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ORIGIN, true, trackable.getOrigin()));
-
- // trackable spotted
- try {
- final Matcher matcherSpottedCache = GCConstants.PATTERN_TRACKABLE_SPOTTEDCACHE.matcher(page);
- if (matcherSpottedCache.find() && matcherSpottedCache.groupCount() > 0) {
- trackable.setSpottedGuid(matcherSpottedCache.group(1));
- trackable.setSpottedName(matcherSpottedCache.group(2).trim());
- trackable.setSpottedType(cgTrackable.SPOTTED_CACHE);
- }
-
- final Matcher matcherSpottedUser = GCConstants.PATTERN_TRACKABLE_SPOTTEDUSER.matcher(page);
- if (matcherSpottedUser.find() && matcherSpottedUser.groupCount() > 0) {
- trackable.setSpottedGuid(matcherSpottedUser.group(1));
- trackable.setSpottedName(matcherSpottedUser.group(2).trim());
- trackable.setSpottedType(cgTrackable.SPOTTED_USER);
- }
-
- if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDUNKNOWN)) {
- trackable.setSpottedType(cgTrackable.SPOTTED_UNKNOWN);
- }
-
- if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDOWNER)) {
- trackable.setSpottedType(cgTrackable.SPOTTED_OWNER);
- }
- } catch (Exception e) {
- // failed to parse trackable last known place
- Log.w(Settings.tag, "cgeoBase.parseTrackable: Failed to parse trackable last known place");
- }
-
- // released date - can be missing on the page
- try {
- String releaseString = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_RELEASES, false, null);
- if (releaseString != null) {
- trackable.setReleased(dateTbIn1.parse(releaseString));
- if (trackable.getReleased() == null) {
- trackable.setReleased(dateTbIn2.parse(releaseString));
- }
- }
- } catch (ParseException e1) {
- trackable.setReleased(null);
- }
-
-
- // trackable distance
- try {
- final String distance = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_DISTANCE, false, null);
- if (null != distance) {
- trackable.setDistance(DistanceParser.parseDistance(distance, Settings.isUseMetricUnits()));
- }
- } catch (NumberFormatException e) {
- throw e;
- }
-
- // trackable goal
- trackable.setGoal(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GOAL, true, trackable.getGoal()));
-
- // trackable details & image
- try {
- final Matcher matcherDetailsImage = GCConstants.PATTERN_TRACKABLE_DETAILSIMAGE.matcher(page);
- if (matcherDetailsImage.find() && matcherDetailsImage.groupCount() > 0) {
- final String image = StringUtils.trim(matcherDetailsImage.group(3));
- final String details = StringUtils.trim(matcherDetailsImage.group(4));
-
- if (StringUtils.isNotEmpty(image)) {
- trackable.setImage(image);
- }
- if (StringUtils.isNotEmpty(details) && !StringUtils.equals(details, "No additional details available.")) {
- trackable.setDetails(details);
- }
- }
- } catch (Exception e) {
- // failed to parse trackable details & image
- Log.w(Settings.tag, "cgeoBase.parseTrackable: Failed to parse trackable details & image");
- }
-
- // trackable logs
- try
- {
- final Matcher matcherLogs = GCConstants.PATTERN_TRACKABLE_LOG.matcher(page);
- /*
- * 1. Type (img)
- * 2. Date
- * 3. Author
- * 4. Cache-GUID
- * 5. <ignored> (strike-through property for ancien caches)
- * 6. Cache-name
- * 7. Logtext
- */
- while (matcherLogs.find())
- {
- final cgLog logDone = new cgLog();
-
- logDone.type = LogType.getByIconName(matcherLogs.group(1));
- logDone.author = Html.fromHtml(matcherLogs.group(3)).toString().trim();
-
- try
- {
- logDone.date = Login.parseGcCustomDate(matcherLogs.group(2)).getTime();
- } catch (ParseException e) {
- }
-
- logDone.log = matcherLogs.group(7).trim();
-
- if (matcherLogs.group(4) != null && matcherLogs.group(6) != null)
- {
- logDone.cacheGuid = matcherLogs.group(4);
- logDone.cacheName = matcherLogs.group(6);
- }
-
- // Apply the pattern for images in a trackable log entry against each full log (group(0))
- final Matcher matcherLogImages = GCConstants.PATTERN_TRACKABLE_LOG_IMAGES.matcher(matcherLogs.group(0));
- /*
- * 1. Image URL
- * 2. Image title
- */
- while (matcherLogImages.find())
- {
- final cgImage logImage = new cgImage(matcherLogImages.group(1), matcherLogImages.group(2));
- if (logDone.logImages == null) {
- logDone.logImages = new ArrayList<cgImage>();
- }
- logDone.logImages.add(logImage);
- }
-
- trackable.getLogs().add(logDone);
- }
- } catch (Exception e) {
- // failed to parse logs
- Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache logs" + e.toString());
- }
-
- // trackingcode
- if (!StringUtils.equalsIgnoreCase(trackable.getGeocode(), possibleTrackingcode)) {
- trackable.setTrackingcode(possibleTrackingcode);
- }
-
- if (app != null) {
- app.saveTrackable(trackable);
- }
-
- return trackable;
- }
-
- public static List<LogType> parseTypes(String page) {
- if (StringUtils.isEmpty(page)) {
- return null;
- }
-
- final List<LogType> types = new ArrayList<LogType>();
-
- final Matcher typeBoxMatcher = GCConstants.PATTERN_TYPEBOX.matcher(page);
- String typesText = null;
- if (typeBoxMatcher.find()) {
- if (typeBoxMatcher.groupCount() > 0) {
- typesText = typeBoxMatcher.group(1);
- }
- }
-
- if (typesText != null) {
-
- final Matcher typeMatcher = GCConstants.PATTERN_TYPE2.matcher(typesText);
- while (typeMatcher.find()) {
- if (typeMatcher.groupCount() > 1) {
- final int type = Integer.parseInt(typeMatcher.group(2));
-
- if (type > 0) {
- types.add(LogType.getById(type));
- }
- }
- }
- }
-
- return types;
- }
-
- public static List<cgTrackableLog> parseTrackableLog(final String page) {
- if (StringUtils.isEmpty(page)) {
- return null;
- }
-
- final List<cgTrackableLog> trackables = new ArrayList<cgTrackableLog>();
-
- String table = StringUtils.substringBetween(page, "<table id=\"tblTravelBugs\"", "</table>");
-
- // if no trackables are currently in the account, the table is not available, so return an empty list instead of null
- if (StringUtils.isBlank(table)) {
- return trackables;
- }
-
- table = StringUtils.substringBetween(table, "<tbody>", "</tbody>");
- if (StringUtils.isBlank(table)) {
- Log.e(Settings.tag, "cgeoBase.parseTrackableLog: tbody not found on page");
- return null;
- }
-
- final Matcher trackableMatcher = GCConstants.PATTERN_TRACKABLE.matcher(page);
- while (trackableMatcher.find()) {
- if (trackableMatcher.groupCount() > 0) {
- final cgTrackableLog trackableLog = new cgTrackableLog();
-
- if (trackableMatcher.group(1) != null) {
- trackableLog.trackCode = trackableMatcher.group(1);
- } else {
- continue;
- }
- if (trackableMatcher.group(2) != null) {
- trackableLog.name = Html.fromHtml(trackableMatcher.group(2)).toString();
- } else {
- continue;
- }
- if (trackableMatcher.group(3) != null) {
- trackableLog.ctl = Integer.valueOf(trackableMatcher.group(3));
- } else {
- continue;
- }
- if (trackableMatcher.group(5) != null) {
- trackableLog.id = Integer.valueOf(trackableMatcher.group(5));
- } else {
- continue;
- }
-
- Log.i(Settings.tag, "Trackable in inventory (#" + trackableLog.ctl + "/" + trackableLog.id + "): " + trackableLog.trackCode + " - " + trackableLog.name);
-
- trackables.add(trackableLog);
- }
- }
-
- return trackables;
- }
-
- /**
- * Insert the right cache type restriction in parameters
- *
- * @param params
- * the parameters to insert the restriction into
- * @param cacheType
- * the type of cache, or null to include everything
- */
- static private void insertCacheType(final Parameters params, final CacheType cacheType) {
- params.put("tx", cacheType.guid);
- }
-
public static SearchResult searchByNextPage(cgSearchThread thread, final SearchResult search, boolean showCaptcha) {
if (search == null) {
return search;
@@ -1265,12 +719,12 @@ public class cgBase {
final String url = search.getUrl();
if (StringUtils.isBlank(url)) {
- Log.e(Settings.tag, "cgeoBase.searchByNextPage: No url found");
+ Log.e("cgeoBase.searchByNextPage: No url found");
return search;
}
- if (isEmpty(viewstates)) {
- Log.e(Settings.tag, "cgeoBase.searchByNextPage: No viewstate given");
+ if (Login.isEmpty(viewstates)) {
+ Log.e("cgeoBase.searchByNextPage: No viewstate given");
return search;
}
@@ -1282,33 +736,25 @@ public class cgBase {
"__EVENTARGUMENT", "");
Login.putViewstates(params, viewstates);
- String page = Network.getResponseData(Network.postRequest(uri, params));
+ final String page = Login.postRequestLogged(uri, params);
if (!Login.getLoginStatus(page)) {
- final StatusCode loginState = Login.login();
- if (loginState == StatusCode.NO_ERROR) {
- page = Network.getResponseData(Network.postRequest(uri, params));
- } else if (loginState == StatusCode.NO_LOGIN_INFO_STORED) {
- Log.i(Settings.tag, "Working as guest.");
- } else {
- search.setError(loginState);
- Log.e(Settings.tag, "cgeoBase.searchByNextPage: Can not log in geocaching");
- return search;
- }
+ Log.e("cgeoBase.postLogTrackable: Can not log in geocaching");
+ return search;
}
if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.searchByNextPage: No data from server");
+ Log.e("cgeoBase.searchByNextPage: No data from server");
return search;
}
final SearchResult searchResult = parseSearch(thread, url, page, showCaptcha);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) {
- Log.e(Settings.tag, "cgeoBase.searchByNextPage: No cache parsed");
+ Log.e("cgeoBase.searchByNextPage: No cache parsed");
return search;
}
// save to application
- search.setError(searchResult.error);
+ search.setError(searchResult.getError());
search.setViewstates(searchResult.viewstates);
for (String geocode : searchResult.getGeocodes()) {
search.addGeocode(geocode);
@@ -1316,30 +762,25 @@ public class cgBase {
return search;
}
- public static SearchResult searchByGeocode(final String geocode, final String guid, final int listId, final boolean forceReload, final CancellableHandler handler) {
- if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) {
- Log.e(Settings.tag, "cgeoBase.searchByGeocode: No geocode nor guid given");
- return null;
- }
-
- cgeoapplication app = cgeoapplication.getInstance();
- if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) {
- final SearchResult search = new SearchResult();
- final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : app.getGeocode(guid);
- search.addGeocode(realGeocode);
- return search;
- }
-
- // if we have no geocode, we can't dynamically select the handler, but must explicitly use GC
- if (geocode == null && guid != null) {
- return GCConnector.getInstance().searchByGeocode(null, guid, app, handler);
+ /**
+ * Possibly hide caches found or hidden by user. This mutates its params argument when possible.
+ *
+ * @param params
+ * the parameters to mutate, or null to create a new Parameters if needed
+ * @param my
+ * @param addF
+ * @return the original params if not null, maybe augmented with f=1, or a new Parameters with f=1 or null otherwise
+ */
+ public static Parameters addFToParams(final Parameters params, final boolean my, final boolean addF) {
+ if (!my && Settings.isExcludeMyCaches() && addF) {
+ if (params == null) {
+ return new Parameters("f", "1");
+ }
+ params.put("f", "1");
+ Log.i("Skipping caches found or hidden by user.");
}
- return ConnectorFactory.getConnector(geocode).searchByGeocode(geocode, guid, app, handler);
- }
-
- public static SearchResult searchByStored(final Geopoint coords, final CacheType cacheType, final int list) {
- return cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, cacheType, list);
+ return params;
}
/**
@@ -1357,16 +798,16 @@ public class cgBase {
final String uri = "http://www.geocaching.com/seek/nearest.aspx";
final String fullUri = uri + "?" + addFToParams(params, false, true);
- String page = Network.requestLogged(uri, params, false, my, true);
+ final String page = Login.getRequestLogged(uri, addFToParams(params, my, true));
if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.searchByAny: No data from server");
+ Log.e("cgeoBase.searchByAny: No data from server");
return null;
}
final SearchResult searchResult = parseSearch(thread, fullUri, page, showCaptcha);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) {
- Log.e(Settings.tag, "cgeoBase.searchByAny: No cache parsed");
+ Log.e("cgeoBase.searchByAny: No cache parsed");
return searchResult;
}
@@ -1384,7 +825,7 @@ public class cgBase {
public static SearchResult searchByKeyword(final cgSearchThread thread, final String keyword, final CacheType cacheType, final boolean showCaptcha) {
if (StringUtils.isBlank(keyword)) {
- Log.e(Settings.tag, "cgeoBase.searchByKeyword: No keyword given");
+ Log.e("cgeoBase.searchByKeyword: No keyword given");
return null;
}
@@ -1394,7 +835,7 @@ public class cgBase {
public static SearchResult searchByUsername(final cgSearchThread thread, final String userName, final CacheType cacheType, final boolean showCaptcha) {
if (StringUtils.isBlank(userName)) {
- Log.e(Settings.tag, "cgeoBase.searchByUsername: No user name given");
+ Log.e("cgeoBase.searchByUsername: No user name given");
return null;
}
@@ -1403,7 +844,7 @@ public class cgBase {
boolean my = false;
if (userName.equalsIgnoreCase(Settings.getLogin().left)) {
my = true;
- Log.i(Settings.tag, "cgBase.searchByUsername: Overriding users choice, downloading all caches.");
+ Log.i("cgBase.searchByUsername: Overriding users choice, downloading all caches.");
}
return searchByAny(thread, cacheType, my, showCaptcha, params);
@@ -1411,7 +852,7 @@ public class cgBase {
public static SearchResult searchByOwner(final cgSearchThread thread, final String userName, final CacheType cacheType, final boolean showCaptcha) {
if (StringUtils.isBlank(userName)) {
- Log.e(Settings.tag, "cgeoBase.searchByOwner: No user name given");
+ Log.e("cgeoBase.searchByOwner: No user name given");
return null;
}
@@ -1421,7 +862,7 @@ public class cgBase {
public static cgTrackable searchTrackable(final String geocode, final String guid, final String id) {
if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid) && StringUtils.isBlank(id)) {
- Log.w(Settings.tag, "cgeoBase.searchTrackable: No geocode nor guid nor id given");
+ Log.w("cgeoBase.searchTrackable: No geocode nor guid nor id given");
return null;
}
@@ -1437,16 +878,16 @@ public class cgBase {
params.put("id", id);
}
- String page = Network.requestLogged("http://www.geocaching.com/track/details.aspx", params, false, false, false);
+ final String page = Login.getRequestLogged("http://www.geocaching.com/track/details.aspx", params);
if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.searchTrackable: No data from server");
+ Log.e("cgeoBase.searchTrackable: No data from server");
return trackable;
}
trackable = parseTrackable(page, cgeoapplication.getInstance(), geocode);
if (trackable == null) {
- Log.e(Settings.tag, "cgeoBase.searchTrackable: No trackable parsed");
+ Log.e("cgeoBase.searchTrackable: No trackable parsed");
return null;
}
@@ -1455,14 +896,14 @@ public class cgBase {
public static StatusCode postLog(final String geocode, final String cacheid, final String[] viewstates,
final LogType logType, final int year, final int month, final int day,
- final String log, final List<cgTrackableLog> trackables) {
- if (isEmpty(viewstates)) {
- Log.e(Settings.tag, "cgeoBase.postLog: No viewstate given");
+ final String log, final List<TrackableLog> trackables) {
+ if (Login.isEmpty(viewstates)) {
+ Log.e("cgeoBase.postLog: No viewstate given");
return StatusCode.LOG_POST_ERROR;
}
if (StringUtils.isBlank(log)) {
- Log.e(Settings.tag, "cgeoBase.postLog: No log text given");
+ Log.e("cgeoBase.postLog: No log text given");
return StatusCode.NO_LOG_TEXT;
}
@@ -1485,9 +926,9 @@ public class cgBase {
final String logInfo = logUpdated.toString().replace("\n", "\r\n").trim(); // windows' eol and remove leading and trailing whitespaces
if (trackables != null) {
- Log.i(Settings.tag, "Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + logInfo + "; trackables: " + trackables.size());
+ Log.i("Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + logInfo + "; trackables: " + trackables.size());
} else {
- Log.i(Settings.tag, "Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + logInfo + "; trackables: 0");
+ Log.i("Trying to post log for cache #" + cacheid + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + logInfo + "; trackables: 0");
}
final Parameters params = new Parameters(
@@ -1506,7 +947,7 @@ public class cgBase {
if (trackables != null && !trackables.isEmpty()) { // we have some trackables to proceed
final StringBuilder hdnSelected = new StringBuilder();
- for (final cgTrackableLog tb : trackables) {
+ for (final TrackableLog tb : trackables) {
if (tb.action != LogTypeTrackable.DO_NOTHING) {
hdnSelected.append(Integer.toString(tb.id));
hdnSelected.append(tb.action.action);
@@ -1519,20 +960,10 @@ public class cgBase {
}
final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/seek/log.aspx").encodedQuery("ID=" + cacheid).build().toString();
- String page = Network.getResponseData(Network.postRequest(uri, params));
+ String page = Login.postRequestLogged(uri, params);
if (!Login.getLoginStatus(page)) {
- final StatusCode loginState = Login.login();
- if (loginState == StatusCode.NO_ERROR) {
- page = Network.getResponseData(Network.postRequest(uri, params));
- } else {
- Log.e(Settings.tag, "cgeoBase.postLog: Can not log in geocaching (error: " + loginState + ")");
- return loginState;
- }
- }
-
- if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.postLog: No data from server");
- return StatusCode.NO_DATA_FROM_SERVER;
+ Log.e("cgeoBase.postLogTrackable: Can not log in geocaching");
+ return StatusCode.NOT_LOGGED_IN;
}
// maintenance, archived needs to be confirmed
@@ -1543,8 +974,8 @@ public class cgBase {
if (matcher.find() && matcher.groupCount() > 0) {
final String[] viewstatesConfirm = Login.getViewstates(page);
- if (isEmpty(viewstatesConfirm)) {
- Log.e(Settings.tag, "cgeoBase.postLog: No viewstate for confirm log");
+ if (Login.isEmpty(viewstatesConfirm)) {
+ Log.e("cgeoBase.postLog: No viewstate for confirm log");
return StatusCode.LOG_POST_ERROR;
}
@@ -1559,8 +990,8 @@ public class cgBase {
if (trackables != null && !trackables.isEmpty()) { // we have some trackables to proceed
final StringBuilder hdnSelected = new StringBuilder();
- for (cgTrackableLog tb : trackables) {
- String ctl = null;
+ for (TrackableLog tb : trackables) {
+ String ctl;
final String action = Integer.toString(tb.id) + tb.action.action;
if (tb.ctl < 10) {
@@ -1583,14 +1014,14 @@ public class cgBase {
page = Network.getResponseData(Network.postRequest(uri, params));
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeoBase.postLog.confim: " + e.toString());
+ Log.e("cgeoBase.postLog.confim: " + e.toString());
}
try {
final Matcher matcherOk = GCConstants.PATTERN_OK1.matcher(page);
if (matcherOk.find()) {
- Log.i(Settings.tag, "Log successfully posted to cache #" + cacheid);
+ Log.i("Log successfully posted to cache #" + cacheid);
if (geocode != null) {
cgeoapplication.getInstance().saveVisitDate(geocode);
@@ -1604,26 +1035,26 @@ public class cgBase {
return StatusCode.NO_ERROR;
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeoBase.postLog.check: " + e.toString());
+ Log.e("cgeoBase.postLog.check: " + e.toString());
}
- Log.e(Settings.tag, "cgeoBase.postLog: Failed to post log because of unknown error");
+ Log.e("cgeoBase.postLog: Failed to post log because of unknown error");
return StatusCode.LOG_POST_ERROR;
}
public static StatusCode postLogTrackable(final String tbid, final String trackingCode, final String[] viewstates,
final LogType logType, final int year, final int month, final int day, final String log) {
- if (isEmpty(viewstates)) {
- Log.e(Settings.tag, "cgeoBase.postLogTrackable: No viewstate given");
+ if (Login.isEmpty(viewstates)) {
+ Log.e("cgeoBase.postLogTrackable: No viewstate given");
return StatusCode.LOG_POST_ERROR;
}
if (StringUtils.isBlank(log)) {
- Log.e(Settings.tag, "cgeoBase.postLogTrackable: No log text given");
+ Log.e("cgeoBase.postLogTrackable: No log text given");
return StatusCode.NO_LOG_TEXT;
}
- Log.i(Settings.tag, "Trying to post log for trackable #" + trackingCode + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log);
+ Log.i("Trying to post log for trackable #" + trackingCode + " - action: " + logType + "; date: " + year + "." + month + "." + day + ", log: " + log);
final String logInfo = log.replace("\n", "\r\n"); // windows' eol
@@ -1649,34 +1080,24 @@ public class cgBase {
"ctl00$ContentBody$uxVistOtherListingGC", "");
final String uri = new Uri.Builder().scheme("http").authority("www.geocaching.com").path("/track/log.aspx").encodedQuery("wid=" + tbid).build().toString();
- String page = Network.getResponseData(Network.postRequest(uri, params));
+ final String page = Login.postRequestLogged(uri, params);
if (!Login.getLoginStatus(page)) {
- final StatusCode loginState = Login.login();
- if (loginState == StatusCode.NO_ERROR) {
- page = Network.getResponseData(Network.postRequest(uri, params));
- } else {
- Log.e(Settings.tag, "cgeoBase.postLogTrackable: Can not log in geocaching (error: " + loginState + ")");
- return loginState;
- }
- }
-
- if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.postLogTrackable: No data from server");
- return StatusCode.NO_DATA_FROM_SERVER;
+ Log.e("cgeoBase.postLogTrackable: Can not log in geocaching");
+ return StatusCode.NOT_LOGGED_IN;
}
try {
final Matcher matcherOk = GCConstants.PATTERN_OK2.matcher(page);
if (matcherOk.find()) {
- Log.i(Settings.tag, "Log successfully posted to trackable #" + trackingCode);
+ Log.i("Log successfully posted to trackable #" + trackingCode);
return StatusCode.NO_ERROR;
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeoBase.postLogTrackable.check: " + e.toString());
+ Log.e("cgeoBase.postLogTrackable.check: " + e.toString());
}
- Log.e(Settings.tag, "cgeoBase.postLogTrackable: Failed to post log because of unknown error");
+ Log.e("cgeoBase.postLogTrackable: Failed to post log because of unknown error");
return StatusCode.LOG_POST_ERROR;
}
@@ -1689,19 +1110,19 @@ public class cgBase {
*/
public static int addToWatchlist(final cgCache cache) {
final String uri = "http://www.geocaching.com/my/watchlist.aspx?w=" + cache.getCacheId();
- String page = Network.postRequestLogged(uri);
+ String page = Login.postRequestLogged(uri, null);
if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgBase.addToWatchlist: No data from server");
+ Log.e("cgBase.addToWatchlist: No data from server");
return -1; // error
}
boolean guidOnPage = cache.isGuidContainedInPage(page);
if (guidOnPage) {
- Log.i(Settings.tag, "cgBase.addToWatchlist: cache is on watchlist");
+ Log.i("cgBase.addToWatchlist: cache is on watchlist");
cache.setOnWatchlist(true);
} else {
- Log.e(Settings.tag, "cgBase.addToWatchlist: cache is not on watchlist");
+ Log.e("cgBase.addToWatchlist: cache is not on watchlist");
}
return guidOnPage ? 1 : -1; // on watchlist (=added) / else: error
}
@@ -1715,10 +1136,10 @@ public class cgBase {
*/
public static int removeFromWatchlist(final cgCache cache) {
final String uri = "http://www.geocaching.com/my/watchlist.aspx?ds=1&action=rem&id=" + cache.getCacheId();
- String page = Network.postRequestLogged(uri);
+ String page = Login.postRequestLogged(uri, null);
if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgBase.removeFromWatchlist: No data from server");
+ Log.e("cgBase.removeFromWatchlist: No data from server");
return -1; // error
}
@@ -1732,273 +1153,424 @@ public class cgBase {
page = Network.getResponseData(Network.postRequest(uri, params));
boolean guidOnPage = cache.isGuidContainedInPage(page);
if (!guidOnPage) {
- Log.i(Settings.tag, "cgBase.removeFromWatchlist: cache removed from watchlist");
+ Log.i("cgBase.removeFromWatchlist: cache removed from watchlist");
cache.setOnWatchlist(false);
} else {
- Log.e(Settings.tag, "cgBase.removeFromWatchlist: cache not removed from watchlist");
+ Log.e("cgBase.removeFromWatchlist: cache not removed from watchlist");
}
return guidOnPage ? -1 : 0; // on watchlist (=error) / not on watchlist
}
/**
- * Possibly hide caches found or hidden by user. This mutates its params argument when possible.
+ * Parse a trackable HTML description into a cgTrackable object
*
- * @param params
- * the parameters to mutate, or null to create a new Parameters if needed
- * @param my
- * @param addF
- * @return the original params if not null, maybe augmented with f=1, or a new Parameters with f=1 or null otherwise
+ * @param page
+ * the HTML page to parse, already processed through {@link BaseUtils#replaceWhitespace}
+ * @param app
+ * if not null, the application to use to save the trackable
+ * @return the parsed trackable, or null if none could be parsed
*/
- public static Parameters addFToParams(final Parameters params, final boolean my, final boolean addF) {
- if (!my && Settings.isExcludeMyCaches() && addF) {
- if (params == null) {
- return new Parameters("f", "1");
- }
- params.put("f", "1");
- Log.i(Settings.tag, "Skipping caches found or hidden by user.");
+ public static cgTrackable parseTrackable(final String page, final cgeoapplication app, final String possibleTrackingcode) {
+ if (StringUtils.isBlank(page)) {
+ Log.e("cgeoBase.parseTrackable: No page given");
+ return null;
}
- return params;
- }
+ final cgTrackable trackable = new cgTrackable();
+
+ // trackable geocode
+ trackable.setGeocode(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GEOCODE, true, trackable.getGeocode()).toUpperCase());
- public static void storeCache(Activity activity, cgCache origCache, String geocode, int listId, CancellableHandler handler) {
+ // trackable id
+ trackable.setGuid(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GUID, true, trackable.getGuid()));
+
+ // trackable icon
+ trackable.setIconUrl(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ICON, true, trackable.getIconUrl()));
+
+ // trackable name
+ trackable.setName(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_NAME, true, trackable.getName()));
+
+ // trackable type
+ if (StringUtils.isNotBlank(trackable.getName())) {
+ trackable.setType(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_TYPE, true, trackable.getType()));
+ }
+
+ // trackable owner name
try {
- cgCache cache;
- // get cache details, they may not yet be complete
- if (origCache != null) {
- // only reload the cache, if it was already stored or has not all details (by checking the description)
- if (origCache.getListId() >= StoredList.STANDARD_LIST_ID || StringUtils.isBlank(origCache.getDescription())) {
- final SearchResult search = searchByGeocode(origCache.getGeocode(), null, listId, false, null);
- cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
- } else {
- cache = origCache;
- }
- } else if (StringUtils.isNotBlank(geocode)) {
- final SearchResult search = searchByGeocode(geocode, null, listId, false, null);
- cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
- } else {
- cache = null;
+ final Matcher matcherOwner = GCConstants.PATTERN_TRACKABLE_OWNER.matcher(page);
+ if (matcherOwner.find() && matcherOwner.groupCount() > 0) {
+ trackable.setOwnerGuid(matcherOwner.group(1));
+ trackable.setOwner(matcherOwner.group(2).trim());
}
+ } catch (Exception e) {
+ // failed to parse trackable owner name
+ Log.w("cgeoBase.parseTrackable: Failed to parse trackable owner name");
+ }
- if (cache == null) {
- if (handler != null) {
- handler.sendMessage(Message.obtain());
- }
+ // trackable origin
+ trackable.setOrigin(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_ORIGIN, true, trackable.getOrigin()));
- return;
+ // trackable spotted
+ try {
+ final Matcher matcherSpottedCache = GCConstants.PATTERN_TRACKABLE_SPOTTEDCACHE.matcher(page);
+ if (matcherSpottedCache.find() && matcherSpottedCache.groupCount() > 0) {
+ trackable.setSpottedGuid(matcherSpottedCache.group(1));
+ trackable.setSpottedName(matcherSpottedCache.group(2).trim());
+ trackable.setSpottedType(cgTrackable.SPOTTED_CACHE);
}
- if (CancellableHandler.isCancelled(handler)) {
- return;
+ final Matcher matcherSpottedUser = GCConstants.PATTERN_TRACKABLE_SPOTTEDUSER.matcher(page);
+ if (matcherSpottedUser.find() && matcherSpottedUser.groupCount() > 0) {
+ trackable.setSpottedGuid(matcherSpottedUser.group(1));
+ trackable.setSpottedName(matcherSpottedUser.group(2).trim());
+ trackable.setSpottedType(cgTrackable.SPOTTED_USER);
}
- final HtmlImage imgGetter = new HtmlImage(activity, cache.getGeocode(), false, listId, true);
-
- // store images from description
- if (StringUtils.isNotBlank(cache.getDescription())) {
- Html.fromHtml(cache.getDescription(), imgGetter, null);
+ if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDUNKNOWN)) {
+ trackable.setSpottedType(cgTrackable.SPOTTED_UNKNOWN);
}
- if (CancellableHandler.isCancelled(handler)) {
- return;
+ if (BaseUtils.matches(page, GCConstants.PATTERN_TRACKABLE_SPOTTEDOWNER)) {
+ trackable.setSpottedType(cgTrackable.SPOTTED_OWNER);
}
+ } catch (Exception e) {
+ // failed to parse trackable last known place
+ Log.w("cgeoBase.parseTrackable: Failed to parse trackable last known place");
+ }
- // store spoilers
- if (CollectionUtils.isNotEmpty(cache.getSpoilers())) {
- for (cgImage oneSpoiler : cache.getSpoilers()) {
- imgGetter.getDrawable(oneSpoiler.getUrl());
+ // released date - can be missing on the page
+ try {
+ String releaseString = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_RELEASES, false, null);
+ if (releaseString != null) {
+ trackable.setReleased(dateTbIn1.parse(releaseString));
+ if (trackable.getReleased() == null) {
+ trackable.setReleased(dateTbIn2.parse(releaseString));
}
}
+ } catch (ParseException e1) {
+ trackable.setReleased(null);
+ }
- if (CancellableHandler.isCancelled(handler)) {
- return;
- }
+ // trackable distance
+ final String distance = BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_DISTANCE, false, null);
+ if (null != distance) {
+ trackable.setDistance(DistanceParser.parseDistance(distance, Settings.isUseMetricUnits()));
+ }
- // store images from logs
- if (Settings.isStoreLogImages()) {
- for (cgLog log : cache.getLogs(true)) {
- if (CollectionUtils.isNotEmpty(log.logImages)) {
- for (cgImage oneLogImg : log.logImages) {
- imgGetter.getDrawable(oneLogImg.getUrl());
- }
- }
+ // trackable goal
+ trackable.setGoal(BaseUtils.getMatch(page, GCConstants.PATTERN_TRACKABLE_GOAL, true, trackable.getGoal()));
+
+ // trackable details & image
+ try {
+ final Matcher matcherDetailsImage = GCConstants.PATTERN_TRACKABLE_DETAILSIMAGE.matcher(page);
+ if (matcherDetailsImage.find() && matcherDetailsImage.groupCount() > 0) {
+ final String image = StringUtils.trim(matcherDetailsImage.group(3));
+ final String details = StringUtils.trim(matcherDetailsImage.group(4));
+
+ if (StringUtils.isNotEmpty(image)) {
+ trackable.setImage(image);
+ }
+ if (StringUtils.isNotEmpty(details) && !StringUtils.equals(details, "No additional details available.")) {
+ trackable.setDetails(details);
}
}
+ } catch (Exception e) {
+ // failed to parse trackable details & image
+ Log.w("cgeoBase.parseTrackable: Failed to parse trackable details & image");
+ }
- if (CancellableHandler.isCancelled(handler)) {
- return;
- }
+ // trackable logs
+ try {
+ final Matcher matcherLogs = GCConstants.PATTERN_TRACKABLE_LOG.matcher(page);
+ /*
+ * 1. Type (img)
+ * 2. Date
+ * 3. Author
+ * 4. Cache-GUID
+ * 5. <ignored> (strike-through property for ancien caches)
+ * 6. Cache-name
+ * 7. Logtext
+ */
+ while (matcherLogs.find()) {
+ long date = 0;
+ try {
+ date = Login.parseGcCustomDate(matcherLogs.group(2)).getTime();
+ } catch (ParseException e) {
+ }
- // store map previews
- StaticMapsProvider.downloadMaps(cache, activity);
+ final LogEntry logDone = new LogEntry(
+ Html.fromHtml(matcherLogs.group(3)).toString().trim(),
+ date,
+ LogType.getByIconName(matcherLogs.group(1)),
+ matcherLogs.group(7).trim());
- if (CancellableHandler.isCancelled(handler)) {
- return;
- }
+ if (matcherLogs.group(4) != null && matcherLogs.group(6) != null) {
+ logDone.cacheGuid = matcherLogs.group(4);
+ logDone.cacheName = matcherLogs.group(6);
+ }
- cache.setListId(listId);
- cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
+ // Apply the pattern for images in a trackable log entry against each full log (group(0))
+ final Matcher matcherLogImages = GCConstants.PATTERN_TRACKABLE_LOG_IMAGES.matcher(matcherLogs.group(0));
+ /*
+ * 1. Image URL
+ * 2. Image title
+ */
+ while (matcherLogImages.find()) {
+ final cgImage logImage = new cgImage(matcherLogImages.group(1), matcherLogImages.group(2));
+ logDone.addLogImage(logImage);
+ }
- if (handler != null) {
- handler.sendMessage(Message.obtain());
+ trackable.getLogs().add(logDone);
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.storeCache");
+ // failed to parse logs
+ Log.w("cgeoBase.parseCache: Failed to parse cache logs" + e.toString());
+ }
+
+ // trackingcode
+ if (!StringUtils.equalsIgnoreCase(trackable.getGeocode(), possibleTrackingcode)) {
+ trackable.setTrackingcode(possibleTrackingcode);
}
+
+ if (app != null) {
+ app.saveTrackable(trackable);
+ }
+
+ return trackable;
}
- public static void dropCache(final cgCache cache, final Handler handler) {
+ /**
+ * Load logs from a cache details page.
+ *
+ * @param page
+ * the text of the details page
+ * @param cache
+ * the cache object to put the logs in
+ * @param friends
+ * retrieve friend logs
+ */
+ private static List<LogEntry> loadLogsFromDetails(final String page, final cgCache cache, final boolean friends, final boolean getDataFromPage) {
+ String rawResponse;
+
+ if (!getDataFromPage) {
+ final Matcher userTokenMatcher = GCConstants.PATTERN_USERTOKEN2.matcher(page);
+ if (!userTokenMatcher.find()) {
+ Log.e("cgBase.loadLogsFromDetails: unable to extract userToken");
+ return null;
+ }
+
+ final String userToken = userTokenMatcher.group(1);
+ final Parameters params = new Parameters(
+ "tkn", userToken,
+ "idx", "1",
+ "num", String.valueOf(GCConstants.NUMBER_OF_LOGS),
+ "decrypt", "true",
+ // "sp", Boolean.toString(personal), // personal logs
+ "sf", Boolean.toString(friends));
+
+ final HttpResponse response = Network.getRequest("http://www.geocaching.com/seek/geocache.logbook", params);
+ if (response == null) {
+ Log.e("cgBase.loadLogsFromDetails: cannot log logs, response is null");
+ return null;
+ }
+ final int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != 200) {
+ Log.e("cgBase.loadLogsFromDetails: error " + statusCode + " when requesting log information");
+ return null;
+ }
+ rawResponse = Network.getResponseData(response);
+ if (rawResponse == null) {
+ Log.e("cgBase.loadLogsFromDetails: unable to read whole response");
+ return null;
+ }
+ } else {
+ // extract embedded JSON data from page
+ rawResponse = BaseUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, "");
+ }
+
+ List<LogEntry> logs = new ArrayList<LogEntry>();
+
try {
- cgeoapplication.getInstance().markDropped(cache.getGeocode());
- cgeoapplication.getInstance().removeCache(cache.getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE));
+ final JSONObject resp = new JSONObject(rawResponse);
+ if (!resp.getString("status").equals("success")) {
+ Log.e("cgBase.loadLogsFromDetails: status is " + resp.getString("status"));
+ return null;
+ }
- handler.sendMessage(Message.obtain());
- } catch (Exception e) {
- Log.e(Settings.tag, "cgBase.dropCache: " + e.toString());
+ final JSONArray data = resp.getJSONArray("data");
+
+ for (int index = 0; index < data.length(); index++) {
+ final JSONObject entry = data.getJSONObject(index);
+
+ // FIXME: use the "LogType" field instead of the "LogTypeImage" one.
+ final String logIconNameExt = entry.optString("LogTypeImage", ".gif");
+ final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4);
+
+ long date = 0;
+ try {
+ date = Login.parseGcCustomDate(entry.getString("Visited")).getTime();
+ } catch (ParseException e) {
+ Log.e("GCParser.loadLogsFromDetails: failed to parse log date.");
+ }
+
+ final LogEntry logDone = new LogEntry(
+ entry.getString("UserName"),
+ date,
+ LogType.getByIconName(logIconName),
+ entry.getString("LogText"));
+ logDone.found = entry.getInt("GeocacheFindCount");
+ logDone.friend = friends;
+
+ final JSONArray images = entry.getJSONArray("Images");
+ for (int i = 0; i < images.length(); i++) {
+ final JSONObject image = images.getJSONObject(i);
+ String url = "http://img.geocaching.com/cache/log/" + image.getString("FileName");
+ String title = image.getString("Name");
+ final cgImage logImage = new cgImage(url, title);
+ logDone.addLogImage(logImage);
+ }
+
+ logs.add(logDone);
+ }
+ } catch (JSONException e) {
+ // failed to parse logs
+ Log.w("cgBase.loadLogsFromDetails: Failed to parse cache logs", e);
}
- }
- public static boolean runNavigation(Activity activity, Resources res, Settings settings, final Geopoint coords) {
- return runNavigation(activity, res, settings, coords, null);
+ return logs;
}
- public static boolean runNavigation(Activity activity, Resources res, Settings settings, final Geopoint coords, final Geopoint coordsNow) {
- if (activity == null) {
- return false;
- }
- if (settings == null) {
- return false;
+ public static List<LogType> parseTypes(String page) {
+ if (StringUtils.isEmpty(page)) {
+ return null;
}
- // Google Navigation
- if (Settings.isUseGoogleNavigation()) {
- try {
- activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:ll=" + coords.getLatitude() + "," + coords.getLongitude())));
+ final List<LogType> types = new ArrayList<LogType>();
- return true;
- } catch (Exception e) {
- // nothing
+ final Matcher typeBoxMatcher = GCConstants.PATTERN_TYPEBOX.matcher(page);
+ String typesText = null;
+ if (typeBoxMatcher.find()) {
+ if (typeBoxMatcher.groupCount() > 0) {
+ typesText = typeBoxMatcher.group(1);
}
}
- // Google Maps Directions
- try {
- if (coordsNow != null) {
- activity.startActivity(new Intent(Intent.ACTION_VIEW,
- Uri.parse("http://maps.google.com/maps?f=d&saddr=" + coordsNow.getLatitude() + "," + coordsNow.getLongitude() +
- "&daddr=" + coords.getLatitude() + "," + coords.getLongitude())));
- } else {
- activity.startActivity(new Intent(Intent.ACTION_VIEW,
- Uri.parse("http://maps.google.com/maps?f=d&daddr=" + coords.getLatitude() + "," + coords.getLongitude())));
+ if (typesText != null) {
+
+ final Matcher typeMatcher = GCConstants.PATTERN_TYPE2.matcher(typesText);
+ while (typeMatcher.find()) {
+ if (typeMatcher.groupCount() > 1) {
+ final int type = Integer.parseInt(typeMatcher.group(2));
+
+ if (type > 0) {
+ types.add(LogType.getById(type));
+ }
+ }
}
+ }
- return true;
- } catch (Exception e) {
- // nothing
+ return types;
+ }
+
+ public static List<TrackableLog> parseTrackableLog(final String page) {
+ if (StringUtils.isEmpty(page)) {
+ return null;
}
- Log.i(Settings.tag, "cgBase.runNavigation: No navigation application available.");
+ String table = StringUtils.substringBetween(page, "<table id=\"tblTravelBugs\"", "</table>");
- if (res != null) {
- ActivityMixin.showToast(activity, res.getString(R.string.err_navigation_no));
+ // if no trackables are currently in the account, the table is not available, so return an empty list instead of null
+ if (StringUtils.isBlank(table)) {
+ return Collections.emptyList();
}
- return false;
- }
+ table = StringUtils.substringBetween(table, "<tbody>", "</tbody>");
+ if (StringUtils.isBlank(table)) {
+ Log.e("cgeoBase.parseTrackableLog: tbody not found on page");
+ return null;
+ }
- /**
- * Generate a time string according to system-wide settings (locale, 12/24 hour)
- * such as "13:24".
- *
- * @param date
- * milliseconds since the epoch
- * @return the formatted string
- */
- public static String formatTime(long date) {
- return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_TIME);
- }
+ final List<TrackableLog> trackableLogs = new ArrayList<TrackableLog>();
- /**
- * Generate a date string according to system-wide settings (locale, date format)
- * such as "20 December" or "20 December 2010". The year will only be included when necessary.
- *
- * @param date
- * milliseconds since the epoch
- * @return the formatted string
- */
- public static String formatDate(long date) {
- return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE);
- }
+ final Matcher trackableMatcher = GCConstants.PATTERN_TRACKABLE.matcher(page);
+ while (trackableMatcher.find()) {
+ if (trackableMatcher.groupCount() > 0) {
- /**
- * Generate a date string according to system-wide settings (locale, date format)
- * such as "20 December 2010". The year will always be included, making it suitable
- * to generate long-lived log entries.
- *
- * @param date
- * milliseconds since the epoch
- * @return the formatted string
- */
- public static String formatFullDate(long date) {
- return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE
- | DateUtils.FORMAT_SHOW_YEAR);
- }
+ final String trackCode = trackableMatcher.group(1);
+ final String name = Html.fromHtml(trackableMatcher.group(2)).toString();
+ try {
+ final Integer ctl = Integer.valueOf(trackableMatcher.group(3));
+ final Integer id = Integer.valueOf(trackableMatcher.group(5));
+ if (trackCode != null && name != null && ctl != null && id != null) {
+ final TrackableLog entry = new TrackableLog(trackCode, name, id, ctl);
- /**
- * Generate a numeric date string according to system-wide settings (locale, date format)
- * such as "10/20/2010".
- *
- * @param date
- * milliseconds since the epoch
- * @return the formatted string
- */
- public static String formatShortDate(long date) {
- return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE
- | DateUtils.FORMAT_NUMERIC_DATE);
+ Log.i("Trackable in inventory (#" + entry.ctl + "/" + entry.id + "): " + entry.trackCode + " - " + entry.name);
+ trackableLogs.add(entry);
+ }
+ } catch (NumberFormatException e) {
+ Log.e("GCParser.parseTrackableLog", e);
+ }
+ }
+ }
+
+ return trackableLogs;
}
/**
- * Generate a numeric date and time string according to system-wide settings (locale,
- * date format) such as "7 sept. at 12:35".
+ * Insert the right cache type restriction in parameters
*
- * @param context
- * a Context
- * @param date
- * milliseconds since the epoch
- * @return the formatted string
+ * @param params
+ * the parameters to insert the restriction into
+ * @param cacheType
+ * the type of cache, or null to include everything
*/
- public static String formatShortDateTime(Context context, long date) {
- return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL);
+ static private void insertCacheType(final Parameters params, final CacheType cacheType) {
+ params.put("tx", cacheType.guid);
}
- /**
- * Indicates whether the specified action can be used as an intent. This
- * method queries the package manager for installed packages that can
- * respond to an intent with the specified action. If no suitable package is
- * found, this method returns false.
- *
- * @param context
- * The application's environment.
- * @param action
- * The Intent action to check for availability.
- * @param uri
- * The Intent URI to check for availability.
- *
- * @return True if an Intent with the specified action can be sent and
- * responded to, false otherwise.
- */
- public static boolean isIntentAvailable(Context context, String action, Uri uri) {
- final PackageManager packageManager = context.getPackageManager();
- final Intent intent;
- if (uri == null) {
- intent = new Intent(action);
- } else {
- intent = new Intent(action, uri);
+ private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) {
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
+ //cache.setLogs(loadLogsFromDetails(page, cache, false));
+ if (Settings.isFriendLogsWanted()) {
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs);
+ List<LogEntry> allLogs = cache.getLogs();
+ List<LogEntry> friendLogs = loadLogsFromDetails(page, cache, true, false);
+ if (friendLogs != null) {
+ for (LogEntry log : friendLogs) {
+ if (allLogs.contains(log)) {
+ allLogs.get(allLogs.indexOf(log)).friend = true;
+ } else {
+ allLogs.add(log);
+ }
+ }
+ }
+ }
+
+ if (Settings.isElevationWanted()) {
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_elevation);
+ if (cache.getCoords() != null) {
+ cache.setElevation(cache.getCoords().getElevation());
+ }
+ }
+
+ if (Settings.isRatingWanted()) {
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_gcvote);
+ final GCVoteRating rating = GCVote.getRating(cache.getGuid(), cache.getGeocode());
+ if (rating != null) {
+ cache.setRating(rating.getRating());
+ cache.setVotes(rating.getVotes());
+ cache.setMyVote(rating.getMyVote());
+ }
}
- List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
- PackageManager.MATCH_DEFAULT_ONLY);
- return list.size() > 0;
}
}
-
diff --git a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
index 43ca2ce..74e78cc 100644
--- a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
+++ b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
@@ -153,12 +153,10 @@ public abstract class IconDecoder {
}
if ((bitmap.getPixel(x + POSX_FOUND, y + POSY_FOUND) & 0x00FFFFFF) == COLOR_FOUND) {
cache.setFound(true);
- return;
}
} catch (IllegalArgumentException e) {
// intentionally left blank
}
- return;
}
}
diff --git a/main/src/cgeo/geocaching/network/Login.java b/main/src/cgeo/geocaching/connector/gc/Login.java
index be80a19..28b2c6a 100644
--- a/main/src/cgeo/geocaching/network/Login.java
+++ b/main/src/cgeo/geocaching/connector/gc/Login.java
@@ -1,11 +1,15 @@
-package cgeo.geocaching.network;
+package cgeo.geocaching.connector.gc;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
-import cgeo.geocaching.connector.gc.GCConstants;
+import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.network.Cookies;
+import cgeo.geocaching.network.HtmlImage;
+import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.BaseUtils;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
@@ -14,7 +18,6 @@ import org.apache.http.HttpResponse;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
-import android.util.Log;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -32,7 +35,6 @@ public abstract class Login {
// false = not logged in
private static boolean actualLoginStatus = false;
private static String actualUserName = "";
- private static String actualMemberStatus = "";
private static int actualCachesFound = -1;
private static String actualStatus = "";
@@ -61,33 +63,30 @@ public abstract class Login {
final ImmutablePair<String, String> login = Settings.getLogin();
if (login == null || StringUtils.isEmpty(login.left) || StringUtils.isEmpty(login.right)) {
- Login.setActualStatus(cgBase.res.getString(R.string.err_login));
- Log.e(Settings.tag, "cgeoBase.login: No login information stored");
+ Login.setActualStatus(cgeoapplication.getInstance().getString(R.string.err_login));
+ Log.e("cgeoBase.login: No login information stored");
return StatusCode.NO_LOGIN_INFO_STORED;
}
- // res is null during the unit tests
- if (cgBase.res != null) {
- Login.setActualStatus(cgBase.res.getString(R.string.init_login_popup_working));
- }
- HttpResponse loginResponse = Network.request("https://www.geocaching.com/login/default.aspx", null, false, false, false);
+ Login.setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_working));
+ HttpResponse loginResponse = Network.getRequest("https://www.geocaching.com/login/default.aspx");
String loginData = Network.getResponseData(loginResponse);
if (loginResponse != null && loginResponse.getStatusLine().getStatusCode() == 503 && BaseUtils.matches(loginData, GCConstants.PATTERN_MAINTENANCE)) {
return StatusCode.MAINTENANCE;
}
if (StringUtils.isBlank(loginData)) {
- Log.e(Settings.tag, "cgeoBase.login: Failed to retrieve login page (1st)");
+ Log.e("cgeoBase.login: Failed to retrieve login page (1st)");
return StatusCode.CONNECTION_FAILED; // no loginpage
}
if (Login.getLoginStatus(loginData)) {
- Log.i(Settings.tag, "Already logged in Geocaching.com as " + login.left + " (" + getActualMemberStatus() + ')');
+ Log.i("Already logged in Geocaching.com as " + login.left + " (" + Settings.getMemberStatus() + ')');
Login.switchToEnglish(loginData);
return StatusCode.NO_ERROR; // logged in
}
- Network.clearCookies();
+ Cookies.clearCookies();
Settings.setCookieStore(null);
final Parameters params = new Parameters(
@@ -98,8 +97,8 @@ public abstract class Login {
"ctl00$ContentBody$cbRememberMe", "on",
"ctl00$ContentBody$btnSignIn", "Login");
final String[] viewstates = Login.getViewstates(loginData);
- if (cgBase.isEmpty(viewstates)) {
- Log.e(Settings.tag, "cgeoBase.login: Failed to find viewstates");
+ if (isEmpty(viewstates)) {
+ Log.e("cgeoBase.login: Failed to find viewstates");
return StatusCode.LOGIN_PARSE_ERROR; // no viewstates
}
Login.putViewstates(params, viewstates);
@@ -107,38 +106,38 @@ public abstract class Login {
loginResponse = Network.postRequest("https://www.geocaching.com/login/default.aspx", params);
loginData = Network.getResponseData(loginResponse);
- if (StringUtils.isNotBlank(loginData)) {
- if (Login.getLoginStatus(loginData)) {
- Log.i(Settings.tag, "Successfully logged in Geocaching.com as " + login.left + " (" + getActualMemberStatus() + ')');
-
- Login.switchToEnglish(loginData);
- Settings.setCookieStore(Network.dumpCookieStore());
-
- return StatusCode.NO_ERROR; // logged in
- } else {
- if (loginData.contains("Your username/password combination does not match.")) {
- Log.i(Settings.tag, "Failed to log in Geocaching.com as " + login.left + " because of wrong username/password");
- return StatusCode.WRONG_LOGIN_DATA; // wrong login
- } else {
- Log.i(Settings.tag, "Failed to log in Geocaching.com as " + login.left + " for some unknown reason");
- return StatusCode.UNKNOWN_ERROR; // can't login
- }
- }
- } else {
- Log.e(Settings.tag, "cgeoBase.login: Failed to retrieve login page (2nd)");
+ if (StringUtils.isBlank(loginData)) {
+ Log.e("cgeoBase.login: Failed to retrieve login page (2nd)");
// FIXME: should it be CONNECTION_FAILED to match the first attempt?
return StatusCode.COMMUNICATION_ERROR; // no login page
}
+
+ if (Login.getLoginStatus(loginData)) {
+ Log.i("Successfully logged in Geocaching.com as " + login.left + " (" + Settings.getMemberStatus() + ')');
+
+ Login.switchToEnglish(loginData);
+ Settings.setCookieStore(Cookies.dumpCookieStore());
+
+ return StatusCode.NO_ERROR; // logged in
+ }
+
+ if (loginData.contains("Your username/password combination does not match.")) {
+ Log.i("Failed to log in Geocaching.com as " + login.left + " because of wrong username/password");
+ return StatusCode.WRONG_LOGIN_DATA; // wrong login
+ }
+
+ Log.i("Failed to log in Geocaching.com as " + login.left + " for some unknown reason");
+ return StatusCode.UNKNOWN_ERROR; // can't login
}
public static StatusCode logout() {
- HttpResponse logoutResponse = Network.request("https://www.geocaching.com/login/default.aspx?RESET=Y&redir=http%3a%2f%2fwww.geocaching.com%2fdefault.aspx%3f", null, false, false, false);
+ HttpResponse logoutResponse = Network.getRequest("https://www.geocaching.com/login/default.aspx?RESET=Y&redir=http%3a%2f%2fwww.geocaching.com%2fdefault.aspx%3f");
String logoutData = Network.getResponseData(logoutResponse);
if (logoutResponse != null && logoutResponse.getStatusLine().getStatusCode() == 503 && BaseUtils.matches(logoutData, GCConstants.PATTERN_MAINTENANCE)) {
return StatusCode.MAINTENANCE;
}
- Network.clearCookies();
+ Cookies.clearCookies();
Settings.setCookieStore(null);
return StatusCode.NO_ERROR;
}
@@ -171,14 +170,6 @@ public abstract class Login {
actualUserName = userName;
}
- public static String getActualMemberStatus() {
- return actualMemberStatus;
- }
-
- public static void setActualMemberStatus(final String memberStatus) {
- actualMemberStatus = memberStatus;
- }
-
public static int getActualCachesFound() {
return actualCachesFound;
}
@@ -191,21 +182,18 @@ public abstract class Login {
*/
public static boolean getLoginStatus(final String page) {
if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.checkLogin: No page given");
+ Log.e("cgeoBase.checkLogin: No page given");
return false;
}
- // res is null during the unit tests
- if (cgBase.res != null) {
- setActualStatus(cgBase.res.getString(R.string.init_login_popup_ok));
- }
+ setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_ok));
// on every page except login page
setActualLoginStatus(BaseUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME));
if (isActualLoginStatus()) {
setActualUserName(BaseUtils.getMatch(page, GCConstants.PATTERN_LOGIN_NAME, true, "???"));
- setActualMemberStatus(BaseUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, "???"));
setActualCachesFound(Integer.parseInt(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "0").replaceAll("[,.]", "")));
+ Settings.setMemberStatus(BaseUtils.getMatch(page, GCConstants.PATTERN_MEMBER_STATUS, true, null));
return true;
}
@@ -213,28 +201,24 @@ public abstract class Login {
setActualLoginStatus(BaseUtils.matches(page, GCConstants.PATTERN_LOGIN_NAME_LOGIN_PAGE));
if (isActualLoginStatus()) {
setActualUserName(Settings.getUsername());
- setActualMemberStatus(Settings.getMemberStatus());
// number of caches found is not part of this page
return true;
}
- // res is null during the unit tests
- if (cgBase.res != null) {
- setActualStatus(cgBase.res.getString(R.string.init_login_popup_failed));
- }
+ setActualStatus(cgeoapplication.getInstance().getString(R.string.init_login_popup_failed));
return false;
}
private static void switchToEnglish(String previousPage) {
- if (previousPage != null && previousPage.indexOf(ENGLISH) >= 0) {
- Log.i(Settings.tag, "Geocaching.com language already set to English");
+ if (previousPage != null && previousPage.contains(ENGLISH)) {
+ Log.i("Geocaching.com language already set to English");
// get find count
- getLoginStatus(Network.getResponseData(Network.request("http://www.geocaching.com/email/", null, false)));
+ getLoginStatus(Network.getResponseData(Network.getRequest("http://www.geocaching.com/email/")));
} else {
- final String page = Network.getResponseData(Network.request("http://www.geocaching.com/default.aspx", null, false));
+ final String page = Network.getResponseData(Network.getRequest("http://www.geocaching.com/default.aspx"));
getLoginStatus(page);
if (page == null) {
- Log.e(Settings.tag, "Failed to read viewstates to set geocaching.com language");
+ Log.e("Failed to read viewstates to set geocaching.com language");
}
final Parameters params = new Parameters(
"__EVENTTARGET", "ctl00$uxLocaleList$uxLocaleList$ctl00$uxLocaleItem", // switch to english
@@ -242,14 +226,14 @@ public abstract class Login {
Login.transferViewstates(page, params);
final HttpResponse response = Network.postRequest("http://www.geocaching.com/default.aspx", params);
if (!Network.isSuccess(response)) {
- Log.e(Settings.tag, "Failed to set geocaching.com language to English");
+ Log.e("Failed to set geocaching.com language to English");
}
}
}
public static BitmapDrawable downloadAvatarAndGetMemberStatus(final Context context) {
try {
- final String profile = BaseUtils.replaceWhitespace(Network.getResponseData(Network.request("http://www.geocaching.com/my/", null, false)));
+ final String profile = BaseUtils.replaceWhitespace(Network.getResponseData(Network.getRequest("http://www.geocaching.com/my/")));
Settings.setMemberStatus(BaseUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null));
@@ -261,9 +245,9 @@ public abstract class Login {
return imgGetter.getDrawable(avatarURL);
}
// No match? There may be no avatar set by user.
- Log.d(Settings.tag, "No avatar set for user");
+ Log.d("No avatar set for user");
} catch (Exception e) {
- Log.w(Settings.tag, "Error when retrieving user avatar", e);
+ Log.w("Error when retrieving user avatar", e);
}
return null;
}
@@ -273,10 +257,10 @@ public abstract class Login {
*/
public static void detectGcCustomDate() {
- final String result = Network.getResponseData(Network.request("http://www.geocaching.com/account/ManagePreferences.aspx", null, false, false, false));
+ final String result = Network.getResponseData(Network.getRequest("http://www.geocaching.com/account/ManagePreferences.aspx"));
if (null == result) {
- Log.w(Settings.tag, "cgeoBase.detectGcCustomDate: result is null");
+ Log.w("cgeoBase.detectGcCustomDate: result is null");
return;
}
@@ -315,6 +299,24 @@ public abstract class Login {
}
/**
+ * checks if an Array of Strings is empty or not. Empty means:
+ * - Array is null
+ * - or all elements are null or empty strings
+ */
+ public static boolean isEmpty(String[] a) {
+ if (a == null) {
+ return true;
+ }
+
+ for (String s : a) {
+ if (StringUtils.isNotEmpty(s)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* read all viewstates from page
*
* @return String[] with all view states
@@ -333,7 +335,7 @@ public abstract class Login {
try {
count = Integer.parseInt(matcherViewstateCount.group(1));
} catch (NumberFormatException e) {
- Log.e(Settings.tag, "getViewStates", e);
+ Log.e("getViewStates", e);
}
}
@@ -351,7 +353,7 @@ public abstract class Login {
try {
no = Integer.parseInt(sno);
} catch (NumberFormatException e) {
- Log.e(Settings.tag, "getViewStates", e);
+ Log.e("getViewStates", e);
no = 0;
}
}
@@ -389,10 +391,47 @@ public abstract class Login {
putViewstates(params, getViewstates(page));
}
- static public String[] requestViewstates(final String uri, final Parameters params, boolean xContentType, boolean my) {
- final HttpResponse response = Network.request(uri, params, xContentType, my, false);
+ /**
+ * POST HTTP request. Do the request a second time if the user is not logged in
+ *
+ * @param uri
+ * @return
+ */
+ public static String postRequestLogged(final String uri, final Parameters params) {
+ HttpResponse response = Network.postRequest(uri, params);
+ String data = Network.getResponseData(response);
+
+ if (!getLoginStatus(data)) {
+ if (login() == StatusCode.NO_ERROR) {
+ response = Network.postRequest(uri, params);
+ data = Network.getResponseData(response);
+ } else {
+ Log.i("Working as guest.");
+ }
+ }
+ return data;
+ }
+
+ /**
+ * GET HTTP request. Do the request a second time if the user is not logged in
+ *
+ * @param uri
+ * @param params
+ * @return
+ */
+ public static String getRequestLogged(final String uri, final Parameters params) {
+ final String data = Network.getResponseData(Network.getRequest(uri, params));
+
+ if (getLoginStatus(data)) {
+ return data;
+ }
+
+ if (login() == StatusCode.NO_ERROR) {
+ return Network.getResponseData(Network.getRequest(uri, params));
+ }
- return getViewstates(Network.getResponseData(response));
+ Log.w("Working as guest.");
+ return data;
}
}
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java
index 8613787..692f28b 100644
--- a/main/src/cgeo/geocaching/connector/gc/Tile.java
+++ b/main/src/cgeo/geocaching/connector/gc/Tile.java
@@ -1,15 +1,16 @@
package cgeo.geocaching.connector.gc;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.ICoordinates;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpGet;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.util.Log;
import java.io.IOException;
@@ -45,22 +46,16 @@ public class Tile {
private final int tileX;
private final int tileY;
private final int zoomlevel;
+ private final Viewport viewPort;
public Tile(Geopoint origin, int zoomlevel) {
- assert zoomlevel >= ZOOMLEVEL_MIN && zoomlevel <= ZOOMLEVEL_MAX : "zoomlevel out of range";
this.zoomlevel = Math.max(Math.min(zoomlevel, ZOOMLEVEL_MAX), ZOOMLEVEL_MIN);
tileX = calcX(origin);
tileY = calcY(origin);
- }
-
- public Tile(int tileX, int tileY, int zoomlevel) {
- assert zoomlevel >= ZOOMLEVEL_MIN && zoomlevel <= ZOOMLEVEL_MAX : "zoomlevel out of range";
- this.zoomlevel = zoomlevel;
- this.tileX = tileX;
- this.tileY = tileY;
+ viewPort = new Viewport(getCoord(new UTFGridPosition(0, 0)), getCoord(new UTFGridPosition(63, 63)));
}
public int getZoomlevel() {
@@ -141,7 +136,7 @@ public class Tile {
Tile tileRight = new Tile(right, zoom);
if (tileLeft.tileX == tileRight.tileX) {
- zoom = zoom + 1;
+ zoom += 1;
}
return Math.min(zoom, ZOOMLEVEL_MAX);
@@ -161,7 +156,7 @@ public class Tile {
public static int calcZoomLat(final Geopoint bottom, final Geopoint top) {
int zoom = (int) Math.ceil(
- Math.log(2 * Math.PI /
+ Math.log(2.0 * Math.PI /
Math.abs(
asinh(tanGrad(bottom.getLatitude()))
- asinh(tanGrad(top.getLatitude()))
@@ -173,7 +168,7 @@ public class Tile {
Tile tileTop = new Tile(top, zoom);
if (Math.abs(tileBottom.tileY - tileTop.tileY) > 1) {
- zoom = zoom - 1;
+ zoom -= 1;
}
return Math.min(zoom, ZOOMLEVEL_MAX);
@@ -213,26 +208,22 @@ public class Tile {
}
/** Request JSON informations for a tile */
- public static String requestMapInfo(final String url, final String referer) {
- final HttpGet request = new HttpGet(url);
- request.addHeader("Accept", "application/json, text/javascript, */*; q=0.01");
- request.addHeader("Referer", referer);
- request.addHeader("X-Requested-With", "XMLHttpRequest");
- return Network.getResponseData(Network.request(request), false);
+ public static String requestMapInfo(final String url, final Parameters params, final String referer) {
+ return Network.getResponseData(Network.getRequest(url, params, new Parameters("Referer", referer)));
}
/** Request .png image for a tile. */
- public static Bitmap requestMapTile(final String url, final String referer) {
- final HttpGet request = new HttpGet(url);
- request.addHeader("Accept", "image/png,image/*;q=0.8,*/*;q=0.5");
- request.addHeader("Referer", referer);
- request.addHeader("X-Requested-With", "XMLHttpRequest");
- final HttpResponse response = Network.request(request);
+ public static Bitmap requestMapTile(final String url, final Parameters params, final String referer) {
+ final HttpResponse response = Network.getRequest(url, params, new Parameters("Referer", referer));
try {
return response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null;
} catch (IOException e) {
- Log.e(Settings.tag, "cgBase.requestMapTile() " + e.getMessage());
+ Log.e("cgBase.requestMapTile() " + e.getMessage());
}
return null;
}
+
+ public boolean containsPoint(final ICoordinates point) {
+ return viewPort.contains(point);
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java
index 8ed6acd..e4f382b 100644
--- a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java
+++ b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java
@@ -40,8 +40,6 @@ public class ApiOpenCachingConnector extends OpenCachingConnector {
}
final SearchResult searchResult = new SearchResult();
searchResult.addCache(cache);
-
- final SearchResult search = searchResult.filterSearchResults(false, false, Settings.getCacheType());
- return search;
+ return searchResult.filterSearchResults(false, false, Settings.getCacheType());
}
}
diff --git a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java
index 9c3ab4a..165e277 100644
--- a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java
@@ -1,19 +1,20 @@
package cgeo.geocaching.connector.opencaching;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.LogEntry;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgImage;
-import cgeo.geocaching.cgLog;
+import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
+import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter;
-import cgeo.geocaching.geopoint.GeopointParser;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
@@ -22,12 +23,12 @@ import org.json.JSONObject;
import android.net.Uri;
import android.text.Html;
-import android.util.Log;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
@@ -75,13 +76,7 @@ final public class OkapiClient {
return null;
}
- final cgCache cache = parseCache(data);
-
- long time = new Date().getTime();
- cache.setUpdated(time);
- cache.setDetailedUpdate(time);
-
- return cache;
+ return parseCache(data);
}
public static List<cgCache> getCachesAround(final Geopoint center, IConnector connector) {
@@ -117,7 +112,7 @@ final public class OkapiClient {
return caches;
}
} catch (JSONException e) {
- Log.e(Settings.tag, "OkapiClient.parseCaches", e);
+ Log.e("OkapiClient.parseCaches", e);
}
return null;
}
@@ -177,8 +172,14 @@ final public class OkapiClient {
cache.setLogs(parseLogs(response.getJSONArray(CACHE_LATEST_LOGS)));
cache.setHidden(parseDate(response.getString(CACHE_HIDDEN)));
+ cache.setUpdated(System.currentTimeMillis());
+ cache.setDetailedUpdate(cache.getUpdated());
+ cache.setDetailed(true);
+
+ // save full detailed caches
+ cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
} catch (JSONException e) {
- Log.e(Settings.tag, "OkapiClient.parseCache", e);
+ Log.e("OkapiClient.parseCache", e);
}
return cache;
}
@@ -200,22 +201,22 @@ final public class OkapiClient {
return user.getString(USER_USERNAME);
}
- private static List<cgLog> parseLogs(JSONArray logsJSON) {
- List<cgLog> result = null;
+ private static List<LogEntry> parseLogs(JSONArray logsJSON) {
+ List<LogEntry> result = null;
for (int i = 0; i < logsJSON.length(); i++) {
try {
JSONObject logResponse = logsJSON.getJSONObject(i);
- cgLog log = new cgLog();
- log.date = parseDate(logResponse.getString(LOG_DATE)).getTime();
- log.log = logResponse.getString(LOG_COMMENT).trim();
- log.type = parseLogType(logResponse.getString(LOG_TYPE));
- log.author = parseUser(logResponse.getJSONObject(LOG_USER));
+ LogEntry log = new LogEntry(
+ parseUser(logResponse.getJSONObject(LOG_USER)),
+ parseDate(logResponse.getString(LOG_DATE)).getTime(),
+ parseLogType(logResponse.getString(LOG_TYPE)),
+ logResponse.getString(LOG_COMMENT).trim());
if (result == null) {
- result = new ArrayList<cgLog>();
+ result = new ArrayList<LogEntry>();
}
result.add(log);
} catch (JSONException e) {
- Log.e(Settings.tag, "OkapiClient.parseLogs", e);
+ Log.e("OkapiClient.parseLogs", e);
}
}
return result;
@@ -225,7 +226,7 @@ final public class OkapiClient {
if ("Found it".equalsIgnoreCase(logType)) {
return LogType.LOG_FOUND_IT;
}
- else if ("Didn't find it".equalsIgnoreCase(logType)) {
+ if ("Didn't find it".equalsIgnoreCase(logType)) {
return LogType.LOG_DIDNT_FIND_IT;
}
return LogType.LOG_NOTE;
@@ -237,7 +238,7 @@ final public class OkapiClient {
try {
return ISO8601DATEFORMAT.parse(strippedDate);
} catch (ParseException e) {
- Log.e(Settings.tag, "OkapiClient.parseDate", e);
+ Log.e("OkapiClient.parseDate", e);
}
return null;
}
@@ -246,7 +247,7 @@ final public class OkapiClient {
final String latitude = StringUtils.substringBefore(location, "|");
final String longitude = StringUtils.substringAfter(location, "|");
// FIXME: the next line should be a setter at cgCache
- cache.setCoords(GeopointParser.parse(latitude, longitude));
+ cache.setCoords(new Geopoint(latitude, longitude));
}
private static CacheSize getCacheSize(final JSONObject response) {
@@ -257,7 +258,7 @@ final public class OkapiClient {
try {
size = response.getDouble(CACHE_SIZE);
} catch (JSONException e) {
- Log.e(Settings.tag, "OkapiClient.getCacheSize", e);
+ Log.e("OkapiClient.getCacheSize", e);
}
switch ((int) Math.round(size)) {
case 1:
@@ -279,11 +280,14 @@ final public class OkapiClient {
private static CacheType getCacheType(final String cacheType) {
if (cacheType.equalsIgnoreCase("Traditional")) {
return CacheType.TRADITIONAL;
- } else if (cacheType.equalsIgnoreCase("Multi")) {
+ }
+ if (cacheType.equalsIgnoreCase("Multi")) {
return CacheType.MULTI;
- } else if (cacheType.equalsIgnoreCase("Quiz")) {
+ }
+ if (cacheType.equalsIgnoreCase("Quiz")) {
return CacheType.MYSTERY;
- } else if (cacheType.equalsIgnoreCase("Virtual")) {
+ }
+ if (cacheType.equalsIgnoreCase("Virtual")) {
return CacheType.VIRTUAL;
}
return CacheType.UNKNOWN;
diff --git a/main/src/cgeo/geocaching/enumerations/CacheAttribute.java b/main/src/cgeo/geocaching/enumerations/CacheAttribute.java
new file mode 100644
index 0000000..4a502fb
--- /dev/null
+++ b/main/src/cgeo/geocaching/enumerations/CacheAttribute.java
@@ -0,0 +1,140 @@
+package cgeo.geocaching.enumerations;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgeoapplication;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public enum CacheAttribute {
+ UNKNOWN(0, "", R.drawable.attribute__strikethru, 0, 0),
+ DOGS(1, "dogs", R.drawable.attribute_dogs, R.string.attribute_dogs_yes, R.string.attribute_dogs_no),
+ FEE(2, "fee", R.drawable.attribute_fee, R.string.attribute_fee_yes, R.string.attribute_fee_no),
+ RAPPELLING(3, "rappelling", R.drawable.attribute_rappelling, R.string.attribute_rappelling_yes, R.string.attribute_rappelling_no),
+ BOAT(4, "boat", R.drawable.attribute_boat, R.string.attribute_boat_yes, R.string.attribute_boat_no),
+ SCUBA(5, "scuba", R.drawable.attribute_scuba, R.string.attribute_scuba_yes, R.string.attribute_scuba_no),
+ KIDS(6, "kids", R.drawable.attribute_kids, R.string.attribute_kids_yes, R.string.attribute_kids_no),
+ ONEHOUR(7, "onehour", R.drawable.attribute_onehour, R.string.attribute_onehour_yes, R.string.attribute_onehour_no),
+ SCENIC(8, "scenic", R.drawable.attribute_scenic, R.string.attribute_scenic_yes, R.string.attribute_scenic_no),
+ HIKING(9, "hiking", R.drawable.attribute_hiking, R.string.attribute_hiking_yes, R.string.attribute_hiking_no),
+ CLIMBING(10, "climbing", R.drawable.attribute_climbing, R.string.attribute_climbing_yes, R.string.attribute_climbing_no),
+ WADING(11, "wading", R.drawable.attribute_wading, R.string.attribute_wading_yes, R.string.attribute_wading_no),
+ SWIMMING(12, "swimming", R.drawable.attribute_swimming, R.string.attribute_swimming_yes, R.string.attribute_swimming_no),
+ AVAILABLE(13, "available", R.drawable.attribute_available, R.string.attribute_available_yes, R.string.attribute_available_no),
+ NIGHT(14, "night", R.drawable.attribute_night, R.string.attribute_night_yes, R.string.attribute_night_no),
+ WINTER(15, "winter", R.drawable.attribute_winter, R.string.attribute_winter_yes, R.string.attribute_winter_no),
+ POISONOAK(17, "poisonoak", R.drawable.attribute_poisonoak, R.string.attribute_poisonoak_yes, R.string.attribute_poisonoak_no),
+ DANGEROUSANIMALS(18, "dangerousanimals", R.drawable.attribute_dangerousanimals, R.string.attribute_dangerousanimals_yes, R.string.attribute_dangerousanimals_no),
+ TICKS(19, "ticks", R.drawable.attribute_ticks, R.string.attribute_ticks_yes, R.string.attribute_ticks_no),
+ MINE(29, "mine", R.drawable.attribute_mine, R.string.attribute_mine_yes, R.string.attribute_mine_no),
+ CLIFF(21, "cliff", R.drawable.attribute_cliff, R.string.attribute_cliff_yes, R.string.attribute_cliff_no),
+ HUNTING(22, "hunting", R.drawable.attribute_hunting, R.string.attribute_hunting_yes, R.string.attribute_hunting_no),
+ DANGER(23, "danger", R.drawable.attribute_danger, R.string.attribute_danger_yes, R.string.attribute_danger_no),
+ WHEELCHAIR(24, "wheelchair", R.drawable.attribute_wheelchair, R.string.attribute_wheelchair_yes, R.string.attribute_wheelchair_no),
+ PARKING(25, "parking", R.drawable.attribute_parking, R.string.attribute_parking_yes, R.string.attribute_parking_no),
+ PUBLIC(26, "public", R.drawable.attribute_public, R.string.attribute_public_yes, R.string.attribute_public_no),
+ WATER(27, "water", R.drawable.attribute_water, R.string.attribute_water_yes, R.string.attribute_water_no),
+ RESTROOMS(28, "restrooms", R.drawable.attribute_restrooms, R.string.attribute_restrooms_yes, R.string.attribute_restrooms_no),
+ PHONE(29, "phone", R.drawable.attribute_phone, R.string.attribute_phone_yes, R.string.attribute_phone_no),
+ PICNIC(30, "picnic", R.drawable.attribute_picnic, R.string.attribute_picnic_yes, R.string.attribute_picnic_no),
+ CAMPING(31, "camping", R.drawable.attribute_camping, R.string.attribute_camping_yes, R.string.attribute_camping_no),
+ BICYCLES(32, "bicycles", R.drawable.attribute_bicycles, R.string.attribute_bicycles_yes, R.string.attribute_bicycles_no),
+ MOTORCYCLES(33, "motorcycles", R.drawable.attribute_motorcycles, R.string.attribute_motorcycles_yes, R.string.attribute_motorcycles_no),
+ QUADS(34, "quads", R.drawable.attribute_quads, R.string.attribute_quads_yes, R.string.attribute_quads_no),
+ JEEPS(35, "jeeps", R.drawable.attribute_jeeps, R.string.attribute_jeeps_yes, R.string.attribute_jeeps_no),
+ SNOWMOBILES(36, "snowmobiles", R.drawable.attribute_snowmobiles, R.string.attribute_snowmobiles_yes, R.string.attribute_snowmobiles_no),
+ HORSES(37, "horses", R.drawable.attribute_horses, R.string.attribute_horses_yes, R.string.attribute_horses_no),
+ CAMPFIRES(38, "campfires", R.drawable.attribute_campfires, R.string.attribute_campfires_yes, R.string.attribute_campfires_no),
+ THORN(39, "thorn", R.drawable.attribute_thorn, R.string.attribute_thorn_yes, R.string.attribute_thorn_no),
+ STEALTH(40, "stealth", R.drawable.attribute_stealth, R.string.attribute_stealth_yes, R.string.attribute_stealth_no),
+ STROLLER(41, "stroller", R.drawable.attribute_stroller, R.string.attribute_stroller_yes, R.string.attribute_stroller_no),
+ FIRSTAID(42, "firstaid", R.drawable.attribute_firstaid, R.string.attribute_firstaid_yes, R.string.attribute_firstaid_no),
+ COW(43, "cow", R.drawable.attribute_cow, R.string.attribute_cow_yes, R.string.attribute_cow_no),
+ FLASHLIGHT(44, "flashlight", R.drawable.attribute_flashlight, R.string.attribute_flashlight_yes, R.string.attribute_flashlight_no),
+ LANDF(45, "landf", R.drawable.attribute_landf, R.string.attribute_landf_yes, R.string.attribute_landf_no),
+ RV(46, "rv", R.drawable.attribute_rv, R.string.attribute_rv_yes, R.string.attribute_rv_no),
+ FIELD_PUZZLE(47, "field_puzzle", R.drawable.attribute_field_puzzle, R.string.attribute_field_puzzle_yes, R.string.attribute_field_puzzle_no),
+ UV(48, "uv", R.drawable.attribute_uv, R.string.attribute_uv_yes, R.string.attribute_uv_no),
+ SNOWSHOES(49, "snowshoes", R.drawable.attribute_snowshoes, R.string.attribute_snowshoes_yes, R.string.attribute_snowshoes_no),
+ SKIIS(50, "skiis", R.drawable.attribute_skiis, R.string.attribute_skiis_yes, R.string.attribute_skiis_no),
+ SPECIAL_TOOLS(51, "s_tool", R.drawable.attribute_s_tool, R.string.attribute_s_tool_yes, R.string.attribute_s_tool_no),
+ NIGHTCACHE(52, "nightcache", R.drawable.attribute_nightcache, R.string.attribute_nightcache_yes, R.string.attribute_nightcache_no),
+ PARKNGRAB(53, "parkngrab", R.drawable.attribute_parkngrab, R.string.attribute_parkngrab_yes, R.string.attribute_parkngrab_no),
+ ABANDONED_BUILDING(54, "abandonedbuilding", R.drawable.attribute_abandonedbuilding, R.string.attribute_abandonedbuilding_yes, R.string.attribute_abandonedbuilding_no),
+ HIKE_SHORT(55, "hike_short", R.drawable.attribute_hike_short, R.string.attribute_hike_short_yes, R.string.attribute_hike_short_no),
+ HIKE_MED(56, "hike_med", R.drawable.attribute_hike_med, R.string.attribute_hike_med_yes, R.string.attribute_hike_med_no),
+ HIKE_LONG(57, "hike_long", R.drawable.attribute_hike_long, R.string.attribute_hike_long_yes, R.string.attribute_hike_long_no),
+ FUEL(58, "fuel", R.drawable.attribute_fuel, R.string.attribute_fuel_yes, R.string.attribute_fuel_no),
+ FOOD(59, "food", R.drawable.attribute_food, R.string.attribute_food_yes, R.string.attribute_food_no),
+ WIRELESS_BEACON(60, "wirelessbeacon", R.drawable.attribute_wirelessbeacon, R.string.attribute_wirelessbeacon_yes, R.string.attribute_wirelessbeacon_no),
+ PARTNERSHIP(61, "partnership", R.drawable.attribute_partnership, R.string.attribute_partnership_yes, R.string.attribute_partnership_no),
+ SEASONAL(62, "seasonal", R.drawable.attribute_seasonal, R.string.attribute_seasonal_yes, R.string.attribute_seasonal_no),
+ TOURIST_OK(63, "touristok", R.drawable.attribute_touristok, R.string.attribute_touristok_yes, R.string.attribute_touristok_no),
+ TREECLIMBING(64, "treeclimbing", R.drawable.attribute_treeclimbing, R.string.attribute_treeclimbing_yes, R.string.attribute_treeclimbing_no),
+ FRONTYARD(65, "frontyard", R.drawable.attribute_frontyard, R.string.attribute_frontyard_yes, R.string.attribute_frontyard_no),
+ TEAMWORK(66, "teamwork", R.drawable.attribute_teamwork, R.string.attribute_teamwork_yes, R.string.attribute_teamwork_no);
+
+ private static final String INTERNAL_PRE = "attribute_";
+ private static final String INTERNAL_YES = "_yes";
+ private static final String INTERNAL_NO = "_no";
+
+ public final int id;
+ public final String gcRawName;
+ public final int drawableId;
+ public final int stringIdYes;
+ public final int stringIdNo;
+
+ private CacheAttribute(final int id, final String gcRawName, final int drawableId, final int stringIdYes, final int stringIdNo) {
+ this.id = id;
+ this.gcRawName = gcRawName;
+ this.drawableId = drawableId;
+ this.stringIdYes = stringIdYes;
+ this.stringIdNo = stringIdNo;
+ }
+
+ public String getL10n(final boolean enabled) {
+ return cgeoapplication.getInstance().getResources().getString(enabled ? stringIdYes : stringIdNo);
+ }
+
+ private final static Map<String, CacheAttribute> FIND_BY_GCRAWNAME;
+
+ static {
+ final HashMap<String, CacheAttribute> mapGcRawNames = new HashMap<String, CacheAttribute>();
+ for (CacheAttribute attr : values()) {
+ mapGcRawNames.put(attr.gcRawName, attr);
+ }
+ FIND_BY_GCRAWNAME = Collections.unmodifiableMap(mapGcRawNames);
+ }
+
+ public static CacheAttribute getById(final int id) {
+ for (CacheAttribute attr : values()) {
+ if (attr.id == id) {
+ return attr;
+ }
+ }
+ return UNKNOWN;
+ }
+
+ public static CacheAttribute getByGcRawName(final String gcRawName) {
+ final CacheAttribute result = gcRawName != null ? FIND_BY_GCRAWNAME.get(gcRawName) : null;
+ if (result == null) {
+ return UNKNOWN;
+ }
+ return result;
+ }
+
+ public static String trimAttributeName(String attributeName) {
+ if (null == attributeName) {
+ return "";
+ }
+ return attributeName.replace(INTERNAL_PRE, "").replace(INTERNAL_YES, "").replace(INTERNAL_NO, "").trim();
+ }
+
+ public static boolean isEnabled(final String attributeName) {
+ return !StringUtils.endsWithIgnoreCase(attributeName, INTERNAL_NO);
+ }
+}
diff --git a/main/src/cgeo/geocaching/enumerations/CacheSize.java b/main/src/cgeo/geocaching/enumerations/CacheSize.java
index 9b0a559..6fffcdb 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheSize.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheSize.java
@@ -25,13 +25,11 @@ public enum CacheSize {
public final String id;
public final int comparable;
private final int stringId;
- private String l10n; // not final because the locale can be changed
private CacheSize(String id, int comparable, int stringId) {
this.id = id;
this.comparable = comparable;
this.stringId = stringId;
- setL10n();
}
final private static Map<String, CacheSize> FIND_BY_ID;
@@ -43,7 +41,7 @@ public enum CacheSize {
FIND_BY_ID = Collections.unmodifiableMap(mapping);
}
- public final static CacheSize getById(final String id) {
+ public static CacheSize getById(final String id) {
if (id == null) {
return UNKNOWN;
}
@@ -61,12 +59,7 @@ public enum CacheSize {
}
public final String getL10n() {
- return l10n;
+ return cgeoapplication.getInstance().getBaseContext().getResources().getString(stringId);
}
-
- public void setL10n() {
- this.l10n = cgeoapplication.getInstance().getBaseContext().getResources().getString(stringId);
- }
-
}
diff --git a/main/src/cgeo/geocaching/enumerations/CacheType.java b/main/src/cgeo/geocaching/enumerations/CacheType.java
index 96e7eb5..9667911 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheType.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheType.java
@@ -37,7 +37,6 @@ public enum CacheType {
public final String pattern;
public final String guid;
private final int stringId;
- private String l10n; // not final because the locale can be changed
public final int markerId;
private CacheType(String id, String pattern, String guid, int stringId, int markerId) {
@@ -45,7 +44,6 @@ public enum CacheType {
this.pattern = pattern;
this.guid = guid;
this.stringId = stringId;
- setL10n();
this.markerId = markerId;
}
@@ -62,16 +60,16 @@ public enum CacheType {
FIND_BY_PATTERN = Collections.unmodifiableMap(mappingPattern);
}
- public final static CacheType getById(final String id) {
- final CacheType result = id != null ? CacheType.FIND_BY_ID.get(id.toLowerCase().trim()) : null;
+ public static CacheType getById(final String id) {
+ final CacheType result = (id != null) ? CacheType.FIND_BY_ID.get(id.toLowerCase().trim()) : null;
if (result == null) {
return UNKNOWN;
}
return result;
}
- public final static CacheType getByPattern(final String pattern) {
- final CacheType result = pattern != null ? CacheType.FIND_BY_PATTERN.get(pattern.toLowerCase().trim()) : null;
+ public static CacheType getByPattern(final String pattern) {
+ final CacheType result = (pattern != null) ? CacheType.FIND_BY_PATTERN.get(pattern.toLowerCase().trim()) : null;
if (result == null) {
return UNKNOWN;
}
@@ -79,11 +77,10 @@ public enum CacheType {
}
public final String getL10n() {
- return l10n;
+ return cgeoapplication.getInstance().getBaseContext().getResources().getString(stringId);
}
- public void setL10n() {
- this.l10n = cgeoapplication.getInstance().getBaseContext().getResources().getString(this.stringId);
+ public boolean isEvent() {
+ return CacheType.EVENT == this || CacheType.MEGA_EVENT == this || CacheType.CITO == this || CacheType.LOSTANDFOUND == this;
}
-
}
diff --git a/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java b/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java
index 0f0b721..5cc7efc 100644
--- a/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java
+++ b/main/src/cgeo/geocaching/enumerations/LiveMapStrategy.java
@@ -28,16 +28,14 @@ public interface LiveMapStrategy {
public final int id;
public final EnumSet<StrategyFlag> flags;
private final int stringId;
- private String l10n; // not final because the locale can be changed
private Strategy(int id, EnumSet<StrategyFlag> flags, int stringId) {
this.id = id;
this.flags = flags;
this.stringId = stringId;
- setL10n();
}
- public final static Strategy getById(final int id) {
+ public static Strategy getById(final int id) {
for (Strategy strategy : Strategy.values()) {
if (strategy.id == id) {
return strategy;
@@ -47,12 +45,7 @@ public interface LiveMapStrategy {
}
public final String getL10n() {
- return l10n;
- }
-
- public void setL10n() {
- this.l10n = cgeoapplication.getInstance().getBaseContext().getResources().getString(this.stringId);
+ return cgeoapplication.getInstance().getBaseContext().getResources().getString(stringId);
}
}
-
}
diff --git a/main/src/cgeo/geocaching/enumerations/LogType.java b/main/src/cgeo/geocaching/enumerations/LogType.java
index aab4196..e4add78 100644
--- a/main/src/cgeo/geocaching/enumerations/LogType.java
+++ b/main/src/cgeo/geocaching/enumerations/LogType.java
@@ -42,17 +42,15 @@ public enum LogType {
LOG_UNKNOWN(0, "unknown", "", R.string.err_unknown); // LogType not init. yet
public final int id;
- private final String iconName;
- private final String type;
+ public final String iconName;
+ public final String type;
private final int stringId;
- private String l10n; // not final because the locale can be changed
private LogType(int id, String iconName, String type, int stringId) {
this.id = id;
this.iconName = iconName;
this.type = type;
this.stringId = stringId;
- setL10n();
}
private final static Map<String, LogType> FIND_BY_ICONNAME;
@@ -68,7 +66,7 @@ public enum LogType {
FIND_BY_TYPE = Collections.unmodifiableMap(mappingType);
}
- public final static LogType getById(final int id) {
+ public static LogType getById(final int id) {
for (LogType logType : values()) {
if (logType.id == id) {
return logType;
@@ -94,12 +92,6 @@ public enum LogType {
}
public final String getL10n() {
- return l10n;
+ return cgeoapplication.getInstance().getBaseContext().getResources().getString(stringId);
}
-
- public void setL10n() {
- this.l10n = cgeoapplication.getInstance().getBaseContext().getResources().getString(this.stringId);
- }
-
}
-
diff --git a/main/src/cgeo/geocaching/enumerations/StatusCode.java b/main/src/cgeo/geocaching/enumerations/StatusCode.java
index d49acb2..1a1f05d 100644
--- a/main/src/cgeo/geocaching/enumerations/StatusCode.java
+++ b/main/src/cgeo/geocaching/enumerations/StatusCode.java
@@ -2,41 +2,34 @@ package cgeo.geocaching.enumerations;
import cgeo.geocaching.R;
-import android.content.Context;
import android.content.res.Resources;
public enum StatusCode {
- COMMUNICATION_NOT_STARTED(0, R.string.err_start),
- NO_ERROR(1, R.string.err_none),
- LOG_SAVED(2, R.string.info_log_saved),
- LOGIN_PARSE_ERROR(-1, R.string.err_parse),
- CONNECTION_FAILED(-2, R.string.err_server),
- NO_LOGIN_INFO_STORED(-3, R.string.err_login),
- UNKNOWN_ERROR(-4, R.string.err_unknown),
- COMMUNICATION_ERROR(-5, R.string.err_comm),
- WRONG_LOGIN_DATA(-6, R.string.err_wrong),
- UNAPPROVED_LICENSE(-7, R.string.err_license),
- UNPUBLISHED_CACHE(-8, R.string.err_unpublished),
- PREMIUM_ONLY(-9, R.string.err_premium_only),
- MAINTENANCE(-10, R.string.err_maintenance),
- LOG_POST_ERROR(1000, R.string.err_log_post_failed),
- NO_LOG_TEXT(1001, R.string.warn_log_text_fill),
- NO_DATA_FROM_SERVER(1002, R.string.err_log_failed_server),
- NOT_LOGGED_IN(-11, R.string.init_login_popup_failed);
-
- final private int error_code;
+ COMMUNICATION_NOT_STARTED(R.string.err_start),
+ NO_ERROR(R.string.err_none),
+ LOG_SAVED(R.string.info_log_saved),
+ LOGIN_PARSE_ERROR(R.string.err_parse),
+ CONNECTION_FAILED(R.string.err_server),
+ NO_LOGIN_INFO_STORED(R.string.err_login),
+ UNKNOWN_ERROR(R.string.err_unknown),
+ COMMUNICATION_ERROR(R.string.err_comm),
+ WRONG_LOGIN_DATA(R.string.err_wrong),
+ UNAPPROVED_LICENSE(R.string.err_license),
+ UNPUBLISHED_CACHE(R.string.err_unpublished),
+ PREMIUM_ONLY(R.string.err_premium_only),
+ MAINTENANCE(R.string.err_maintenance),
+ LOG_POST_ERROR(R.string.err_log_post_failed),
+ NO_LOG_TEXT(R.string.warn_log_text_fill),
+ NO_DATA_FROM_SERVER(R.string.err_log_failed_server),
+ NOT_LOGGED_IN(R.string.init_login_popup_failed);
+
final private int error_string;
- StatusCode(int error_code, int error_string) {
- this.error_code = error_code;
+ StatusCode(int error_string) {
this.error_string = error_string;
}
- public int getCode() {
- return error_code;
- }
-
public int getErrorString() {
return error_string;
}
@@ -45,8 +38,4 @@ public enum StatusCode {
return res.getString(error_string);
}
- public String getErrorString(final Context context) {
- return getErrorString(context.getResources());
- }
-
}
diff --git a/main/src/cgeo/geocaching/enumerations/WaypointType.java b/main/src/cgeo/geocaching/enumerations/WaypointType.java
index 78e5ceb..44004c0 100644
--- a/main/src/cgeo/geocaching/enumerations/WaypointType.java
+++ b/main/src/cgeo/geocaching/enumerations/WaypointType.java
@@ -5,7 +5,9 @@ import cgeo.geocaching.cgeoapplication;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* Enum listing waypoint types
@@ -23,13 +25,11 @@ public enum WaypointType {
public final String id;
public final int stringId;
- private String l10n; // not final because the locale can be changed
public final int markerId;
private WaypointType(String id, int stringId, int markerId) {
this.id = id;
this.stringId = stringId;
- setL10n();
this.markerId = markerId;
}
@@ -38,13 +38,13 @@ public enum WaypointType {
* non public so that <code>null</code> handling can be handled centrally in the enum type itself
*/
private static final Map<String, WaypointType> FIND_BY_ID;
- public static final Map<WaypointType, String> ALL_TYPES_EXCEPT_OWN = new HashMap<WaypointType, String>();
+ public static final Set<WaypointType> ALL_TYPES_EXCEPT_OWN = new HashSet<WaypointType>();
static {
final HashMap<String, WaypointType> mapping = new HashMap<String, WaypointType>();
for (WaypointType wt : values()) {
mapping.put(wt.id, wt);
if (wt != WaypointType.OWN) {
- ALL_TYPES_EXCEPT_OWN.put(wt, wt.getL10n());
+ ALL_TYPES_EXCEPT_OWN.add(wt);
}
}
FIND_BY_ID = Collections.unmodifiableMap(mapping);
@@ -66,15 +66,9 @@ public enum WaypointType {
}
public final String getL10n() {
- return l10n;
+ return cgeoapplication.getInstance().getBaseContext().getResources().getString(stringId);
}
- public void setL10n() {
- this.l10n = cgeoapplication.getInstance().getBaseContext().getResources().getString(this.stringId);
- if (WaypointType.ALL_TYPES_EXCEPT_OWN != null && WaypointType.ALL_TYPES_EXCEPT_OWN.containsKey(this)) {
- WaypointType.ALL_TYPES_EXCEPT_OWN.put(this, this.getL10n());
- }
- }
@Override
public final String toString() {
diff --git a/main/src/cgeo/geocaching/export/AbstractExport.java b/main/src/cgeo/geocaching/export/AbstractExport.java
new file mode 100644
index 0000000..85b060b
--- /dev/null
+++ b/main/src/cgeo/geocaching/export/AbstractExport.java
@@ -0,0 +1,32 @@
+package cgeo.geocaching.export;
+
+import cgeo.geocaching.cgeoapplication;
+
+abstract class AbstractExport implements Export {
+ private final String name;
+
+ protected AbstractExport(final String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Generates a localized string from a resource id.
+ *
+ * @param resourceId
+ * the resource id of the string
+ * @return localized string
+ */
+ protected static String getString(int resourceId) {
+ return cgeoapplication.getInstance().getString(resourceId);
+ }
+
+ @Override
+ public String toString() {
+ // used in the array adapter of the dialog showing the exports
+ return getName();
+ }
+}
diff --git a/main/src/cgeo/geocaching/export/Export.java b/main/src/cgeo/geocaching/export/Export.java
new file mode 100644
index 0000000..7a2b075
--- /dev/null
+++ b/main/src/cgeo/geocaching/export/Export.java
@@ -0,0 +1,29 @@
+package cgeo.geocaching.export;
+
+import cgeo.geocaching.cgCache;
+
+import android.app.Activity;
+
+import java.util.List;
+
+/**
+ * Represents an exporter to export a {@link List} of {@link cgCache} to various formats.
+ */
+interface Export {
+ /**
+ * Export a {@link List} of {@link cgCache} to various formats.
+ *
+ * @param caches
+ * The {@link List} of {@link cgCache} to be exported
+ * @param activity
+ * optional: Some exporters might have an UI which requires an {@link Activity}
+ */
+ public void export(List<cgCache> caches, Activity activity);
+
+ /**
+ * Get the localized name of this exporter.
+ *
+ * @return localized name
+ */
+ public String getName();
+}
diff --git a/main/src/cgeo/geocaching/export/ExportFactory.java b/main/src/cgeo/geocaching/export/ExportFactory.java
new file mode 100644
index 0000000..8b3df58
--- /dev/null
+++ b/main/src/cgeo/geocaching/export/ExportFactory.java
@@ -0,0 +1,65 @@
+package cgeo.geocaching.export;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.utils.Log;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.widget.ArrayAdapter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Factory to create a dialog with all available exporters.
+ */
+public abstract class ExportFactory {
+
+ /**
+ * Contains instances of all available exporter classes.
+ */
+ private static final List<Class<? extends Export>> exporterClasses;
+
+ static {
+ final ArrayList<Class<? extends Export>> temp = new ArrayList<Class<? extends Export>>();
+ temp.add(FieldnoteExport.class);
+ temp.add(GpxExport.class);
+ exporterClasses = Collections.unmodifiableList(temp);
+ }
+
+ /**
+ * Creates a dialog so that the user can select an exporter.
+ *
+ * @param caches
+ * The {@link List} of {@link cgCache} to be exported
+ * @param activity
+ * The {@link Activity} in whose context the dialog should be shown
+ */
+ public static void showExportMenu(final List<cgCache> caches, final Activity activity) {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setTitle(R.string.export).setIcon(android.R.drawable.ic_menu_share);
+
+ final ArrayList<Export> export = new ArrayList<Export>();
+ for (Class<? extends Export> exporterClass : exporterClasses) {
+ try {
+ export.add(exporterClass.newInstance());
+ } catch (Exception ex) {
+ Log.e("showExportMenu", ex);
+ }
+ }
+
+ final ArrayAdapter<Export> adapter = new ArrayAdapter<Export>(activity, android.R.layout.select_dialog_item, export);
+
+ builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ final Export selectedExport = adapter.getItem(item);
+ selectedExport.export(caches, activity);
+ }
+ });
+
+ builder.create().show();
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/export/FieldnoteExport.java b/main/src/cgeo/geocaching/export/FieldnoteExport.java
new file mode 100644
index 0000000..babc4b6
--- /dev/null
+++ b/main/src/cgeo/geocaching/export/FieldnoteExport.java
@@ -0,0 +1,257 @@
+package cgeo.geocaching.export;
+
+import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.activity.Progress;
+import cgeo.geocaching.enumerations.LogType;
+import cgeo.geocaching.utils.Log;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Exports offline-logs in the Groundspeak Field Note format.<br>
+ * <br>
+ *
+ * Field Notes are simple plain text files, but poorly documented. Syntax:<br>
+ * <code>GCxxxxx,yyyy-mm-ddThh:mm:ssZ,Found it,"logtext"</code>
+ */
+class FieldnoteExport extends AbstractExport {
+ private static final File exportLocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/field-notes");
+ private static final SimpleDateFormat fieldNoteDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+
+ protected FieldnoteExport() {
+ super(getString(R.string.export_fieldnotes));
+ }
+
+ /**
+ * A dialog to allow the user to set options for the export.
+ *
+ * Currently available options are: upload field notes, only new logs since last export/upload
+ */
+ private class ExportOptionsDialog extends AlertDialog {
+ public ExportOptionsDialog(final List<cgCache> caches, final Activity activity) {
+ super(activity);
+
+ View layout = activity.getLayoutInflater().inflate(R.layout.fieldnote_export_dialog, null);
+ setView(layout);
+
+ ((Button) layout.findViewById(R.id.export)).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dismiss();
+ new ExportTask(
+ caches,
+ activity,
+ ((CheckBox) findViewById(R.id.upload)).isChecked(),
+ ((CheckBox) findViewById(R.id.onlynew)).isChecked())
+ .execute((Void) null);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void export(final List<cgCache> caches, final Activity activity) {
+ if (null == activity) {
+ // No activity given, so no user interaction possible.
+ // Start export with default parameters.
+ new ExportTask(caches, null, false, false).execute((Void) null);
+ } else {
+ // Show configuration dialog
+ new ExportOptionsDialog(caches, activity).show();
+ }
+ }
+
+ private class ExportTask extends AsyncTask<Void, Integer, Boolean> {
+ private final List<cgCache> caches;
+ private final Activity activity;
+ private final boolean onlyNew;
+ private final Progress progress = new Progress();
+ private File exportFile;
+
+ private static final int STATUS_UPLOAD = -1;
+
+ /**
+ * Instantiates and configurates the task for exporting field notes.
+ *
+ * @param caches
+ * The {@link List} of {@link cgCache} to be exported
+ * @param activity
+ * optional: Show a progress bar and toasts
+ * @param upload
+ * Upload the Field Note to geocaching.com
+ * @param onlyNew
+ * Upload/export only new logs since last export
+ */
+ public ExportTask(final List<cgCache> caches, final Activity activity, final boolean upload, final boolean onlyNew) {
+ this.caches = caches;
+ this.activity = activity;
+ this.onlyNew = onlyNew;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ if (null != activity) {
+ progress.show(activity, null, getString(R.string.export) + ": " + getName(), ProgressDialog.STYLE_HORIZONTAL, null);
+ progress.setMaxProgressAndReset(caches.size());
+ }
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ final StringBuilder fieldNoteBuffer = new StringBuilder();
+
+ // We need our own HashMap because LogType will give us localized and maybe
+ // different strings than gc.com expects in the field note
+ // We only need such logtypes that are possible to log via c:geo
+ Map<LogType, String> logTypes = new HashMap<LogType, String>();
+ logTypes.put(LogType.LOG_FOUND_IT, "Found it");
+ logTypes.put(LogType.LOG_DIDNT_FIND_IT, "Didn't find it");
+ logTypes.put(LogType.LOG_NOTE, "Write Note");
+ logTypes.put(LogType.LOG_NEEDS_ARCHIVE, "Needs archived");
+ logTypes.put(LogType.LOG_NEEDS_MAINTENANCE, "Needs Maintenance");
+ logTypes.put(LogType.LOG_WILL_ATTEND, "Will Attend");
+ logTypes.put(LogType.LOG_ATTENDED, "Attended");
+ logTypes.put(LogType.LOG_WEBCAM_PHOTO_TAKEN, "Webcam Photo Taken");
+
+ for (int i = 0; i < caches.size(); i++) {
+ try {
+ final cgCache cache = caches.get(i);
+ if (cache.isLogOffline()) {
+ LogEntry log = cgeoapplication.getInstance().loadLogOffline(cache.getGeocode());
+ if (null != logTypes.get(log.type)) {
+ fieldNoteBuffer.append(cache.getGeocode())
+ .append(',')
+ .append(fieldNoteDateFormat.format(new Date(log.date)))
+ .append(',')
+ .append(logTypes.get(log.type))
+ .append(",\"")
+ .append(StringUtils.replaceChars(log.log, '"', '\''))
+ .append("\"\n");
+ }
+ }
+ publishProgress(i + 1);
+ } catch (Exception e) {
+ Log.e("FieldnoteExport.ExportTask generation", e);
+ return false;
+ }
+ }
+
+ fieldNoteBuffer.append('\n');
+
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ exportLocation.mkdirs();
+
+ SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+ exportFile = new File(exportLocation.toString() + '/' + fileNameDateFormat.format(new Date()) + ".txt");
+
+ OutputStream os;
+ Writer fw = null;
+ try {
+ os = new FileOutputStream(exportFile);
+ fw = new OutputStreamWriter(os, "ISO-8859-1"); // TODO: gc.com doesn't support UTF-8
+ fw.write(fieldNoteBuffer.toString());
+ } catch (IOException e) {
+ Log.e("FieldnoteExport.ExportTask export", e);
+ return false;
+ } finally {
+ if (fw != null) {
+ try {
+ fw.close();
+ } catch (IOException e) {
+ Log.e("FieldnoteExport.ExportTask export", e);
+ return false;
+ }
+ }
+ }
+ } else {
+ return false;
+ }
+
+ /*
+ * if (upload) {
+ * TODO Use multipart POST request for uploading
+ * publishProgress(STATUS_UPLOAD);
+ *
+ * final Parameters uploadParams = new Parameters(
+ * "__EVENTTARGET", "",
+ * "__EVENTARGUMENT", "",
+ * "__VIEWSTATE", "",
+ * //TODO "ctl00$ContentBody$chkSuppressDate", "on",
+ * "ctl00$ContentBody$FieldNoteLoader", fieldNoteBuffer.toString(),
+ * "ctl00$ContentBody$btnUpload", "Upload Field Note");
+ * final String uri = "http://www.geocaching.com/my/uploadfieldnotes.aspx";
+ *
+ * String page = Network.getResponseData(Network.postRequest(uri, uploadParams));
+ * if (!Login.getLoginStatus(page)) {
+ * final StatusCode loginState = Login.login();
+ * if (loginState == StatusCode.NO_ERROR) {
+ * page = Network.getResponseData(Network.postRequest(uri, uploadParams));
+ * } else {
+ * Log.e(Settings.tag, "FieldnoteExport.ExportTask upload: No login (error: " + loginState + ")");
+ * return false;
+ * }
+ * }
+ *
+ * if (StringUtils.isBlank(page)) {
+ * Log.e(Settings.tag, "FieldnoteExport.ExportTask upload: No data from server");
+ * return false;
+ * }
+ * }
+ */
+
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ if (null != activity) {
+ progress.dismiss();
+
+ if (result) {
+ if (onlyNew) {
+ // update last export time in settings
+ }
+ ActivityMixin.showToast(activity, getName() + ' ' + getString(R.string.export_exportedto) + ": " + exportFile.toString());
+ } else {
+ ActivityMixin.showToast(activity, getString(R.string.export_failed));
+ }
+ }
+ }
+
+ @Override
+ protected void onProgressUpdate(Integer... status) {
+ if (null != activity) {
+ if (STATUS_UPLOAD == status[0]) {
+ progress.setMessage(getString(R.string.export_fieldnotes_uploading));
+ } else {
+ progress.setProgress(status[0]);
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/cgeo/geocaching/export/GpxExport.java b/main/src/cgeo/geocaching/export/GpxExport.java
new file mode 100644
index 0000000..e7579f3
--- /dev/null
+++ b/main/src/cgeo/geocaching/export/GpxExport.java
@@ -0,0 +1,328 @@
+package cgeo.geocaching.export;
+
+import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgWaypoint;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.activity.Progress;
+import cgeo.geocaching.enumerations.CacheAttribute;
+import cgeo.geocaching.enumerations.LoadFlags;
+import cgeo.geocaching.utils.BaseUtils;
+import cgeo.geocaching.utils.Log;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.os.AsyncTask;
+import android.os.Environment;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+class GpxExport extends AbstractExport {
+ private static final File exportLocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/gpx");
+ private static final SimpleDateFormat dateFormatZ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+
+ protected GpxExport() {
+ super(getString(R.string.export_gpx));
+ }
+
+ @Override
+ public void export(final List<cgCache> caches, final Activity activity) {
+ new ExportTask(caches, activity).execute((Void) null);
+ }
+
+ private class ExportTask extends AsyncTask<Void, Integer, Boolean> {
+ private final List<cgCache> caches;
+ private final Activity activity;
+ private final Progress progress = new Progress();
+ private File exportFile;
+
+ /**
+ * Instantiates and configures the task for exporting field notes.
+ *
+ * @param caches
+ * The {@link List} of {@link cgCache} to be exported
+ * @param activity
+ * optional: Show a progress bar and toasts
+ */
+ public ExportTask(final List<cgCache> caches, final Activity activity) {
+ this.caches = caches;
+ this.activity = activity;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ if (null != activity) {
+ progress.show(activity, null, getString(R.string.export) + ": " + getName(), ProgressDialog.STYLE_HORIZONTAL, null);
+ progress.setMaxProgressAndReset(caches.size());
+ }
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ // quick check for being able to write the GPX file
+ if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ return false;
+ }
+
+ Writer gpx = null;
+
+ try {
+ exportLocation.mkdirs();
+
+ final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+ exportFile = new File(exportLocation.toString() + File.separatorChar + "export_" + fileNameDateFormat.format(new Date()) + ".gpx");
+
+ gpx = new BufferedWriter(new FileWriter(exportFile));
+
+ gpx.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ gpx.write("<gpx version=\"1.0\" creator=\"c:geo - http://www.cgeo.org\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0/1 http://www.groundspeak.com/cache/1/0/1/cache.xsd\">");
+
+
+ for (int i = 0; i < caches.size(); i++) {
+ cgCache cache = caches.get(i);
+
+ if (!cache.isDetailed()) {
+ cache = cgeoapplication.getInstance().loadCache(caches.get(i).getGeocode(), LoadFlags.LOAD_ALL_DB_ONLY);
+ }
+
+ gpx.write("<wpt ");
+ gpx.write("lat=\"");
+ gpx.write(Double.toString(cache.getCoords().getLatitude()));
+ gpx.write("\" ");
+ gpx.write("lon=\"");
+ gpx.write(Double.toString(cache.getCoords().getLongitude()));
+ gpx.write("\">");
+
+ gpx.write("<time>");
+ gpx.write(StringEscapeUtils.escapeXml(dateFormatZ.format(cache.getHiddenDate())));
+ gpx.write("</time>");
+
+ gpx.write("<name>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getGeocode()));
+ gpx.write("</name>");
+
+ gpx.write("<desc>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getName()));
+ gpx.write("</desc>");
+
+ gpx.write("<sym>");
+ gpx.write(cache.isFound() ? "Geocache Found" : "Geocache");
+ gpx.write("</sym>");
+
+ gpx.write("<type>");
+ gpx.write(StringEscapeUtils.escapeXml("Geocache|" + cache.getType().toString())); //TODO: Correct (english) string
+ gpx.write("</type>");
+
+ gpx.write("<groundspeak:cache ");
+ gpx.write("available=\"");
+ gpx.write(!cache.isDisabled() ? "True" : "False");
+ gpx.write("\" archived=\"");
+ gpx.write(cache.isArchived() ? "True" : "False");
+ gpx.write("\" ");
+ gpx.write("xmlns:groundspeak=\"http://www.groundspeak.com/cache/1/0/1\">");
+
+ gpx.write("<groundspeak:name>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getName()));
+ gpx.write("</groundspeak:name>");
+
+ gpx.write("<groundspeak:placed_by>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getOwner()));
+ gpx.write("</groundspeak:placed_by>");
+
+ gpx.write("<groundspeak:owner>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getOwnerReal()));
+ gpx.write("</groundspeak:owner>");
+
+ gpx.write("<groundspeak:type>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getType().toString())); //TODO: Correct (english) string
+ gpx.write("</groundspeak:type>");
+
+ gpx.write("<groundspeak:container>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getSize().toString())); //TODO: Correct (english) string
+ gpx.write("</groundspeak:container>");
+
+ if (cache.hasAttributes()) {
+ //TODO: Attribute conversion required: English verbose name, gpx-id
+ gpx.write("<groundspeak:attributes>");
+
+ for (String attribute : cache.getAttributes()) {
+ final CacheAttribute attr = CacheAttribute.getByGcRawName(CacheAttribute.trimAttributeName(attribute));
+ final boolean enabled = CacheAttribute.isEnabled(attribute);
+
+ gpx.write("<groundspeak:attribute id=\"");
+ gpx.write(Integer.toString(attr.id));
+ gpx.write("\" inc=\"");
+ if (enabled) {
+ gpx.write('1');
+ } else {
+ gpx.write('0');
+ }
+ gpx.write("\">");
+ gpx.write(StringEscapeUtils.escapeXml(attr.getL10n(enabled)));
+ gpx.write("</groundspeak:attribute>");
+ }
+
+ gpx.write("</groundspeak:attributes>");
+ }
+
+ gpx.write("<groundspeak:difficulty>");
+ gpx.write(Float.toString(cache.getDifficulty()));
+ gpx.write("</groundspeak:difficulty>");
+
+ gpx.write("<groundspeak:terrain>");
+ gpx.write(Float.toString(cache.getTerrain()));
+ gpx.write("</groundspeak:terrain>");
+
+ gpx.write("<groundspeak:country>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getLocation()));
+ gpx.write("</groundspeak:country>");
+
+ gpx.write("<groundspeak:state>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getLocation()));
+ gpx.write("</groundspeak:state>");
+
+ gpx.write("<groundspeak:short_description html=\"");
+ if (BaseUtils.containsHtml(cache.getShortDescription())) {
+ gpx.write("True");
+ } else {
+ gpx.write("False");
+ }
+ gpx.write("\">");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getShortDescription()));
+ gpx.write("</groundspeak:short_description>");
+
+ gpx.write("<groundspeak:long_description html=\"");
+ if (BaseUtils.containsHtml(cache.getDescription())) {
+ gpx.write("True");
+ } else {
+ gpx.write("False");
+ }
+ gpx.write("\">");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getDescription()));
+ gpx.write("</groundspeak:long_description>");
+
+ gpx.write("<groundspeak:encoded_hints>");
+ gpx.write(StringEscapeUtils.escapeXml(cache.getHint()));
+ gpx.write("</groundspeak:encoded_hints>");
+
+ gpx.write("</groundspeak:cache>");
+
+ if (cache.getLogs().size() > 0) {
+ gpx.write("<groundspeak:logs>");
+
+ for (LogEntry log : cache.getLogs()) {
+ gpx.write("<groundspeak:log id=\"");
+ gpx.write(Integer.toString(log.id));
+ gpx.write("\">");
+
+ gpx.write("<groundspeak:date>");
+ gpx.write(StringEscapeUtils.escapeXml(dateFormatZ.format(new Date(log.date))));
+ gpx.write("</groundspeak:date>");
+
+ gpx.write("<groundspeak:type>");
+ gpx.write(StringEscapeUtils.escapeXml(log.type.type));
+ gpx.write("</groundspeak:type>");
+
+ gpx.write("<groundspeak:finder id=\"\">");
+ gpx.write(StringEscapeUtils.escapeXml(log.author));
+ gpx.write("</groundspeak:finder>");
+
+ gpx.write("<groundspeak:text encoded=\"False\">");
+ gpx.write(StringEscapeUtils.escapeXml(log.log));
+ gpx.write("</groundspeak:text>");
+
+ gpx.write("</groundspeak:log>");
+ }
+
+ gpx.write("</groundspeak:logs>");
+ }
+
+ gpx.write("</wpt>");
+
+ for (cgWaypoint wp : cache.getWaypoints()) {
+ gpx.write("<wpt lat=\"");
+ gpx.write(Double.toString(wp.getCoords().getLatitude()));
+ gpx.write("\" lon=\"");
+ gpx.write(Double.toString(wp.getCoords().getLongitude()));
+ gpx.write("\">");
+
+ gpx.write("<name>");
+ gpx.write(StringEscapeUtils.escapeXml(wp.getPrefix()));
+ gpx.write(StringEscapeUtils.escapeXml(cache.getGeocode().substring(2)));
+ gpx.write("</name>");
+
+ gpx.write("<cmt />");
+
+ gpx.write("<desc>");
+ gpx.write(StringEscapeUtils.escapeXml(wp.getNote()));
+ gpx.write("</desc>");
+
+ gpx.write("<sym>");
+ gpx.write(StringEscapeUtils.escapeXml(wp.getWaypointType().toString()));
+ gpx.write("</sym>");
+
+ gpx.write("<type>Waypoint|");
+ gpx.write(StringEscapeUtils.escapeXml(wp.getWaypointType().toString()));
+ gpx.write("</type>");
+
+ gpx.write("</wpt>");
+ }
+
+ publishProgress(i + 1);
+ }
+
+ gpx.write("</gpx>");
+
+ gpx.close();
+ } catch (Exception e) {
+ Log.e("GpxExport.ExportTask export", e);
+
+ if (gpx != null) {
+ try {
+ gpx.close();
+ } catch (IOException ee) {
+ }
+ }
+
+ // delete partial gpx file on error
+ if (exportFile.exists()) {
+ exportFile.delete();
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ if (null != activity) {
+ progress.dismiss();
+ if (result) {
+ ActivityMixin.showToast(activity, getName() + ' ' + getString(R.string.export_exportedto) + ": " + exportFile.toString());
+ } else {
+ ActivityMixin.showToast(activity, getString(R.string.export_failed));
+ }
+ }
+ }
+
+ @Override
+ protected void onProgressUpdate(Integer... status) {
+ if (null != activity) {
+ progress.setProgress(status[0]);
+ }
+ }
+ }
+}
diff --git a/main/src/cgeo/geocaching/files/FileList.java b/main/src/cgeo/geocaching/files/FileList.java
index cef7b89..2fa4e5d 100644
--- a/main/src/cgeo/geocaching/files/FileList.java
+++ b/main/src/cgeo/geocaching/files/FileList.java
@@ -1,9 +1,9 @@
package cgeo.geocaching.files;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.StoredList;
import cgeo.geocaching.activity.AbstractListActivity;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
@@ -15,7 +15,6 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.widget.ArrayAdapter;
import java.io.File;
@@ -64,30 +63,14 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
@Override
public void handleMessage(Message msg) {
- try {
- if (CollectionUtils.isEmpty(files)) {
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
-
- showToast(res.getString(R.string.file_list_no_files));
-
- finish();
- return;
- } else {
- if (adapter != null) {
- adapter.notifyDataSetChanged();
- }
- }
-
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
- } catch (Exception e) {
- if (waitDialog != null) {
- waitDialog.dismiss();
- }
- Log.e(Settings.tag, "cgFileList.loadFilesHandler: " + e.toString());
+ if (waitDialog != null) {
+ waitDialog.dismiss();
+ }
+ if (CollectionUtils.isEmpty(files)) {
+ showToast(res.getString(R.string.file_list_no_files));
+ finish();
+ } else if (adapter != null) {
+ adapter.notifyDataSetChanged();
}
}
};
@@ -188,10 +171,10 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
listDir(list, Environment.getExternalStorageDirectory());
}
} else {
- Log.w(Settings.tag, "No external media mounted.");
+ Log.w("No external media mounted.");
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgFileList.loadFiles.run: " + e.toString());
+ Log.e("cgFileList.loadFiles.run: " + e.toString());
}
changeWaitDialogHandler.sendMessage(Message.obtain(changeWaitDialogHandler, 0, "loaded directories"));
@@ -237,7 +220,6 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis
}
}
- return;
}
/**
diff --git a/main/src/cgeo/geocaching/files/FileParser.java b/main/src/cgeo/geocaching/files/FileParser.java
index 20e757c..090573a 100644
--- a/main/src/cgeo/geocaching/files/FileParser.java
+++ b/main/src/cgeo/geocaching/files/FileParser.java
@@ -52,7 +52,7 @@ public abstract class FileParser {
final BufferedReader input = new BufferedReader(new InputStreamReader(progressInputStream));
try {
- String line = null;
+ String line;
while ((line = input.readLine()) != null) {
buffer.append(line);
showProgressMessage(progressHandler, progressInputStream.getProgress());
diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java
index 4697a62..c669dcb 100644
--- a/main/src/cgeo/geocaching/files/GPXImporter.java
+++ b/main/src/cgeo/geocaching/files/GPXImporter.java
@@ -11,6 +11,7 @@ import cgeo.geocaching.activity.Progress;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
@@ -23,7 +24,6 @@ import android.content.res.Resources;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
@@ -34,7 +34,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -56,8 +55,8 @@ public class GPXImporter {
public static final String WAYPOINTS_FILE_SUFFIX = "-wpts";
public static final String WAYPOINTS_FILE_SUFFIX_AND_EXTENSION = WAYPOINTS_FILE_SUFFIX + GPX_FILE_EXTENSION;
- private static final List<String> GPX_MIME_TYPES = Arrays.asList(new String[] { "text/xml", "application/xml" });
- private static final List<String> ZIP_MIME_TYPES = Arrays.asList(new String[] { "application/zip", "application/x-compressed", "application/x-zip-compressed", "application/x-zip", "application/octet-stream" });
+ private static final List<String> GPX_MIME_TYPES = Arrays.asList("text/xml", "application/xml");
+ private static final List<String> ZIP_MIME_TYPES = Arrays.asList("application/zip", "application/x-compressed", "application/x-zip-compressed", "application/x-zip", "application/octet-stream");
private Progress progress = new Progress();
@@ -113,7 +112,7 @@ public class GPXImporter {
}
}
- Log.i(Settings.tag, "importGPX: " + uri + ", mimetype=" + mimeType);
+ Log.i("importGPX: " + uri + ", mimetype=" + mimeType);
if (GPX_MIME_TYPES.contains(mimeType)) {
new ImportGpxAttachmentThread(uri, contentResolver, listId, importStepHandler, progressHandler).start();
} else if (ZIP_MIME_TYPES.contains(mimeType)) {
@@ -143,25 +142,29 @@ public class GPXImporter {
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_STORE_CACHES, R.string.gpx_import_storing, caches.size()));
SearchResult search = storeParsedCaches(caches);
- Log.i(Settings.tag, "Imported successfully " + caches.size() + " caches.");
+ Log.i("Imported successfully " + caches.size() + " caches.");
if (Settings.isStoreOfflineMaps() || Settings.isStoreOfflineWpMaps()) {
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_STORE_STATIC_MAPS, R.string.gpx_import_store_static_maps, search.getCount()));
- importStaticMaps(search);
+ boolean finishedWithoutCancel = importStaticMaps(search);
+ // Skip last message if static maps where canceled
+ if (!finishedWithoutCancel) {
+ return;
+ }
}
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED, search.getCount(), 0, search));
} catch (IOException e) {
- Log.i(Settings.tag, "Importing caches failed - error reading data: " + e.getMessage());
+ Log.i("Importing caches failed - error reading data: " + e.getMessage());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_io, 0, e.getLocalizedMessage()));
} catch (ParserException e) {
- Log.i(Settings.tag, "Importing caches failed - data format error" + e.getMessage());
+ Log.i("Importing caches failed - data format error" + e.getMessage());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_parser, 0, e.getLocalizedMessage()));
} catch (CancellationException e) {
- Log.i(Settings.tag, "Importing caches canceled");
+ Log.i("Importing caches canceled");
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_CANCELED));
} catch (Exception e) {
- Log.e(Settings.tag, "Importing caches failed - unknown error: ", e);
+ Log.e("Importing caches failed - unknown error: ", e);
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_FINISHED_WITH_ERROR, R.string.gpx_import_error_unexpected, 0, e.getLocalizedMessage()));
}
}
@@ -186,19 +189,20 @@ public class GPXImporter {
return search;
}
- private void importStaticMaps(final SearchResult importedCaches) {
+ private boolean importStaticMaps(final SearchResult importedCaches) {
final cgeoapplication app = cgeoapplication.getInstance();
- Set<cgCache> caches = importedCaches.getCachesFromSearchResult(LoadFlags.LOAD_WAYPOINTS);
int storedCacheMaps = 0;
- for (cgCache cache : caches) {
- Log.d(Settings.tag, "GPXImporter.ImportThread.importStaticMaps start downloadMaps");
+ for (String geocode : importedCaches.getGeocodes()) {
+ cgCache cache = app.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS);
+ Log.d("GPXImporter.ImportThread.importStaticMaps start downloadMaps for cache " + geocode);
StaticMapsProvider.downloadMaps(cache, app);
storedCacheMaps++;
if (progressHandler.isCancelled()) {
- return;
+ return false;
}
progressHandler.sendMessage(progressHandler.obtainMessage(0, storedCacheMaps, 0));
}
+ return true;
}
}
@@ -212,7 +216,7 @@ public class GPXImporter {
@Override
protected Collection<cgCache> doImport() throws IOException, ParserException {
- Log.i(Settings.tag, "Import LOC file: " + file.getAbsolutePath());
+ Log.i("Import LOC file: " + file.getAbsolutePath());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) file.length()));
LocParser parser = new LocParser(listId);
return parser.parse(file, progressHandler);
@@ -249,7 +253,7 @@ public class GPXImporter {
@Override
protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
- Log.i(Settings.tag, "Import GPX file: " + cacheFile.getAbsolutePath());
+ Log.i("Import GPX file: " + cacheFile.getAbsolutePath());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) cacheFile.length()));
Collection<cgCache> caches = parser.parse(cacheFile, progressHandler);
@@ -257,7 +261,7 @@ public class GPXImporter {
if (wptsFilename != null) {
final File wptsFile = new File(cacheFile.getParentFile(), wptsFilename);
if (wptsFile.canRead()) {
- Log.i(Settings.tag, "Import GPX waypoint file: " + wptsFile.getAbsolutePath());
+ Log.i("Import GPX waypoint file: " + wptsFile.getAbsolutePath());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_WPT_FILE, R.string.gpx_import_loading_waypoints, (int) wptsFile.length()));
caches = parser.parse(wptsFile, progressHandler);
}
@@ -278,7 +282,7 @@ public class GPXImporter {
@Override
protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
- Log.i(Settings.tag, "Import GPX from uri: " + uri);
+ Log.i("Import GPX from uri: " + uri);
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, -1));
InputStream is = contentResolver.openInputStream(uri);
try {
@@ -343,7 +347,7 @@ public class GPXImporter {
public ImportGpxZipFileThread(final File file, int listId, Handler importStepHandler, CancellableHandler progressHandler) {
super(listId, importStepHandler, progressHandler);
this.cacheFile = file;
- Log.i(Settings.tag, "Import zipped GPX: " + file);
+ Log.i("Import zipped GPX: " + file);
}
@Override
@@ -360,7 +364,7 @@ public class GPXImporter {
super(listId, importStepHandler, progressHandler);
this.uri = uri;
this.contentResolver = contentResolver;
- Log.i(Settings.tag, "Import zipped GPX from uri: " + uri);
+ Log.i("Import zipped GPX from uri: " + uri);
}
@Override
@@ -377,6 +381,8 @@ public class GPXImporter {
};
final private Handler importStepHandler = new Handler() {
+ private boolean showProgressAfterCancel = false;
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -387,9 +393,16 @@ public class GPXImporter {
case IMPORT_STEP_READ_FILE:
case IMPORT_STEP_READ_WPT_FILE:
+ progress.setProgressDivider(1024);
+ progress.setMessage(res.getString(msg.arg1));
+ progress.setMaxProgressAndReset(msg.arg2);
+ break;
+
case IMPORT_STEP_STORE_CACHES:
+ progress.setProgressDivider(1);
progress.setMessage(res.getString(msg.arg1));
progress.setMaxProgressAndReset(msg.arg2);
+ showProgressAfterCancel = true;
break;
case IMPORT_STEP_STORE_STATIC_MAPS:
@@ -401,6 +414,7 @@ public class GPXImporter {
case IMPORT_STEP_STATIC_MAPS_SKIPPED:
progress.dismiss();
+ progressHandler.cancel();
StringBuilder bufferSkipped = new StringBuilder(20);
bufferSkipped.append(res.getString(R.string.gpx_import_static_maps_skipped)).append(", ").append(msg.arg1).append(' ').append(res.getString(R.string.gpx_import_caches_imported));
fromActivity.helpDialog(res.getString(R.string.gpx_import_title_caches_imported), bufferSkipped.toString());
@@ -426,7 +440,10 @@ public class GPXImporter {
case IMPORT_STEP_CANCELED:
StringBuilder bufferCanceled = new StringBuilder(20);
- bufferCanceled.append(res.getString(R.string.gpx_import_canceled)).append(", ").append(progress.getProgress()).append(' ').append(res.getString(R.string.gpx_import_caches_imported));
+ bufferCanceled.append(res.getString(R.string.gpx_import_canceled));
+ if (showProgressAfterCancel) {
+ bufferCanceled.append(", ").append(progress.getProgress()).append(' ').append(res.getString(R.string.gpx_import_caches_imported));
+ }
fromActivity.showShortToast(bufferCanceled.toString());
importFinished();
break;
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java
index e4e4e3a..7870a16 100644
--- a/main/src/cgeo/geocaching/files/GPXParser.java
+++ b/main/src/cgeo/geocaching/files/GPXParser.java
@@ -1,10 +1,9 @@
package cgeo.geocaching.files;
+import cgeo.geocaching.LogEntry;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.StoredList;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgLog;
import cgeo.geocaching.cgTrackable;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.cgeoapplication;
@@ -15,6 +14,7 @@ import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.xml.sax.Attributes;
@@ -25,7 +25,6 @@ import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
-import android.util.Log;
import android.util.Xml;
import java.io.IOException;
@@ -77,7 +76,7 @@ public abstract class GPXParser extends FileParser {
private cgCache cache;
private cgTrackable trackable = new cgTrackable();
- private cgLog log = new cgLog();
+ private LogEntry log = null;
private String type = null;
private String sym = null;
@@ -194,7 +193,7 @@ public abstract class GPXParser extends FileParser {
return null; // id not found
}
// get text for string
- String stringName = null;
+ String stringName;
try {
stringName = cgeoapplication.getInstance().getResources().getResourceName(stringId);
} catch (NullPointerException e) {
@@ -259,7 +258,7 @@ public abstract class GPXParser extends FileParser {
Double.valueOf(attrs.getValue("lon"))));
}
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to parse waypoint's latitude and/or longitude.");
+ Log.w("Failed to parse waypoint's latitude and/or longitude.");
}
}
});
@@ -295,7 +294,7 @@ public abstract class GPXParser extends FileParser {
final String key = cache.getGeocode();
if (result.containsKey(key)) {
- Log.w(Settings.tag, "Duplicate geocode during GPX import: " + key);
+ Log.w("Duplicate geocode during GPX import: " + key);
}
result.put(key, cache);
showProgressMessage(progressHandler, progressStream.getProgress());
@@ -346,7 +345,7 @@ public abstract class GPXParser extends FileParser {
try {
cache.setHidden(parseDate(body));
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to parse cache date: " + e.toString());
+ Log.w("Failed to parse cache date: " + e.toString());
}
}
});
@@ -437,7 +436,7 @@ public abstract class GPXParser extends FileParser {
@Override
public void end(String watchList) {
- cache.setOnWatchlist(Boolean.valueOf(watchList.trim()).booleanValue());
+ cache.setOnWatchlist(Boolean.valueOf(watchList.trim()));
}
});
@@ -468,7 +467,7 @@ public abstract class GPXParser extends FileParser {
cache.setDisabled(!attrs.getValue("available").equalsIgnoreCase("true"));
}
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to parse cache attributes.");
+ Log.w("Failed to parse cache attributes.");
}
}
});
@@ -548,7 +547,7 @@ public abstract class GPXParser extends FileParser {
try {
cache.setDifficulty(Float.parseFloat(body));
} catch (NumberFormatException e) {
- Log.w(Settings.tag, "Failed to parse difficulty: " + e.toString());
+ Log.w("Failed to parse difficulty: " + e.toString());
}
}
});
@@ -561,7 +560,7 @@ public abstract class GPXParser extends FileParser {
try {
cache.setTerrain(Float.parseFloat(body));
} catch (NumberFormatException e) {
- Log.w(Settings.tag, "Failed to parse terrain: " + e.toString());
+ Log.w("Failed to parse terrain: " + e.toString());
}
}
});
@@ -675,7 +674,7 @@ public abstract class GPXParser extends FileParser {
@Override
public void start(Attributes attrs) {
- log = new cgLog();
+ log = new LogEntry("", 0, LogType.LOG_UNKNOWN, "");
try {
if (attrs.getIndex("id") > -1) {
@@ -705,7 +704,7 @@ public abstract class GPXParser extends FileParser {
try {
log.date = parseDate(body).getTime();
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to parse log date: " + e.toString());
+ Log.w("Failed to parse log date: " + e.toString());
}
}
});
@@ -744,7 +743,7 @@ public abstract class GPXParser extends FileParser {
Xml.parse(progressStream, Xml.Encoding.UTF_8, root.getContentHandler());
return result.values();
} catch (SAXException e) {
- Log.e(Settings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString());
+ Log.e("Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString());
throw new ParserException("Cannot parse .gpx file as GPX " + version + ": could not parse XML", e);
}
}
@@ -821,9 +820,9 @@ public abstract class GPXParser extends FileParser {
private void createNoteFromGSAKUserdata() {
if (StringUtils.isBlank(cache.getPersonalNote())) {
final StringBuilder buffer = new StringBuilder();
- for (int i = 0; i < userData.length; i++) {
- if (StringUtils.isNotBlank(userData[i])) {
- buffer.append(' ').append(userData[i]);
+ for (final String anUserData : userData) {
+ if (StringUtils.isNotBlank(anUserData)) {
+ buffer.append(' ').append(anUserData);
}
}
final String note = buffer.toString().trim();
diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java
index 029d049..b17b203 100644
--- a/main/src/cgeo/geocaching/files/LocParser.java
+++ b/main/src/cgeo/geocaching/files/LocParser.java
@@ -1,21 +1,17 @@
package cgeo.geocaching.files;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgCoord;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.geopoint.GeopointParser;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
-import android.util.Log;
-
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -30,6 +26,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class LocParser extends FileParser {
+
private static final Pattern patternGeocode = Pattern
.compile("name id=\"([^\"]+)\"");
private static final Pattern patternLat = Pattern
@@ -45,10 +42,21 @@ public final class LocParser extends FileParser {
.compile("<container>([^<]+)</container>");
private static final Pattern patternName = Pattern.compile("CDATA\\[([^\\]]+)\\]");
+ private static final CacheSize[] SIZES = {
+ CacheSize.NOT_CHOSEN, // 1
+ CacheSize.MICRO, // 2
+ CacheSize.REGULAR, // 3
+ CacheSize.LARGE, // 4
+ CacheSize.VIRTUAL, // 5
+ CacheSize.OTHER, // 6
+ CacheSize.UNKNOWN, // 7
+ CacheSize.SMALL, // 8
+ };
+
private int listId;
public static void parseLoc(final SearchResult searchResult, final String fileContent) {
- final Map<String, cgCoord> cidCoords = parseCoordinates(fileContent);
+ final Map<String, cgCache> cidCoords = parseCoordinates(fileContent);
// save found cache coordinates
final HashSet<String> contained = new HashSet<String>();
@@ -59,12 +67,12 @@ public final class LocParser extends FileParser {
}
Set<cgCache> caches = cgeoapplication.getInstance().loadCaches(contained, LoadFlags.LOAD_CACHE_OR_DB);
for (cgCache cache : caches) {
- cgCoord coord = cidCoords.get(cache.getGeocode());
+ cgCache coord = cidCoords.get(cache.getGeocode());
copyCoordToCache(coord, cache);
}
}
- private static void copyCoordToCache(final cgCoord coord, final cgCache cache) {
+ private static void copyCoordToCache(final cgCache coord, final cgCache cache) {
cache.setCoords(coord.getCoords());
cache.setDifficulty(coord.getDifficulty());
cache.setTerrain(coord.getTerrain());
@@ -76,9 +84,8 @@ public final class LocParser extends FileParser {
}
}
- static Map<String, cgCoord> parseCoordinates(
- final String fileContent) {
- final Map<String, cgCoord> coords = new HashMap<String, cgCoord>();
+ static Map<String, cgCache> parseCoordinates(final String fileContent) {
+ final Map<String, cgCache> coords = new HashMap<String, cgCache>();
if (StringUtils.isBlank(fileContent)) {
return coords;
}
@@ -88,76 +95,25 @@ public final class LocParser extends FileParser {
// parse coordinates
for (String pointString : points) {
- final cgCoord pointCoord = new cgCoord();
-
- final Matcher matcherGeocode = patternGeocode.matcher(pointString);
- if (matcherGeocode.find()) {
- String geocode = matcherGeocode.group(1).trim().toUpperCase();
- pointCoord.setName(geocode);
- pointCoord.setGeocode(geocode);
- }
- final Matcher matcherName = patternName.matcher(pointString);
- if (matcherName.find()) {
- String name = matcherName.group(1).trim();
- pointCoord.setName(StringUtils.substringBeforeLast(name, " by ").trim());
- // owner = StringUtils.substringAfterLast(" by ").trim();
- }
- final Matcher matcherLat = patternLat.matcher(pointString);
- final Matcher matcherLon = patternLon.matcher(pointString);
- if (matcherLat.find() && matcherLon.find()) {
- pointCoord.setCoords(parsePoint(matcherLat.group(1).trim(), matcherLon.group(1).trim()));
- }
- final Matcher matcherDifficulty = patternDifficulty.matcher(pointString);
- if (matcherDifficulty.find()) {
- pointCoord.setDifficulty(Float.parseFloat(matcherDifficulty.group(1).trim()));
- }
- final Matcher matcherTerrain = patternTerrain.matcher(pointString);
- if (matcherTerrain.find()) {
- pointCoord.setTerrain(Float.parseFloat(matcherTerrain.group(1).trim()));
- }
- final Matcher matcherContainer = patternContainer.matcher(pointString);
- if (matcherContainer.find()) {
- final int size = Integer.parseInt(matcherContainer.group(1)
- .trim());
-
- if (size == 1) {
- pointCoord.setSize(CacheSize.NOT_CHOSEN);
- } else if (size == 2) {
- pointCoord.setSize(CacheSize.MICRO);
- } else if (size == 3) {
- pointCoord.setSize(CacheSize.REGULAR);
- } else if (size == 4) {
- pointCoord.setSize(CacheSize.LARGE);
- } else if (size == 5) {
- pointCoord.setSize(CacheSize.VIRTUAL);
- } else if (size == 6) {
- pointCoord.setSize(CacheSize.OTHER);
- } else if (size == 8) {
- pointCoord.setSize(CacheSize.SMALL);
- } else {
- pointCoord.setSize(CacheSize.UNKNOWN);
- }
- }
-
+ final cgCache pointCoord = parseCache(pointString);
if (StringUtils.isNotBlank(pointCoord.getGeocode())) {
coords.put(pointCoord.getGeocode(), pointCoord);
}
}
- Log.i(Settings.tag,
- "Coordinates found in .loc file: " + coords.size());
+ Log.i("Coordinates found in .loc file: " + coords.size());
return coords;
}
- private static Geopoint parsePoint(String latitude, String longitude) {
+ public static Geopoint parsePoint(final String latitude, final String longitude) {
// the loc file contains the coordinates as plain floating point values, therefore avoid using the GeopointParser
try {
return new Geopoint(Double.valueOf(latitude), Double.valueOf(longitude));
} catch (NumberFormatException e) {
- Log.e(Settings.tag, "LOC format has changed");
+ Log.e("LOC format has changed");
}
// fall back to parser, just in case the format changes
- return GeopointParser.parse(latitude, longitude);
+ return new Geopoint(latitude, longitude);
}
public LocParser(int listId) {
@@ -168,10 +124,10 @@ public final class LocParser extends FileParser {
public Collection<cgCache> parse(InputStream stream, CancellableHandler progressHandler) throws IOException, ParserException {
// TODO: progress reporting happens during reading stream only, not during parsing
String streamContent = readStream(stream, progressHandler).toString();
- final Map<String, cgCoord> coords = parseCoordinates(streamContent);
+ final Map<String, cgCache> coords = parseCoordinates(streamContent);
final List<cgCache> caches = new ArrayList<cgCache>();
- for (Entry<String, cgCoord> entry : coords.entrySet()) {
- cgCoord coord = entry.getValue();
+ for (Entry<String, cgCache> entry : coords.entrySet()) {
+ cgCache coord = entry.getValue();
if (StringUtils.isBlank(coord.getGeocode()) || StringUtils.isBlank(coord.getName())) {
continue;
}
@@ -185,7 +141,50 @@ public final class LocParser extends FileParser {
cache.setListId(listId);
cache.setDetailed(true);
}
- Log.i(Settings.tag, "Caches found in .loc file: " + caches.size());
+ Log.i("Caches found in .loc file: " + caches.size());
return caches;
}
+
+ public static cgCache parseCache(final String pointString) {
+ final cgCache cache = new cgCache();
+ final Matcher matcherGeocode = patternGeocode.matcher(pointString);
+ if (matcherGeocode.find()) {
+ final String geocode = matcherGeocode.group(1).trim().toUpperCase();
+ cache.setGeocode(geocode.toUpperCase());
+ }
+
+ final Matcher matcherName = patternName.matcher(pointString);
+ if (matcherName.find()) {
+ final String name = matcherName.group(1).trim();
+ cache.setName(StringUtils.substringBeforeLast(name, " by ").trim());
+ } else {
+ cache.setName(cache.getGeocode());
+ }
+
+ final Matcher matcherLat = patternLat.matcher(pointString);
+ final Matcher matcherLon = patternLon.matcher(pointString);
+ if (matcherLat.find() && matcherLon.find()) {
+ cache.setCoords(parsePoint(matcherLat.group(1).trim(), matcherLon.group(1).trim()));
+ }
+
+ final Matcher matcherDifficulty = patternDifficulty.matcher(pointString);
+ if (matcherDifficulty.find()) {
+ cache.setDifficulty(Float.parseFloat(matcherDifficulty.group(1).trim()));
+ }
+
+ final Matcher matcherTerrain = patternTerrain.matcher(pointString);
+ if (matcherTerrain.find()) {
+ cache.setTerrain(Float.parseFloat(matcherTerrain.group(1).trim()));
+ }
+
+ final Matcher matcherContainer = patternContainer.matcher(pointString);
+ if (matcherContainer.find()) {
+ final int size = Integer.parseInt(matcherContainer.group(1).trim());
+ if (size >= 1 && size <= 8) {
+ cache.setSize(SIZES[size - 1]);
+ }
+ }
+
+ return cache;
+ }
}
diff --git a/main/src/cgeo/geocaching/files/LocalStorage.java b/main/src/cgeo/geocaching/files/LocalStorage.java
index b5fa5f6..6853c08 100644
--- a/main/src/cgeo/geocaching/files/LocalStorage.java
+++ b/main/src/cgeo/geocaching/files/LocalStorage.java
@@ -1,18 +1,20 @@
package cgeo.geocaching.files;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.utils.CryptUtils;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Header;
import org.apache.http.HttpResponse;
import android.os.Environment;
-import android.util.Log;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -59,12 +61,7 @@ public class LocalStorage {
*/
static String getExtension(final String url) {
final String urlExt = StringUtils.substringAfterLast(url, ".");
- if (urlExt.length() > 4) {
- return "";
- } else if (urlExt.length() > 0) {
- return "." + urlExt;
- }
- return "";
+ return urlExt.length() >= 1 && urlExt.length() <= 4 ? "." + urlExt : "";
}
/**
@@ -143,7 +140,7 @@ public class LocalStorage {
* the entity whose content will be saved
* @param targetFile
* the target file, which will be created if necessary
- * @return true if the operation was successful, false otherwise
+ * @return true if the operation was successful, false otherwise, in which case the file will not exist
*/
public static boolean saveEntityToFile(final HttpResponse response, final File targetFile) {
if (response == null) {
@@ -151,16 +148,65 @@ public class LocalStorage {
}
try {
- return saveToFile(response.getEntity().getContent(), targetFile);
+ final boolean saved = saveToFile(response.getEntity().getContent(), targetFile);
+ saveHeader("etag", saved ? response : null, targetFile);
+ saveHeader("last-modified", saved ? response : null, targetFile);
+ return saved;
} catch (IOException e) {
- Log.e(Settings.tag, "LocalStorage.saveEntityToFile", e);
+ Log.e("LocalStorage.saveEntityToFile", e);
}
return false;
}
+ private static void saveHeader(final String name, final HttpResponse response, final File baseFile) {
+ final Header header = response != null ? response.getFirstHeader(name) : null;
+ final File file = filenameForHeader(baseFile, name);
+ if (header == null) {
+ file.delete();
+ } else {
+ saveToFile(new ByteArrayInputStream(header.getValue().getBytes()), file);
+ }
+ }
+
+ private static File filenameForHeader(final File baseFile, final String name) {
+ return new File(baseFile.getAbsolutePath() + "-" + name);
+ }
+
+ /**
+ * Get the saved header value for this file.
+ *
+ * @param baseFile
+ * the name of the cached resource
+ * @param name
+ * the name of the header ("etag" or "last-modified")
+ * @return null if no value has been cached, the value otherwise
+ */
+ public static String getSavedHeader(final File baseFile, final String name) {
+ try {
+ final File file = filenameForHeader(baseFile, name);
+ final FileReader f = new FileReader(file);
+ try {
+ // No header will be more than 256 bytes
+ final char[] value = new char[256];
+ final int count = f.read(value);
+ return new String(value, 0, count);
+ } finally {
+ f.close();
+ }
+ } catch (final FileNotFoundException e) {
+ // Do nothing, the file does not exist
+ } catch (final Exception e) {
+ Log.w("could not read saved header " + name + " for " + baseFile, e);
+ }
+ return null;
+ }
+
/**
* Save an HTTP response to a file.
+ * <p/>
+ * If the response could not be saved to the file due, for example, to a network error,
+ * the file will not exist when this method returns.
*
* @param entity
* the entity whose content will be saved
@@ -176,16 +222,18 @@ public class LocalStorage {
try {
try {
final FileOutputStream fos = new FileOutputStream(targetFile);
- try {
- return copy(inputStream, fos);
- } finally {
- fos.close();
+ final boolean written = copy(inputStream, fos);
+ fos.close();
+ if (!written) {
+ targetFile.delete();
}
+ return written;
} finally {
inputStream.close();
}
} catch (IOException e) {
- Log.e(Settings.tag, "LocalStorage.saveToFile", e);
+ Log.e("LocalStorage.saveToFile", e);
+ targetFile.delete();
}
return false;
}
@@ -208,7 +256,7 @@ public class LocalStorage {
input = new FileInputStream(source);
output = new FileOutputStream(destination);
} catch (FileNotFoundException e) {
- Log.e(Settings.tag, "LocalStorage.copy: could not open file", e);
+ Log.e("LocalStorage.copy: could not open file", e);
if (input != null) {
try {
input.close();
@@ -225,7 +273,7 @@ public class LocalStorage {
input.close();
output.close();
} catch (IOException e) {
- Log.e(Settings.tag, "LocalStorage.copy: could not close file", e);
+ Log.e("LocalStorage.copy: could not close file", e);
return false;
}
@@ -233,15 +281,16 @@ public class LocalStorage {
}
private static boolean copy(final InputStream input, final OutputStream output) {
- byte[] buffer = new byte[4096];
+ final byte[] buffer = new byte[4096];
int length;
try {
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
- output.flush(); // FIXME: is that necessary?
+ // Flushing is only necessary if the stream is not immediately closed afterwards.
+ // We rely on all callers to do that correctly outside of this method
} catch (IOException e) {
- Log.e(Settings.tag, "LocalStorage.copy: error when copying data", e);
+ Log.e("LocalStorage.copy: error when copying data", e);
return false;
}
@@ -267,7 +316,7 @@ public class LocalStorage {
}
}
}
-
+
return path.delete();
}
diff --git a/main/src/cgeo/geocaching/filter/AbstractFilter.java b/main/src/cgeo/geocaching/filter/AbstractFilter.java
index 49cf84a..e9f9003 100644
--- a/main/src/cgeo/geocaching/filter/AbstractFilter.java
+++ b/main/src/cgeo/geocaching/filter/AbstractFilter.java
@@ -26,4 +26,14 @@ abstract class AbstractFilter implements IFilter {
public String getName() {
return name;
}
+
+ /*
+ * show name in array adapter
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getName();
+ }
}
diff --git a/main/src/cgeo/geocaching/filter/AbstractRangeFilter.java b/main/src/cgeo/geocaching/filter/AbstractRangeFilter.java
new file mode 100644
index 0000000..ff3fce5
--- /dev/null
+++ b/main/src/cgeo/geocaching/filter/AbstractRangeFilter.java
@@ -0,0 +1,16 @@
+package cgeo.geocaching.filter;
+
+import cgeo.geocaching.cgeoapplication;
+
+
+abstract class AbstractRangeFilter extends AbstractFilter {
+
+ protected final float rangeMin;
+ protected final float rangeMax;
+
+ public AbstractRangeFilter(int ressourceId, int range) {
+ super(cgeoapplication.getInstance().getResources().getString(ressourceId) + ' ' + (range == 5 ? '5' : String.valueOf(range) + " + " + String.format("%.1f", range + 0.5)));
+ this.rangeMin = range;
+ rangeMax = rangeMin + 1f;
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/filter/AttributeFilter.java b/main/src/cgeo/geocaching/filter/AttributeFilter.java
index 7b8992b..2565178 100644
--- a/main/src/cgeo/geocaching/filter/AttributeFilter.java
+++ b/main/src/cgeo/geocaching/filter/AttributeFilter.java
@@ -11,7 +11,7 @@ import android.content.res.Resources;
import java.util.EnumSet;
-public class AttributeFilter extends AbstractFilter {
+class AttributeFilter extends AbstractFilter {
private final String attribute;
@@ -41,16 +41,20 @@ public class AttributeFilter extends AbstractFilter {
return fullCache.getAttributes().contains(attribute);
}
- public static IFilter[] getAllFilters() {
- final String packageName = cgeoapplication.getInstance().getBaseContext().getPackageName();
- final Resources res = cgeoapplication.getInstance().getResources();
+ public static class Factory implements IFilterFactory {
- final String[] ids = res.getStringArray(R.array.attribute_ids);
- final IFilter[] filters = new IFilter[ids.length];
- for (int i = 0; i < ids.length; i++) {
- filters[i] = new AttributeFilter(getName("attribute_" + ids[i], res, packageName), ids[i]);
+ @Override
+ public IFilter[] getFilters() {
+ final String packageName = cgeoapplication.getInstance().getBaseContext().getPackageName();
+ final Resources res = cgeoapplication.getInstance().getResources();
+
+ final String[] ids = res.getStringArray(R.array.attribute_ids);
+ final IFilter[] filters = new IFilter[ids.length];
+ for (int i = 0; i < ids.length; i++) {
+ filters[i] = new AttributeFilter(getName("attribute_" + ids[i], res, packageName), ids[i]);
+ }
+ return filters;
}
- return filters;
- }
+ }
}
diff --git a/main/src/cgeo/geocaching/filter/DifficultyFilter.java b/main/src/cgeo/geocaching/filter/DifficultyFilter.java
new file mode 100644
index 0000000..368c20f
--- /dev/null
+++ b/main/src/cgeo/geocaching/filter/DifficultyFilter.java
@@ -0,0 +1,31 @@
+package cgeo.geocaching.filter;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgCache;
+
+import java.util.ArrayList;
+
+class DifficultyFilter extends AbstractRangeFilter {
+
+ public DifficultyFilter(int difficulty) {
+ super(R.string.cache_difficulty, difficulty);
+ }
+
+ @Override
+ public boolean accepts(cgCache cache) {
+ return rangeMin <= cache.getDifficulty() && cache.getDifficulty() < rangeMax;
+ }
+
+ public static class Factory implements IFilterFactory {
+
+ @Override
+ public IFilter[] getFilters() {
+ final ArrayList<IFilter> filters = new ArrayList<IFilter>(5);
+ for (int difficulty = 1; difficulty <= 5; difficulty++) {
+ filters.add(new DifficultyFilter(difficulty));
+ }
+ return filters.toArray(new IFilter[filters.size()]);
+ }
+
+ }
+}
diff --git a/main/src/cgeo/geocaching/filter/FilterUserInterface.java b/main/src/cgeo/geocaching/filter/FilterUserInterface.java
new file mode 100644
index 0000000..1d22e52
--- /dev/null
+++ b/main/src/cgeo/geocaching/filter/FilterUserInterface.java
@@ -0,0 +1,122 @@
+package cgeo.geocaching.filter;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.Settings;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.activity.IAbstractActivity;
+import cgeo.geocaching.enumerations.CacheType;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.RunnableWithArgument;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.widget.ArrayAdapter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public final class FilterUserInterface {
+
+ private static class FactoryEntry {
+ private final String name;
+ private final Class<? extends IFilterFactory> filterFactory;
+
+ public FactoryEntry(final String name, final Class<? extends IFilterFactory> filterFactory) {
+ this.name = name;
+ this.filterFactory = filterFactory;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ private final IAbstractActivity activity;
+ private final ArrayList<FactoryEntry> registry;
+ private final Resources res;
+
+ public FilterUserInterface(final IAbstractActivity activity) {
+ this.activity = activity;
+ this.res = cgeoapplication.getInstance().getResources();
+
+ registry = new ArrayList<FactoryEntry>();
+ if (Settings.getCacheType() == CacheType.ALL) {
+ register(R.string.caches_filter_type, TypeFilter.Factory.class);
+ }
+ register(R.string.caches_filter_size, SizeFilter.Factory.class);
+ register(R.string.cache_terrain, TerrainFilter.Factory.class);
+ register(R.string.cache_difficulty, DifficultyFilter.Factory.class);
+ register(R.string.cache_attributes, AttributeFilter.Factory.class);
+ register(R.string.cache_status, StateFilter.Factory.class);
+ register(R.string.caches_filter_track, TrackablesFilter.class);
+ register(R.string.caches_filter_modified, ModifiedFilter.class);
+
+ // sort by localized names
+ Collections.sort(registry, new Comparator<FactoryEntry>() {
+
+ @Override
+ public int compare(FactoryEntry lhs, FactoryEntry rhs) {
+ return lhs.name.compareToIgnoreCase(rhs.name);
+ }
+ });
+
+ // reset shall be last
+ register(R.string.caches_filter_clear, null);
+ }
+
+ private void register(int resourceId, Class<? extends IFilterFactory> factoryClass) {
+ registry.add(new FactoryEntry(res.getString(resourceId), factoryClass));
+ }
+
+ public void selectFilter(final RunnableWithArgument<IFilter> runAfterwards) {
+ final AlertDialog.Builder builder = new AlertDialog.Builder((Activity) activity);
+ builder.setTitle(R.string.caches_filter);
+
+ final ArrayAdapter<FactoryEntry> adapter = new ArrayAdapter<FactoryEntry>((Activity) activity, android.R.layout.select_dialog_item, registry);
+
+ builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int itemIndex) {
+ FactoryEntry entry = adapter.getItem(itemIndex);
+ // reset?
+ if (entry.filterFactory == null) {
+ runAfterwards.run(null);
+ }
+ else {
+ try {
+ IFilterFactory factoryInstance = entry.filterFactory.newInstance();
+ selectFromFactory(factoryInstance, entry.name, runAfterwards);
+ } catch (Exception e) {
+ Log.e("selectFilter", e);
+ }
+ }
+ }
+ });
+
+ builder.create().show();
+ }
+
+ private void selectFromFactory(final IFilterFactory factory, final String menuTitle, final RunnableWithArgument<IFilter> runAfterwards) {
+ final IFilter[] filters = factory.getFilters();
+ if (filters.length == 1) {
+ runAfterwards.run(filters[0]);
+ return;
+ }
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder((Activity) activity);
+ builder.setTitle(menuTitle);
+
+ final ArrayAdapter<IFilter> adapter = new ArrayAdapter<IFilter>((Activity) activity, android.R.layout.select_dialog_item, filters);
+ builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ runAfterwards.run(filters[item]);
+ }
+ });
+
+ builder.create().show();
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/filter/IFilterFactory.java b/main/src/cgeo/geocaching/filter/IFilterFactory.java
new file mode 100644
index 0000000..3491fd7
--- /dev/null
+++ b/main/src/cgeo/geocaching/filter/IFilterFactory.java
@@ -0,0 +1,5 @@
+package cgeo.geocaching.filter;
+
+interface IFilterFactory {
+ public IFilter[] getFilters();
+}
diff --git a/main/src/cgeo/geocaching/filter/ModifiedFilter.java b/main/src/cgeo/geocaching/filter/ModifiedFilter.java
index 6063f58..f74bb4d 100644
--- a/main/src/cgeo/geocaching/filter/ModifiedFilter.java
+++ b/main/src/cgeo/geocaching/filter/ModifiedFilter.java
@@ -1,11 +1,13 @@
package cgeo.geocaching.filter;
+import cgeo.geocaching.R;
import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgeoapplication;
-public class ModifiedFilter extends AbstractFilter {
+class ModifiedFilter extends AbstractFilter implements IFilterFactory {
- public ModifiedFilter(String name) {
- super(name);
+ public ModifiedFilter() {
+ super(cgeoapplication.getInstance().getString(R.string.caches_filter_modified));
}
@Override
@@ -13,4 +15,9 @@ public class ModifiedFilter extends AbstractFilter {
// modified on GC
return cache.hasUserModifiedCoords() || cache.hasFinalDefined();
}
+
+ @Override
+ public IFilter[] getFilters() {
+ return new IFilter[] { this };
+ }
}
diff --git a/main/src/cgeo/geocaching/filter/SizeFilter.java b/main/src/cgeo/geocaching/filter/SizeFilter.java
index 4f0d830..b08c2ae 100644
--- a/main/src/cgeo/geocaching/filter/SizeFilter.java
+++ b/main/src/cgeo/geocaching/filter/SizeFilter.java
@@ -5,7 +5,7 @@ import cgeo.geocaching.enumerations.CacheSize;
import java.util.ArrayList;
-public class SizeFilter extends AbstractFilter {
+class SizeFilter extends AbstractFilter {
private final CacheSize cacheSize;
public SizeFilter(CacheSize cacheSize) {
@@ -23,14 +23,19 @@ public class SizeFilter extends AbstractFilter {
return cacheSize.getL10n();
}
- public static AbstractFilter[] getAllFilters() {
- final CacheSize[] cacheSizes = CacheSize.values();
- ArrayList<SizeFilter> filters = new ArrayList<SizeFilter>();
- for (CacheSize cacheSize : cacheSizes) {
- if (cacheSize != CacheSize.UNKNOWN) {
- filters.add(new SizeFilter(cacheSize));
+ public static class Factory implements IFilterFactory {
+
+ @Override
+ public IFilter[] getFilters() {
+ final CacheSize[] cacheSizes = CacheSize.values();
+ final ArrayList<SizeFilter> filters = new ArrayList<SizeFilter>();
+ for (CacheSize cacheSize : cacheSizes) {
+ if (cacheSize != CacheSize.UNKNOWN) {
+ filters.add(new SizeFilter(cacheSize));
+ }
}
+ return filters.toArray(new SizeFilter[filters.size()]);
}
- return filters.toArray(new SizeFilter[filters.size()]);
+
}
}
diff --git a/main/src/cgeo/geocaching/filter/StateFilter.java b/main/src/cgeo/geocaching/filter/StateFilter.java
index 454cc92..b086477 100644
--- a/main/src/cgeo/geocaching/filter/StateFilter.java
+++ b/main/src/cgeo/geocaching/filter/StateFilter.java
@@ -10,16 +10,18 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-public abstract class StateFilter extends AbstractFilter {
+abstract class StateFilter extends AbstractFilter {
- public StateFilter(String name) {
+ final static Resources res = cgeoapplication.getInstance().getResources();
+
+ protected StateFilter(String name) {
super(name);
}
- private static class StateFoundFilter extends StateFilter {
+ static class StateFoundFilter extends StateFilter {
- public StateFoundFilter(String name) {
- super(name);
+ public StateFoundFilter() {
+ super(res.getString(R.string.cache_status_found));
}
@Override
@@ -29,9 +31,9 @@ public abstract class StateFilter extends AbstractFilter {
}
- private static class StateArchivedFilter extends StateFilter {
- public StateArchivedFilter(String name) {
- super(name);
+ static class StateArchivedFilter extends StateFilter {
+ public StateArchivedFilter() {
+ super(res.getString(R.string.cache_status_archived));
}
@Override
@@ -40,9 +42,9 @@ public abstract class StateFilter extends AbstractFilter {
}
}
- private static class StateDisabledFilter extends StateFilter {
- public StateDisabledFilter(String name) {
- super(name);
+ static class StateDisabledFilter extends StateFilter {
+ public StateDisabledFilter() {
+ super(res.getString(R.string.cache_status_disabled));
}
@Override
@@ -51,9 +53,9 @@ public abstract class StateFilter extends AbstractFilter {
}
}
- private static class StatePremiumFilter extends StateFilter {
- public StatePremiumFilter(String name) {
- super(name);
+ static class StatePremiumFilter extends StateFilter {
+ public StatePremiumFilter() {
+ super(res.getString(R.string.cache_status_premium));
}
@Override
@@ -63,8 +65,8 @@ public abstract class StateFilter extends AbstractFilter {
}
private static class StateOfflineLogFilter extends StateFilter {
- public StateOfflineLogFilter(String name) {
- super(name);
+ public StateOfflineLogFilter() {
+ super(res.getString(R.string.cache_status_offline_log));
}
@Override
@@ -73,24 +75,28 @@ public abstract class StateFilter extends AbstractFilter {
}
}
- public static AbstractFilter[] getAllFilters() {
- final Resources res = cgeoapplication.getInstance().getResources();
- final ArrayList<StateFilter> filters = new ArrayList<StateFilter>();
- filters.add(new StateFoundFilter(res.getString(R.string.cache_status_found)));
- filters.add(new StateArchivedFilter(res.getString(R.string.cache_status_archived)));
- filters.add(new StateDisabledFilter(res.getString(R.string.cache_status_disabled)));
- filters.add(new StatePremiumFilter(res.getString(R.string.cache_status_premium)));
- filters.add(new StateOfflineLogFilter(res.getString(R.string.cache_status_offline_log)));
-
- Collections.sort(filters, new Comparator<StateFilter>() {
+ public static class Factory implements IFilterFactory {
- @Override
- public int compare(StateFilter filter1, StateFilter filter2) {
- return filter1.getName().compareToIgnoreCase(filter2.getName());
- }
- });
+ @Override
+ public IFilter[] getFilters() {
+ final ArrayList<StateFilter> filters = new ArrayList<StateFilter>();
+ filters.add(new StateFoundFilter());
+ filters.add(new StateArchivedFilter());
+ filters.add(new StateDisabledFilter());
+ filters.add(new StatePremiumFilter());
+ filters.add(new StateOfflineLogFilter());
+
+ Collections.sort(filters, new Comparator<StateFilter>() {
+
+ @Override
+ public int compare(StateFilter filter1, StateFilter filter2) {
+ return filter1.getName().compareToIgnoreCase(filter2.getName());
+ }
+ });
+
+ return filters.toArray(new StateFilter[filters.size()]);
+ }
- return filters.toArray(new StateFilter[filters.size()]);
}
}
diff --git a/main/src/cgeo/geocaching/filter/TerrainFilter.java b/main/src/cgeo/geocaching/filter/TerrainFilter.java
new file mode 100644
index 0000000..5cee87e
--- /dev/null
+++ b/main/src/cgeo/geocaching/filter/TerrainFilter.java
@@ -0,0 +1,31 @@
+package cgeo.geocaching.filter;
+
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgCache;
+
+import java.util.ArrayList;
+
+class TerrainFilter extends AbstractRangeFilter {
+
+ public TerrainFilter(int terrain) {
+ super(R.string.cache_terrain, terrain);
+ }
+
+ @Override
+ public boolean accepts(cgCache cache) {
+ return rangeMin <= cache.getTerrain() && cache.getTerrain() < rangeMax;
+ }
+
+ public static class Factory implements IFilterFactory {
+ @Override
+ public IFilter[] getFilters() {
+ final ArrayList<IFilter> filters = new ArrayList<IFilter>(5);
+ for (int terrain = 1; terrain <= 5; terrain++) {
+ filters.add(new TerrainFilter(terrain));
+ }
+ return filters.toArray(new IFilter[filters.size()]);
+ }
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/filter/TrackablesFilter.java b/main/src/cgeo/geocaching/filter/TrackablesFilter.java
index 99d888b..90def5b 100644
--- a/main/src/cgeo/geocaching/filter/TrackablesFilter.java
+++ b/main/src/cgeo/geocaching/filter/TrackablesFilter.java
@@ -1,14 +1,22 @@
package cgeo.geocaching.filter;
+import cgeo.geocaching.R;
import cgeo.geocaching.cgCache;
+import cgeo.geocaching.cgeoapplication;
-public class TrackablesFilter extends AbstractFilter {
- public TrackablesFilter(String name) {
- super(name);
+class TrackablesFilter extends AbstractFilter implements IFilterFactory {
+ public TrackablesFilter() {
+ super(cgeoapplication.getInstance().getString(R.string.caches_filter_track));
}
@Override
public boolean accepts(cgCache cache) {
return cache.hasTrackables();
}
+
+ @Override
+ public IFilter[] getFilters() {
+ return new IFilter[] { this };
+ }
+
}
diff --git a/main/src/cgeo/geocaching/filter/TypeFilter.java b/main/src/cgeo/geocaching/filter/TypeFilter.java
index bb32fdd..05b97e0 100644
--- a/main/src/cgeo/geocaching/filter/TypeFilter.java
+++ b/main/src/cgeo/geocaching/filter/TypeFilter.java
@@ -5,7 +5,7 @@ import cgeo.geocaching.enumerations.CacheType;
import java.util.ArrayList;
-public class TypeFilter extends AbstractFilter {
+class TypeFilter extends AbstractFilter {
private final CacheType cacheType;
public TypeFilter(final CacheType cacheType) {
@@ -23,14 +23,19 @@ public class TypeFilter extends AbstractFilter {
return cacheType.getL10n();
}
- public static IFilter[] getAllFilters() {
- final CacheType[] types = CacheType.values();
- ArrayList<IFilter> filters = new ArrayList<IFilter>(types.length);
- for (CacheType cacheType : types) {
- if (cacheType != CacheType.ALL) {
- filters.add(new TypeFilter(cacheType));
+ public static class Factory implements IFilterFactory {
+
+ @Override
+ public IFilter[] getFilters() {
+ final CacheType[] types = CacheType.values();
+ final ArrayList<IFilter> filters = new ArrayList<IFilter>(types.length);
+ for (CacheType cacheType : types) {
+ if (cacheType != CacheType.ALL) {
+ filters.add(new TypeFilter(cacheType));
+ }
}
+ return filters.toArray(new IFilter[filters.size()]);
}
- return filters.toArray(new TypeFilter[filters.size()]);
+
}
}
diff --git a/main/src/cgeo/geocaching/gcvote/GCVote.java b/main/src/cgeo/geocaching/gcvote/GCVote.java
index fa2af0d..5a00009 100644
--- a/main/src/cgeo/geocaching/gcvote/GCVote.java
+++ b/main/src/cgeo/geocaching/gcvote/GCVote.java
@@ -4,19 +4,17 @@ import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
-import cgeo.geocaching.utils.LeastRecentlyUsedCache;
+import cgeo.geocaching.utils.LeastRecentlyUsedMap;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
-import android.util.Log;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -29,7 +27,7 @@ public final class GCVote {
private static final Pattern patternVoteElement = Pattern.compile("<vote ([^>]+)>", Pattern.CASE_INSENSITIVE);
private static final int MAX_CACHED_RATINGS = 1000;
- private static LeastRecentlyUsedCache<String, GCVoteRating> ratingsCache = new LeastRecentlyUsedCache<String, GCVoteRating>(MAX_CACHED_RATINGS);
+ private static LeastRecentlyUsedMap<String, GCVoteRating> ratingsCache = new LeastRecentlyUsedMap.LruCache<String, GCVoteRating>(MAX_CACHED_RATINGS);
/**
* Get user rating for a given guid or geocode. For a guid first the ratings cache is checked
@@ -59,13 +57,12 @@ public final class GCVote {
}
final Map<String, GCVoteRating> ratings = getRating(guids, geocodes);
- if (ratings != null) {
- for (Entry<String, GCVoteRating> entry : ratings.entrySet()) {
- return entry.getValue();
- }
+
+ if (MapUtils.isEmpty(ratings)) {
+ return null;
}
- return null;
+ return ratings.values().iterator().next();
}
/**
@@ -96,12 +93,12 @@ public final class GCVote {
params.put("waypoints", StringUtils.join(geocodes.toArray(), ','));
}
params.put("version", "cgeo");
- final String page = Network.getResponseData(Network.request("http://gcvote.com/getVotes.php", params, false, false, false));
+ final String page = Network.getResponseData(Network.getRequest("http://gcvote.com/getVotes.php", params));
if (page == null) {
return null;
}
- String voteData = null;
+ String voteData;
final Matcher matcherVoteElement = patternVoteElement.matcher(page);
while (matcherVoteElement.find()) {
voteData = matcherVoteElement.group(1);
@@ -118,7 +115,7 @@ public final class GCVote {
}
}
} catch (Exception e) {
- Log.w(Settings.tag, "GCVote.getRating: Failed to parse guid");
+ Log.w("GCVote.getRating: Failed to parse guid");
}
if (guid == null) {
continue;
@@ -135,7 +132,7 @@ public final class GCVote {
}
}
} catch (Exception e) {
- Log.w(Settings.tag, "GCVote.getRating: Failed to parse loggedIn");
+ Log.w("GCVote.getRating: Failed to parse loggedIn");
}
float rating = 0;
@@ -145,7 +142,7 @@ public final class GCVote {
rating = Float.parseFloat(matcherRating.group(1));
}
} catch (Exception e) {
- Log.w(Settings.tag, "GCVote.getRating: Failed to parse rating");
+ Log.w("GCVote.getRating: Failed to parse rating");
}
if (rating <= 0) {
continue;
@@ -158,7 +155,7 @@ public final class GCVote {
votes = Integer.parseInt(matcherVotes.group(1));
}
} catch (Exception e) {
- Log.w(Settings.tag, "GCVote.getRating: Failed to parse vote count");
+ Log.w("GCVote.getRating: Failed to parse vote count");
}
if (votes < 0) {
continue;
@@ -172,7 +169,7 @@ public final class GCVote {
myVote = Float.parseFloat(matcherVote.group(1));
}
} catch (Exception e) {
- Log.w(Settings.tag, "GCVote.getRating: Failed to parse user's vote");
+ Log.w("GCVote.getRating: Failed to parse user's vote");
}
}
@@ -183,7 +180,7 @@ public final class GCVote {
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "GCVote.getRating: " + e.toString());
+ Log.e("GCVote.getRating: " + e.toString());
}
return ratings;
@@ -220,7 +217,7 @@ public final class GCVote {
"voteUser", String.format("%.1f", vote).replace(',', '.'),
"version", "cgeo");
- final String result = Network.getResponseData(Network.request("http://gcvote.com/setVote.php", params, false, false, false));
+ final String result = Network.getResponseData(Network.getRequest("http://gcvote.com/setVote.php", params));
return result.trim().equalsIgnoreCase("ok");
}
@@ -258,7 +255,7 @@ public final class GCVote {
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "GCvote.loadRatings: " + e.toString());
+ Log.e("GCvote.loadRatings: " + e.toString());
}
}
}
diff --git a/main/src/cgeo/geocaching/geopoint/Geopoint.java b/main/src/cgeo/geocaching/geopoint/Geopoint.java
index be4a622..974c902 100644
--- a/main/src/cgeo/geocaching/geopoint/Geopoint.java
+++ b/main/src/cgeo/geocaching/geopoint/Geopoint.java
@@ -1,25 +1,28 @@
package cgeo.geocaching.geopoint;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.ICoordinates;
+import cgeo.geocaching.R;
import cgeo.geocaching.geopoint.GeopointFormatter.Format;
+import cgeo.geocaching.geopoint.direction.DDD;
+import cgeo.geocaching.geopoint.direction.DMM;
+import cgeo.geocaching.geopoint.direction.DMS;
+import cgeo.geocaching.geopoint.direction.Direction;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import android.location.Location;
-import android.util.Log;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
+import android.os.Parcel;
+import android.os.Parcelable;
/**
* Abstraction of geographic point.
*/
-public final class Geopoint
-{
+public final class Geopoint implements ICoordinates, Parcelable {
public static final double deg2rad = Math.PI / 180;
public static final double rad2deg = 180 / Math.PI;
public static final float erad = 6371.0f;
@@ -47,29 +50,18 @@ public final class Geopoint
}
/**
- * Creates new Geopoint with given latitude and longitude (both microdegree).
- *
- * @param lat
- * latitude
- * @param lon
- * longitude
- */
- public Geopoint(final int lat, final int lon)
- {
- this(lat / 1e6, lon / 1e6);
- }
-
- /**
* Creates new Geopoint with latitude and longitude parsed from string.
*
* @param text
* string to parse
- * @throws GeopointParser.ParseException
+ * @throws Geopoint.ParseException
* if the string cannot be parsed
- * @see GeopointParser.parse()
+ * @see GeopointParser#parse(String)
*/
public Geopoint(final String text) {
- this(GeopointParser.parseLatitude(text), GeopointParser.parseLongitude(text));
+ final Geopoint parsed = GeopointParser.parse(text);
+ this.latitude = parsed.latitude;
+ this.longitude = parsed.longitude;
}
/**
@@ -79,9 +71,9 @@ public final class Geopoint
* latitude string to parse
* @param lonText
* longitude string to parse
- * @throws GeopointParser.ParseException
+ * @throws Geopoint.ParseException
* if any argument string cannot be parsed
- * @see GeopointParser.parse()
+ * @see GeopointParser#parse(String, String)
*/
public Geopoint(final String latText, final String lonText) {
this(GeopointParser.parseLatitude(latText), GeopointParser.parseLongitude(lonText));
@@ -90,7 +82,7 @@ public final class Geopoint
/**
* Creates new Geopoint with given Location.
*
- * @param gp
+ * @param loc
* the Location to clone
*/
public Geopoint(final Location loc) {
@@ -98,6 +90,17 @@ public final class Geopoint
}
/**
+ * Create new Geopoint from Parcel.
+ *
+ * @param in
+ * a Parcel to read the saved data from
+ */
+ public Geopoint(final Parcel in) {
+ latitude = in.readDouble();
+ longitude = in.readDouble();
+ }
+
+ /**
* Get latitude in degree.
*
* @return latitude
@@ -114,7 +117,7 @@ public final class Geopoint
*/
public int getLatitudeE6()
{
- return (int) (latitude * 1E6);
+ return (int) Math.round(latitude * 1E6);
}
/**
@@ -134,7 +137,7 @@ public final class Geopoint
*/
public int getLongitudeE6()
{
- return (int) (longitude * 1E6);
+ return (int) Math.round(longitude * 1E6);
}
/**
@@ -200,16 +203,21 @@ public final class Geopoint
return new Geopoint(rlat * rad2deg, rlon * rad2deg);
}
- /**
- * Checks if given Geopoint is identical with this Geopoint.
- *
- * @param gp
- * Geopoint to check
- * @return true if identical, false otherwise
- */
- public boolean isEqualTo(Geopoint gp)
- {
- return null != gp && gp.latitude == latitude && gp.longitude == longitude;
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || !(obj instanceof Geopoint)) {
+ return false;
+ }
+ final Geopoint gp = (Geopoint) obj;
+ return getLatitudeE6() == gp.getLatitudeE6() && getLongitudeE6() == gp.getLongitudeE6();
+ }
+
+ @Override
+ public int hashCode() {
+ return getLatitudeE6() ^ getLongitudeE6();
}
/**
@@ -242,7 +250,7 @@ public final class Geopoint
/**
* Returns formatted coordinates with default format.
* Default format is decimalminutes, e.g. N 52° 36.123 E 010° 03.456
- *
+ *
* @return formatted coordinates
*/
@Override
@@ -299,188 +307,27 @@ public final class Geopoint
return dms;
}
- /* Constant values needed for calculation */
- private static final double D60 = 60.0d;
- private static final double D1000 = 1000.0d;
- private static final double D3600 = 3600.0d;
- private static final BigDecimal BD_SIXTY = BigDecimal.valueOf(D60);
- private static final BigDecimal BD_THOUSAND = BigDecimal.valueOf(D1000);
- private static final BigDecimal BD_ONEHOUNDREDTHOUSAND = BigDecimal.valueOf(100000.0d);
-
- /**
- * Value type for the direction.
- */
- public static class Direction {
- /** latitude direction, 'N' or 'S' */
- public final char latDir;
- /** longitude direction, 'E' or 'W' */
- public final char lonDir;
-
- private Direction(final double latSigned, final double lonSigned) {
- latDir = latSigned < 0 ? 'S' : 'N';
- lonDir = lonSigned < 0 ? 'W' : 'E';
- }
-
- protected static String addZeros(final int value, final int len) {
- return StringUtils.leftPad(Integer.toString(value), len, '0');
- }
- }
-
- /**
- * Value type for the DDD.DDDDD format.
- */
- public static final class DDD extends Direction {
-
- /** latitude degree value */
- public final int latDeg;
- /** fractional part of the latitude degree value */
- public final int latDegFrac;
-
- public final int lonDeg;
- public final int lonDegFrac;
-
- private DDD(final double latSigned, final double lonSigned) {
- super(latSigned, lonSigned);
- BigDecimal bdLat = BigDecimal.valueOf(latSigned).abs();
- latDeg = bdLat.intValue();
- BigDecimal bdLatFrac = bdLat.subtract(BigDecimal.valueOf(latDeg)).multiply(BD_ONEHOUNDREDTHOUSAND);
- latDegFrac = bdLatFrac.setScale(0, RoundingMode.HALF_UP).intValue();
-
- BigDecimal bdlon = BigDecimal.valueOf(lonSigned).abs();
- lonDeg = bdlon.intValue();
- BigDecimal bdLonFrac = bdlon.subtract(BigDecimal.valueOf(lonDeg)).multiply(BD_ONEHOUNDREDTHOUSAND);
- lonDegFrac = bdLonFrac.setScale(0, RoundingMode.HALF_UP).intValue();
- }
-
- public static Geopoint createGeopoint(final String latDir, final String latDeg, final String latDegFrac,
- final String lonDir, final String lonDeg, final String lonDegFrac) {
- double lat = 0.0d;
- double lon = 0.0d;
- try {
- lat = Double.parseDouble(latDeg + "." + addZeros(Integer.parseInt(latDegFrac), 5));
- lon = Double.parseDouble(lonDeg + "." + addZeros(Integer.parseInt(lonDegFrac), 5));
- } catch (NumberFormatException e) {
- }
- lat *= "S".equalsIgnoreCase(latDir) ? -1 : 1;
- lon *= "W".equalsIgnoreCase(lonDir) ? -1 : 1;
- return new Geopoint(lat, lon);
- }
- }
-
- public static final class DMM extends Direction {
-
- public final int latDeg;
- public final double latMinRaw;
- public final int latMin;
- public final int latMinFrac;
-
- public final int lonDeg;
- public final double lonMinRaw;
- public final int lonMin;
- public final int lonMinFrac;
-
- private DMM(final double latSigned, final double lonSigned) {
- super(latSigned, lonSigned);
- BigDecimal bdLat = BigDecimal.valueOf(latSigned).abs();
- latDeg = bdLat.intValue();
- BigDecimal bdLatMin = bdLat.subtract(BigDecimal.valueOf(latDeg)).multiply(BD_SIXTY);
- // Rounding here ...
- bdLatMin = bdLatMin.setScale(3, RoundingMode.HALF_UP);
- latMinRaw = bdLatMin.doubleValue();
- latMin = bdLatMin.intValue();
- BigDecimal bdLatMinFrac = bdLatMin.subtract(BigDecimal.valueOf(latMin)).multiply(BD_THOUSAND);
- latMinFrac = bdLatMinFrac.setScale(0, RoundingMode.HALF_UP).intValue();
-
- BigDecimal bdlon = BigDecimal.valueOf(lonSigned).abs();
- lonDeg = bdlon.intValue();
- BigDecimal bdLonMin = bdlon.subtract(BigDecimal.valueOf(lonDeg)).multiply(BD_SIXTY);
- // Rounding here ...
- bdLonMin = bdLonMin.setScale(3, RoundingMode.HALF_UP);
- lonMinRaw = bdLonMin.doubleValue();
- lonMin = bdLonMin.intValue();
- BigDecimal bdLonMinFrac = bdLonMin.subtract(BigDecimal.valueOf(lonMin)).multiply(BD_THOUSAND);
- lonMinFrac = bdLonMinFrac.setScale(0, RoundingMode.HALF_UP).intValue();
- }
-
- public static Geopoint createGeopoint(final String latDir, final String latDeg, final String latMin, final String latMinFrac,
- final String lonDir, final String lonDeg, final String lonMin, final String lonMinFrac) {
- double lat = 0.0d;
- double lon = 0.0d;
- try {
- lat = Double.parseDouble(latDeg) + Double.parseDouble(latMin + "." + addZeros(Integer.parseInt(latMinFrac), 3)) / D60;
- lon = Double.parseDouble(lonDeg) + Double.parseDouble(lonMin + "." + addZeros(Integer.parseInt(lonMinFrac), 3)) / D60;
- } catch (NumberFormatException e) {
- }
- lat *= "S".equalsIgnoreCase(latDir) ? -1 : 1;
- lon *= "W".equalsIgnoreCase(lonDir) ? -1 : 1;
- return new Geopoint(lat, lon);
- }
- }
-
- public static final class DMS extends Direction {
-
- public final int latDeg;
- public final int latMin;
- public final double latSecRaw;
- public final int latSec;
- public final int latSecFrac;
-
- public final int lonDeg;
- public final int lonMin;
- public final double lonSecRaw;
- public final int lonSec;
- public final int lonSecFrac;
-
- private DMS(final double latSigned, final double lonSigned) {
- super(latSigned, lonSigned);
- BigDecimal bdLat = BigDecimal.valueOf(latSigned).abs();
- latDeg = bdLat.intValue();
- BigDecimal bdLatMin = bdLat.subtract(BigDecimal.valueOf(latDeg)).multiply(BD_SIXTY);
- latMin = bdLatMin.intValue();
- BigDecimal bdLatSec = bdLatMin.subtract(BigDecimal.valueOf(latMin)).multiply(BD_SIXTY);
- // Rounding here ...
- bdLatSec = bdLatSec.setScale(3, RoundingMode.HALF_UP);
- latSecRaw = bdLatSec.doubleValue();
- latSec = bdLatSec.intValue();
- BigDecimal bdLatSecFrac = bdLatSec.subtract(BigDecimal.valueOf(latSec)).multiply(BD_THOUSAND);
- latSecFrac = bdLatSecFrac.setScale(0, RoundingMode.HALF_UP).intValue();
-
- BigDecimal bdlon = BigDecimal.valueOf(lonSigned).abs();
- lonDeg = bdlon.intValue();
- BigDecimal bdLonMin = bdlon.subtract(BigDecimal.valueOf(lonDeg)).multiply(BD_SIXTY);
- lonMin = bdLonMin.intValue();
- BigDecimal bdLonSec = bdLonMin.subtract(BigDecimal.valueOf(lonMin)).multiply(BD_SIXTY);
- // Rounding here ...
- bdLonSec = bdLonSec.setScale(3, RoundingMode.HALF_UP);
- lonSecRaw = bdLonSec.doubleValue();
- lonSec = bdLonSec.intValue();
- BigDecimal bdLonSecFrac = bdLonSec.subtract(BigDecimal.valueOf(lonSec)).multiply(BD_THOUSAND);
- lonSecFrac = bdLonSecFrac.setScale(0, RoundingMode.HALF_UP).intValue();
- }
+ abstract public static class GeopointException
+ extends RuntimeException
+ {
+ private static final long serialVersionUID = 1L;
- public static Geopoint createGeopoint(final String latDir, final String latDeg, final String latMin, final String latSec, final String latSecFrac,
- final String lonDir, final String lonDeg, final String lonMin, final String lonSec, final String lonSecFrac) {
- double lat = 0.0d;
- double lon = 0.0d;
- try {
- lat = Double.parseDouble(latDeg) + Double.parseDouble(latMin) / D60 + Double.parseDouble(latSec + "." + addZeros(Integer.parseInt(latSecFrac), 3)) / D3600;
- lon = Double.parseDouble(lonDeg) + Double.parseDouble(lonMin) / D60 + Double.parseDouble(lonSec + "." + addZeros(Integer.parseInt(lonSecFrac), 3)) / D3600;
- } catch (NumberFormatException e) {
- }
- lat *= "S".equalsIgnoreCase(latDir) ? -1 : 1;
- lon *= "W".equalsIgnoreCase(lonDir) ? -1 : 1;
- return new Geopoint(lat, lon);
+ public GeopointException(String msg)
+ {
+ super(msg);
}
}
- abstract public static class GeopointException
- extends RuntimeException
+ public static class ParseException
+ extends GeopointException
{
private static final long serialVersionUID = 1L;
+ public final int resource;
- public GeopointException(String msg)
+ public ParseException(final String msg, final GeopointParser.LatLon faulty)
{
super(msg);
+ resource = faulty == GeopointParser.LatLon.LAT ? R.string.err_parse_lat : R.string.err_parse_lon;
}
}
@@ -506,10 +353,38 @@ public final class Geopoint
return result.getDouble("elevation");
}
} catch (Exception e) {
- Log.w(Settings.tag, "cgBase.getElevation: " + e.toString());
+ Log.w("cgBase.getElevation: " + e.toString());
}
return null;
}
+ //FIXME: this interface implementation is totally confusing as it returns the class itself.
+ // it can therefore be removed completely (and any invocation of it) without any disadvantages
+ @Override
+ public Geopoint getCoords() {
+ return this;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(final Parcel dest, final int flags) {
+ dest.writeDouble(latitude);
+ dest.writeDouble(longitude);
+ }
+
+ public static final Parcelable.Creator<Geopoint> CREATOR = new Parcelable.Creator<Geopoint>() {
+ public Geopoint createFromParcel(final Parcel in) {
+ return new Geopoint(in);
+ }
+
+ public Geopoint[] newArray(final int size) {
+ return new Geopoint[size];
+ }
+ };
+
}
diff --git a/main/src/cgeo/geocaching/geopoint/GeopointFormatter.java b/main/src/cgeo/geocaching/geopoint/GeopointFormatter.java
index d0baee9..43f83a3 100644
--- a/main/src/cgeo/geocaching/geopoint/GeopointFormatter.java
+++ b/main/src/cgeo/geocaching/geopoint/GeopointFormatter.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.geopoint;
-import cgeo.geocaching.geopoint.Geopoint.DMM;
-import cgeo.geocaching.geopoint.Geopoint.DMS;
+import cgeo.geocaching.geopoint.direction.DMM;
+import cgeo.geocaching.geopoint.direction.DMS;
import java.util.Locale;
diff --git a/main/src/cgeo/geocaching/geopoint/GeopointParser.java b/main/src/cgeo/geocaching/geopoint/GeopointParser.java
index ad5d6ba..7604b9d 100644
--- a/main/src/cgeo/geocaching/geopoint/GeopointParser.java
+++ b/main/src/cgeo/geocaching/geopoint/GeopointParser.java
@@ -1,7 +1,5 @@
package cgeo.geocaching.geopoint;
-import cgeo.geocaching.R;
-import cgeo.geocaching.geopoint.Geopoint.GeopointException;
import org.apache.commons.lang3.StringUtils;
@@ -11,8 +9,7 @@ import java.util.regex.Pattern;
/**
* Parse coordinates.
*/
-public class GeopointParser
-{
+class GeopointParser {
private static class ResultWrapper {
final double result;
final int matcherPos;
@@ -29,7 +26,7 @@ public class GeopointParser
private static final Pattern patternLat = Pattern.compile("\\b([NS])\\s*(\\d+)°?(?:\\s*(\\d+)(?:[.,](\\d+)|'?\\s*(\\d+(?:[.,]\\d+)?)(?:''|\")?)?)?", Pattern.CASE_INSENSITIVE);
private static final Pattern patternLon = Pattern.compile("\\b([WE])\\s*(\\d+)°?(?:\\s*(\\d+)(?:[.,](\\d+)|'?\\s*(\\d+(?:[.,]\\d+)?)(?:''|\")?)?)?", Pattern.CASE_INSENSITIVE);
- private enum LatLon
+ enum LatLon
{
LAT,
LON
@@ -52,7 +49,7 @@ public class GeopointParser
* @param text
* the string to parse
* @return an Geopoint with parsed latitude and longitude
- * @throws ParseException
+ * @throws Geopoint.ParseException
* if lat or lon could not be parsed
*/
public static Geopoint parse(final String text)
@@ -63,7 +60,7 @@ public class GeopointParser
final ResultWrapper longitudeWrapper = parseHelper(text.substring(latitudeWrapper.matcherPos + latitudeWrapper.matcherLength), LatLon.LON);
if (longitudeWrapper.matcherPos - (latitudeWrapper.matcherPos + latitudeWrapper.matcherLength) >= 10) {
- throw new ParseException("Distance between latitude and longitude text is to large.", LatLon.LON);
+ throw new Geopoint.ParseException("Distance between latitude and longitude text is to large.", LatLon.LON);
}
final double lon = longitudeWrapper.result;
@@ -89,7 +86,7 @@ public class GeopointParser
* @param longitude
* the longitude string to parse
* @return an Geopoint with parsed latitude and longitude
- * @throws ParseException
+ * @throws Geopoint.ParseException
* if lat or lon could not be parsed
*/
public static Geopoint parse(final String latitude, final String longitude)
@@ -129,32 +126,31 @@ public class GeopointParser
return new ResultWrapper(sign * (degree + minutes / 60.0 + seconds / 3600.0), matcher.start(), matcher.group().length());
- } else {
+ }
- // Nothing found with "N 52...", try to match string as decimaldegree
- try {
- final String[] items = StringUtils.split(text.trim());
- if (items.length > 0) {
- final int index = (latlon == LatLon.LON ? items.length - 1 : 0);
- final int pos = (latlon == LatLon.LON ? text.lastIndexOf(items[index]) : text.indexOf(items[index]));
- return new ResultWrapper(Double.parseDouble(items[index]), pos, items[index].length());
- }
- } catch (NumberFormatException e) {
- // The right exception will be raised below.
+ // Nothing found with "N 52...", try to match string as decimaldegree
+ try {
+ final String[] items = StringUtils.split(text.trim());
+ if (items.length > 0) {
+ final int index = (latlon == LatLon.LON ? items.length - 1 : 0);
+ final int pos = (latlon == LatLon.LON ? text.lastIndexOf(items[index]) : text.indexOf(items[index]));
+ return new ResultWrapper(Double.parseDouble(items[index]), pos, items[index].length());
}
+ } catch (NumberFormatException e) {
+ // The right exception will be raised below.
}
- throw new ParseException("Could not parse coordinates as " + latlon + ": \"" + text + "\"", latlon);
+ throw new Geopoint.ParseException("Could not parse coordinates as " + latlon + ": \"" + text + "\"", latlon);
}
/**
* Parses latitude out of a given string.
*
- * @see parse()
+ * @see #parse(String)
* @param text
* the string to be parsed
* @return the latitude as decimal degree
- * @throws ParseException
+ * @throws Geopoint.ParseException
* if latitude could not be parsed
*/
public static double parseLatitude(final String text)
@@ -165,28 +161,15 @@ public class GeopointParser
/**
* Parses longitude out of a given string.
*
- * @see parse()
+ * @see #parse(String)
* @param text
* the string to be parsed
* @return the longitude as decimal degree
- * @throws ParseException
+ * @throws Geopoint.ParseException
* if longitude could not be parsed
*/
public static double parseLongitude(final String text)
{
return parseHelper(text, LatLon.LON).result;
}
-
- public static class ParseException
- extends GeopointException
- {
- private static final long serialVersionUID = 1L;
- public final int resource;
-
- public ParseException(final String msg, final LatLon faulty)
- {
- super(msg);
- resource = faulty == LatLon.LAT ? R.string.err_parse_lat : R.string.err_parse_lon;
- }
- }
}
diff --git a/main/src/cgeo/geocaching/geopoint/HumanDistance.java b/main/src/cgeo/geocaching/geopoint/HumanDistance.java
index 278bb7b..25d1bb7 100644
--- a/main/src/cgeo/geocaching/geopoint/HumanDistance.java
+++ b/main/src/cgeo/geocaching/geopoint/HumanDistance.java
@@ -2,41 +2,48 @@ package cgeo.geocaching.geopoint;
import cgeo.geocaching.Settings;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
public class HumanDistance {
- public static String getHumanDistance(final Float distanceKilometers) {
- if (distanceKilometers == null) {
- return "?";
- }
+ public static ImmutablePair<Double, String> scaleUnit(final double distanceKilometers) {
+ double distance;
+ String units;
if (Settings.isUseMetricUnits()) {
- if (distanceKilometers > 100) {
- return String.format("%d", Math.round(distanceKilometers)) + " km";
- } else if (distanceKilometers > 10) {
- return String.format("%.1f", Double.valueOf(Math.round(distanceKilometers * 10.0) / 10.0)) + " km";
- } else if (distanceKilometers > 1) {
- return String.format("%.2f", Double.valueOf(Math.round(distanceKilometers * 100.0) / 100.0)) + " km";
- } else if (distanceKilometers > 0.1) {
- return String.format("%d", Math.round(distanceKilometers * 1000.0)) + " m";
- } else if (distanceKilometers > 0.01) {
- return String.format("%.1f", Double.valueOf(Math.round(distanceKilometers * 1000.0 * 10.0) / 10.0)) + " m";
+ if (distanceKilometers >= 1) {
+ distance = distanceKilometers;
+ units = "km";
} else {
- return String.format("%.2f", Double.valueOf(Math.round(distanceKilometers * 1000.0 * 100.0) / 100.0)) + " m";
+ distance = distanceKilometers * 1000;
+ units = "m";
}
} else {
- final float miles = distanceKilometers / IConversion.MILES_TO_KILOMETER;
- if (distanceKilometers > 100) {
- return String.format("%d", Math.round(miles)) + " mi";
- } else if (distanceKilometers > 0.5) {
- return String.format("%.1f", Double.valueOf(Math.round(miles * 10.0) / 10.0)) + " mi";
- } else if (distanceKilometers > 0.1) {
- return String.format("%.2f", Double.valueOf(Math.round(miles * 100.0) / 100.0)) + " mi";
- } else if (distanceKilometers > 0.05) {
- return String.format("%d", Math.round(miles * 5280.0)) + " ft";
- } else if (distanceKilometers > 0.01) {
- return String.format("%.1f", Double.valueOf(Math.round(miles * 5280 * 10.0) / 10.0)) + " ft";
+ distance = distanceKilometers / IConversion.MILES_TO_KILOMETER;
+ if (distance >= 0.1) {
+ units = "mi";
} else {
- return String.format("%.2f", Double.valueOf(Math.round(miles * 5280 * 100.0) / 100.0)) + " ft";
+ distance *= 5280;
+ units = "ft";
}
}
+ return new ImmutablePair<Double, String>(distance, units);
+ }
+
+ public static String getHumanDistance(final Float distanceKilometers) {
+ if (distanceKilometers == null) {
+ return "?";
+ }
+
+ final ImmutablePair<Double, String> scaled = scaleUnit(distanceKilometers);
+ String formatString;
+ if (scaled.left >= 100) {
+ formatString = "%.0f";
+ } else if (scaled.left >= 10) {
+ formatString = "%.1f";
+ } else {
+ formatString = "%.2f";
+ }
+
+ return String.format(formatString + " %s", scaled.left, scaled.right);
}
}
diff --git a/main/src/cgeo/geocaching/geopoint/Viewport.java b/main/src/cgeo/geocaching/geopoint/Viewport.java
index 4d46970..1eeadce 100644
--- a/main/src/cgeo/geocaching/geopoint/Viewport.java
+++ b/main/src/cgeo/geocaching/geopoint/Viewport.java
@@ -1,8 +1,11 @@
package cgeo.geocaching.geopoint;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.ICoordinates;
+
+import java.util.Locale;
+import java.util.Set;
+
-import android.util.Log;
public class Viewport {
@@ -10,19 +13,25 @@ public class Viewport {
public final Geopoint bottomLeft;
public final Geopoint topRight;
- public Viewport(final Geopoint bottomLeft, final Geopoint topRight) {
- this.bottomLeft = bottomLeft;
- this.topRight = topRight;
- this.center = new Geopoint((bottomLeft.getLatitude() + topRight.getLatitude()) / 2,
- (bottomLeft.getLongitude() + topRight.getLongitude()) / 2);
+ public Viewport(final ICoordinates point1, final ICoordinates point2) {
+ final Geopoint gp1 = point1.getCoords();
+ final Geopoint gp2 = point2.getCoords();
+ this.bottomLeft = new Geopoint(Math.min(gp1.getLatitude(), gp2.getLatitude()),
+ Math.min(gp1.getLongitude(), gp2.getLongitude()));
+ this.topRight = new Geopoint(Math.max(gp1.getLatitude(), gp2.getLatitude()),
+ Math.max(gp1.getLongitude(), gp2.getLongitude()));
+ this.center = new Geopoint((gp1.getLatitude() + gp2.getLatitude()) / 2,
+ (gp1.getLongitude() + gp2.getLongitude()) / 2);
}
- public Viewport(final Geopoint center, final double latSpan, final double lonSpan) {
- this.center = center;
- final double centerLat = center.getLatitude();
- final double centerLon = center.getLongitude();
- bottomLeft = new Geopoint(centerLat - latSpan / 2, centerLon - lonSpan / 2);
- topRight = new Geopoint(centerLat + latSpan / 2, centerLon + lonSpan / 2);
+ public Viewport(final ICoordinates center, final double latSpan, final double lonSpan) {
+ this.center = center.getCoords();
+ final double centerLat = this.center.getLatitude();
+ final double centerLon = this.center.getLongitude();
+ final double latHalfSpan = Math.abs(latSpan) / 2;
+ final double lonHalfSpan = Math.abs(lonSpan) / 2;
+ bottomLeft = new Geopoint(centerLat - latHalfSpan, centerLon - lonHalfSpan);
+ topRight = new Geopoint(centerLat + latHalfSpan, centerLon + lonHalfSpan);
}
public double getLatitudeMin() {
@@ -45,78 +54,125 @@ public class Viewport {
return center;
}
+ public double getLatitudeSpan() {
+ return getLatitudeMax() - getLatitudeMin();
+ }
+
+ public double getLongitudeSpan() {
+ return getLongitudeMax() - getLongitudeMin();
+ }
+
+ /**
+ * Check whether a point is contained in this viewport.
+ *
+ * @param point
+ * the coordinates to check
+ * @return true if the point is contained in this viewport, false otherwise
+ */
+ public boolean contains(final ICoordinates point) {
+ final Geopoint coords = point.getCoords();
+ return coords.getLongitudeE6() >= bottomLeft.getLongitudeE6()
+ && coords.getLongitudeE6() <= topRight.getLongitudeE6()
+ && coords.getLatitudeE6() >= bottomLeft.getLatitudeE6()
+ && coords.getLatitudeE6() <= topRight.getLatitudeE6();
+ }
+
@Override
public String toString() {
return "(" + bottomLeft.toString() + "," + topRight.toString() + ")";
}
/**
- * Check if coordinates are located in a viewport (defined by its center and span
- * in each direction).
+ * Check whether another viewport is fully included into the current one.
*
- * @param centerLat
- * the viewport center latitude
- * @param centerLon
- * the viewport center longitude
- * @param spanLat
- * the latitude span
- * @param spanLon
- * the longitude span
- * @param coords
- * the coordinates to check
- * @return true if the coordinates are in the viewport
+ * @param vp
+ * the other viewport
+ * @return true if the vp is fully included into this one, false otherwise
*/
- public static boolean isCacheInViewPort(int centerLat, int centerLon, int spanLat, int spanLon, final Geopoint coords) {
- return 2 * Math.abs(coords.getLatitudeE6() - centerLat) <= Math.abs(spanLat) &&
- 2 * Math.abs(coords.getLongitudeE6() - centerLon) <= Math.abs(spanLon);
+ public boolean includes(final Viewport vp) {
+ return contains(vp.bottomLeft) && contains(vp.topRight);
}
/**
- * Check if an area is located in a viewport (defined by its center and span
- * in each direction).
+ * Return the "where" part of the string appropriate for a SQL query.
*
- * expects coordinates in E6 format
+ * @param dbTable
+ * the database table to use as prefix, or null if no prefix is required
+ * @return the string without the "where" keyword
+ */
+ public String sqlWhere(final String dbTable) {
+ final String prefix = dbTable == null ? "" : (dbTable + ".");
+ return String.format((Locale) null,
+ "%slatitude >= %s and %slatitude <= %s and %slongitude >= %s and %slongitude <= %s",
+ prefix, getLatitudeMin(), prefix, getLatitudeMax(), prefix, getLongitudeMin(), prefix, getLongitudeMax());
+ }
+
+ /**
+ * Return a widened or shrunk viewport.
*
- * @param centerLat1
- * @param centerLon1
- * @param centerLat2
- * @param centerLon2
- * @param spanLat1
- * @param spanLon1
- * @param spanLat2
- * @param spanLon2
- * @return
+ * @param factor
+ * multiplicative factor for the latitude and longitude span (> 1 to widen, < 1 to shrink)
+ * @return a widened or shrunk viewport
*/
- public static boolean isInViewPort(int centerLat1, int centerLon1, int centerLat2, int centerLon2, int spanLat1, int spanLon1, int spanLat2, int spanLon2) {
- try {
- final int left1 = centerLat1 - (spanLat1 / 2);
- final int left2 = centerLat2 - (spanLat2 / 2);
- if (left2 <= left1) {
- return false;
- }
+ public Viewport resize(final double factor) {
+ return new Viewport(getCenter(), getLatitudeSpan() * factor, getLongitudeSpan() * factor);
+ }
- final int right1 = centerLat1 + (spanLat1 / 2);
- final int right2 = centerLat2 + (spanLat2 / 2);
- if (right2 >= right1) {
- return false;
- }
+ /**
+ * Return a viewport that contains the current viewport as well as another point.
+ *
+ * @param coords
+ * the point we want in the viewport
+ * @return either the same or an expanded viewport
+ */
+ public Viewport expand(final ICoordinates point) {
+ if (contains(point)) {
+ return this;
+ }
- final int top1 = centerLon1 + (spanLon1 / 2);
- final int top2 = centerLon2 + (spanLon2 / 2);
- if (top2 >= top1) {
- return false;
- }
+ final Geopoint coords = point.getCoords();
+ final double latitude = coords.getLatitude();
+ final double longitude = coords.getLongitude();
+ final double latMin = Math.min(getLatitudeMin(), latitude);
+ final double latMax = Math.max(getLatitudeMax(), latitude);
+ final double lonMin = Math.min(getLongitudeMin(), longitude);
+ final double lonMax = Math.max(getLongitudeMax(), longitude);
+ return new Viewport(new Geopoint(latMin, lonMin), new Geopoint(latMax, lonMax));
+ }
- final int bottom1 = centerLon1 - (spanLon1 / 2);
- final int bottom2 = centerLon2 - (spanLon2 / 2);
- if (bottom2 <= bottom1) {
- return false;
+ /**
+ * Return the smallest viewport containing all the given points.
+ *
+ * @param points
+ * a set of points. Point with null coordinates (or null themselves) will be ignored
+ * @return the smallest viewport containing the non-null coordinates, or null if no coordinates are non-null
+ */
+ static public Viewport containing(final Set<? extends ICoordinates> points) {
+ Viewport viewport = null;
+ for (final ICoordinates point : points) {
+ if (point != null && point.getCoords() != null) {
+ if (viewport == null) {
+ viewport = new Viewport(point, point);
+ } else {
+ viewport = viewport.expand(point);
+ }
}
+ }
+ return viewport;
+ }
- return true;
- } catch (Exception e) {
- Log.e(Settings.tag, "Viewport.isInViewPort: " + e.toString());
+ @Override
+ public boolean equals(final Object other) {
+ if (other == null || !(other instanceof Viewport)) {
return false;
}
+ final Viewport vp = (Viewport) other;
+ return bottomLeft.equals(vp.bottomLeft) && topRight.equals(vp.topRight);
}
+
+ @Override
+ public int hashCode() {
+ return bottomLeft.hashCode() ^ topRight.hashCode();
+ }
+
}
diff --git a/main/src/cgeo/geocaching/geopoint/direction/DDD.java b/main/src/cgeo/geocaching/geopoint/direction/DDD.java
new file mode 100644
index 0000000..939d6ca
--- /dev/null
+++ b/main/src/cgeo/geocaching/geopoint/direction/DDD.java
@@ -0,0 +1,47 @@
+package cgeo.geocaching.geopoint.direction;
+
+import cgeo.geocaching.geopoint.Geopoint;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * Value type for the DDD.DDDDD format.
+ */
+public final class DDD extends Direction {
+
+ /** latitude degree value */
+ public final int latDeg;
+ /** fractional part of the latitude degree value */
+ public final int latDegFrac;
+
+ public final int lonDeg;
+ public final int lonDegFrac;
+
+ public DDD(final double latSigned, final double lonSigned) {
+ super(latSigned, lonSigned);
+ BigDecimal bdLat = BigDecimal.valueOf(latSigned).abs();
+ latDeg = bdLat.intValue();
+ BigDecimal bdLatFrac = bdLat.subtract(BigDecimal.valueOf(latDeg)).multiply(BD_ONEHOUNDREDTHOUSAND);
+ latDegFrac = bdLatFrac.setScale(0, RoundingMode.HALF_UP).intValue();
+
+ BigDecimal bdlon = BigDecimal.valueOf(lonSigned).abs();
+ lonDeg = bdlon.intValue();
+ BigDecimal bdLonFrac = bdlon.subtract(BigDecimal.valueOf(lonDeg)).multiply(BD_ONEHOUNDREDTHOUSAND);
+ lonDegFrac = bdLonFrac.setScale(0, RoundingMode.HALF_UP).intValue();
+ }
+
+ public static Geopoint createGeopoint(final String latDir, final String latDeg, final String latDegFrac,
+ final String lonDir, final String lonDeg, final String lonDegFrac) {
+ double lat = 0.0d;
+ double lon = 0.0d;
+ try {
+ lat = Double.parseDouble(latDeg + "." + addZeros(Integer.parseInt(latDegFrac), 5));
+ lon = Double.parseDouble(lonDeg + "." + addZeros(Integer.parseInt(lonDegFrac), 5));
+ } catch (NumberFormatException e) {
+ }
+ lat *= "S".equalsIgnoreCase(latDir) ? -1 : 1;
+ lon *= "W".equalsIgnoreCase(lonDir) ? -1 : 1;
+ return new Geopoint(lat, lon);
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/geopoint/direction/DMM.java b/main/src/cgeo/geocaching/geopoint/direction/DMM.java
new file mode 100644
index 0000000..7426f28
--- /dev/null
+++ b/main/src/cgeo/geocaching/geopoint/direction/DMM.java
@@ -0,0 +1,56 @@
+package cgeo.geocaching.geopoint.direction;
+
+import cgeo.geocaching.geopoint.Geopoint;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public final class DMM extends Direction {
+
+ public final int latDeg;
+ public final double latMinRaw;
+ public final int latMin;
+ public final int latMinFrac;
+
+ public final int lonDeg;
+ public final double lonMinRaw;
+ public final int lonMin;
+ public final int lonMinFrac;
+
+ public DMM(final double latSigned, final double lonSigned) {
+ super(latSigned, lonSigned);
+ BigDecimal bdLat = BigDecimal.valueOf(latSigned).abs();
+ latDeg = bdLat.intValue();
+ BigDecimal bdLatMin = bdLat.subtract(BigDecimal.valueOf(latDeg)).multiply(BD_SIXTY);
+ // Rounding here ...
+ bdLatMin = bdLatMin.setScale(3, RoundingMode.HALF_UP);
+ latMinRaw = bdLatMin.doubleValue();
+ latMin = bdLatMin.intValue();
+ BigDecimal bdLatMinFrac = bdLatMin.subtract(BigDecimal.valueOf(latMin)).multiply(BD_THOUSAND);
+ latMinFrac = bdLatMinFrac.setScale(0, RoundingMode.HALF_UP).intValue();
+
+ BigDecimal bdlon = BigDecimal.valueOf(lonSigned).abs();
+ lonDeg = bdlon.intValue();
+ BigDecimal bdLonMin = bdlon.subtract(BigDecimal.valueOf(lonDeg)).multiply(BD_SIXTY);
+ // Rounding here ...
+ bdLonMin = bdLonMin.setScale(3, RoundingMode.HALF_UP);
+ lonMinRaw = bdLonMin.doubleValue();
+ lonMin = bdLonMin.intValue();
+ BigDecimal bdLonMinFrac = bdLonMin.subtract(BigDecimal.valueOf(lonMin)).multiply(BD_THOUSAND);
+ lonMinFrac = bdLonMinFrac.setScale(0, RoundingMode.HALF_UP).intValue();
+ }
+
+ public static Geopoint createGeopoint(final String latDir, final String latDeg, final String latMin, final String latMinFrac,
+ final String lonDir, final String lonDeg, final String lonMin, final String lonMinFrac) {
+ double lat = 0.0d;
+ double lon = 0.0d;
+ try {
+ lat = Double.parseDouble(latDeg) + Double.parseDouble(latMin + "." + addZeros(Integer.parseInt(latMinFrac), 3)) / D60;
+ lon = Double.parseDouble(lonDeg) + Double.parseDouble(lonMin + "." + addZeros(Integer.parseInt(lonMinFrac), 3)) / D60;
+ } catch (NumberFormatException e) {
+ }
+ lat *= "S".equalsIgnoreCase(latDir) ? -1 : 1;
+ lon *= "W".equalsIgnoreCase(lonDir) ? -1 : 1;
+ return new Geopoint(lat, lon);
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/geopoint/direction/DMS.java b/main/src/cgeo/geocaching/geopoint/direction/DMS.java
new file mode 100644
index 0000000..34a9a3d
--- /dev/null
+++ b/main/src/cgeo/geocaching/geopoint/direction/DMS.java
@@ -0,0 +1,62 @@
+package cgeo.geocaching.geopoint.direction;
+
+import cgeo.geocaching.geopoint.Geopoint;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public final class DMS extends Direction {
+
+ public final int latDeg;
+ public final int latMin;
+ public final double latSecRaw;
+ public final int latSec;
+ public final int latSecFrac;
+
+ public final int lonDeg;
+ public final int lonMin;
+ public final double lonSecRaw;
+ public final int lonSec;
+ public final int lonSecFrac;
+
+ public DMS(final double latSigned, final double lonSigned) {
+ super(latSigned, lonSigned);
+ BigDecimal bdLat = BigDecimal.valueOf(latSigned).abs();
+ latDeg = bdLat.intValue();
+ BigDecimal bdLatMin = bdLat.subtract(BigDecimal.valueOf(latDeg)).multiply(BD_SIXTY);
+ latMin = bdLatMin.intValue();
+ BigDecimal bdLatSec = bdLatMin.subtract(BigDecimal.valueOf(latMin)).multiply(BD_SIXTY);
+ // Rounding here ...
+ bdLatSec = bdLatSec.setScale(3, RoundingMode.HALF_UP);
+ latSecRaw = bdLatSec.doubleValue();
+ latSec = bdLatSec.intValue();
+ BigDecimal bdLatSecFrac = bdLatSec.subtract(BigDecimal.valueOf(latSec)).multiply(BD_THOUSAND);
+ latSecFrac = bdLatSecFrac.setScale(0, RoundingMode.HALF_UP).intValue();
+
+ BigDecimal bdlon = BigDecimal.valueOf(lonSigned).abs();
+ lonDeg = bdlon.intValue();
+ BigDecimal bdLonMin = bdlon.subtract(BigDecimal.valueOf(lonDeg)).multiply(BD_SIXTY);
+ lonMin = bdLonMin.intValue();
+ BigDecimal bdLonSec = bdLonMin.subtract(BigDecimal.valueOf(lonMin)).multiply(BD_SIXTY);
+ // Rounding here ...
+ bdLonSec = bdLonSec.setScale(3, RoundingMode.HALF_UP);
+ lonSecRaw = bdLonSec.doubleValue();
+ lonSec = bdLonSec.intValue();
+ BigDecimal bdLonSecFrac = bdLonSec.subtract(BigDecimal.valueOf(lonSec)).multiply(BD_THOUSAND);
+ lonSecFrac = bdLonSecFrac.setScale(0, RoundingMode.HALF_UP).intValue();
+ }
+
+ public static Geopoint createGeopoint(final String latDir, final String latDeg, final String latMin, final String latSec, final String latSecFrac,
+ final String lonDir, final String lonDeg, final String lonMin, final String lonSec, final String lonSecFrac) {
+ double lat = 0.0d;
+ double lon = 0.0d;
+ try {
+ lat = Double.parseDouble(latDeg) + Double.parseDouble(latMin) / D60 + Double.parseDouble(latSec + "." + addZeros(Integer.parseInt(latSecFrac), 3)) / D3600;
+ lon = Double.parseDouble(lonDeg) + Double.parseDouble(lonMin) / D60 + Double.parseDouble(lonSec + "." + addZeros(Integer.parseInt(lonSecFrac), 3)) / D3600;
+ } catch (NumberFormatException e) {
+ }
+ lat *= "S".equalsIgnoreCase(latDir) ? -1 : 1;
+ lon *= "W".equalsIgnoreCase(lonDir) ? -1 : 1;
+ return new Geopoint(lat, lon);
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/geopoint/direction/Direction.java b/main/src/cgeo/geocaching/geopoint/direction/Direction.java
new file mode 100644
index 0000000..ad91516
--- /dev/null
+++ b/main/src/cgeo/geocaching/geopoint/direction/Direction.java
@@ -0,0 +1,29 @@
+package cgeo.geocaching.geopoint.direction;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+
+public class Direction {
+ /* Constant values needed for calculation */
+ static final double D60 = 60.0d;
+ private static final double D1000 = 1000.0d;
+ static final double D3600 = 3600.0d;
+ static final BigDecimal BD_SIXTY = BigDecimal.valueOf(D60);
+ static final BigDecimal BD_THOUSAND = BigDecimal.valueOf(D1000);
+ static final BigDecimal BD_ONEHOUNDREDTHOUSAND = BigDecimal.valueOf(100000.0d);
+
+ /** latitude direction, 'N' or 'S' */
+ public final char latDir;
+ /** longitude direction, 'E' or 'W' */
+ public final char lonDir;
+
+ public Direction(final double latSigned, final double lonSigned) {
+ latDir = latSigned < 0 ? 'S' : 'N';
+ lonDir = lonSigned < 0 ? 'W' : 'E';
+ }
+
+ protected static String addZeros(final int value, final int len) {
+ return StringUtils.leftPad(Integer.toString(value), len, '0');
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/go4cache/Go4Cache.java b/main/src/cgeo/geocaching/go4cache/Go4Cache.java
index fb53c27..b0a7b35 100644
--- a/main/src/cgeo/geocaching/go4cache/Go4Cache.java
+++ b/main/src/cgeo/geocaching/go4cache/Go4Cache.java
@@ -1,7 +1,6 @@
package cgeo.geocaching.go4cache;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter.Format;
@@ -9,13 +8,15 @@ import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.CryptUtils;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-import android.util.Log;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -41,6 +42,7 @@ public final class Go4Cache extends Thread {
private final static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 2010-07-25 14:44:01
final private ArrayBlockingQueue<Geopoint> queue = new ArrayBlockingQueue<Geopoint>(1);
+ private String packageVersion;
public static Go4Cache getInstance() { // no need to be synchronized
return InstanceHolder.INSTANCE;
@@ -48,10 +50,22 @@ public final class Go4Cache extends Thread {
private Go4Cache() { // private singleton constructor
super("Go4Cache");
+ initializeVersion();
setPriority(Thread.MIN_PRIORITY);
start();
}
+ private void initializeVersion() {
+ try {
+ final PackageManager manager = cgeoapplication.getInstance().getPackageManager();
+ final PackageInfo info = manager.getPackageInfo(cgeoapplication.getInstance().getPackageName(), 0);
+ packageVersion = info.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e("unable to get version information", e);
+ packageVersion = null;
+ }
+ }
+
/**
* Send the coordinates to go4cache.com if the user opted in to do so.
*
@@ -68,7 +82,7 @@ public final class Go4Cache extends Thread {
@Override
public void run() {
- Log.d(Settings.tag, "Go4Cache task started");
+ Log.d("Go4Cache task started");
Geopoint latestCoords = null;
String latestAction = null;
@@ -96,8 +110,8 @@ public final class Go4Cache extends Thread {
"ln", lonStr,
"a", currentAction,
"s", (CryptUtils.sha1(username + "|" + latStr + "|" + lonStr + "|" + currentAction + "|" + CryptUtils.md5("carnero: developing your dreams"))).toLowerCase());
- if (null != cgBase.version) {
- params.put("v", cgBase.version);
+ if (null != packageVersion) {
+ params.put("v", packageVersion);
}
Network.postRequest("http://api.go4cache.com/", params);
@@ -108,7 +122,7 @@ public final class Go4Cache extends Thread {
latestAction = currentAction;
}
} catch (InterruptedException e) {
- Log.e(Settings.tag, "Go4Cache.run: interrupted", e);
+ Log.e("Go4Cache.run: interrupted", e);
}
}
@@ -138,7 +152,7 @@ public final class Go4Cache extends Thread {
final String data = Network.getResponseData(Network.postRequest("http://api.go4cache.com/get.php", params));
if (StringUtils.isBlank(data)) {
- Log.e(Settings.tag, "cgeoBase.getGeocachersInViewport: No data from server");
+ Log.e("cgeoBase.getGeocachersInViewport: No data from server");
return null;
}
@@ -150,7 +164,7 @@ public final class Go4Cache extends Thread {
users.add(parseUser(oneUser));
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.getGeocachersInViewport: " + e.toString());
+ Log.e("cgBase.getGeocachersInViewport: " + e.toString());
}
return Collections.unmodifiableList(users);
diff --git a/main/src/cgeo/geocaching/go4cache/Go4CacheUser.java b/main/src/cgeo/geocaching/go4cache/Go4CacheUser.java
index 606d8f3..08fd02e 100644
--- a/main/src/cgeo/geocaching/go4cache/Go4CacheUser.java
+++ b/main/src/cgeo/geocaching/go4cache/Go4CacheUser.java
@@ -44,14 +44,16 @@ public class Go4CacheUser {
}
public int getIconId() {
- if (null == client) {
+ if (client == null) {
return -1;
}
if (client.equalsIgnoreCase("c:geo")) {
return R.drawable.client_cgeo;
- } else if (client.equalsIgnoreCase("preCaching")) {
+ }
+ if (client.equalsIgnoreCase("preCaching")) {
return R.drawable.client_precaching;
- } else if (client.equalsIgnoreCase("Handy Geocaching")) {
+ }
+ if (client.equalsIgnoreCase("Handy Geocaching")) {
return R.drawable.client_handygeocaching;
}
return -1;
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index a1f703d..18815af 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -1,23 +1,23 @@
package cgeo.geocaching.maps;
+import cgeo.geocaching.GeoObserver;
+import cgeo.geocaching.IGeoData;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.LiveMapInfo;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.StoredList;
import cgeo.geocaching.UpdateDirectionCallback;
-import cgeo.geocaching.UpdateLocationCallback;
-import cgeo.geocaching.cgBase;
+import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgCoord;
import cgeo.geocaching.cgDirection;
-import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.cgeocaches;
-import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.gc.GCBase;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LiveMapStrategy.Strategy;
import cgeo.geocaching.enumerations.LoadFlags;
@@ -35,9 +35,9 @@ import cgeo.geocaching.maps.interfaces.MapProvider;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnMapDragListener;
import cgeo.geocaching.maps.interfaces.OtherCachersOverlayItemImpl;
-import cgeo.geocaching.network.Login;
import cgeo.geocaching.utils.CancellableHandler;
-import cgeo.geocaching.utils.LRUList;
+import cgeo.geocaching.utils.LeastRecentlyUsedSet;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -54,7 +54,7 @@ import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
+import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
@@ -67,10 +67,8 @@ import android.widget.TextView;
import android.widget.ViewSwitcher.ViewFactory;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@@ -95,8 +93,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
//Menu
private static final String EXTRAS_GEOCODE = "geocode";
- private static final String EXTRAS_LONGITUDE = "longitude";
- private static final String EXTRAS_LATITUDE = "latitude";
+ private static final String EXTRAS_COORDS = "coords";
private static final String EXTRAS_WPTTYPE = "wpttype";
private static final String EXTRAS_MAPSTATE = "mapstate";
private static final String EXTRAS_SEARCH = "search";
@@ -116,6 +113,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private static final String EXTRAS_MAP_TITLE = "mapTitle";
private static final String BUNDLE_MAP_SOURCE = "mapSource";
+ private static final String BUNDLE_MAP_STATE = "mapState";
private Resources res = null;
private MapProvider mapProvider = null;
@@ -123,9 +121,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private MapViewImpl mapView = null;
private MapControllerImpl mapController = null;
private cgeoapplication app = null;
- private cgGeo geo = null;
private cgDirection dir = null;
- private UpdateLocationCallback geoUpdate = new UpdateLoc();
+ final private GeoObserver geoUpdate = new UpdateLoc();
private UpdateDirectionCallback dirUpdate = new UpdateDir();
private SearchResult searchIntent = null;
private String geocodeIntent = null;
@@ -138,14 +135,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private boolean noMapTokenShowed = false;
// map status data
private boolean followMyLocation = false;
- private Integer centerLatitude = null;
- private Integer centerLongitude = null;
- private Integer spanLatitude = null;
- private Integer spanLongitude = null;
- private Integer centerLatitudeUsers = null;
- private Integer centerLongitudeUsers = null;
- private Integer spanLatitudeUsers = null;
- private Integer spanLongitudeUsers = null;
+ private Viewport viewport = null;
+ private Viewport viewportUsers = null;
private int zoom = -100;
// threads
private LoadTimer loadTimer = null;
@@ -170,10 +161,12 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private static final int[][] INSET_USERMODIFIEDCOORDS = { { 21, 28, 0, 0 }, { 19, 25, 0, 0 } }; // bottom right, 12x12 / 26x26
private static final int[][] INSET_PERSONALNOTE = { { 0, 28, 21, 0 }, { 0, 25, 19, 0 } }; // bottom left, 12x12 / 26x26
- private static Map<Integer, LayerDrawable> overlaysCache = new HashMap<Integer, LayerDrawable>();
+ private static SparseArray<LayerDrawable> overlaysCache = new SparseArray<LayerDrawable>();
private int cachesCnt = 0;
/** List of caches in the viewport */
- private final LRUList<cgCache> caches = new LRUList<cgCache>(MAX_CACHES);
+ private final LeastRecentlyUsedSet<cgCache> caches = new LeastRecentlyUsedSet<cgCache>(MAX_CACHES);
+ /** List of waypoints in the viewport */
+ private final LeastRecentlyUsedSet<cgWaypoint> waypoints = new LeastRecentlyUsedSet<cgWaypoint>(MAX_CACHES);
// storing for offline
private ProgressDialog waitDialog = null;
private int detailTotal = 0;
@@ -289,9 +282,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
waitDialog.setOnCancelListener(null);
}
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
if (Settings.isUseCompass() && dir == null) {
dir = app.startDir(activity, dirUpdate);
}
@@ -304,9 +294,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
loadDetailsThread.stopIt();
}
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
if (Settings.isUseCompass() && dir == null) {
dir = app.startDir(activity, dirUpdate);
}
@@ -337,19 +324,15 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
protected void countVisibleCaches() {
- final ArrayList<cgCache> protectedCaches = new ArrayList<cgCache>(caches);
+ final List<cgCache> protectedCaches = caches.getAsList();
int count = 0;
if (protectedCaches.size() > 0) {
- final GeoPointImpl mapCenter = mapView.getMapViewCenter();
- final int mapCenterLat = mapCenter.getLatitudeE6();
- final int mapCenterLon = mapCenter.getLongitudeE6();
- final int mapSpanLat = mapView.getLatitudeSpan();
- final int mapSpanLon = mapView.getLongitudeSpan();
+ final Viewport viewport = mapView.getViewport();
- for (cgCache cache : protectedCaches) {
+ for (final cgCache cache : protectedCaches) {
if (cache != null && cache.getCoords() != null) {
- if (Viewport.isCacheInViewPort(mapCenterLat, mapCenterLon, mapSpanLat, mapSpanLon, cache.getCoords())) {
+ if (viewport.contains(cache)) {
count++;
}
}
@@ -361,6 +344,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
@Override
public void onSaveInstanceState(final Bundle outState) {
outState.putInt(BUNDLE_MAP_SOURCE, currentSourceId);
+ outState.putIntArray(BUNDLE_MAP_STATE, currentMapState());
}
@Override
@@ -373,34 +357,29 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
app = (cgeoapplication) activity.getApplication();
mapProvider = Settings.getMapProvider();
- // Restore previously saved map source if any
- if (savedInstanceState != null) {
- currentSourceId = savedInstanceState.getInt(BUNDLE_MAP_SOURCE, Settings.getMapSource());
- } else {
- currentSourceId = Settings.getMapSource();
- }
- // get parameters
- Bundle extras = activity.getIntent().getExtras();
+ // Get parameters from the intent
+ final Bundle extras = activity.getIntent().getExtras();
if (extras != null) {
searchIntent = (SearchResult) extras.getParcelable(EXTRAS_SEARCH);
geocodeIntent = extras.getString(EXTRAS_GEOCODE);
- final double latitudeIntent = extras.getDouble(EXTRAS_LATITUDE);
- final double longitudeIntent = extras.getDouble(EXTRAS_LONGITUDE);
- coordsIntent = new Geopoint(latitudeIntent, longitudeIntent);
+ coordsIntent = (Geopoint) extras.getParcelable(EXTRAS_COORDS);
waypointTypeIntent = WaypointType.findById(extras.getString(EXTRAS_WPTTYPE));
mapStateIntent = extras.getIntArray(EXTRAS_MAPSTATE);
mapTitle = extras.getString(EXTRAS_MAP_TITLE);
-
- if (coordsIntent.getLatitude() == 0.0 || coordsIntent.getLongitude() == 0.0) {
- coordsIntent = null;
- }
}
-
if (StringUtils.isBlank(mapTitle)) {
mapTitle = res.getString(R.string.map_map);
}
+ // Get fresh map information from the bundle if any
+ if (savedInstanceState != null) {
+ currentSourceId = savedInstanceState.getInt(BUNDLE_MAP_SOURCE, Settings.getMapSource());
+ mapStateIntent = savedInstanceState.getIntArray(BUNDLE_MAP_STATE);
+ } else {
+ currentSourceId = Settings.getMapSource();
+ }
+
// If recreating from an obsolete map source, we may need a restart
if (changeMapSource(Settings.getMapSource())) {
return;
@@ -416,9 +395,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
activity.setContentView(mapProvider.getMapLayoutId());
ActivityMixin.setTitle(activity, res.getString(R.string.map_map));
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
if (Settings.isUseCompass() && dir == null) {
dir = app.startDir(activity, dirUpdate);
}
@@ -456,9 +432,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
mapController.setZoom(Settings.getMapZoom());
// start location and directory services
- if (geo != null) {
- geoUpdate.updateLocation(geo);
- }
if (dir != null) {
dirUpdate.updateDirection(dir);
}
@@ -470,7 +443,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (null == mapStateIntent) {
followMyLocation = live;
} else {
- followMyLocation = 1 == mapStateIntent[3] ? true : false;
+ followMyLocation = 1 == mapStateIntent[3];
}
if (geocodeIntent != null || searchIntent != null || coordsIntent != null || mapStateIntent != null) {
centerMap(geocodeIntent, searchIntent, coordsIntent, mapStateIntent);
@@ -512,15 +485,11 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
app.setAction(StringUtils.defaultIfBlank(geocodeIntent, null));
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
+ app.addGeoObserver(geoUpdate);
if (Settings.isUseCompass() && dir == null) {
dir = app.startDir(activity, dirUpdate);
}
- geoUpdate.updateLocation(geo);
-
if (dir != null) {
dirUpdate.updateDirection(dir);
}
@@ -534,12 +503,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
dirtyCaches.clear();
// Update display
- GeoPointImpl mapCenterNow = mapView.getMapViewCenter();
- int centerLatitudeNow = mapCenterNow.getLatitudeE6();
- int centerLongitudeNow = mapCenterNow.getLongitudeE6();
- int spanLatitudeNow = mapView.getLatitudeSpan();
- int spanLongitudeNow = mapView.getLongitudeSpan();
- displayExecutor.execute(new DisplayRunnable(centerLatitudeNow, centerLongitudeNow, spanLatitudeNow, spanLongitudeNow));
+ displayExecutor.execute(new DisplayRunnable(mapView.getViewport()));
}
startTimer();
@@ -560,9 +524,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (dir != null) {
dir = app.removeDir();
}
- if (geo != null) {
- geo = app.removeGeo();
- }
savePrefs();
@@ -588,9 +549,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (dir != null) {
dir = app.removeDir();
}
- if (geo != null) {
- geo = app.removeGeo();
- }
+ app.deleteGeoObserver(geoUpdate);
savePrefs();
@@ -616,9 +575,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (dir != null) {
dir = app.removeDir();
}
- if (geo != null) {
- geo = app.removeGeo();
- }
savePrefs();
@@ -698,7 +654,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
menu.findItem(SUBMENU_STRATEGY).setEnabled(live);
} catch (Exception e) {
- Log.e(Settings.tag, "cgeomap.onPrepareOptionsMenu: " + e.toString());
+ Log.e("cgeomap.onPrepareOptionsMenu: " + e.toString());
}
return true;
@@ -723,25 +679,22 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (live && !isLoading() && CollectionUtils.isNotEmpty(caches)) {
final List<String> geocodes = new ArrayList<String>();
- List<cgCache> cachesProtected = new ArrayList<cgCache>(caches);
+ final List<cgCache> cachesProtected = caches.getAsList();
+
try {
if (cachesProtected.size() > 0) {
- final GeoPointImpl mapCenter = mapView.getMapViewCenter();
- final int mapCenterLat = mapCenter.getLatitudeE6();
- final int mapCenterLon = mapCenter.getLongitudeE6();
- final int mapSpanLat = mapView.getLatitudeSpan();
- final int mapSpanLon = mapView.getLongitudeSpan();
+ final Viewport viewport = mapView.getViewport();
- for (cgCache cache : cachesProtected) {
+ for (final cgCache cache : cachesProtected) {
if (cache != null && cache.getCoords() != null) {
- if (Viewport.isCacheInViewPort(mapCenterLat, mapCenterLon, mapSpanLat, mapSpanLon, cache.getCoords()) && !app.isOffline(cache.getGeocode(), null)) {
+ if (viewport.contains(cache) && !app.isOffline(cache.getGeocode(), null)) {
geocodes.add(cache.getGeocode());
}
}
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeomap.onOptionsItemSelected.#4: " + e.toString());
+ Log.e("cgeomap.onOptionsItemSelected.#4: " + e.toString());
}
detailTotal = geocodes.size();
@@ -768,14 +721,11 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
loadDetailsThread.stopIt();
}
- if (geo == null) {
- geo = app.startGeo(geoUpdate);
- }
if (Settings.isUseCompass() && dir == null) {
dir = app.startDir(activity, dirUpdate);
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.onPrepareOptionsMenu.onCancel: " + e.toString());
+ Log.e("cgeocaches.onPrepareOptionsMenu.onCancel: " + e.toString());
}
}
});
@@ -806,11 +756,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
ActivityMixin.invalidateOptionsMenu(activity);
return true;
case MENU_AS_LIST: {
- final SearchResult searchResult = new SearchResult();
- search.totalCnt = caches.size();
- for (cgCache cache : caches) {
- searchResult.addCache(cache);
- }
cgeocaches.startActivityMap(activity, search);
return true;
}
@@ -882,19 +827,13 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
mapIntent.putExtra(EXTRAS_SEARCH, searchIntent);
mapIntent.putExtra(EXTRAS_GEOCODE, geocodeIntent);
if (coordsIntent != null) {
- mapIntent.putExtra(EXTRAS_LATITUDE, coordsIntent.getLatitude());
- mapIntent.putExtra(EXTRAS_LONGITUDE, coordsIntent.getLongitude());
+ mapIntent.putExtra(EXTRAS_COORDS, coordsIntent);
}
mapIntent.putExtra(EXTRAS_WPTTYPE, waypointTypeIntent != null ? waypointTypeIntent.id : null);
mapIntent.putExtra(EXTRAS_MAP_TITLE, mapTitle);
- if (mapView != null) {
- int[] mapState = new int[4];
- GeoPointImpl mapCenter = mapView.getMapViewCenter();
- mapState[0] = mapCenter.getLatitudeE6();
- mapState[1] = mapCenter.getLongitudeE6();
- mapState[2] = mapView.getMapZoomLevel();
- mapState[3] = followMyLocation ? 1 : 0;
+ final int[] mapState = currentMapState();
+ if (mapState != null) {
mapIntent.putExtra(EXTRAS_MAPSTATE, mapState);
}
@@ -902,6 +841,25 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
activity.startActivity(mapIntent);
}
+ /**
+ * Get the current map state from the map view if it exists or from the mapStateIntent field otherwise.
+ *
+ * @return the current map state as an array of int, or null if no map state is available
+ */
+ private int[] currentMapState() {
+ if (mapView == null) {
+ return mapStateIntent;
+ }
+
+ final GeoPointImpl mapCenter = mapView.getMapViewCenter();
+ return new int[] {
+ mapCenter.getLatitudeE6(),
+ mapCenter.getLongitudeE6(),
+ mapView.getMapZoomLevel(),
+ followMyLocation ? 1 : 0
+ };
+ }
+
private void savePrefs() {
if (mapView == null) {
return;
@@ -911,21 +869,17 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
// Set center of map to my location if appropriate.
- private void myLocationInMiddle() {
- if (followMyLocation && geo != null) {
- centerMap(geo.coordsNow);
+ private void myLocationInMiddle(final IGeoData geo) {
+ if (followMyLocation) {
+ centerMap(geo.getCoords());
}
}
// class: update location
- private class UpdateLoc implements UpdateLocationCallback {
+ private class UpdateLoc extends GeoObserver {
@Override
- public void updateLocation(cgGeo geo) {
- if (geo == null) {
- return;
- }
-
+ protected void updateLocation(final IGeoData geo) {
try {
boolean repaintRequired = false;
@@ -933,20 +887,20 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
overlayPosition = mapView.createAddPositionOverlay(activity);
}
- if (overlayPosition != null && geo.location != null) {
- overlayPosition.setCoordinates(geo.location);
+ if (overlayPosition != null && geo.getLocation() != null) {
+ overlayPosition.setCoordinates(geo.getLocation());
}
- if (geo.coordsNow != null) {
+ if (geo.getCoords() != null) {
if (followMyLocation) {
- myLocationInMiddle();
+ myLocationInMiddle(geo);
} else {
repaintRequired = true;
}
}
- if (!Settings.isUseCompass() || geo.speedNow > 5) { // use GPS when speed is higher than 18 km/h
- overlayPosition.setHeading(geo.bearingNow);
+ if (!Settings.isUseCompass() || geo.getSpeed() > 5) { // use GPS when speed is higher than 18 km/h
+ overlayPosition.setHeading(geo.getBearing());
repaintRequired = true;
}
@@ -955,7 +909,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
} catch (Exception e) {
- Log.w(Settings.tag, "Failed to update location.");
+ Log.w("Failed to update location.");
}
}
}
@@ -969,7 +923,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
return;
}
- if (overlayPosition != null && mapView != null && (geo == null || geo.speedNow <= 5)) { // use compass when speed is lower than 18 km/h
+ if (overlayPosition != null && mapView != null && (app.currentGeo().getSpeed() <= 5)) { // use compass when speed is lower than 18 km/h
overlayPosition.setHeading(dir.directionNow);
mapView.repaintRequired(overlayPosition);
}
@@ -1028,11 +982,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (mapView != null) {
// get current viewport
- GeoPointImpl mapCenterNow = mapView.getMapViewCenter();
- int centerLatitudeNow = mapCenterNow.getLatitudeE6();
- int centerLongitudeNow = mapCenterNow.getLongitudeE6();
- int spanLatitudeNow = mapView.getLatitudeSpan();
- int spanLongitudeNow = mapView.getLongitudeSpan();
+ final Viewport viewportNow = mapView.getViewport();
+ int zoomNow = mapView.getMapZoomLevel();
// check if map moved or zoomed
//TODO Portree Use Rectangle inside with bigger search window. That will stop reloading on every move
@@ -1042,20 +993,16 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
moved = true;
} else if (live && Settings.isLiveMap() && !downloaded) {
moved = true;
- } else if (centerLatitude == null || centerLongitude == null) {
+ } else if (viewport == null) {
moved = true;
- } else if (spanLatitude == null || spanLongitude == null) {
+ } else if (zoomNow != zoom) {
moved = true;
- } else if (((Math.abs(spanLatitudeNow - spanLatitude) > 50) || (Math.abs(spanLongitudeNow - spanLongitude) > 50) || // changed zoom
- (Math.abs(centerLatitudeNow - centerLatitude) > (spanLatitudeNow / 4)) || (Math.abs(centerLongitudeNow - centerLongitude) > (spanLongitudeNow / 4)) // map moved
- ) && (cachesCnt <= 0 || CollectionUtils.isEmpty(caches)
- || !Viewport.isInViewPort(centerLatitude, centerLongitude, centerLatitudeNow, centerLongitudeNow, spanLatitude, spanLongitude, spanLatitudeNow, spanLongitudeNow))) {
+ } else if (mapMoved(viewport, viewportNow) && (cachesCnt <= 0 || CollectionUtils.isEmpty(caches) || !viewport.includes(viewportNow))) {
moved = true;
}
// update title on any change
- int zoomNow = mapView.getMapZoomLevel();
- if (moved || zoomNow != zoom || spanLatitudeNow != spanLatitude || spanLongitudeNow != spanLongitude || centerLatitudeNow != centerLatitude || centerLongitudeNow != centerLongitude) {
+ if (moved || zoomNow != zoom || !viewportNow.equals(viewport)) {
displayHandler.sendEmptyMessage(UPDATE_TITLE);
}
zoom = zoomNow;
@@ -1067,19 +1014,15 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
long currentTime = System.currentTimeMillis();
if (1000 < (currentTime - loadThreadRun)) {
- centerLatitude = centerLatitudeNow;
- centerLongitude = centerLongitudeNow;
- spanLatitude = spanLatitudeNow;
- spanLongitude = spanLongitudeNow;
-
- loadExecutor.execute(new LoadRunnable(centerLatitude, centerLongitude, spanLatitude, spanLongitude));
+ viewport = viewportNow;
+ loadExecutor.execute(new LoadRunnable(viewport));
}
}
}
yield();
} catch (Exception e) {
- Log.w(Settings.tag, "cgeomap.LoadTimer.run: " + e.toString());
+ Log.w("cgeomap.LoadTimer.run: " + e.toString());
}
}
}
@@ -1116,11 +1059,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (mapView != null) {
// get current viewport
- GeoPointImpl mapCenterNow = mapView.getMapViewCenter();
- int centerLatitudeNow = mapCenterNow.getLatitudeE6();
- int centerLongitudeNow = mapCenterNow.getLongitudeE6();
- int spanLatitudeNow = mapView.getLatitudeSpan();
- int spanLongitudeNow = mapView.getLongitudeSpan();
+ final Viewport viewportNow = mapView.getViewport();
// check if map moved or zoomed
boolean moved = false;
@@ -1129,30 +1068,22 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (60000 < (currentTime - go4CacheThreadRun)) {
moved = true;
- } else if (centerLatitudeUsers == null || centerLongitudeUsers == null) {
- moved = true;
- } else if (spanLatitudeUsers == null || spanLongitudeUsers == null) {
+ } else if (viewportUsers == null) {
moved = true;
- } else if (((Math.abs(spanLatitudeNow - spanLatitudeUsers) > 50) || (Math.abs(spanLongitudeNow - spanLongitudeUsers) > 50) || // changed zoom
- (Math.abs(centerLatitudeNow - centerLatitudeUsers) > (spanLatitudeNow / 4)) || (Math.abs(centerLongitudeNow - centerLongitudeUsers) > (spanLongitudeNow / 4)) // map moved
- ) && !Viewport.isInViewPort(centerLatitudeUsers, centerLongitudeUsers, centerLatitudeNow, centerLongitudeNow, spanLatitudeUsers, spanLongitudeUsers, spanLatitudeNow, spanLongitudeNow)) {
+ } else if (mapMoved(viewportUsers, viewportNow) && !viewportUsers.includes(viewportNow)) {
moved = true;
}
// save new values
if (moved && (1000 < (currentTime - go4CacheThreadRun))) {
- centerLatitudeUsers = centerLatitudeNow;
- centerLongitudeUsers = centerLongitudeNow;
- spanLatitudeUsers = spanLatitudeNow;
- spanLongitudeUsers = spanLongitudeNow;
-
- Go4CacheExecutor.execute(new Go4CacheRunnable(centerLatitudeNow, centerLongitudeNow, spanLatitudeNow, spanLongitudeNow));
+ viewportUsers = viewportNow;
+ Go4CacheExecutor.execute(new Go4CacheRunnable(viewportUsers));
}
}
yield();
} catch (Exception e) {
- Log.w(Settings.tag, "cgeomap.LoadUsersTimer.run: " + e.toString());
+ Log.w("cgeomap.LoadUsersTimer.run: " + e.toString());
}
}
}
@@ -1165,8 +1096,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private class LoadRunnable extends DoRunnable {
- public LoadRunnable(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) {
- super(centerLatIn, centerLonIn, spanLatIn, spanLonIn);
+ public LoadRunnable(final Viewport viewport) {
+ super(viewport);
}
@Override
@@ -1185,34 +1116,50 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
} else {
// live map
if (!live || !Settings.isLiveMap()) {
- search = new SearchResult(app.getStoredInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType()));
+ search = new SearchResult(app.getStoredInViewport(viewport, Settings.getCacheType()));
} else {
- search = new SearchResult(app.getCachedInViewport(centerLat, centerLon, spanLat, spanLon, Settings.getCacheType()));
+ search = new SearchResult(app.getCachedInViewport(viewport, Settings.getCacheType()));
}
}
if (search != null) {
downloaded = true;
- caches.addAll(search.getCachesFromSearchResult(LoadFlags.LOAD_WAYPOINTS));
+ Set<cgCache> cachesFromSearchResult = search.getCachesFromSearchResult(LoadFlags.LOAD_WAYPOINTS);
+ caches.addAll(cachesFromSearchResult);
}
if (live) {
final boolean excludeMine = Settings.isExcludeMyCaches();
final boolean excludeDisabled = Settings.isExcludeDisabledCaches();
- final ArrayList<cgCache> tempList = new ArrayList<cgCache>(caches);
+ final List<cgCache> tempList = caches.getAsList();
+
for (cgCache cache : tempList) {
if ((cache.isFound() && excludeMine) || (cache.isOwn() && excludeMine) || (cache.isDisabled() && excludeDisabled)) {
caches.remove(cache);
}
}
}
+ countVisibleCaches();
+ if (cachesCnt < Settings.getWayPointsThreshold())
+ {
+ waypoints.clear();
+ if (searchIntent == null && geocodeIntent == null) {
+ //All visible waypoints
+ waypoints.addAll(app.getWaypointsInViewport(viewport, Settings.isExcludeMyCaches(), Settings.isExcludeDisabledCaches()));
+ } else {
+ //All waypoints from the viewed caches
+ for (cgCache c : caches.getAsList()) {
+ waypoints.addAll(c.getWaypoints());
+ }
+ }
+ }
//render
- displayExecutor.execute(new DisplayRunnable(centerLat, centerLon, spanLat, spanLon));
+ displayExecutor.execute(new DisplayRunnable(viewport));
if (live && Settings.isLiveMap()) {
- downloadExecutor.execute(new DownloadRunnable(centerLat, centerLon, spanLat, spanLon));
+ downloadExecutor.execute(new DownloadRunnable(viewport));
}
} finally {
showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); // hide progress
@@ -1227,8 +1174,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private class DownloadRunnable extends DoRunnable {
- public DownloadRunnable(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) {
- super(centerLatIn, centerLonIn, spanLatIn, spanLonIn);
+ public DownloadRunnable(final Viewport viewport) {
+ super(viewport);
}
@Override
@@ -1246,11 +1193,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
}
- final Viewport viewport = new Viewport(new Geopoint(centerLat / 1e6, centerLon / 1e6), 0.8 * spanLat / 1e6, 0.8 * spanLon / 1e6);
- search = ConnectorFactory.searchByViewport(viewport, tokens);
+ search = ConnectorFactory.searchByViewport(viewport.resize(0.8), tokens);
if (search != null) {
downloaded = true;
- if (search.error == StatusCode.NOT_LOGGED_IN) {
+ if (search.getError() == StatusCode.NOT_LOGGED_IN) {
Login.login();
tokens = null;
} else {
@@ -1269,10 +1215,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
//render
- displayExecutor.execute(new DisplayRunnable(centerLat, centerLon, spanLat, spanLon));
+ displayExecutor.execute(new DisplayRunnable(viewport));
} catch (ThreadDeath e) {
- Log.d(Settings.tag, "DownloadThread stopped");
+ Log.d("DownloadThread stopped");
displayHandler.sendEmptyMessage(UPDATE_TITLE);
} finally {
showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); // hide progress
@@ -1285,8 +1231,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
*/
private class DisplayRunnable extends DoRunnable {
- public DisplayRunnable(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) {
- super(centerLatIn, centerLonIn, spanLatIn, spanLonIn);
+ public DisplayRunnable(final Viewport viewport) {
+ super(viewport);
}
@Override
@@ -1298,30 +1244,29 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
// display caches
- final List<cgCache> cachesToDisplay = new ArrayList<cgCache>(caches);
+ final List<cgCache> cachesToDisplay = caches.getAsList();
+ final List<cgWaypoint> waypointsToDisplay = new ArrayList<cgWaypoint>(waypoints);
final List<CachesOverlayItemImpl> itemsToDisplay = new ArrayList<CachesOverlayItemImpl>();
if (!cachesToDisplay.isEmpty()) {
+ // Only show waypoints for single view or setting
+ // when less than showWaypointsthreshold Caches shown
+ if (cachesToDisplay.size() == 1 || (cachesCnt < Settings.getWayPointsThreshold())) {
+ for (cgWaypoint waypoint : waypointsToDisplay) {
+
+ if (waypoint.getCoords() == null) {
+ continue;
+ }
+
+ itemsToDisplay.add(getItem(waypoint, null, waypoint));
+ }
+ }
for (cgCache cache : cachesToDisplay) {
if (cache.getCoords() == null) {
continue;
}
-
- // display cache waypoints
- if (cache.hasWaypoints()
- // Only show waypoints for single view or setting
- // when less than showWaypointsthreshold Caches shown
- && (cachesToDisplay.size() == 1 || (cachesToDisplay.size() < Settings.getWayPointsThreshold()))) {
- for (cgWaypoint waypoint : cache.getWaypoints()) {
- if (waypoint.getCoords() == null) {
- continue;
- }
-
- itemsToDisplay.add(getItem(new cgCoord(waypoint), null, waypoint));
- }
- }
- itemsToDisplay.add(getItem(new cgCoord(cache), cache, null));
+ itemsToDisplay.add(getItem(cache, cache, null));
}
overlayCaches.updateItems(itemsToDisplay);
@@ -1336,7 +1281,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
displayHandler.sendEmptyMessage(UPDATE_TITLE);
} catch (ThreadDeath e) {
- Log.d(Settings.tag, "DisplayThread stopped");
+ Log.d("DisplayThread stopped");
displayHandler.sendEmptyMessage(UPDATE_TITLE);
} finally {
showProgressHandler.sendEmptyMessage(HIDE_PROGRESS);
@@ -1350,21 +1295,15 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private class Go4CacheRunnable extends DoRunnable {
- public Go4CacheRunnable(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) {
- super(centerLatIn, centerLonIn, spanLatIn, spanLonIn);
+ public Go4CacheRunnable(final Viewport viewport) {
+ super(viewport);
}
@Override
public void run() {
- final Geopoint center = new Geopoint((int) centerLat, (int) centerLon);
- final Viewport viewport = new Viewport(center, spanLat / 1e6 * 1.5, spanLon / 1e6 * 1.5);
-
- try {
- go4CacheThreadRun = System.currentTimeMillis();
- List<Go4CacheUser> go4CacheUsers = Go4Cache.getGeocachersInViewport(Settings.getUsername(), viewport);
- go4CacheDisplayExecutor.execute(new Go4CacheDisplayRunnable(go4CacheUsers, centerLat, centerLon, spanLat, spanLon));
- } finally {
- }
+ go4CacheThreadRun = System.currentTimeMillis();
+ List<Go4CacheUser> go4CacheUsers = Go4Cache.getGeocachersInViewport(Settings.getUsername(), viewport.resize(1.5));
+ go4CacheDisplayExecutor.execute(new Go4CacheDisplayRunnable(go4CacheUsers, viewport));
}
}
@@ -1375,42 +1314,39 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private List<Go4CacheUser> users = null;
- public Go4CacheDisplayRunnable(List<Go4CacheUser> usersIn, long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) {
- super(centerLatIn, centerLonIn, spanLatIn, spanLonIn);
+ public Go4CacheDisplayRunnable(List<Go4CacheUser> usersIn, final Viewport viewport) {
+ super(viewport);
users = usersIn;
}
@Override
public void run() {
- try {
- if (mapView == null || CollectionUtils.isEmpty(users)) {
- return;
- }
+ if (mapView == null || CollectionUtils.isEmpty(users)) {
+ return;
+ }
- // display users
- List<OtherCachersOverlayItemImpl> items = new ArrayList<OtherCachersOverlayItemImpl>();
+ // display users
+ List<OtherCachersOverlayItemImpl> items = new ArrayList<OtherCachersOverlayItemImpl>();
- int counter = 0;
- OtherCachersOverlayItemImpl item = null;
+ int counter = 0;
+ OtherCachersOverlayItemImpl item;
- for (Go4CacheUser userOne : users) {
- if (userOne.getCoords() == null) {
- continue;
- }
+ for (Go4CacheUser userOne : users) {
+ if (userOne.getCoords() == null) {
+ continue;
+ }
- item = mapProvider.getOtherCachersOverlayItemBase(activity, userOne);
- items.add(item);
+ item = mapProvider.getOtherCachersOverlayItemBase(activity, userOne);
+ items.add(item);
- counter++;
- if ((counter % 10) == 0) {
- overlayGo4Cache.updateItems(items);
- displayHandler.sendEmptyMessage(INVALIDATE_MAP);
- }
+ counter++;
+ if ((counter % 10) == 0) {
+ overlayGo4Cache.updateItems(items);
+ displayHandler.sendEmptyMessage(INVALIDATE_MAP);
}
-
- overlayGo4Cache.updateItems(items);
- } finally {
}
+
+ overlayGo4Cache.updateItems(items);
}
}
@@ -1426,14 +1362,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
if (coordsIntent != null) {
- final cgCoord coord = new cgCoord();
- coord.setCoordType("waypoint");
- coord.setCoords(coordsIntent);
- coord.setName("some place");
-
final cgWaypoint waypoint = new cgWaypoint("some place", waypointTypeIntent != null ? waypointTypeIntent : WaypointType.WAYPOINT, false);
+ waypoint.setCoords(coordsIntent);
- final CachesOverlayItemImpl item = getItem(coord, null, waypoint);
+ final CachesOverlayItemImpl item = getItem(waypoint, null, waypoint);
overlayCaches.updateItems(item);
displayHandler.sendEmptyMessage(INVALIDATE_MAP);
@@ -1446,18 +1378,12 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
}
- private abstract class DoRunnable implements Runnable {
+ private static abstract class DoRunnable implements Runnable {
- protected long centerLat = 0L;
- protected long centerLon = 0L;
- protected long spanLat = 0L;
- protected long spanLon = 0L;
+ final protected Viewport viewport;
- public DoRunnable(long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) {
- centerLat = centerLatIn;
- centerLon = centerLonIn;
- spanLat = spanLatIn;
- spanLon = spanLonIn;
+ public DoRunnable(final Viewport viewport) {
+ this.viewport = viewport;
}
public abstract void run();
@@ -1504,11 +1430,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if (dir != null) {
dir = app.removeDir();
}
- if (geo != null) {
- geo = app.removeGeo();
- }
- for (String geocode : geocodes) {
+ app.deleteGeoObserver(geoUpdate);
+
+ for (final String geocode : geocodes) {
try {
if (handler.isCancelled()) {
break;
@@ -1529,15 +1454,15 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
if (handler.isCancelled()) {
- Log.i(Settings.tag, "Stopped storing process.");
+ Log.i("Stopped storing process.");
break;
}
- cgBase.storeCache(activity, null, geocode, StoredList.STANDARD_LIST_ID, handler);
+ cgCache.storeCache(activity, null, geocode, StoredList.STANDARD_LIST_ID, false, handler);
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgeocaches.LoadDetails.run: " + e.toString());
+ Log.e("cgeocaches.LoadDetails.run: " + e.toString());
} finally {
// one more cache over
detailProgress++;
@@ -1552,9 +1477,17 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
// we're done
handler.sendEmptyMessage(FINISHED_LOADING_DETAILS);
+ app.addGeoObserver(geoUpdate);
}
}
+ private static boolean mapMoved(final Viewport referenceViewport, final Viewport newViewport) {
+ return Math.abs(newViewport.getLatitudeSpan() - referenceViewport.getLatitudeSpan()) > 50e-6 ||
+ Math.abs(newViewport.getLongitudeSpan() - referenceViewport.getLongitudeSpan()) > 50e-6 ||
+ Math.abs(newViewport.center.getLatitude() - referenceViewport.center.getLatitude()) > referenceViewport.getLatitudeSpan() / 4 ||
+ Math.abs(newViewport.center.getLongitude() - referenceViewport.center.getLongitude()) > referenceViewport.getLongitudeSpan() / 4;
+ }
+
// center map to desired location
private void centerMap(final Geopoint coords) {
if (coords == null) {
@@ -1588,46 +1521,21 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
alreadyCentered = true;
} else if (!centered && (geocodeCenter != null || searchIntent != null)) {
try {
- List<Number> viewport = null;
+ Viewport viewport = null;
if (geocodeCenter != null) {
viewport = app.getBounds(geocodeCenter);
- } else {
- if (searchCenter != null) {
- viewport = app.getBounds(searchCenter.getGeocodes());
- }
- }
-
- if (viewport == null || viewport.size() < 5) {
- return;
+ } else if (searchCenter != null) {
+ viewport = app.getBounds(searchCenter.getGeocodes());
}
- int cnt = (Integer) viewport.get(0);
- if (cnt <= 0) {
+ if (viewport == null) {
return;
}
- int minLat = (int) ((Double) viewport.get(1) * 1e6);
- int maxLat = (int) ((Double) viewport.get(2) * 1e6);
- int maxLon = (int) ((Double) viewport.get(3) * 1e6);
- int minLon = (int) ((Double) viewport.get(4) * 1e6);
-
- int centerLat = 0;
- int centerLon = 0;
- if ((Math.abs(maxLat) - Math.abs(minLat)) != 0) {
- centerLat = minLat + ((maxLat - minLat) / 2);
- } else {
- centerLat = maxLat;
- }
- if ((Math.abs(maxLon) - Math.abs(minLon)) != 0) {
- centerLon = minLon + ((maxLon - minLon) / 2);
- } else {
- centerLon = maxLon;
- }
-
- mapController.setCenter(mapProvider.getGeoPointBase(new Geopoint(centerLat, centerLon)));
- if (Math.abs(maxLat - minLat) != 0 && Math.abs(maxLon - minLon) != 0) {
- mapController.zoomToSpan(Math.abs(maxLat - minLat), Math.abs(maxLon - minLon));
+ mapController.setCenter(mapProvider.getGeoPointBase(viewport.center));
+ if (viewport.getLatitudeSpan() != 0 && viewport.getLongitudeSpan() != 0) {
+ mapController.zoomToSpan((int) (viewport.getLatitudeSpan() * 1e6), (int) (viewport.getLongitudeSpan() * 1e6));
}
} catch (Exception e) {
// nothing at all
@@ -1651,7 +1559,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private void switchMyLocationButton() {
if (followMyLocation) {
myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_on);
- myLocationInMiddle();
+ myLocationInMiddle(app.currentGeo());
} else {
myLocSwitch.setImageResource(R.drawable.actionbar_mylocation_off);
}
@@ -1717,8 +1625,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
public static void startActivityCoords(final Activity fromActivity, final Geopoint coords, final WaypointType type, final String title) {
final Intent mapIntent = newIntent(fromActivity);
- mapIntent.putExtra(EXTRAS_LATITUDE, coords.getLatitude());
- mapIntent.putExtra(EXTRAS_LONGITUDE, coords.getLongitude());
+ mapIntent.putExtra(EXTRAS_COORDS, coords);
if (type != null) {
mapIntent.putExtra(EXTRAS_WPTTYPE, type.id);
}
@@ -1753,12 +1660,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
* Waypoint. Mutally exclusive with cache
* @return
*/
- private CachesOverlayItemImpl getItem(cgCoord coord, cgCache cache, cgWaypoint waypoint) {
+ private CachesOverlayItemImpl getItem(final IWaypoint coord, final cgCache cache, final cgWaypoint waypoint) {
if (cache != null) {
-
- CachesOverlayItemImpl item = mapProvider.getCachesOverlayItem(coord, cache.getType());
-
- int hashcode = new HashCodeBuilder()
+ final CachesOverlayItemImpl item = mapProvider.getCachesOverlayItem(coord, cache.getType());
+ final int hashcode = new HashCodeBuilder()
.append(cache.isReliableLatLon())
.append(cache.getType().id)
.append(cache.isDisabled() || cache.isArchived())
@@ -1770,23 +1675,20 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
.append(cache.getListId() > 0)
.toHashCode();
- LayerDrawable ldFromCache = CGeoMap.overlaysCache.get(hashcode);
+ final LayerDrawable ldFromCache = CGeoMap.overlaysCache.get(hashcode);
if (ldFromCache != null) {
item.setMarker(ldFromCache);
return item;
}
- ArrayList<Drawable> layers = new ArrayList<Drawable>();
- ArrayList<int[]> insets = new ArrayList<int[]>();
-
+ // Set initial capacities to the maximum of layers and insets to avoid dynamic reallocation
+ final ArrayList<Drawable> layers = new ArrayList<Drawable>(9);
+ final ArrayList<int[]> insets = new ArrayList<int[]>(8);
// background: disabled or not
- Drawable marker = getResources().getDrawable(R.drawable.marker);
- if (cache.isDisabled() || cache.isArchived()) {
- marker = getResources().getDrawable(R.drawable.marker_disabled);
- }
+ final Drawable marker = getResources().getDrawable(cache.isDisabled() || cache.isArchived() ? R.drawable.marker_disabled : R.drawable.marker);
layers.add(marker);
- int resolution = marker.getIntrinsicWidth() > 40 ? 1 : 0;
+ final int resolution = marker.getIntrinsicWidth() > 40 ? 1 : 0;
// reliable or not
if (!cache.isReliableLatLon()) {
insets.add(INSET_RELIABLE[resolution]);
@@ -1796,7 +1698,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
layers.add(getResources().getDrawable(cache.getType().markerId));
insets.add(INSET_TYPE[resolution]);
// own
- if ( cache.isOwn() ) {
+ if (cache.isOwn()) {
layers.add(getResources().getDrawable(R.drawable.marker_own));
insets.add(INSET_OWN[resolution]);
// if not, checked if stored
@@ -1824,11 +1726,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
insets.add(INSET_PERSONALNOTE[resolution]);
}
-
- LayerDrawable ld = new LayerDrawable(layers.toArray(new Drawable[layers.size()]));
+ final LayerDrawable ld = new LayerDrawable(layers.toArray(new Drawable[layers.size()]));
int index = 1;
- for ( int[] inset : insets) {
+ for (final int[] inset : insets) {
ld.setLayerInset(index++, inset[0], inset[1], inset[2], inset[3]);
}
@@ -1836,10 +1737,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
item.setMarker(ld);
return item;
+ }
- } else if (waypoint != null) {
-
- CachesOverlayItemImpl item = mapProvider.getCachesOverlayItem(coord, null);
+ if (waypoint != null) {
+ final CachesOverlayItemImpl item = mapProvider.getCachesOverlayItem(coord, null);
Drawable[] layers = new Drawable[2];
layers[0] = getResources().getDrawable(R.drawable.marker);
layers[1] = getResources().getDrawable(waypoint.getWaypointType().markerId);
@@ -1855,7 +1756,6 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
return null;
-
}
}
diff --git a/main/src/cgeo/geocaching/maps/CachesOverlay.java b/main/src/cgeo/geocaching/maps/CachesOverlay.java
index 0a952bc..d3a7865 100644
--- a/main/src/cgeo/geocaching/maps/CachesOverlay.java
+++ b/main/src/cgeo/geocaching/maps/CachesOverlay.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.maps;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgCoord;
import cgeo.geocaching.cgeopopup;
import cgeo.geocaching.cgeowaypoint;
import cgeo.geocaching.enumerations.CacheType;
@@ -12,12 +12,12 @@ import cgeo.geocaching.maps.interfaces.ItemizedOverlayImpl;
import cgeo.geocaching.maps.interfaces.MapProjectionImpl;
import cgeo.geocaching.maps.interfaces.MapProvider;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import android.app.ProgressDialog;
import android.content.Context;
-import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
@@ -25,7 +25,6 @@ import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
import android.location.Location;
-import android.util.Log;
import java.util.ArrayList;
import java.util.List;
@@ -36,11 +35,9 @@ public class CachesOverlay extends AbstractItemizedOverlay {
private Context context = null;
private boolean displayCircles = false;
private ProgressDialog waitDialog = null;
- private Point center = new Point();
- private Point left = new Point();
private Paint blockedCircle = null;
- private PaintFlagsDrawFilter setfil = null;
- private PaintFlagsDrawFilter remfil = null;
+ private PaintFlagsDrawFilter setFilter = null;
+ private PaintFlagsDrawFilter removeFilter = null;
private MapProvider mapProvider = null;
public CachesOverlay(ItemizedOverlayImpl ovlImpl, Context contextIn) {
@@ -107,65 +104,90 @@ public class CachesOverlay extends AbstractItemizedOverlay {
}
private void drawInternal(Canvas canvas, MapProjectionImpl projection) {
+ if (!displayCircles || items.isEmpty()) {
+ return;
+ }
// prevent content changes
getOverlayImpl().lock();
try {
- if (displayCircles) {
- if (blockedCircle == null) {
- blockedCircle = new Paint();
- blockedCircle.setAntiAlias(true);
- blockedCircle.setStrokeWidth(2.0f);
- blockedCircle.setARGB(127, 0, 0, 0);
- blockedCircle.setPathEffect(new DashPathEffect(new float[] { 3, 2 }, 0));
+ lazyInitializeDrawingObjects();
+ canvas.setDrawFilter(setFilter);
+
+ final int radius = calculateDrawingRadius(projection);
+ final Point center = new Point();
+
+ for (CachesOverlayItemImpl item : items) {
+ final Geopoint itemCoord = item.getCoord().getCoords();
+ final GeoPointImpl itemGeo = mapProvider.getGeoPointBase(itemCoord);
+ projection.toPixels(itemGeo, center);
+
+ final CacheType type = item.getType();
+ if (type == null || type == CacheType.MULTI || type == CacheType.MYSTERY || type == CacheType.VIRTUAL || type.isEvent()) {
+ blockedCircle.setColor(0x66000000);
+ blockedCircle.setStyle(Style.STROKE);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ } else {
+ blockedCircle.setColor(0x66BB0000);
+ blockedCircle.setStyle(Style.STROKE);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+
+ blockedCircle.setColor(0x44BB0000);
+ blockedCircle.setStyle(Style.FILL);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
}
+ }
+ canvas.setDrawFilter(removeFilter);
+ } finally {
+ getOverlayImpl().unlock();
+ }
+ }
- if (setfil == null) {
- setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
- }
- if (remfil == null) {
- remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
- }
+ /**
+ * calculate the radius of the circle to be drawn for the first item only. Those circles are only 161 meters in
+ * reality and therefore the minor changes due to the projection will not make any visible difference at the zoom
+ * levels which are used to see the circles.
+ *
+ * @param projection
+ * @return
+ */
+ private int calculateDrawingRadius(MapProjectionImpl projection) {
+ float[] distanceArray = new float[1];
+ final Geopoint itemCoord = items.get(0).getCoord().getCoords();
- canvas.setDrawFilter(setfil);
+ Location.distanceBetween(itemCoord.getLatitude(), itemCoord.getLongitude(),
+ itemCoord.getLatitude(), itemCoord.getLongitude() + 1, distanceArray);
+ final float longitudeLineDistance = distanceArray[0];
- for (CachesOverlayItemImpl item : items) {
- final cgCoord itemCoord = item.getCoord();
- float[] result = new float[1];
+ final GeoPointImpl itemGeo = mapProvider.getGeoPointBase(itemCoord);
- Location.distanceBetween(itemCoord.getCoords().getLatitude(), itemCoord.getCoords().getLongitude(),
- itemCoord.getCoords().getLatitude(), itemCoord.getCoords().getLongitude() + 1, result);
- final float longitudeLineDistance = result[0];
+ final Geopoint leftCoords = new Geopoint(itemCoord.getLatitude(),
+ itemCoord.getLongitude() - 161 / longitudeLineDistance);
+ final GeoPointImpl leftGeo = mapProvider.getGeoPointBase(leftCoords);
- GeoPointImpl itemGeo = mapProvider.getGeoPointBase(itemCoord.getCoords());
+ final Point center = new Point();
+ projection.toPixels(itemGeo, center);
- final Geopoint leftCoords = new Geopoint(itemCoord.getCoords().getLatitude(),
- itemCoord.getCoords().getLongitude() - 161 / longitudeLineDistance);
- GeoPointImpl leftGeo = mapProvider.getGeoPointBase(leftCoords);
+ final Point left = new Point();
+ projection.toPixels(leftGeo, left);
- projection.toPixels(itemGeo, center);
- projection.toPixels(leftGeo, left);
- int radius = center.x - left.x;
+ return center.x - left.x;
+ }
- final CacheType type = item.getType();
- if (type == null || type == CacheType.MULTI || type == CacheType.MYSTERY || type == CacheType.VIRTUAL) {
- blockedCircle.setColor(0x66000000);
- blockedCircle.setStyle(Style.STROKE);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
- } else {
- blockedCircle.setColor(0x66BB0000);
- blockedCircle.setStyle(Style.STROKE);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ private void lazyInitializeDrawingObjects() {
+ if (blockedCircle == null) {
+ blockedCircle = new Paint();
+ blockedCircle.setAntiAlias(true);
+ blockedCircle.setStrokeWidth(2.0f);
+ blockedCircle.setARGB(127, 0, 0, 0);
+ blockedCircle.setPathEffect(new DashPathEffect(new float[] { 3, 2 }, 0));
+ }
- blockedCircle.setColor(0x44BB0000);
- blockedCircle.setStyle(Style.FILL);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
- }
- }
- canvas.setDrawFilter(remfil);
- }
- } finally {
- getOverlayImpl().unlock();
+ if (setFilter == null) {
+ setFilter = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
+ }
+ if (removeFilter == null) {
+ removeFilter = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
}
}
@@ -200,22 +222,14 @@ public class CachesOverlay extends AbstractItemizedOverlay {
return false;
}
- cgCoord coordinate = item.getCoord();
+ final IWaypoint coordinate = item.getCoord();
if (StringUtils.isNotBlank(coordinate.getCoordType()) && coordinate.getCoordType().equalsIgnoreCase("cache") && StringUtils.isNotBlank(coordinate.getGeocode())) {
- Intent popupIntent = new Intent(context, cgeopopup.class);
-
- popupIntent.putExtra("geocode", coordinate.getGeocode());
-
CGeoMap.markCacheAsDirty(coordinate.getGeocode());
- context.startActivity(popupIntent);
+ cgeopopup.startActivity(context, coordinate.getGeocode());
} else if (coordinate.getCoordType() != null && coordinate.getCoordType().equalsIgnoreCase("waypoint") && coordinate.getId() > 0) {
- Intent popupIntent = new Intent(context, cgeowaypoint.class);
-
- popupIntent.putExtra("waypoint", coordinate.getId());
-
CGeoMap.markCacheAsDirty(coordinate.getGeocode());
- context.startActivity(popupIntent);
+ cgeowaypoint.startActivity(context, coordinate.getId());
} else {
waitDialog.dismiss();
return false;
@@ -223,7 +237,7 @@ public class CachesOverlay extends AbstractItemizedOverlay {
waitDialog.dismiss();
} catch (Exception e) {
- Log.e(Settings.tag, "cgMapOverlay.onTap: " + e.toString());
+ Log.e("cgMapOverlay.onTap: " + e.toString());
}
return false;
@@ -234,7 +248,7 @@ public class CachesOverlay extends AbstractItemizedOverlay {
try {
return items.get(index);
} catch (Exception e) {
- Log.e(Settings.tag, "cgMapOverlay.createItem: " + e.toString());
+ Log.e("cgMapOverlay.createItem: " + e.toString());
}
return null;
@@ -245,7 +259,7 @@ public class CachesOverlay extends AbstractItemizedOverlay {
try {
return items.size();
} catch (Exception e) {
- Log.e(Settings.tag, "cgMapOverlay.size: " + e.toString());
+ Log.e("cgMapOverlay.size: " + e.toString());
}
return 0;
diff --git a/main/src/cgeo/geocaching/maps/MapProviderFactory.java b/main/src/cgeo/geocaching/maps/MapProviderFactory.java
index c7865f3..3509209 100644
--- a/main/src/cgeo/geocaching/maps/MapProviderFactory.java
+++ b/main/src/cgeo/geocaching/maps/MapProviderFactory.java
@@ -16,11 +16,24 @@ public class MapProviderFactory {
private static MapProviderFactory instance = null;
- private MapProvider[] mapProviders;
+ private final MapProvider[] mapProviders;
private SortedMap<Integer, String> mapSources;
private MapProviderFactory() {
- mapProviders = new MapProvider[] { new GoogleMapProvider(GOOGLEMAP_BASEID), new MapsforgeMapProvider(MFMAP_BASEID) };
+ // add GoogleMapProvider only if google api is available in order to support x86 android emulator
+ boolean googleMaps = true;
+ try {
+ Class.forName("com.google.android.maps.MapActivity");
+ } catch (ClassNotFoundException e) {
+ googleMaps = false;
+ }
+ if (googleMaps) {
+ mapProviders = new MapProvider[] { new GoogleMapProvider(GOOGLEMAP_BASEID), new MapsforgeMapProvider(MFMAP_BASEID) };
+ }
+ else {
+ mapProviders = new MapProvider[] { new MapsforgeMapProvider(MFMAP_BASEID) };
+ }
+
mapSources = new TreeMap<Integer, String>();
for (MapProvider mp : mapProviders) {
mapSources.putAll(mp.getMapSources());
diff --git a/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java b/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java
index 4dd217b..6ca050e 100644
--- a/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java
+++ b/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java
@@ -1,21 +1,19 @@
package cgeo.geocaching.maps;
import cgeo.geocaching.CacheDetailActivity;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.go4cache.Go4CacheUser;
import cgeo.geocaching.maps.interfaces.ItemizedOverlayImpl;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OtherCachersOverlayItemImpl;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.Intent;
import android.graphics.Canvas;
-import android.util.Log;
import java.util.ArrayList;
import java.util.List;
@@ -92,7 +90,7 @@ public class OtherCachersOverlay extends AbstractItemizedOverlay {
return true;
} catch (Exception e) {
- Log.e(Settings.tag, "cgUsersOverlay.onTap: " + e.toString());
+ Log.e("cgUsersOverlay.onTap: " + e.toString());
}
return false;
@@ -108,7 +106,7 @@ public class OtherCachersOverlay extends AbstractItemizedOverlay {
try {
return items.get(index);
} catch (Exception e) {
- Log.e(Settings.tag, "cgUsersOverlay.createItem: " + e.toString());
+ Log.e("cgUsersOverlay.createItem: " + e.toString());
}
return null;
@@ -119,7 +117,7 @@ public class OtherCachersOverlay extends AbstractItemizedOverlay {
try {
return items.size();
} catch (Exception e) {
- Log.e(Settings.tag, "cgUsersOverlay.size: " + e.toString());
+ Log.e("cgUsersOverlay.size: " + e.toString());
}
return 0;
@@ -135,9 +133,7 @@ public class OtherCachersOverlay extends AbstractItemizedOverlay {
public void onClick(DialogInterface dialog, int id) {
if (geocode != null) {
- final Intent detailIntent = new Intent(context, CacheDetailActivity.class);
- detailIntent.putExtra("geocode", geocode);
- context.startActivity(detailIntent);
+ CacheDetailActivity.startActivity(context, geocode);
}
dialog.cancel();
diff --git a/main/src/cgeo/geocaching/maps/OtherCachersOverlayItem.java b/main/src/cgeo/geocaching/maps/OtherCachersOverlayItem.java
index d71bbcf..9844e83 100644
--- a/main/src/cgeo/geocaching/maps/OtherCachersOverlayItem.java
+++ b/main/src/cgeo/geocaching/maps/OtherCachersOverlayItem.java
@@ -16,7 +16,7 @@ public class OtherCachersOverlayItem {
}
public Drawable getMarker() {
- Drawable marker = null;
+ Drawable marker;
if (user != null && user.getDate() != null && user.getDate().getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) {
marker = context.getResources().getDrawable(R.drawable.user_location_active);
diff --git a/main/src/cgeo/geocaching/maps/PositionOverlay.java b/main/src/cgeo/geocaching/maps/PositionOverlay.java
index a09b6de..9099498 100644
--- a/main/src/cgeo/geocaching/maps/PositionOverlay.java
+++ b/main/src/cgeo/geocaching/maps/PositionOverlay.java
@@ -150,7 +150,7 @@ public class PositionOverlay implements GeneralOverlay {
if (Settings.isMapTrail()) {
int size = history.size();
if (size > 1) {
- int alpha = 0;
+ int alpha;
int alphaCnt = size - 201;
if (alphaCnt < 1) {
alphaCnt = 1;
@@ -210,7 +210,7 @@ public class PositionOverlay implements GeneralOverlay {
marginTop = center.y - heightArrowHalf;
Matrix matrix = new Matrix();
- matrix.setRotate(heading.floatValue(), widthArrowHalf, heightArrowHalf);
+ matrix.setRotate(heading, widthArrowHalf, heightArrowHalf);
matrix.postTranslate(marginLeft, marginTop);
canvas.drawBitmap(arrow, matrix, null);
diff --git a/main/src/cgeo/geocaching/maps/ScaleOverlay.java b/main/src/cgeo/geocaching/maps/ScaleOverlay.java
index f43ba25..321624d 100644
--- a/main/src/cgeo/geocaching/maps/ScaleOverlay.java
+++ b/main/src/cgeo/geocaching/maps/ScaleOverlay.java
@@ -1,14 +1,15 @@
package cgeo.geocaching.maps;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.geopoint.IConversion;
+import cgeo.geocaching.geopoint.HumanDistance;
import cgeo.geocaching.maps.interfaces.GeneralOverlay;
import cgeo.geocaching.maps.interfaces.GeoPointImpl;
import cgeo.geocaching.maps.interfaces.MapProjectionImpl;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OverlayImpl;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
import android.app.Activity;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
@@ -25,11 +26,6 @@ public class ScaleOverlay implements GeneralOverlay {
private Paint scaleShadow = null;
private BlurMaskFilter blur = null;
private float pixelDensity = 0;
- private double pixels = 0d;
- private int bottom = 0;
- private double distance = 0d;
- private double distanceRound = 0d;
- private String units = null;
private OverlayImpl ovlImpl = null;
public ScaleOverlay(Activity activity, OverlayImpl overlayImpl) {
@@ -51,64 +47,25 @@ public class ScaleOverlay implements GeneralOverlay {
drawInternal(canvas, mapView);
}
+ static private double keepSignificantDigit(final double distance) {
+ final double scale = Math.pow(10, Math.floor(Math.log10(distance)));
+ return scale * Math.floor(distance / scale);
+ }
+
private void drawInternal(Canvas canvas, MapViewImpl mapView) {
final double span = mapView.getLongitudeSpan() / 1e6;
final GeoPointImpl center = mapView.getMapViewCenter();
- pixels = mapView.getWidth() * SCALE_WIDTH_FACTOR; // pixels related to following latitude span
- bottom = mapView.getHeight() - 14; // pixels from bottom side of screen
+ final int bottom = mapView.getHeight() - 14; // pixels from bottom side of screen
final Geopoint leftCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 - span / 2);
final Geopoint rightCoords = new Geopoint(center.getLatitudeE6() / 1e6, center.getLongitudeE6() / 1e6 + span / 2);
- distance = leftCoords.distanceTo(rightCoords) * SCALE_WIDTH_FACTOR;
- distanceRound = 0d;
-
- //FIXME: merge with getHumanDistance()
- if (Settings.isUseMetricUnits()) {
- if (distance > 100) { // 100+ km > 1xx km
- distanceRound = Math.floor(distance / 100) * 100;
- units = "km";
- } else if (distance > 10) { // 10 - 100 km > 1x km
- distanceRound = Math.floor(distance / 10) * 10;
- units = "km";
- } else if (distance > 1) { // 1 - 10 km > 1.x km
- distanceRound = Math.floor(distance);
- units = "km";
- } else if (distance > 0.1) { // 100 m - 1 km > 1xx m
- distance *= 1000;
- distanceRound = Math.floor(distance / 100) * 100;
- units = "m";
- } else { // 1 - 100 m > 1x m
- distance *= 1000;
- distanceRound = Math.round(distance / 10) * 10;
- units = "m";
- }
- } else {
- distance /= IConversion.MILES_TO_KILOMETER;
-
- if (distance > 100) { // 100+ mi > 1xx mi
- distanceRound = Math.floor(distance / 100) * 100;
- units = "mi";
- } else if (distance > 10) { // 10 - 100 mi > 1x mi
- distanceRound = Math.floor(distance / 10) * 10;
- units = "mi";
- } else if (distance > 1) { // 1 - 10 mi > 1.x mi
- distanceRound = Math.floor(distance);
- units = "mi";
- } else if (distance > 0.1) { // 0.1 mi - 1.0 mi > 1xx ft
- distance *= 5280;
- distanceRound = Math.floor(distance / 100) * 100;
- units = "ft";
- } else { // 1 - 100 ft > 1x ft
- distance *= 5280;
- distanceRound = Math.round(distance / 10) * 10;
- units = "ft";
- }
- }
+ final ImmutablePair<Double, String> scaled = HumanDistance.scaleUnit(leftCoords.distanceTo(rightCoords) * SCALE_WIDTH_FACTOR);
- pixels = Math.round((pixels / distance) * distanceRound);
+ final double distanceRound = keepSignificantDigit(scaled.left);
+ final double pixels = Math.round((mapView.getWidth() * SCALE_WIDTH_FACTOR / scaled.left) * distanceRound);
if (blur == null) {
blur = new BlurMaskFilter(3, BlurMaskFilter.Blur.NORMAL);
@@ -139,15 +96,17 @@ public class ScaleOverlay implements GeneralOverlay {
scale.setColor(0xFF000000);
}
+ final String formatString = distanceRound >= 1 ? "%.0f" : "%.1f";
+
canvas.drawLine(10, bottom, 10, (bottom - (8 * pixelDensity)), scaleShadow);
canvas.drawLine((int) (pixels + 10), bottom, (int) (pixels + 10), (bottom - (8 * pixelDensity)), scaleShadow);
canvas.drawLine(8, bottom, (int) (pixels + 12), bottom, scaleShadow);
- canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scaleShadow);
+ canvas.drawText(String.format(formatString, distanceRound) + " " + scaled.right, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scaleShadow);
canvas.drawLine(11, bottom, 11, (bottom - (6 * pixelDensity)), scale);
canvas.drawLine((int) (pixels + 9), bottom, (int) (pixels + 9), (bottom - (6 * pixelDensity)), scale);
canvas.drawLine(10, bottom, (int) (pixels + 10), bottom, scale);
- canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scale);
+ canvas.drawText(String.format(formatString, distanceRound) + " " + scaled.right, (float) (pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scale);
}
@Override
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlayItem.java b/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlayItem.java
index 5f41c54..27a1b56 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlayItem.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleCacheOverlayItem.java
@@ -1,6 +1,6 @@
package cgeo.geocaching.maps.google;
-import cgeo.geocaching.cgCoord;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.maps.interfaces.CachesOverlayItemImpl;
@@ -9,16 +9,16 @@ import com.google.android.maps.OverlayItem;
public class GoogleCacheOverlayItem extends OverlayItem implements CachesOverlayItemImpl {
final private CacheType cacheType;
- final private cgCoord coord;
+ final private IWaypoint coord;
- public GoogleCacheOverlayItem(final cgCoord coordinate, final CacheType type) {
+ public GoogleCacheOverlayItem(final IWaypoint coordinate, final CacheType type) {
super(new GeoPoint(coordinate.getCoords().getLatitudeE6(), coordinate.getCoords().getLongitudeE6()), coordinate.getName(), "");
this.cacheType = type;
this.coord = coordinate;
}
- public cgCoord getCoord() {
+ public IWaypoint getCoord() {
return coord;
}
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleGeoPoint.java b/main/src/cgeo/geocaching/maps/google/GoogleGeoPoint.java
index 56bc40c..d5f6385 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleGeoPoint.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleGeoPoint.java
@@ -1,5 +1,6 @@
package cgeo.geocaching.maps.google;
+import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.maps.interfaces.GeoPointImpl;
import com.google.android.maps.GeoPoint;
@@ -10,4 +11,9 @@ public class GoogleGeoPoint extends GeoPoint implements GeoPointImpl {
super(latitudeE6, longitudeE6);
}
+ @Override
+ public Geopoint getCoords() {
+ return new Geopoint(getLatitudeE6() / 1e6, getLongitudeE6() / 1e6);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java b/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java
index 7191428..b659042 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleMapProvider.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.maps.google;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.R;
-import cgeo.geocaching.cgCoord;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.geopoint.Geopoint;
@@ -81,15 +81,13 @@ public class GoogleMapProvider implements MapProvider {
}
@Override
- public CachesOverlayItemImpl getCachesOverlayItem(final cgCoord coordinate, final CacheType type) {
- GoogleCacheOverlayItem baseItem = new GoogleCacheOverlayItem(coordinate, type);
- return baseItem;
+ public CachesOverlayItemImpl getCachesOverlayItem(final IWaypoint coordinate, final CacheType type) {
+ return new GoogleCacheOverlayItem(coordinate, type);
}
@Override
public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context, Go4CacheUser userOne) {
- GoogleOtherCachersOverlayItem baseItem = new GoogleOtherCachersOverlayItem(context, userOne);
- return baseItem;
+ return new GoogleOtherCachersOverlayItem(context, userOne);
}
}
diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
index 8afba89..8bf7deb 100644
--- a/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
+++ b/main/src/cgeo/geocaching/maps/google/GoogleMapView.java
@@ -3,6 +3,7 @@ package cgeo.geocaching.maps.google;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import cgeo.geocaching.Settings;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.maps.CachesOverlay;
import cgeo.geocaching.maps.OtherCachersOverlay;
import cgeo.geocaching.maps.PositionOverlay;
@@ -15,6 +16,7 @@ import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnMapDragListener;
import cgeo.geocaching.maps.interfaces.OverlayImpl;
import cgeo.geocaching.maps.interfaces.OverlayImpl.overlayType;
+import cgeo.geocaching.utils.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
@@ -25,7 +27,6 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Gravity;
@@ -60,7 +61,7 @@ public class GoogleMapView extends MapView implements MapViewImpl {
super.draw(canvas);
} catch (Exception e) {
- Log.e(Settings.tag, "GoogleMapView.draw: " + e.toString());
+ Log.e("GoogleMapView.draw: " + e.toString());
}
}
@@ -74,7 +75,7 @@ public class GoogleMapView extends MapView implements MapViewImpl {
super.displayZoomControls(takeFocus);
} catch (Exception e) {
- Log.e(Settings.tag, "GoogleMapView.displayZoomControls: " + e.toString());
+ Log.e("GoogleMapView.displayZoomControls: " + e.toString());
}
}
@@ -90,6 +91,11 @@ public class GoogleMapView extends MapView implements MapViewImpl {
}
@Override
+ public Viewport getViewport() {
+ return new Viewport(getMapViewCenter(), getLatitudeSpan() / 1e6, getLongitudeSpan() / 1e6);
+ }
+
+ @Override
public void addOverlay(OverlayImpl ovl) {
getOverlays().add((Overlay) ovl);
}
diff --git a/main/src/cgeo/geocaching/maps/interfaces/CachesOverlayItemImpl.java b/main/src/cgeo/geocaching/maps/interfaces/CachesOverlayItemImpl.java
index e2bf552..1afc120 100644
--- a/main/src/cgeo/geocaching/maps/interfaces/CachesOverlayItemImpl.java
+++ b/main/src/cgeo/geocaching/maps/interfaces/CachesOverlayItemImpl.java
@@ -1,6 +1,6 @@
package cgeo.geocaching.maps.interfaces;
-import cgeo.geocaching.cgCoord;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.enumerations.CacheType;
/**
@@ -12,7 +12,7 @@ import cgeo.geocaching.enumerations.CacheType;
*/
public interface CachesOverlayItemImpl extends OverlayItemImpl {
- public cgCoord getCoord();
+ public IWaypoint getCoord();
public CacheType getType();
diff --git a/main/src/cgeo/geocaching/maps/interfaces/GeoPointImpl.java b/main/src/cgeo/geocaching/maps/interfaces/GeoPointImpl.java
index 55f014b..5636da2 100644
--- a/main/src/cgeo/geocaching/maps/interfaces/GeoPointImpl.java
+++ b/main/src/cgeo/geocaching/maps/interfaces/GeoPointImpl.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.maps.interfaces;
+import cgeo.geocaching.ICoordinates;
+
/**
* Defines the common functions of the provider-specific
* GeoPoint implementations
@@ -7,7 +9,7 @@ package cgeo.geocaching.maps.interfaces;
* @author rsudev
*
*/
-public interface GeoPointImpl {
+public interface GeoPointImpl extends ICoordinates {
int getLatitudeE6();
diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapProvider.java b/main/src/cgeo/geocaching/maps/interfaces/MapProvider.java
index c2c46ac..dd935c4 100644
--- a/main/src/cgeo/geocaching/maps/interfaces/MapProvider.java
+++ b/main/src/cgeo/geocaching/maps/interfaces/MapProvider.java
@@ -1,6 +1,6 @@
package cgeo.geocaching.maps.interfaces;
-import cgeo.geocaching.cgCoord;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.go4cache.Go4CacheUser;
@@ -31,7 +31,7 @@ public interface MapProvider {
public GeoPointImpl getGeoPointBase(final Geopoint coords);
- public CachesOverlayItemImpl getCachesOverlayItem(final cgCoord coordinate, final CacheType type);
+ public CachesOverlayItemImpl getCachesOverlayItem(final IWaypoint iWaypoint, final CacheType type);
public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context,
Go4CacheUser userOne);
diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
index 08e04f1..c567cf2 100644
--- a/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
+++ b/main/src/cgeo/geocaching/maps/interfaces/MapViewImpl.java
@@ -1,5 +1,6 @@
package cgeo.geocaching.maps.interfaces;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.maps.CachesOverlay;
import cgeo.geocaching.maps.OtherCachersOverlay;
import cgeo.geocaching.maps.PositionOverlay;
@@ -78,4 +79,6 @@ public interface MapViewImpl {
*/
boolean needsInvertedColors();
+ Viewport getViewport();
+
}
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlayItem.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlayItem.java
index ccc0e78..f2ffae7 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlayItem.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeCacheOverlayItem.java
@@ -1,6 +1,6 @@
package cgeo.geocaching.maps.mapsforge;
-import cgeo.geocaching.cgCoord;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.maps.interfaces.CachesOverlayItemImpl;
@@ -11,16 +11,16 @@ import android.graphics.drawable.Drawable;
public class MapsforgeCacheOverlayItem extends OverlayItem implements CachesOverlayItemImpl {
final private CacheType cacheType;
- final private cgCoord coord;
+ final private IWaypoint coord;
- public MapsforgeCacheOverlayItem(cgCoord coordinate, final CacheType type) {
+ public MapsforgeCacheOverlayItem(IWaypoint coordinate, final CacheType type) {
super(new GeoPoint(coordinate.getCoords().getLatitudeE6(), coordinate.getCoords().getLongitudeE6()), coordinate.getName(), "");
this.cacheType = type;
this.coord = coordinate;
}
- public cgCoord getCoord() {
+ public IWaypoint getCoord() {
return coord;
}
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeGeoPoint.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeGeoPoint.java
index 19dc7c5..490822b 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeGeoPoint.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeGeoPoint.java
@@ -1,5 +1,6 @@
package cgeo.geocaching.maps.mapsforge;
+import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.maps.interfaces.GeoPointImpl;
import org.mapsforge.android.maps.GeoPoint;
@@ -9,4 +10,9 @@ public class MapsforgeGeoPoint extends GeoPoint implements GeoPointImpl {
public MapsforgeGeoPoint(int latitudeE6, int longitudeE6) {
super(latitudeE6, longitudeE6);
}
+
+ @Override
+ public Geopoint getCoords() {
+ return new Geopoint(getLatitudeE6() / 1e6, getLongitudeE6() / 1e6);
+ }
}
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapProvider.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapProvider.java
index 19c1335..c119fd0 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapProvider.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapProvider.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.maps.mapsforge;
+import cgeo.geocaching.IWaypoint;
import cgeo.geocaching.R;
-import cgeo.geocaching.cgCoord;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.geopoint.Geopoint;
@@ -12,6 +12,8 @@ import cgeo.geocaching.maps.interfaces.GeoPointImpl;
import cgeo.geocaching.maps.interfaces.MapProvider;
import cgeo.geocaching.maps.interfaces.OtherCachersOverlayItemImpl;
+import org.mapsforge.android.maps.MapDatabase;
+
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
@@ -80,15 +82,17 @@ public class MapsforgeMapProvider implements MapProvider {
}
@Override
- public CachesOverlayItemImpl getCachesOverlayItem(final cgCoord coordinate, final CacheType type) {
- MapsforgeCacheOverlayItem baseItem = new MapsforgeCacheOverlayItem(coordinate, type);
- return baseItem;
+ public CachesOverlayItemImpl getCachesOverlayItem(final IWaypoint coordinate, final CacheType type) {
+ return new MapsforgeCacheOverlayItem(coordinate, type);
}
@Override
public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context, Go4CacheUser userOne) {
- MapsforgeOtherCachersOverlayItem baseItem = new MapsforgeOtherCachersOverlayItem(context, userOne);
- return baseItem;
+ return new MapsforgeOtherCachersOverlayItem(context, userOne);
+ }
+
+ public static boolean isValidMapFile(String mapFileIn) {
+ return MapDatabase.isValidMapFile(mapFileIn);
}
}
diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
index d14ea8c..aaede4d 100644
--- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
+++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapView.java
@@ -1,6 +1,8 @@
package cgeo.geocaching.maps.mapsforge;
+import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.maps.CachesOverlay;
import cgeo.geocaching.maps.OtherCachersOverlay;
import cgeo.geocaching.maps.PositionOverlay;
@@ -13,9 +15,9 @@ import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnMapDragListener;
import cgeo.geocaching.maps.interfaces.OverlayImpl;
import cgeo.geocaching.maps.interfaces.OverlayImpl.overlayType;
+import cgeo.geocaching.utils.Log;
import org.mapsforge.android.maps.GeoPoint;
-import org.mapsforge.android.maps.MapDatabase;
import org.mapsforge.android.maps.MapView;
import org.mapsforge.android.maps.MapViewMode;
import org.mapsforge.android.maps.Overlay;
@@ -26,10 +28,10 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
+import android.widget.Toast;
public class MapsforgeMapView extends MapView implements MapViewImpl {
private GestureDetector gestureDetector;
@@ -49,7 +51,7 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
super.draw(canvas);
} catch (Exception e) {
- Log.e(Settings.tag, "MapsforgeMapView.draw: " + e.toString());
+ Log.e("MapsforgeMapView.draw: " + e.toString());
}
}
@@ -70,6 +72,11 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
}
@Override
+ public Viewport getViewport() {
+ return new Viewport(getMapViewCenter(), getLatitudeSpan() / 1e6, getLongitudeSpan() / 1e6);
+ }
+
+ @Override
public void addOverlay(OverlayImpl ovl) {
getOverlays().add((Overlay) ovl);
}
@@ -170,11 +177,14 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
setMapViewMode(MapViewMode.OPENCYCLEMAP_TILE_DOWNLOAD);
break;
case MapsforgeMapProvider.OFFLINE:
- if (MapDatabase.isValidMapFile(Settings.getMapFile())) {
- setMapViewMode(MapViewMode.CANVAS_RENDERER);
- super.setMapFile(Settings.getMapFile());
- } else {
- setMapViewMode(MapViewMode.MAPNIK_TILE_DOWNLOAD);
+ setMapViewMode(MapViewMode.CANVAS_RENDERER);
+ super.setMapFile(Settings.getMapFile());
+ if (!Settings.isValidMapFile(Settings.getMapFile())) {
+ Toast.makeText(
+ getContext(),
+ getContext().getResources().getString(R.string.warn_invalid_mapfile),
+ Toast.LENGTH_LONG)
+ .show();
}
break;
default:
@@ -196,7 +206,7 @@ public class MapsforgeMapView extends MapView implements MapViewImpl {
}
} catch (Exception e) {
- Log.e(Settings.tag, "MapsforgeMapView.repaintRequired: " + e.toString());
+ Log.e("MapsforgeMapView.repaintRequired: " + e.toString());
}
}
}
diff --git a/main/src/cgeo/geocaching/network/Cookies.java b/main/src/cgeo/geocaching/network/Cookies.java
new file mode 100644
index 0000000..68310e6
--- /dev/null
+++ b/main/src/cgeo/geocaching/network/Cookies.java
@@ -0,0 +1,47 @@
+package cgeo.geocaching.network;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.client.CookieStore;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.cookie.BasicClientCookie;
+
+public abstract class Cookies {
+
+ private static boolean cookieStoreRestored = false;
+ final static CookieStore cookieStore = new BasicCookieStore();
+
+ public static void restoreCookieStore(final String oldCookies) {
+ if (!cookieStoreRestored) {
+ clearCookies();
+ if (oldCookies != null) {
+ for (final String cookie : StringUtils.split(oldCookies, ';')) {
+ final String[] split = StringUtils.split(cookie, "=", 3);
+ if (split.length == 3) {
+ final BasicClientCookie newCookie = new BasicClientCookie(split[0], split[1]);
+ newCookie.setDomain(split[2]);
+ cookieStore.addCookie(newCookie);
+ }
+ }
+ }
+ cookieStoreRestored = true;
+ }
+ }
+
+ public static String dumpCookieStore() {
+ StringBuilder cookies = new StringBuilder();
+ for (final Cookie cookie : cookieStore.getCookies()) {
+ cookies.append(cookie.getName());
+ cookies.append('=');
+ cookies.append(cookie.getValue());
+ cookies.append('=');
+ cookies.append(cookie.getDomain());
+ cookies.append(';');
+ }
+ return cookies.toString();
+ }
+
+ public static void clearCookies() {
+ cookieStore.clear();
+ }
+}
diff --git a/main/src/cgeo/geocaching/network/HtmlImage.java b/main/src/cgeo/geocaching/network/HtmlImage.java
index 1811110..7e4143e 100644
--- a/main/src/cgeo/geocaching/network/HtmlImage.java
+++ b/main/src/cgeo/geocaching/network/HtmlImage.java
@@ -1,10 +1,10 @@
package cgeo.geocaching.network;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.StoredList;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.files.LocalStorage;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
@@ -16,7 +16,6 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.text.Html;
-import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
@@ -72,26 +71,26 @@ public class HtmlImage implements Html.ImageGetter {
return new BitmapDrawable(getTransparent1x1Image());
}
- Bitmap imagePre = null;
-
- // Load image from cache
- if (!onlySave) {
- imagePre = loadImageFromStorage(url);
- }
+ Bitmap imagePre = loadImageFromStorage(url);
// Download image and save it to the cache
- if (imagePre == null || onlySave) {
+ if (imagePre == null) {
final String absoluteURL = makeAbsoluteURL(url);
if (absoluteURL != null) {
try {
- final HttpResponse httpResponse = Network.request(absoluteURL, null, false);
+ final File file = LocalStorage.getStorageFile(geocode, url, true, true);
+ final HttpResponse httpResponse = Network.getRequest(absoluteURL, null, file);
if (httpResponse != null) {
- final File file = LocalStorage.getStorageFile(geocode, url, true, true);
- LocalStorage.saveEntityToFile(httpResponse, file);
+ final int statusCode = httpResponse.getStatusLine().getStatusCode();
+ if (statusCode == 200) {
+ LocalStorage.saveEntityToFile(httpResponse, file);
+ } else if (statusCode == 304) {
+ file.setLastModified(System.currentTimeMillis());
+ }
}
} catch (Exception e) {
- Log.e(Settings.tag, "HtmlImage.getDrawable (downloading from web)", e);
+ Log.e("HtmlImage.getDrawable (downloading from web)", e);
}
}
}
@@ -107,7 +106,7 @@ public class HtmlImage implements Html.ImageGetter {
// get image and return
if (imagePre == null) {
- Log.d(Settings.tag, "HtmlImage.getDrawable: Failed to obtain image");
+ Log.d("HtmlImage.getDrawable: Failed to obtain image");
if (returnErrorImage) {
imagePre = BitmapFactory.decodeResource(context.getResources(), R.drawable.image_not_loaded);
@@ -130,7 +129,7 @@ public class HtmlImage implements Html.ImageGetter {
try {
imagePre = Bitmap.createScaledBitmap(imagePre, width, height, true);
} catch (Exception e) {
- Log.d(Settings.tag, "HtmlImage.getDrawable: Failed to scale image");
+ Log.d("HtmlImage.getDrawable: Failed to scale image");
return null;
}
} else {
@@ -158,32 +157,31 @@ public class HtmlImage implements Html.ImageGetter {
final File fileSec = LocalStorage.getStorageSecFile(geocode, url, true);
return loadCachedImage(fileSec);
} catch (Exception e) {
- Log.w(Settings.tag, "HtmlImage.getDrawable (reading cache): " + e.toString());
+ Log.w("HtmlImage.getDrawable (reading cache): " + e.toString());
}
return null;
}
- private final String makeAbsoluteURL(final String url) {
- try {
- // Check if uri is absolute or not, if not attach the connector hostname
- // FIXME: that should also include the scheme
- if (Uri.parse(url).isAbsolute()) {
- return url;
- } else {
- final String host = ConnectorFactory.getConnector(geocode).getHost();
- if (StringUtils.isNotEmpty(host)) {
- StringBuilder builder = new StringBuilder("http://");
- builder.append(host);
- if (!StringUtils.startsWith(url, "/")) {
- builder.append('/');
- }
- builder.append(url);
- return builder.toString();
- }
+ private String makeAbsoluteURL(final String url) {
+ // Check if uri is absolute or not, if not attach the connector hostname
+ // FIXME: that should also include the scheme
+ if (Uri.parse(url).isAbsolute()) {
+ return url;
+ }
+
+ final String host = ConnectorFactory.getConnector(geocode).getHost();
+ if (StringUtils.isNotEmpty(host)) {
+ final StringBuilder builder = new StringBuilder("http://");
+ builder.append(host);
+ if (!StringUtils.startsWith(url, "/")) {
+ // FIXME: explain why the result URL would be valid if the path does not start with
+ // a '/', or signal an error.
+ builder.append('/');
}
- } catch (Exception e) {
- Log.e(Settings.tag, "HtmlImage.makeAbsoluteURL (parse URL)", e);
+ builder.append(url);
+ return builder.toString();
}
+
return null;
}
@@ -207,7 +205,7 @@ public class HtmlImage implements Html.ImageGetter {
fis = new FileInputStream(file);
BitmapFactory.decodeStream(fis, null, options);
} catch (FileNotFoundException e) {
- Log.e(Settings.tag, "HtmlImage.setSampleSize", e);
+ Log.e("HtmlImage.setSampleSize", e);
} finally {
if (fis != null) {
try {
diff --git a/main/src/cgeo/geocaching/network/Network.java b/main/src/cgeo/geocaching/network/Network.java
index 0afe095..39c0cf5 100644
--- a/main/src/cgeo/geocaching/network/Network.java
+++ b/main/src/cgeo/geocaching/network/Network.java
@@ -1,11 +1,9 @@
package cgeo.geocaching.network;
-import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
-import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.files.LocalStorage;
import cgeo.geocaching.utils.BaseUtils;
+import cgeo.geocaching.utils.Log;
-import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
@@ -16,17 +14,13 @@ import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.NameValuePair;
-import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.cookie.Cookie;
import org.apache.http.entity.HttpEntityWrapper;
-import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
@@ -38,15 +32,14 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.net.Uri;
-import android.util.Log;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
-import java.util.List;
import java.util.zip.GZIPInputStream;
-
public abstract class Network {
static class GzipDecompressingEntity extends HttpEntityWrapper {
@@ -57,13 +50,12 @@ public abstract class Network {
@Override
public InputStream getContent() throws IOException, IllegalStateException {
// the wrapped entity's getContent() decides about repeatability
- InputStream wrappedin = wrappedEntity.getContent();
- return new GZIPInputStream(wrappedin);
+ return new GZIPInputStream(wrappedEntity.getContent());
}
@Override
public long getContentLength() {
- // length of ungzipped content is not known
+ // length of gunzipped content is not known
return -1;
}
}
@@ -74,8 +66,6 @@ public abstract class Network {
private static final String PATTERN_PASSWORD = "(?<=[\\?&])[Pp]ass(w(or)?d)?=[^&#$]+";
private final static HttpParams clientParams = new BasicHttpParams();
- private static boolean cookieStoreRestored = false;
- private final static CookieStore cookieStore = new BasicCookieStore();
static {
Network.clientParams.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, HTTP.UTF_8);
@@ -89,7 +79,7 @@ public abstract class Network {
private static HttpClient getHttpClient() {
final DefaultHttpClient client = new DefaultHttpClient();
- client.setCookieStore(cookieStore);
+ client.setCookieStore(Cookies.cookieStore);
client.setParams(clientParams);
client.addRequestInterceptor(new HttpRequestInterceptor() {
@@ -108,16 +98,14 @@ public abstract class Network {
public void process(
final HttpResponse response,
final HttpContext context) throws HttpException, IOException {
- HttpEntity entity = response.getEntity();
- if (null != entity) {
- Header ceheader = entity.getContentEncoding();
- if (ceheader != null) {
- HeaderElement[] codecs = ceheader.getElements();
- for (int i = 0; i < codecs.length; i++) {
- if (codecs[i].getName().equalsIgnoreCase("gzip")) {
- Log.d(Settings.tag, "Decompressing response");
- response.setEntity(
- new Network.GzipDecompressingEntity(response.getEntity()));
+ final HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ final Header contentEncoding = entity.getContentEncoding();
+ if (contentEncoding != null) {
+ for (final HeaderElement codec : contentEncoding.getElements()) {
+ if (codec.getName().equalsIgnoreCase("gzip")) {
+ Log.d("Decompressing response");
+ response.setEntity(new GzipDecompressingEntity(response.getEntity()));
return;
}
}
@@ -130,127 +118,80 @@ public abstract class Network {
return client;
}
- public static void restoreCookieStore(final String oldCookies) {
- if (!cookieStoreRestored) {
- Network.clearCookies();
- if (oldCookies != null) {
- for (final String cookie : StringUtils.split(oldCookies, ';')) {
- final String[] split = StringUtils.split(cookie, "=", 3);
- if (split.length == 3) {
- final BasicClientCookie newCookie = new BasicClientCookie(split[0], split[1]);
- newCookie.setDomain(split[2]);
- cookieStore.addCookie(newCookie);
- }
- }
- }
- cookieStoreRestored = true;
- }
- }
-
- public static String dumpCookieStore() {
- StringBuilder cookies = new StringBuilder();
- for (final Cookie cookie : cookieStore.getCookies()) {
- cookies.append(cookie.getName());
- cookies.append('=');
- cookies.append(cookie.getValue());
- cookies.append('=');
- cookies.append(cookie.getDomain());
- cookies.append(';');
- }
- return cookies.toString();
- }
-
- public static void clearCookies() {
- cookieStore.clear();
- }
-
/**
* POST HTTP request
*
- * @param uri
- * @param params
- * @return
- */
- public static HttpResponse postRequest(final String uri, final List<? extends NameValuePair> params) {
- try {
- HttpPost request = new HttpPost(uri);
- if (params != null) {
- request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
- }
- request.setHeader("X-Requested-With", "XMLHttpRequest");
- return Network.request(request);
- } catch (Exception e) {
- // Can be UnsupportedEncodingException, ClientProtocolException or IOException
- Log.e(Settings.tag, "postRequest", e);
- return null;
- }
- }
-
- /**
- * GET HTTP request
- *
- * @param uri
- * @param params
- * @param xContentType
- * @param my
- * @param addF
- * @return
+ * @param uri the URI to request
+ * @param params the parameters to add to the POST request
+ * @return the HTTP response, or null in case of an encoding error params
*/
- public static HttpResponse request(final String uri, final Parameters params, boolean xContentType, boolean my, boolean addF) {
- return Network.request(uri, cgBase.addFToParams(params, my, addF), xContentType);
+ public static HttpResponse postRequest(final String uri, final Parameters params) {
+ return request("POST", uri, params, null, null);
}
/**
- * GET HTTP request
+ * Make an HTTP request
*
+ * @param method
+ * the HTTP method to use ("GET" or "POST")
* @param uri
+ * the URI to request
* @param params
- * @param xContentType
- * @return
+ * the parameters to add the the GET request
+ * @param headers
+ * the headers to add to the GET request
+ * @param cacheFile
+ * the cache file used to cache this query
+ * @return the HTTP response, or null in case of an encoding error in a POST request arguments
*/
- public static HttpResponse request(final String uri, final Parameters params, final boolean xContentType) {
- final String fullUri = params == null ? uri : Uri.parse(uri).buildUpon().encodedQuery(params.toString()).build().toString();
- final HttpRequestBase request = new HttpGet(fullUri);
-
- request.setHeader("X-Requested-With", "XMLHttpRequest");
-
- if (xContentType) {
- request.setHeader("Content-Type", "application/x-www-form-urlencoded");
+ private static HttpResponse request(final String method, final String uri, final Parameters params, final Parameters headers, final File cacheFile) {
+ HttpRequestBase request;
+ if (method.equals("GET")) {
+ final String fullUri = params == null ? uri : Uri.parse(uri).buildUpon().encodedQuery(params.toString()).build().toString();
+ request = new HttpGet(fullUri);
+ } else {
+ request = new HttpPost(uri);
+ if (params != null) {
+ try {
+ ((HttpPost) request).setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
+ } catch (final UnsupportedEncodingException e) {
+ Log.e("request", e);
+ return null;
+ }
+ }
}
- return Network.request(request);
- }
+ for (final NameValuePair header : Parameters.extend(Parameters.merge(headers, cacheHeaders(cacheFile)),
+ "Accept-Charset", "utf-8,iso-8859-1;q=0.8,utf-16;q=0.8,*;q=0.7",
+ "Accept-Language", "en-US,*;q=0.9",
+ "X-Requested-With", "XMLHttpRequest")) {
+ request.setHeader(header.getName(), header.getValue());
+ }
- public static HttpResponse request(final HttpRequestBase request) {
- request.setHeader("Accept-Charset", "utf-8,iso-8859-1;q=0.8,utf-16;q=0.8,*;q=0.7");
- request.setHeader("Accept-Language", "en-US,*;q=0.9");
- request.getParams().setParameter(CoreProtocolPNames.USER_AGENT, USER_AGENT);
- return Network.doRequest(request);
- }
+ request.getParams().setParameter(CoreProtocolPNames.USER_AGENT, Network.USER_AGENT);
- private static HttpResponse doRequest(final HttpRequestBase request) {
- final String reqLogStr = request.getMethod() + " " + hidePassword(request.getURI().toString());
- Log.d(Settings.tag, reqLogStr);
+ final String reqLogStr = request.getMethod() + " " + Network.hidePassword(request.getURI().toString());
+ Log.d(reqLogStr);
- final HttpClient client = getHttpClient();
- for (int i = 0; i <= NB_DOWNLOAD_RETRIES; i++) {
+ final HttpClient client = Network.getHttpClient();
+ for (int i = 0; i <= Network.NB_DOWNLOAD_RETRIES; i++) {
final long before = System.currentTimeMillis();
try {
final HttpResponse response = client.execute(request);
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
- Log.d(Settings.tag, status + Network.formatTimeSpan(before) + reqLogStr);
+ Log.d(status + Network.formatTimeSpan(before) + reqLogStr);
} else {
- Log.w(Settings.tag, status + " [" + response.getStatusLine().getReasonPhrase() + "]" + Network.formatTimeSpan(before) + reqLogStr);
+ Log.w(status + " [" + response.getStatusLine().getReasonPhrase() + "]" + Network.formatTimeSpan(before) + reqLogStr);
}
return response;
} catch (IOException e) {
final String timeSpan = Network.formatTimeSpan(before);
- final String tries = (i + 1) + "/" + (NB_DOWNLOAD_RETRIES + 1);
- if (i == NB_DOWNLOAD_RETRIES) {
- Log.e(Settings.tag, "Failure " + tries + timeSpan + reqLogStr, e);
+ final String tries = (i + 1) + "/" + (Network.NB_DOWNLOAD_RETRIES + 1);
+ if (i == Network.NB_DOWNLOAD_RETRIES) {
+ Log.e("Failure " + tries + timeSpan + reqLogStr, e);
} else {
- Log.e(Settings.tag, "Failure " + tries + " (" + e.toString() + ")" + timeSpan + "- retrying " + reqLogStr);
+ Log.e("Failure " + tries + " (" + e.toString() + ")" + timeSpan + "- retrying " + reqLogStr);
}
}
}
@@ -258,6 +199,79 @@ public abstract class Network {
return null;
}
+ private static Parameters cacheHeaders(final File cacheFile) {
+ if (cacheFile == null || !cacheFile.exists()) {
+ return null;
+ }
+
+ final String etag = LocalStorage.getSavedHeader(cacheFile, "etag");
+ if (etag != null) {
+ return new Parameters("If-None-Match", etag);
+ }
+
+ final String lastModified = LocalStorage.getSavedHeader(cacheFile, "last-modified");
+ if (lastModified != null) {
+ return new Parameters("If-Modified-Since", lastModified);
+ }
+
+ return null;
+ }
+
+ /**
+ * GET HTTP request
+ *
+ * @param uri
+ * the URI to request
+ * @param params
+ * the parameters to add the the GET request
+ * @param cacheFile
+ * the name of the file storing the cached resource, or null not to use one
+ * @return the HTTP response
+ */
+ public static HttpResponse getRequest(final String uri, final Parameters params, final File cacheFile) {
+ return request("GET", uri, params, null, cacheFile);
+ }
+
+
+ /**
+ * GET HTTP request
+ *
+ * @param uri
+ * the URI to request
+ * @param params
+ * the parameters to add the the GET request
+ * @return the HTTP response
+ */
+ public static HttpResponse getRequest(final String uri, final Parameters params) {
+ return request("GET", uri, params, null, null);
+ }
+
+ /**
+ * GET HTTP request
+ *
+ * @param uri
+ * the URI to request
+ * @param params
+ * the parameters to add the the GET request
+ * @param headers
+ * the headers to add to the GET request
+ * @return the HTTP response
+ */
+ public static HttpResponse getRequest(final String uri, final Parameters params, final Parameters headers) {
+ return request("GET", uri, params, headers, null);
+ }
+
+ /**
+ * GET HTTP request
+ *
+ * @param uri
+ * the URI to request
+ * @return the HTTP response
+ */
+ public static HttpResponse getRequest(final String uri) {
+ return request("GET", uri, null, null, null);
+ }
+
private static String formatTimeSpan(final long before) {
// don't use String.format in a pure logging routine, it has very bad performance
return " (" + (System.currentTimeMillis() - before) + " ms) ";
@@ -268,33 +282,24 @@ public abstract class Network {
}
public static JSONObject requestJSON(final String uri, final Parameters params) {
- final HttpGet request = new HttpGet(Network.prepareParameters(uri, params));
- request.setHeader("Accept", "application/json, text/javascript, */*; q=0.01");
- request.setHeader("Content-Type", "application/json; charset=UTF-8");
- request.setHeader("X-Requested-With", "XMLHttpRequest");
-
- final HttpResponse response = doRequest(request);
- if (response != null && response.getStatusLine().getStatusCode() == 200) {
+ final HttpResponse response = request("GET", uri, params, new Parameters("Accept", "application/json, text/javascript, */*; q=0.01"), null);
+ if (isSuccess(response)) {
try {
return new JSONObject(Network.getResponseData(response));
- } catch (JSONException e) {
- Log.e(Settings.tag, "Network.requestJSON", e);
+ } catch (final JSONException e) {
+ Log.e("Network.requestJSON", e);
}
}
return null;
}
- private static String prepareParameters(final String baseUri, final Parameters params) {
- return CollectionUtils.isNotEmpty(params) ? baseUri + "?" + params.toString() : baseUri;
- }
-
private static String getResponseDataNoError(final HttpResponse response, boolean replaceWhitespace) {
try {
String data = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
return replaceWhitespace ? BaseUtils.replaceWhitespace(data) : data;
} catch (Exception e) {
- Log.e(Settings.tag, "getResponseData", e);
+ Log.e("getResponseData", e);
return null;
}
}
@@ -303,62 +308,15 @@ public abstract class Network {
return Network.getResponseData(response, true);
}
- static public String getResponseData(final HttpResponse response, boolean replaceWhitespace) {
+ public static String getResponseData(final HttpResponse response, boolean replaceWhitespace) {
if (!isSuccess(response)) {
return null;
}
return getResponseDataNoError(response, replaceWhitespace);
}
- /**
- * POST HTTP request. Do the request a second time if the user is not logged in
- *
- * @param uri
- * @return
- */
- public static String postRequestLogged(final String uri) {
- HttpResponse response = postRequest(uri, null);
- String data = getResponseData(response);
-
- if (!Login.getLoginStatus(data)) {
- if (Login.login() == StatusCode.NO_ERROR) {
- response = postRequest(uri, null);
- data = getResponseData(response);
- } else {
- Log.i(Settings.tag, "Working as guest.");
- }
- }
- return data;
- }
-
- /**
- * GET HTTP request. Do the request a second time if the user is not logged in
- *
- * @param uri
- * @param params
- * @param xContentType
- * @param my
- * @param addF
- * @return
- */
- public static String requestLogged(final String uri, final Parameters params, boolean xContentType, boolean my, boolean addF) {
- HttpResponse response = request(uri, params, xContentType, my, addF);
- String data = getResponseData(response);
-
- if (!Login.getLoginStatus(data)) {
- if (Login.login() == StatusCode.NO_ERROR) {
- response = request(uri, params, xContentType, my, addF);
- data = getResponseData(response);
- } else {
- Log.i(Settings.tag, "Working as guest.");
- }
- }
- return data;
+ public static String rfc3986URLEncode(String text) {
+ return StringUtils.replace(URLEncoder.encode(text).replace("+", "%20"), "%7E", "~");
}
- public static String urlencode_rfc3986(String text) {
- final String encoded = StringUtils.replace(URLEncoder.encode(text).replace("+", "%20"), "%7E", "~");
-
- return encoded;
- }
}
diff --git a/main/src/cgeo/geocaching/network/OAuth.java b/main/src/cgeo/geocaching/network/OAuth.java
index cefa90d..8cecb22 100644
--- a/main/src/cgeo/geocaching/network/OAuth.java
+++ b/main/src/cgeo/geocaching/network/OAuth.java
@@ -23,11 +23,11 @@ public class OAuth {
final List<String> paramsEncoded = new ArrayList<String>();
for (final NameValuePair nameValue : params) {
- paramsEncoded.add(nameValue.getName() + "=" + Network.urlencode_rfc3986(nameValue.getValue()));
+ paramsEncoded.add(nameValue.getName() + "=" + Network.rfc3986URLEncode(nameValue.getValue()));
}
final String keysPacked = Settings.getKeyConsumerSecret() + "&" + StringUtils.defaultString(tokenSecret); // both even if empty some of them!
- final String requestPacked = method + "&" + Network.urlencode_rfc3986((https ? "https" : "http") + "://" + host + path) + "&" + Network.urlencode_rfc3986(StringUtils.join(paramsEncoded.toArray(), '&'));
+ final String requestPacked = method + "&" + Network.rfc3986URLEncode((https ? "https" : "http") + "://" + host + path) + "&" + Network.rfc3986URLEncode(StringUtils.join(paramsEncoded.toArray(), '&'));
params.put("oauth_signature", CryptUtils.base64Encode(CryptUtils.hashHmac(requestPacked, keysPacked)));
}
}
diff --git a/main/src/cgeo/geocaching/network/Parameters.java b/main/src/cgeo/geocaching/network/Parameters.java
index e65bec2..90965e4 100644
--- a/main/src/cgeo/geocaching/network/Parameters.java
+++ b/main/src/cgeo/geocaching/network/Parameters.java
@@ -12,7 +12,7 @@ import java.util.Comparator;
/**
* List of key/values pairs to be used in a GET or POST request.
- *
+ *
*/
public class Parameters extends ArrayList<NameValuePair> {
@@ -44,14 +44,16 @@ public class Parameters extends ArrayList<NameValuePair> {
* list of key/value pairs
* @throws InvalidParameterException
* if the number of key/values is unbalanced
+ * @return the object itself to facilitate chaining
*/
- public void put(final String... keyValues) {
+ public Parameters put(final String... keyValues) {
if (keyValues.length % 2 == 1) {
throw new InvalidParameterException("odd number of parameters");
}
for (int i = 0; i < keyValues.length; i += 2) {
add(new BasicNameValuePair(keyValues[i], keyValues[i + 1]));
}
+ return this;
}
/**
@@ -63,12 +65,43 @@ public class Parameters extends ArrayList<NameValuePair> {
Collections.sort(this, comparator);
}
- /**
- * @return the URL encoded string corresponding to those parameters
- */
@Override
public String toString() {
return URLEncodedUtils.format(this, HTTP.UTF_8);
}
+ /**
+ * Extend or create a Parameters object with new key/value pairs.
+ *
+ * @param params
+ * an existing object or null to create a new one
+ * @param keyValues
+ * list of key/value pair
+ * @throws InvalidParameterException
+ * if the number of key/values is unbalanced
+ * @return the object itself if it is non-null, a new one otherwise
+ */
+ public static Parameters extend(final Parameters params, final String... keyValues) {
+ return params == null ? new Parameters(keyValues) : params.put(keyValues);
+ }
+
+ /**
+ * Merge two (possibly null) Parameters object.
+ *
+ * @param params
+ * the object to merge into if non-null
+ * @param extra
+ * the object to merge from if non-null
+ * @return params with extra data if params was non-null, extra otherwise
+ */
+ public static Parameters merge(final Parameters params, final Parameters extra) {
+ if (params == null) {
+ return extra;
+ }
+ if (extra != null) {
+ params.addAll(extra);
+ }
+ return params;
+ }
+
}
diff --git a/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java b/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java
index bc93d3b..2015375 100644
--- a/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java
+++ b/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java
@@ -1,9 +1,8 @@
package cgeo.geocaching.sorting;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.utils.Log;
-import android.util.Log;
/**
* abstract super implementation for all cache comparators
@@ -12,7 +11,7 @@ import android.util.Log;
public abstract class AbstractCacheComparator implements CacheComparator {
@Override
- public final int compare(cgCache cache1, cgCache cache2) {
+ public final int compare(final cgCache cache1, final cgCache cache2) {
try {
// first check that we have all necessary data for the comparison
if (!canCompare(cache1, cache2)) {
@@ -20,13 +19,13 @@ public abstract class AbstractCacheComparator implements CacheComparator {
}
return compareCaches(cache1, cache2);
} catch (Exception e) {
- Log.e(Settings.tag, "AbstractCacheComparator.compare: " + e.toString());
+ Log.e("AbstractCacheComparator.compare: " + e.toString());
}
return 0;
}
/**
- * check necessary preconditions (like missing fields) before running the comparison itself
+ * Check necessary preconditions (like missing fields) before running the comparison itself
*
* @param cache1
* @param cache2
@@ -35,7 +34,10 @@ public abstract class AbstractCacheComparator implements CacheComparator {
protected abstract boolean canCompare(final cgCache cache1, final cgCache cache2);
/**
- * compares two caches. Logging and exception handling is implemented outside this method already.
+ * Compares two caches. Logging and exception handling is implemented outside this method already.
+ * <p/>
+ * A cache is smaller than another cache if it is desirable to show it first when presented to the user.
+ * For example, a highly rated cache must be considered smaller than a poorly rated one.
*
* @param cache1
* @param cache2
diff --git a/main/src/cgeo/geocaching/sorting/DifficultyComparator.java b/main/src/cgeo/geocaching/sorting/DifficultyComparator.java
index 0d65660..123bab9 100644
--- a/main/src/cgeo/geocaching/sorting/DifficultyComparator.java
+++ b/main/src/cgeo/geocaching/sorting/DifficultyComparator.java
@@ -15,11 +15,6 @@ public class DifficultyComparator extends AbstractCacheComparator {
@Override
protected int compareCaches(final cgCache cache1, final cgCache cache2) {
- if (cache1.getDifficulty() > cache2.getDifficulty()) {
- return 1;
- } else if (cache2.getDifficulty() > cache1.getDifficulty()) {
- return -1;
- }
- return 0;
+ return Float.compare(cache1.getDifficulty(), cache2.getDifficulty());
}
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/sorting/EventDateComparator.java b/main/src/cgeo/geocaching/sorting/EventDateComparator.java
index 0092901..ac49e66 100644
--- a/main/src/cgeo/geocaching/sorting/EventDateComparator.java
+++ b/main/src/cgeo/geocaching/sorting/EventDateComparator.java
@@ -1,8 +1,5 @@
package cgeo.geocaching.sorting;
-import cgeo.geocaching.cgCache;
-
-
/**
* Compares caches by date. Used only for event caches.
*
@@ -11,13 +8,4 @@ import cgeo.geocaching.cgCache;
*/
public class EventDateComparator extends DateComparator {
- @Override
- protected boolean canCompare(cgCache cache1, cgCache cache2) {
- return super.canCompare(cache1, cache2);
- }
-
- @Override
- protected int compareCaches(cgCache cache1, cgCache cache2) {
- return super.compareCaches(cache1, cache2);
- }
}
diff --git a/main/src/cgeo/geocaching/sorting/FindsComparator.java b/main/src/cgeo/geocaching/sorting/FindsComparator.java
index 7a1555e..98fe1dd 100644
--- a/main/src/cgeo/geocaching/sorting/FindsComparator.java
+++ b/main/src/cgeo/geocaching/sorting/FindsComparator.java
@@ -31,7 +31,7 @@ public class FindsComparator extends AbstractCacheComparator {
}
Integer logged = cache.getLogCounts().get(LogType.LOG_FOUND_IT);
if (logged != null) {
- finds = logged.intValue();
+ finds = logged;
}
return finds;
}
diff --git a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
index 1377cce..fb93c0e 100644
--- a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
+++ b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java
@@ -17,12 +17,8 @@ public class GeocodeComparator extends AbstractCacheComparator {
}
@Override
- protected int compareCaches(cgCache cache1, cgCache cache2) {
- if (cache1.getGeocode().length() > cache2.getGeocode().length()) {
- return 1;
- } else if (cache2.getGeocode().length() > cache1.getGeocode().length()) {
- return -1;
- }
- return cache1.getGeocode().compareToIgnoreCase(cache2.getGeocode());
+ protected int compareCaches(final cgCache cache1, final cgCache cache2) {
+ final int lengthDiff = cache1.getGeocode().length() - cache2.getGeocode().length();
+ return lengthDiff != 0 ? lengthDiff : cache1.getGeocode().compareToIgnoreCase(cache2.getGeocode());
}
}
diff --git a/main/src/cgeo/geocaching/sorting/InventoryComparator.java b/main/src/cgeo/geocaching/sorting/InventoryComparator.java
index b1842d7..d4e9f5e 100644
--- a/main/src/cgeo/geocaching/sorting/InventoryComparator.java
+++ b/main/src/cgeo/geocaching/sorting/InventoryComparator.java
@@ -11,19 +11,12 @@ import cgeo.geocaching.cgCache;
public class InventoryComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(cgCache cache1, cgCache cache2) {
+ protected boolean canCompare(final cgCache cache1, final cgCache cache2) {
return true;
}
@Override
- protected int compareCaches(cgCache cache1, cgCache cache2) {
- int itemCount1 = cache1.getInventoryItems();
- int itemCount2 = cache2.getInventoryItems();
- if (itemCount1 < itemCount2) {
- return 1;
- } else if (itemCount2 < itemCount1) {
- return -1;
- }
- return 0;
+ protected int compareCaches(final cgCache cache1, final cgCache cache2) {
+ return cache2.getInventoryItems() - cache1.getInventoryItems();
}
}
diff --git a/main/src/cgeo/geocaching/sorting/PopularityComparator.java b/main/src/cgeo/geocaching/sorting/PopularityComparator.java
index 9fe254a..62ad9a9 100644
--- a/main/src/cgeo/geocaching/sorting/PopularityComparator.java
+++ b/main/src/cgeo/geocaching/sorting/PopularityComparator.java
@@ -9,17 +9,12 @@ import cgeo.geocaching.cgCache;
public class PopularityComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(cgCache cache1, cgCache cache2) {
+ protected boolean canCompare(final cgCache cache1, final cgCache cache2) {
return true;
}
@Override
- protected int compareCaches(cgCache cache1, cgCache cache2) {
- if (cache1.getFavoritePoints() < cache2.getFavoritePoints()) {
- return 1;
- } else if (cache2.getFavoritePoints() < cache1.getFavoritePoints()) {
- return -1;
- }
- return 0;
+ protected int compareCaches(final cgCache cache1, final cgCache cache2) {
+ return cache2.getFavoritePoints() - cache1.getFavoritePoints();
}
}
diff --git a/main/src/cgeo/geocaching/sorting/RatingComparator.java b/main/src/cgeo/geocaching/sorting/RatingComparator.java
index 935ccd8..be071c5 100644
--- a/main/src/cgeo/geocaching/sorting/RatingComparator.java
+++ b/main/src/cgeo/geocaching/sorting/RatingComparator.java
@@ -9,28 +9,15 @@ import cgeo.geocaching.cgCache;
public class RatingComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(cgCache cache1, cgCache cache2) {
+ protected boolean canCompare(final cgCache cache1, final cgCache cache2) {
return true;
}
@Override
- protected int compareCaches(cgCache cache1, cgCache cache2) {
- float rating1 = cache1.getRating();
- float rating2 = cache2.getRating();
-
- // voting can be disabled for caches, then assume an average rating instead
- if (rating1 == 0.0) {
- rating1 = 2.5f;
- }
- if (rating2 == 0.0) {
- rating2 = 2.5f;
- }
-
- if (rating1 < rating2) {
- return 1;
- } else if (rating2 < rating1) {
- return -1;
- }
- return 0;
+ protected int compareCaches(final cgCache cache1, final cgCache cache2) {
+ final float rating1 = cache1.getRating();
+ final float rating2 = cache2.getRating();
+ // Voting can be disabled for caches, then assume an average rating instead
+ return Float.compare(rating2 != 0.0 ? rating2 : 2.5f, rating1 != 0.0 ? rating1 : 2.5f);
}
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/sorting/TerrainComparator.java b/main/src/cgeo/geocaching/sorting/TerrainComparator.java
index c0590cb..9058a3c 100644
--- a/main/src/cgeo/geocaching/sorting/TerrainComparator.java
+++ b/main/src/cgeo/geocaching/sorting/TerrainComparator.java
@@ -9,17 +9,12 @@ import cgeo.geocaching.cgCache;
public class TerrainComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(cgCache cache1, cgCache cache2) {
+ protected boolean canCompare(final cgCache cache1, final cgCache cache2) {
return cache1.getTerrain() != 0.0 && cache2.getTerrain() != 0.0;
}
@Override
- protected int compareCaches(cgCache cache1, cgCache cache2) {
- if (cache1.getTerrain() > cache2.getTerrain()) {
- return 1;
- } else if (cache2.getTerrain() > cache1.getTerrain()) {
- return -1;
- }
- return 0;
+ protected int compareCaches(final cgCache cache1, final cgCache cache2) {
+ return Float.compare(cache1.getTerrain(), cache2.getTerrain());
}
}
diff --git a/main/src/cgeo/geocaching/sorting/VisitComparator.java b/main/src/cgeo/geocaching/sorting/VisitComparator.java
index a580f2a..548ec7a 100644
--- a/main/src/cgeo/geocaching/sorting/VisitComparator.java
+++ b/main/src/cgeo/geocaching/sorting/VisitComparator.java
@@ -9,17 +9,12 @@ import cgeo.geocaching.cgCache;
public class VisitComparator extends AbstractCacheComparator {
@Override
- protected boolean canCompare(cgCache cache1, cgCache cache2) {
+ protected boolean canCompare(final cgCache cache1, final cgCache cache2) {
return cache1.getVisitedDate() > 0 && cache2.getVisitedDate() > 0;
}
@Override
- protected int compareCaches(cgCache cache1, cgCache cache2) {
- if (cache1.getVisitedDate() > cache2.getVisitedDate()) {
- return -1;
- } else if (cache1.getVisitedDate() < cache2.getVisitedDate()) {
- return 1;
- }
- return 0;
+ protected int compareCaches(final cgCache cache1, final cgCache cache2) {
+ return Long.valueOf(cache2.getVisitedDate()).compareTo(cache1.getVisitedDate());
}
}
diff --git a/main/src/cgeo/geocaching/sorting/VoteComparator.java b/main/src/cgeo/geocaching/sorting/VoteComparator.java
index 82ebdd3..8d9f907 100644
--- a/main/src/cgeo/geocaching/sorting/VoteComparator.java
+++ b/main/src/cgeo/geocaching/sorting/VoteComparator.java
@@ -18,15 +18,6 @@ public class VoteComparator extends AbstractCacheComparator {
@Override
protected int compareCaches(cgCache cache1, cgCache cache2) {
// if there is no vote available, put that cache at the end of the list
- float vote1 = cache1.getMyVote();
- float vote2 = cache2.getMyVote();
-
- // compare
- if (vote1 < vote2) {
- return 1;
- } else if (vote2 < vote1) {
- return -1;
- }
- return 0;
+ return Float.compare(cache2.getMyVote(), cache1.getMyVote());
}
}
diff --git a/main/src/cgeo/geocaching/twitter/Twitter.java b/main/src/cgeo/geocaching/twitter/Twitter.java
index fa1a39d..4a10046 100644
--- a/main/src/cgeo/geocaching/twitter/Twitter.java
+++ b/main/src/cgeo/geocaching/twitter/Twitter.java
@@ -10,10 +10,10 @@ import cgeo.geocaching.geopoint.GeopointFormatter.Format;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.OAuth;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
import org.apache.http.HttpResponse;
-import android.util.Log;
public final class Twitter {
public static final int MAX_TWEET_SIZE = 140;
@@ -38,12 +38,12 @@ public final class Twitter {
OAuth.signOAuth("api.twitter.com", "/1/statuses/update.json", "POST", false, parameters, Settings.getTokenPublic(), Settings.getTokenSecret());
final HttpResponse httpResponse = Network.postRequest("http://api.twitter.com/1/statuses/update.json", parameters);
if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) {
- Log.i(Settings.tag, "Tweet posted");
+ Log.i("Tweet posted");
} else {
- Log.e(Settings.tag, "Tweet could not be posted");
+ Log.e("Tweet could not be posted");
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.postTweet: " + e.toString());
+ Log.e("cgBase.postTweet: " + e.toString());
}
}
diff --git a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java
index fffe12e..86db2d2 100644
--- a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java
+++ b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java
@@ -6,6 +6,7 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.OAuth;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -18,7 +19,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
@@ -141,7 +141,7 @@ public class TwitterAuthorizationActivity extends AbstractActivity {
try {
final Parameters params = new Parameters();
OAuth.signOAuth(host, pathRequest, method, true, params, null, null);
- final String line = Network.getResponseData(Network.request("https://" + host + pathRequest, params, false));
+ final String line = Network.getResponseData(Network.getRequest("https://" + host + pathRequest, params));
if (StringUtils.isNotBlank(line)) {
@@ -164,12 +164,12 @@ public class TwitterAuthorizationActivity extends AbstractActivity {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://" + host + pathAuthorize + "?" + encodedParams)));
status = 1;
} catch (Exception e) {
- Log.e(Settings.tag, "TwitterAuthorizationActivity.requestToken(2): " + e.toString());
+ Log.e("TwitterAuthorizationActivity.requestToken(2): " + e.toString());
}
}
}
} catch (Exception e) {
- Log.e(Settings.tag, "TwitterAuthorizationActivity.requestToken(1): " + e.toString());
+ Log.e("TwitterAuthorizationActivity.requestToken(1): " + e.toString());
}
requestTokenHandler.sendEmptyMessage(status);
@@ -209,7 +209,7 @@ public class TwitterAuthorizationActivity extends AbstractActivity {
status = 1;
}
} catch (Exception e) {
- Log.e(Settings.tag, "TwitterAuthorizationActivity.changeToken: " + e.toString());
+ Log.e("TwitterAuthorizationActivity.changeToken: " + e.toString());
}
changeTokensHandler.sendEmptyMessage(status);
diff --git a/main/src/cgeo/geocaching/ui/AddressListAdapter.java b/main/src/cgeo/geocaching/ui/AddressListAdapter.java
index e557882..327b71d 100644
--- a/main/src/cgeo/geocaching/ui/AddressListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/AddressListAdapter.java
@@ -21,24 +21,23 @@ import java.util.ArrayList;
public class AddressListAdapter extends ArrayAdapter<Address> {
- private LayoutInflater inflater;
- private AddressListView holder;
- private Geopoint location;
+ final private LayoutInflater inflater;
+ final private Geopoint location;
public AddressListAdapter(final Context context) {
super(context, 0);
+ inflater = ((Activity) context).getLayoutInflater();
+ location = cgeoapplication.getInstance().currentGeo().getCoords();
}
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (inflater == null) {
- inflater = ((Activity) getContext()).getLayoutInflater();
- }
-
+ public View getView(final int position, final View convertView, final ViewGroup parent) {
final Address address = getItem(position);
// holder pattern implementation
+ final AddressListView holder;
View view = convertView;
+
if (view == null) {
view = inflater.inflate(R.layout.addresses_item, null);
@@ -54,9 +53,9 @@ public class AddressListAdapter extends ArrayAdapter<Address> {
view.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View v) {
- Activity activity = (Activity) v.getContext();
- cgeocaches.startActivityAddress(activity, address.getLatitude(), address.getLongitude(), StringUtils.defaultString(address.getAddressLine(0)));
+ public void onClick(final View v) {
+ final Activity activity = (Activity) v.getContext();
+ cgeocaches.startActivityAddress(activity, new Geopoint(address.getLatitude(), address.getLongitude()), StringUtils.defaultString(address.getAddressLine(0)));
activity.finish();
}
});
@@ -68,10 +67,6 @@ public class AddressListAdapter extends ArrayAdapter<Address> {
}
private CharSequence getDistanceText(final Address address) {
- if (location == null) {
- location = cgeoapplication.getInstance().getLastCoords();
- }
-
if (location != null && address.hasLatitude() && address.hasLongitude()) {
return HumanDistance.getHumanDistance(location.distanceTo(new Geopoint(address.getLatitude(), address.getLongitude())));
}
@@ -83,7 +78,7 @@ public class AddressListAdapter extends ArrayAdapter<Address> {
final int maxIndex = address.getMaxAddressLineIndex();
final ArrayList<String> lines = new ArrayList<String>();
for (int i = 0; i <= maxIndex; i++) {
- String line = address.getAddressLine(i);
+ final String line = address.getAddressLine(i);
if (StringUtils.isNotBlank(line)) {
lines.add(line);
}
diff --git a/main/src/cgeo/geocaching/ui/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
index 57e2a94..bda53d7 100644
--- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
@@ -3,7 +3,6 @@ package cgeo.geocaching.ui;
import cgeo.geocaching.CacheDetailActivity;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.enumerations.CacheListType;
import cgeo.geocaching.enumerations.CacheSize;
@@ -13,13 +12,13 @@ import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.sorting.CacheComparator;
import cgeo.geocaching.sorting.DistanceComparator;
import cgeo.geocaching.sorting.VisitComparator;
+import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import android.app.Activity;
-import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -29,14 +28,13 @@ import android.text.Spannable;
import android.text.Spanned;
import android.text.style.StrikethroughSpan;
import android.util.DisplayMetrics;
-import android.util.Log;
+import android.util.SparseArray;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
@@ -48,10 +46,8 @@ import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
public class CacheListAdapter extends ArrayAdapter<cgCache> {
@@ -68,7 +64,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
private boolean sort = true;
private int checked = 0;
private boolean selectMode = false;
- final private static Map<Integer, Drawable> gcIconDrawables = new HashMap<Integer, Drawable>();
+ final private static SparseArray<Drawable> gcIconDrawables = new SparseArray<Drawable>();
final private Set<CompassMiniView> compasses = new LinkedHashSet<CompassMiniView>();
final private Set<DistanceView> distances = new LinkedHashSet<DistanceView>();
final private int[] ratingBcgs = new int[3];
@@ -76,7 +72,6 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
private static final int SWIPE_MIN_DISTANCE = 60;
private static final int SWIPE_MAX_OFF_PATH = 100;
private static final int SWIPE_DISTANCE = 80;
- private static final float SWIPE_OPACITY = 0.5f;
/**
* time in milliseconds after which the list may be resorted due to position updates
*/
@@ -195,17 +190,6 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
notifyDataSetChanged();
}
- public void clearFilter() {
- if (originalList != null) {
- list.clear();
- list.addAll(originalList);
-
- currentFilter = null;
- }
-
- notifyDataSetChanged();
- }
-
public boolean isFilter() {
return currentFilter != null;
}
@@ -375,7 +359,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
}
if (position > getCount()) {
- Log.w(Settings.tag, "CacheListAdapter.getView: Attempt to access missing item #" + position);
+ Log.w("CacheListAdapter.getView: Attempt to access missing item #" + position);
return null;
}
@@ -486,7 +470,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
holder.inventory.removeAllViews();
}
- ImageView tbIcon = null;
+ ImageView tbIcon;
if (cache.getInventoryItems() > 0) {
tbIcon = (ImageView) inflater.inflate(R.layout.trackable_icon, null);
tbIcon.setImageResource(R.drawable.trackable_all);
@@ -590,8 +574,8 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
if (cacheListType == CacheListType.HISTORY && cache.getVisitedDate() > 0) {
ArrayList<String> infos = new ArrayList<String>();
infos.add(StringUtils.upperCase(cache.getGeocode()));
- infos.add(cgBase.formatDate(cache.getVisitedDate()));
- infos.add(cgBase.formatTime(cache.getVisitedDate()));
+ infos.add(Formatter.formatDate(cache.getVisitedDate()));
+ infos.add(Formatter.formatTime(cache.getVisitedDate()));
holder.info.setText(StringUtils.join(infos, Formatter.SEPARATOR));
} else {
ArrayList<String> infos = new ArrayList<String>();
@@ -609,7 +593,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
if (cache.getSize() != CacheSize.UNKNOWN && cache.showSize()) {
infos.add(cache.getSize().getL10n());
} else if (cache.isEventCache() && cache.getHiddenDate() != null) {
- infos.add(cgBase.formatShortDate(cache.getHiddenDate().getTime()));
+ infos.add(Formatter.formatShortDate(cache.getHiddenDate().getTime()));
}
if (cache.isPremiumMembersOnly()) {
@@ -626,11 +610,13 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
private static Drawable getCacheIcon(cgCache cache) {
int hashCode = getIconHashCode(cache.getType(), cache.hasUserModifiedCoords() || cache.hasFinalDefined());
- if (!gcIconDrawables.containsKey(hashCode)) {
- // fallback to mystery icon
- hashCode = getIconHashCode(CacheType.MYSTERY, cache.hasUserModifiedCoords() || cache.hasFinalDefined());
+ Drawable drawable = gcIconDrawables.get(hashCode);
+ if (drawable != null) {
+ return drawable;
}
+ // fallback to mystery icon
+ hashCode = getIconHashCode(CacheType.MYSTERY, cache.hasUserModifiedCoords() || cache.hasFinalDefined());
return gcIconDrawables.get(hashCode);
}
@@ -699,10 +685,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
}
// load cache details
- Intent cachesIntent = new Intent(getContext(), CacheDetailActivity.class);
- cachesIntent.putExtra("geocode", geocode);
- cachesIntent.putExtra("name", name);
- getContext().startActivity(cachesIntent);
+ CacheDetailActivity.startActivity(getContext(), geocode, name);
}
// long tap on item
@@ -781,7 +764,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
return true;
}
} catch (Exception e) {
- Log.w(Settings.tag, "CacheListAdapter.detectGesture.onFling: " + e.toString());
+ Log.w("CacheListAdapter.detectGesture.onFling: " + e.toString());
}
return false;
@@ -813,21 +796,12 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
showCheckbox.setFillAfter(true);
showCheckbox.setInterpolator(new AccelerateDecelerateInterpolator());
- // dim cache info
- final Animation dimInfo = new AlphaAnimation(1.0f, SWIPE_OPACITY);
- dimInfo.setRepeatCount(0);
- dimInfo.setDuration(force ? 0 : 400);
- dimInfo.setFillEnabled(true);
- dimInfo.setFillAfter(true);
- dimInfo.setInterpolator(new AccelerateDecelerateInterpolator());
-
// animation set (container)
final AnimationSet selectAnimation = new AnimationSet(true);
selectAnimation.setFillEnabled(true);
selectAnimation.setFillAfter(true);
selectAnimation.addAnimation(showCheckbox);
- selectAnimation.addAnimation(dimInfo);
holder.oneInfo.startAnimation(selectAnimation);
cache.setStatusCheckedView(true);
@@ -848,21 +822,12 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
hideCheckbox.setFillAfter(true);
hideCheckbox.setInterpolator(new AccelerateDecelerateInterpolator());
- // brighten cache info
- final Animation brightenInfo = new AlphaAnimation(SWIPE_OPACITY, 1.0f);
- brightenInfo.setRepeatCount(0);
- brightenInfo.setDuration(force ? 0 : 400);
- brightenInfo.setFillEnabled(true);
- brightenInfo.setFillAfter(true);
- brightenInfo.setInterpolator(new AccelerateDecelerateInterpolator());
-
// animation set (container)
final AnimationSet selectAnimation = new AnimationSet(true);
selectAnimation.setFillEnabled(true);
selectAnimation.setFillAfter(true);
selectAnimation.addAnimation(hideCheckbox);
- selectAnimation.addAnimation(brightenInfo);
holder.oneInfo.startAnimation(selectAnimation);
cache.setStatusCheckedView(false);
@@ -871,4 +836,17 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> {
public List<cgCache> getFilteredList() {
return list;
}
+
+ public List<cgCache> getCheckedCaches() {
+ ArrayList<cgCache> result = new ArrayList<cgCache>();
+ int checked = getChecked();
+ if (checked > 0) {
+ for (cgCache cache : list) {
+ if (cache.isStatusChecked()) {
+ result.add(cache);
+ }
+ }
+ }
+ return result;
+ }
}
diff --git a/main/src/cgeo/geocaching/ui/CompassMiniView.java b/main/src/cgeo/geocaching/ui/CompassMiniView.java
index 1fa4cfb..b51b7a2 100644
--- a/main/src/cgeo/geocaching/ui/CompassMiniView.java
+++ b/main/src/cgeo/geocaching/ui/CompassMiniView.java
@@ -111,8 +111,8 @@ public class CompassMiniView extends View {
// compass margins
canvas.setDrawFilter(setfil);
- int marginLeft = 0;
- int marginTop = 0;
+ int marginLeft;
+ int marginTop;
int compassArrowWidth = compassArrow.getWidth();
int compassArrowHeight = compassArrow.getWidth();
@@ -136,7 +136,7 @@ public class CompassMiniView extends View {
}
private int measureWidth(int measureSpec) {
- int result = 0;
+ int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
@@ -154,7 +154,7 @@ public class CompassMiniView extends View {
}
private int measureHeight(int measureSpec) {
- int result = 0;
+ int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
diff --git a/main/src/cgeo/geocaching/ui/CompassView.java b/main/src/cgeo/geocaching/ui/CompassView.java
index 6fc576f..8a295c3 100644
--- a/main/src/cgeo/geocaching/ui/CompassView.java
+++ b/main/src/cgeo/geocaching/ui/CompassView.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.ui;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.utils.Log;
import android.content.Context;
import android.graphics.Bitmap;
@@ -12,12 +12,10 @@ import android.graphics.PaintFlagsDrawFilter;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.View;
public class CompassView extends View {
- private changeThread watchdog = null;
private volatile boolean wantStop = false;
private Context context = null;
private Bitmap compassUnderlay = null;
@@ -58,7 +56,7 @@ public class CompassView extends View {
try {
invalidate();
} catch (Exception e) {
- Log.e(Settings.tag, "CompassView.changeHandler: " + e.toString());
+ Log.e("CompassView.changeHandler: " + e.toString());
}
}
};
@@ -95,8 +93,7 @@ public class CompassView extends View {
initialDisplay = true;
wantStop = false;
- watchdog = new changeThread();
- watchdog.start();
+ new changeThread().start();
}
@Override
@@ -212,8 +209,8 @@ public class CompassView extends View {
int canvasCenterX = (compassRoseWidth / 2) + ((getWidth() - compassRoseWidth) / 2);
int canvasCenterY = (compassRoseHeight / 2) + ((getHeight() - compassRoseHeight) / 2);
- int marginLeftTemp = 0;
- int marginTopTemp = 0;
+ int marginLeftTemp;
+ int marginTopTemp;
super.onDraw(canvas);
@@ -254,7 +251,7 @@ public class CompassView extends View {
}
private int measureWidth(int measureSpec) {
- int result = 0;
+ int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
@@ -272,7 +269,7 @@ public class CompassView extends View {
}
private int measureHeight(int measureSpec) {
- int result = 0;
+ int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
diff --git a/main/src/cgeo/geocaching/ui/DirectionImage.java b/main/src/cgeo/geocaching/ui/DirectionImage.java
index aa01b97..b246718 100644
--- a/main/src/cgeo/geocaching/ui/DirectionImage.java
+++ b/main/src/cgeo/geocaching/ui/DirectionImage.java
@@ -17,7 +17,7 @@ public class DirectionImage {
}
final HttpResponse httpResponse =
- Network.request("http://www.geocaching.com/ImgGen/seek/CacheDir.ashx", new Parameters("k", code), false);
+ Network.getRequest("http://www.geocaching.com/ImgGen/seek/CacheDir.ashx", new Parameters("k", code));
if (httpResponse != null) {
LocalStorage.saveEntityToFile(httpResponse, getDirectionFile(geocode, true));
}
diff --git a/main/src/cgeo/geocaching/ui/Formatter.java b/main/src/cgeo/geocaching/ui/Formatter.java
index 661a9a0..6ee1a65 100644
--- a/main/src/cgeo/geocaching/ui/Formatter.java
+++ b/main/src/cgeo/geocaching/ui/Formatter.java
@@ -1,8 +1,80 @@
package cgeo.geocaching.ui;
-public interface Formatter {
+import cgeo.geocaching.cgeoapplication;
+
+import android.content.Context;
+import android.text.format.DateUtils;
+
+public abstract class Formatter {
/** Text separator used for formatting texts */
public static final String SEPARATOR = " · ";
+ private static final Context context = cgeoapplication.getInstance().getBaseContext();
+
+ /**
+ * Generate a time string according to system-wide settings (locale, 12/24 hour)
+ * such as "13:24".
+ *
+ * @param date
+ * milliseconds since the epoch
+ * @return the formatted string
+ */
+ public static String formatTime(long date) {
+ return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_TIME);
+ }
+
+ /**
+ * Generate a date string according to system-wide settings (locale, date format)
+ * such as "20 December" or "20 December 2010". The year will only be included when necessary.
+ *
+ * @param date
+ * milliseconds since the epoch
+ * @return the formatted string
+ */
+ public static String formatDate(long date) {
+ return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE);
+ }
+
+ /**
+ * Generate a date string according to system-wide settings (locale, date format)
+ * such as "20 December 2010". The year will always be included, making it suitable
+ * to generate long-lived log entries.
+ *
+ * @param date
+ * milliseconds since the epoch
+ * @return the formatted string
+ */
+ public static String formatFullDate(long date) {
+ return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE
+ | DateUtils.FORMAT_SHOW_YEAR);
+ }
+
+ /**
+ * Generate a numeric date string according to system-wide settings (locale, date format)
+ * such as "10/20/2010".
+ *
+ * @param date
+ * milliseconds since the epoch
+ * @return the formatted string
+ */
+ public static String formatShortDate(long date) {
+ return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE
+ | DateUtils.FORMAT_NUMERIC_DATE);
+ }
+
+ /**
+ * Generate a numeric date and time string according to system-wide settings (locale,
+ * date format) such as "7 sept. at 12:35".
+ *
+ * @param context
+ * a Context
+ * @param date
+ * milliseconds since the epoch
+ * @return the formatted string
+ */
+ public static String formatShortDateTime(Context context, long date) {
+ return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/ui/GPXListAdapter.java b/main/src/cgeo/geocaching/ui/GPXListAdapter.java
index 2ebb893..76dc10e 100644
--- a/main/src/cgeo/geocaching/ui/GPXListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/GPXListAdapter.java
@@ -1,12 +1,11 @@
package cgeo.geocaching.ui;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.cgeogpxes;
import cgeo.geocaching.files.GPXImporter;
+import cgeo.geocaching.utils.Log;
import android.app.Activity;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -17,7 +16,6 @@ import java.io.File;
import java.util.List;
public class GPXListAdapter extends ArrayAdapter<File> {
- private GPXListView holder = null;
private cgeogpxes activity = null;
private LayoutInflater inflater = null;
@@ -34,13 +32,14 @@ public class GPXListAdapter extends ArrayAdapter<File> {
}
if (position > getCount()) {
- Log.w(Settings.tag, "cgGPXListAdapter.getView: Attempt to access missing item #" + position);
+ Log.w("cgGPXListAdapter.getView: Attempt to access missing item #" + position);
return null;
}
final File file = getItem(position);
View v = rowView;
+ GPXListView holder;
if (v == null) {
v = inflater.inflate(R.layout.gpx_item, null);
diff --git a/main/src/cgeo/geocaching/ui/MapfileListAdapter.java b/main/src/cgeo/geocaching/ui/MapfileListAdapter.java
index 9196a41..a14d120 100644
--- a/main/src/cgeo/geocaching/ui/MapfileListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/MapfileListAdapter.java
@@ -1,12 +1,11 @@
package cgeo.geocaching.ui;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
import cgeo.geocaching.cgSelectMapfile;
+import cgeo.geocaching.utils.Log;
import android.app.Activity;
import android.graphics.Typeface;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -20,7 +19,6 @@ public class MapfileListAdapter extends ArrayAdapter<File> {
private cgSelectMapfile parentView;
private LayoutInflater inflater;
- private MapfileView holder;
public MapfileListAdapter(cgSelectMapfile parentIn, List<File> listIn) {
super(parentIn, 0, listIn);
@@ -35,13 +33,14 @@ public class MapfileListAdapter extends ArrayAdapter<File> {
}
if (position > getCount()) {
- Log.w(Settings.tag, "cgGPXListAdapter.getView: Attempt to access missing item #" + position);
+ Log.w("cgGPXListAdapter.getView: Attempt to access missing item #" + position);
return null;
}
File file = getItem(position);
View v = rowView;
+ MapfileView holder;
if (v == null) {
v = inflater.inflate(R.layout.mapfile_item, null);
diff --git a/main/src/cgeo/geocaching/utils/BaseUtils.java b/main/src/cgeo/geocaching/utils/BaseUtils.java
index 44c35a1..d468fc9 100644
--- a/main/src/cgeo/geocaching/utils/BaseUtils.java
+++ b/main/src/cgeo/geocaching/utils/BaseUtils.java
@@ -3,8 +3,6 @@
*/
package cgeo.geocaching.utils;
-import java.util.ArrayList;
-import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -84,17 +82,6 @@ public final class BaseUtils {
return BaseUtils.getMatch(data, p, true, 1, defaultValue, false);
}
- public static List<String> getMatches(final String data, final Pattern p, int count) {
- ArrayList<String> result = new ArrayList<String>();
- final Matcher matcher = p.matcher(data);
- while (matcher.find()) {
- for (int i = 0; i < count; i++) {
- result.add(matcher.group(i));
- }
- }
- return result;
- }
-
/**
* Searches for the pattern p in the data.
*
diff --git a/main/src/cgeo/geocaching/utils/CancellableHandler.java b/main/src/cgeo/geocaching/utils/CancellableHandler.java
index d4915eb..8cf8f28 100644
--- a/main/src/cgeo/geocaching/utils/CancellableHandler.java
+++ b/main/src/cgeo/geocaching/utils/CancellableHandler.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.utils;
+import cgeo.geocaching.cgeoapplication;
+
import android.os.Handler;
import android.os.Message;
@@ -9,6 +11,7 @@ import android.os.Message;
*/
public abstract class CancellableHandler extends Handler {
+ protected static final int UPDATE_LOAD_PROGRESS_DETAIL = 42186;
private volatile boolean cancelled = false;
private static class CancelHolder {
@@ -109,4 +112,9 @@ public abstract class CancellableHandler extends Handler {
return handler != null && handler.isCancelled();
}
+ public static void sendLoadProgressDetail(final Handler handler, final int resourceId) {
+ if (null != handler) {
+ handler.obtainMessage(UPDATE_LOAD_PROGRESS_DETAIL, cgeoapplication.getInstance().getString(resourceId)).sendToTarget();
+ }
+ }
}
diff --git a/main/src/cgeo/geocaching/utils/ClipboardUtils.java b/main/src/cgeo/geocaching/utils/ClipboardUtils.java
index 865d8d6..e6779ad 100644
--- a/main/src/cgeo/geocaching/utils/ClipboardUtils.java
+++ b/main/src/cgeo/geocaching/utils/ClipboardUtils.java
@@ -10,6 +10,7 @@ import android.text.ClipboardManager;
* This class uses the deprecated function ClipboardManager.setText(CharSequence).
* API 11 introduced setPrimaryClip(ClipData)
*/
+@SuppressWarnings("deprecation")
public final class ClipboardUtils {
/**
diff --git a/main/src/cgeo/geocaching/utils/CryptUtils.java b/main/src/cgeo/geocaching/utils/CryptUtils.java
index 907fa1f..f04327e 100644
--- a/main/src/cgeo/geocaching/utils/CryptUtils.java
+++ b/main/src/cgeo/geocaching/utils/CryptUtils.java
@@ -1,10 +1,8 @@
package cgeo.geocaching.utils;
-import cgeo.geocaching.Settings;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
-import android.util.Log;
import java.math.BigInteger;
import java.security.MessageDigest;
@@ -75,7 +73,7 @@ public final class CryptUtils {
digest.update(text.getBytes(), 0, text.length());
hashed = new BigInteger(1, digest.digest()).toString(16);
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.md5: " + e.toString());
+ Log.e("cgBase.md5: " + e.toString());
}
return hashed;
@@ -89,7 +87,7 @@ public final class CryptUtils {
digest.update(text.getBytes(), 0, text.length());
hashed = new BigInteger(1, digest.digest()).toString(16);
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.sha1: " + e.toString());
+ Log.e("cgBase.sha1: " + e.toString());
}
return hashed;
@@ -104,7 +102,7 @@ public final class CryptUtils {
mac.init(secretKeySpec);
macBytes = mac.doFinal(text.getBytes());
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.hashHmac: " + e.toString());
+ Log.e("cgBase.hashHmac: " + e.toString());
}
return macBytes;
@@ -137,49 +135,6 @@ public final class CryptUtils {
return buffer;
}
- public static byte[] base64Decode(String text) {
- char[] in = text.toCharArray();
-
- int iLen = in.length;
- if (iLen % 4 != 0) {
- throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4.");
- }
- while (iLen > 0 && in[iLen - 1] == '=') {
- iLen--;
- }
- int oLen = (iLen * 3) / 4;
- byte[] out = new byte[oLen];
- int ip = 0;
- int op = 0;
- while (ip < iLen) {
- int i0 = in[ip++];
- int i1 = in[ip++];
- int i2 = ip < iLen ? in[ip++] : 'A';
- int i3 = ip < iLen ? in[ip++] : 'A';
- if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) {
- throw new IllegalArgumentException("Illegal character in Base64 encoded data.");
- }
- int b0 = base64map2[i0];
- int b1 = base64map2[i1];
- int b2 = base64map2[i2];
- int b3 = base64map2[i3];
- if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) {
- throw new IllegalArgumentException("Illegal character in Base64 encoded data.");
- }
- int o0 = (b0 << 2) | (b1 >>> 4);
- int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
- int o2 = ((b2 & 3) << 6) | b3;
- out[op++] = (byte) o0;
- if (op < oLen) {
- out[op++] = (byte) o1;
- }
- if (op < oLen) {
- out[op++] = (byte) o2;
- }
- }
- return out;
- }
-
public static String base64Encode(byte[] in) {
int iLen = in.length;
int oDataLen = (iLen * 4 + 2) / 3; // output length without padding
diff --git a/main/src/cgeo/geocaching/utils/IObserver.java b/main/src/cgeo/geocaching/utils/IObserver.java
new file mode 100644
index 0000000..c7842aa
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/IObserver.java
@@ -0,0 +1,22 @@
+package cgeo.geocaching.utils;
+
+/**
+ * Observer interface.
+ * <p/>
+ * An observer will receive updates about the observed object (implementing the {@link ISubject} interface)
+ * through its {@link #update(T)} method.
+ *
+ * @param <T>
+ * the kind of data to observe
+ */
+public interface IObserver<T> {
+
+ /**
+ * Called when an observed object has updated its data.
+ *
+ * @param data
+ * the updated data
+ */
+ void update(final T data);
+
+}
diff --git a/main/src/cgeo/geocaching/utils/ISubject.java b/main/src/cgeo/geocaching/utils/ISubject.java
new file mode 100644
index 0000000..f332ee8
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/ISubject.java
@@ -0,0 +1,57 @@
+package cgeo.geocaching.utils;
+
+/**
+ * Interface for subjects objects. Those can be observed by objects implementing the {@link IObserver} interface.
+ *
+ * @param <T>
+ * the kind of data to observe
+ */
+
+public interface ISubject<T> {
+
+ /**
+ * Add an observer to the observers list.
+ * <p/>
+ * Observers will be notified with no particular order.
+ *
+ * @param observer
+ * the observer to add
+ * @return true if the observer has been added, false if it was present already
+ */
+ public boolean addObserver(final IObserver<? super T> observer);
+
+ /**
+ * Delete an observer from the observers list.
+ *
+ * @param observer
+ * the observer to remove
+ * @return true if the observer has been removed, false if it was not in the list of observers
+ */
+ public boolean deleteObserver(final IObserver<? super T> observer);
+
+ /**
+ * Number of observers currently observing the object.
+ *
+ * @return the number of observers
+ */
+ public int sizeObservers();
+
+ /**
+ * Notify all the observers that new data is available.
+ * <p/>
+ * The {@link IObserver#update(T)} method of each observer will be called with no particular order.
+ *
+ * @param data
+ * the updated data
+ * @return true if at least one observer was notified, false if there were no observers
+ */
+ public boolean notifyObservers(final T data);
+
+ /**
+ * Clear the observers list.
+ *
+ * @return true if there were observers before calling this method, false if the observers list was empty
+ */
+ public boolean clearObservers();
+
+}
diff --git a/main/src/cgeo/geocaching/utils/LRUList.java b/main/src/cgeo/geocaching/utils/LRUList.java
deleted file mode 100644
index 13596b1..0000000
--- a/main/src/cgeo/geocaching/utils/LRUList.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package cgeo.geocaching.utils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Base class for a limited list.
- *
- * @author blafoo
- */
-public class LRUList<T> extends ArrayList<T> {
-
- private static final long serialVersionUID = -5077882607489806620L;
- private final int maxEntries;
-
- public LRUList(int maxEntries) {
- this.maxEntries = maxEntries;
- }
-
- private void removeElements(int count) {
- for (int i = 0; i < count; i++) {
- this.remove(0);
- }
- }
-
- @Override
- public boolean add(T item) {
- removeElements(this.size() + 1 - maxEntries);
- return super.add(item);
- }
-
- @Override
- public boolean addAll(Collection<? extends T> collection) {
- if (collection.size() > this.size()) {
- this.clear();
- for (T item : collection) {
- this.add(item);
- }
- return false;
- } else {
- removeElements(this.size() + collection.size() - maxEntries);
- return super.addAll(collection);
- }
- }
-
-}
diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedCache.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedCache.java
deleted file mode 100644
index 6d18cf5..0000000
--- a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedCache.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package cgeo.geocaching.utils;
-
-import java.util.LinkedHashMap;
-
-/**
- * Base class for a caching cache. Don't mix up with a geocache !
- *
- * @author blafoo
- */
-public class LeastRecentlyUsedCache<K, V> extends LinkedHashMap<K, V> {
-
- private static final long serialVersionUID = -5077882607489806620L;
- private final int maxEntries;
-
- public LeastRecentlyUsedCache(int maxEntries) {
- this.maxEntries = maxEntries;
- }
-
- @Override
- protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
- return size() > maxEntries;
- }
-
-}
diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedMap.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedMap.java
new file mode 100644
index 0000000..953fc47
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedMap.java
@@ -0,0 +1,139 @@
+package cgeo.geocaching.utils;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Base class for caching objects. Don't mix up with a geocache !
+ *
+ * The LeastRecentlyUsedMap is basically a LinkedHashMap which can be configured to have certain modes of operation:
+ * <ul>
+ * <li> LRU_CACHE means that the elements are updated in the LinkedList on every get() access,
+ * so the objects that are dropped are the ones that haven't been used the longest</li>
+ * <li> BOUNDED means that objects are updated only when they are put,
+ * so the objects that are dropped are the ones that haven't been written the longest</li>
+ * </ul>
+ *
+ * @author blafoo
+ * @author Teschi
+ */
+public abstract class LeastRecentlyUsedMap<K, V> extends LinkedHashMap<K, V> {
+
+ private static enum OperationModes {
+ LRU_CACHE, BOUNDED
+ }
+
+ private static final long serialVersionUID = -5077882607489806620L;
+
+ private final int maxEntries;
+ private final OperationModes opMode;
+ private RemoveHandler<V> removeHandler;
+
+ // store the HashMap parameters for serialization, as we can't access the originals in the LinkedHashMap
+ final int initialCapacity;
+ final float loadFactor;
+
+ protected LeastRecentlyUsedMap(int maxEntries, int initialCapacity, float loadFactor, OperationModes opMode) {
+ super(initialCapacity, loadFactor, (opMode==OperationModes.LRU_CACHE));
+ this.initialCapacity = initialCapacity;
+ this.loadFactor = loadFactor;
+ this.maxEntries = maxEntries;
+ this.opMode = opMode;
+ }
+
+ protected LeastRecentlyUsedMap(int maxEntries, OperationModes opMode) {
+ this(maxEntries, 16, 0.75f, opMode);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ // in case the underlying Map is not running with accessOrder==true, the map won't notice any changes
+ // of existing keys, so for the normal BOUNDED mode we remove and put the value to get its order updated.
+ if (opMode == OperationModes.BOUNDED && containsKey(key)) {
+ // avoid trigger the remove notification
+ final V oldVal = super.remove(key);
+ put(key, value);
+ return oldVal;
+ }
+
+ return super.put(key, value);
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+ return size() > maxEntries;
+ }
+
+ public int getMaxEntries() {
+ return maxEntries;
+ }
+
+ @Override
+ public V remove(Object key) {
+
+ V removed = super.remove(key);
+
+ if (removed != null && removeHandler != null) {
+ removeHandler.onRemove(removed);
+ }
+
+ return removed;
+ }
+
+ /**
+ * Sets a handler for remove notifications. Currently only one handler
+ * instance is supported
+ *
+ * @param removeHandler
+ * The new handler to receive notifications or null to remove a handler
+ */
+ public void setRemoveHandler(RemoveHandler<V> removeHandler) {
+ this.removeHandler = removeHandler;
+ }
+
+ public static class LruCache<K, V> extends LeastRecentlyUsedMap<K, V> {
+ private static final long serialVersionUID = 9028478916221334454L;
+
+ public LruCache(int maxEntries, int initialCapacity, float loadFactor) {
+ super(maxEntries, initialCapacity, loadFactor, OperationModes.LRU_CACHE);
+ }
+
+ public LruCache(int maxEntries) {
+ super(maxEntries, OperationModes.LRU_CACHE);
+ }
+ }
+
+ public static class Bounded<K, V> extends LeastRecentlyUsedMap<K, V> {
+
+ private static final long serialVersionUID = -1476389304214398315L;
+
+ public Bounded(int maxEntries, int initialCapacity, float loadFactor) {
+ super(maxEntries, initialCapacity, loadFactor, OperationModes.BOUNDED);
+ }
+
+ public Bounded(int maxEntries) {
+ super(maxEntries, OperationModes.BOUNDED);
+ }
+ }
+
+ /**
+ * Interface for handlers that wish to get notified when items are
+ * removed from the LRUMap
+ *
+ * @author rsudev
+ *
+ * @param <V>
+ */
+ public interface RemoveHandler<V> {
+
+ /**
+ * Method will be called on remove
+ *
+ * @param removed
+ * Item that has been removed
+ */
+ void onRemove(V removed);
+
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
new file mode 100644
index 0000000..986087f
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
@@ -0,0 +1,198 @@
+package cgeo.geocaching.utils;
+
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Synchronized set wrapper for the LeastRecentlyUsedMap.
+ *
+ * This code is heavily based on the HashSet code that represent Map as a Set.
+ * Unfortunately HashSet does not allow to use a custom Map as its Storage.
+ * Therefore overriding removeEldestEntry() is impossible for a normal LinkedHashSet.
+ *
+ * Synchronization is added to guard against concurrent modification. Iterator
+ * access has to be guarded externally or the synchronized getAsList method can be used
+ * to get a clone for iteration
+ *
+ * @author Teschi
+ */
+public class LeastRecentlyUsedSet<E> extends AbstractSet<E>
+ implements Cloneable, java.io.Serializable {
+
+ private static final long serialVersionUID = -1942301031191419547L;
+
+ private transient LeastRecentlyUsedMap<E, Object> map;
+ private static final Object PRESENT = new Object();
+
+ public LeastRecentlyUsedSet(int maxEntries, int initialCapacity, float loadFactor) {
+ // because we don't use any Map.get() methods from the Set, BOUNDED and LRU_CACHE have the exact same Behaviour
+ // So we useLRU_CACHE mode because it should perform a bit better (as it doesn't re-add explicitly)
+ map = new LeastRecentlyUsedMap.LruCache<E, Object>(maxEntries, initialCapacity, loadFactor);
+ }
+
+ public LeastRecentlyUsedSet(int maxEntries) {
+ map = new LeastRecentlyUsedMap.LruCache<E, Object>(maxEntries);
+ }
+
+ /**
+ * Copy of the HashSet code if iterator()
+ * Iterator access has to be synchronized externally!
+ *
+ * @see HashSet
+ */
+ @Override
+ public Iterator<E> iterator() {
+ return map.keySet().iterator();
+ }
+
+ /**
+ * Synchronized access to set size
+ * Copy of the HashSet code if size()
+ *
+ * @see HashSet
+ */
+ @Override
+ public synchronized int size() {
+ return map.size();
+ }
+
+ /**
+ * Synchronized check of set emptiness
+ * Copy of the HashSet code if isEmpty()
+ *
+ * @see HashSet
+ */
+ @Override
+ public synchronized boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ /**
+ * Synchronized check for containment
+ * Copy of the HashSet code if contains()
+ *
+ * @see HashSet
+ */
+ @Override
+ public synchronized boolean contains(Object o) {
+ return map.containsKey(o);
+ }
+
+ /**
+ * Synchronized addition of an item
+ * Copy of the HashSet code if add()
+ *
+ * @see HashSet
+ */
+ @Override
+ public synchronized boolean add(E e) {
+ return map.put(e, PRESENT) == null;
+ }
+
+ /**
+ * Synchronized removal of a contained item
+ * Copy of the HashSet code if remove()
+ *
+ * @see HashSet
+ */
+ @Override
+ public synchronized boolean remove(Object o) {
+ return map.remove(o) == PRESENT;
+ }
+
+ /**
+ * Synchronized clearing of the set
+ * Copy of the HashSet code if clear()
+ *
+ * @see HashSet
+ */
+ @Override
+ public synchronized void clear() {
+ map.clear();
+ }
+
+ /**
+ * (synchronized) Clone of the set
+ * Copy of the HashSet code if clone()
+ *
+ * @see HashSet
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object clone() {
+ try {
+ synchronized (this) {
+ final LeastRecentlyUsedSet<E> newSet = (LeastRecentlyUsedSet<E>) super.clone();
+ newSet.map = (LeastRecentlyUsedMap<E, Object>) map.clone();
+ return newSet;
+ }
+ } catch (CloneNotSupportedException e) {
+ throw new InternalError();
+ }
+ }
+
+ /**
+ * Creates a clone as a list in a synchronized fashion.
+ *
+ * @return List based clone of the set
+ */
+ public synchronized List<E> getAsList() {
+ return new ArrayList<E>(this);
+ }
+
+ /**
+ * Serialization version of HashSet with the additional parameters for the custom Map
+ *
+ * @see HashSet
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ // Write out any hidden serialization magic
+ s.defaultWriteObject();
+
+ // Write out HashMap capacity and load factor
+ s.writeInt(map.initialCapacity);
+ s.writeFloat(map.loadFactor);
+ s.writeInt(map.getMaxEntries());
+
+ // Write out size
+ s.writeInt(map.size());
+
+ // Write out all elements in the proper order.
+ for (final E e : map.keySet()) {
+ s.writeObject(e);
+ }
+ }
+
+ /**
+ * Serialization version of HashSet with the additional parameters for the custom Map
+ *
+ * @see HashSet
+ */
+ @SuppressWarnings("unchecked")
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ // Read in any hidden serialization magic
+ s.defaultReadObject();
+
+ // Read in HashMap capacity and load factor and create backing HashMap
+ final int capacity = s.readInt();
+ final float loadFactor = s.readFloat();
+ final int maxEntries = s.readInt();
+
+ map = new LeastRecentlyUsedMap.LruCache<E, Object>(maxEntries, capacity, loadFactor);
+
+ // Read in size
+ final int size = s.readInt();
+
+ // Read in all elements in the proper order.
+ for (int i = 0; i < size; i++) {
+ E e = (E) s.readObject();
+ map.put(e, PRESENT);
+ }
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/utils/Log.java b/main/src/cgeo/geocaching/utils/Log.java
new file mode 100644
index 0000000..9f5bd3d
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/Log.java
@@ -0,0 +1,69 @@
+package cgeo.geocaching.utils;
+
+
+final public class Log {
+
+ private static final String TAG = "cgeo";
+
+ private static boolean isDebug = true;
+
+ public static boolean isDebug() {
+ return isDebug;
+ }
+
+ public static void setDebugUnsaved(boolean isDebug) {
+ Log.isDebug = isDebug;
+ }
+
+ public static void v(final String msg) {
+ if (isDebug) {
+ android.util.Log.v(TAG, msg);
+ }
+ }
+
+ public static void v(final String msg, final Throwable t) {
+ if (isDebug) {
+ android.util.Log.v(TAG, msg, t);
+ }
+ }
+
+ public static void d(final String msg) {
+ if (isDebug) {
+ android.util.Log.d(TAG, msg);
+ }
+ }
+
+ public static void d(final String msg, final Throwable t) {
+ if (isDebug) {
+ android.util.Log.d(TAG, msg, t);
+ }
+ }
+
+ public static void i(final String msg) {
+ if (isDebug) {
+ android.util.Log.i(TAG, msg);
+ }
+ }
+
+ public static void i(final String msg, final Throwable t) {
+ if (isDebug) {
+ android.util.Log.i(TAG, msg, t);
+ }
+ }
+
+ public static void w(final String msg) {
+ android.util.Log.w(TAG, msg);
+ }
+
+ public static void w(final String msg, final Throwable t) {
+ android.util.Log.w(TAG, msg, t);
+ }
+
+ public static void e(final String msg) {
+ android.util.Log.e(TAG, msg);
+ }
+
+ public static void e(final String msg, final Throwable t) {
+ android.util.Log.e(TAG, msg, t);
+ }
+}
diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
index b9bebc9..60866e0 100644
--- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
+++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
@@ -2,14 +2,13 @@ package cgeo.geocaching.utils;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgBase;
import cgeo.geocaching.connector.gc.GCConstants;
-import cgeo.geocaching.network.Login;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.network.Network;
+import cgeo.geocaching.ui.Formatter;
import org.apache.commons.lang3.StringUtils;
-import android.util.Log;
/**
* provides all the available templates for logging
@@ -56,14 +55,14 @@ public class LogTemplateProvider {
@Override
public String getValue(final boolean offline) {
- return cgBase.formatFullDate(System.currentTimeMillis());
+ return Formatter.formatFullDate(System.currentTimeMillis());
}
},
new LogTemplate("TIME", R.string.init_signature_template_time) {
@Override
public String getValue(final boolean offline) {
- return cgBase.formatTime(System.currentTimeMillis());
+ return Formatter.formatTime(System.currentTimeMillis());
}
},
new LogTemplate("DATETIME", R.string.init_signature_template_datetime) {
@@ -71,7 +70,7 @@ public class LogTemplateProvider {
@Override
public String getValue(final boolean offline) {
final long currentTime = System.currentTimeMillis();
- return cgBase.formatFullDate(currentTime) + " " + cgBase.formatTime(currentTime);
+ return Formatter.formatFullDate(currentTime) + " " + Formatter.formatTime(currentTime);
}
},
new LogTemplate("USER", R.string.init_signature_template_user) {
@@ -90,7 +89,7 @@ public class LogTemplateProvider {
if (offline) {
return "";
}
- final String page = Network.getResponseData(Network.request("http://www.geocaching.com/email/", null, false, false, false));
+ final String page = Network.getResponseData(Network.getRequest("http://www.geocaching.com/email/"));
current = parseFindCount(page);
}
@@ -134,7 +133,7 @@ public class LogTemplateProvider {
try {
return Integer.parseInt(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", ""));
} catch (NumberFormatException e) {
- Log.e(Settings.tag, "parseFindCount", e);
+ Log.e("parseFindCount", e);
return -1;
}
}
diff --git a/main/src/cgeo/geocaching/utils/MemorySubject.java b/main/src/cgeo/geocaching/utils/MemorySubject.java
new file mode 100644
index 0000000..c424528
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/MemorySubject.java
@@ -0,0 +1,45 @@
+package cgeo.geocaching.utils;
+
+/**
+ * Synchronized implementation of the {@link ISubject} interface with an added pull interface.
+ *
+ * @param <T>
+ * the kind of data to observe
+ */
+public class MemorySubject<T> extends Subject<T> {
+
+ /**
+ * The latest version of the observed data.
+ * <p/>
+ * A child class implementation may want to set this field from its constructors, in case early observers request
+ * the data before it got a chance to get updated. Otherwise, <code>null</code> will be returned until updated
+ * data is available.
+ */
+ private T memory;
+
+ @Override
+ public synchronized boolean addObserver(final IObserver<? super T> observer) {
+ final boolean added = super.addObserver(observer);
+ if (added && memory != null) {
+ observer.update(memory);
+ }
+ return added;
+ }
+
+ @Override
+ public synchronized boolean notifyObservers(final T data) {
+ memory = data;
+ return super.notifyObservers(data);
+ }
+
+ /**
+ * Get the memorized version of the data.
+ *
+ * @return the initial data set by the subject (which may be <code>null</code>),
+ * or the updated data if it is available
+ */
+ public synchronized T getMemory() {
+ return memory;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/utils/PeriodicHandler.java b/main/src/cgeo/geocaching/utils/PeriodicHandler.java
new file mode 100644
index 0000000..3f6c345
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/PeriodicHandler.java
@@ -0,0 +1,74 @@
+package cgeo.geocaching.utils;
+
+import android.os.Handler;
+import android.os.Message;
+
+/**
+ * A PeriodicHandler class helps with the implementation of a periodic
+ * action embedded in a thread with a looper such as the UI thread.
+ * The act() method will be called periodically. The clock may drift
+ * as the implementation does not target real-time actions.
+ *
+ * The handler will be interrupted if the device goes to sleep.
+ *
+ */
+abstract public class PeriodicHandler extends Handler {
+
+ final static private int START = 0;
+ final static private int STOP = 1;
+ final static private int ACT = 2;
+
+ final private long period;
+
+ /**
+ * Create a new PeriodicHandler object.
+ *
+ * @param period
+ * The period in milliseconds.
+ */
+ public PeriodicHandler(final long period) {
+ this.period = period;
+ }
+
+ /**
+ * Subclasses of PeriodicHandler must implement this method.
+ */
+ abstract public void act();
+
+ @Override
+ public void handleMessage(final Message msg) {
+ switch (msg.what) {
+ case START:
+ removeMessages(ACT);
+ sendEmptyMessage(ACT);
+ break;
+ case STOP:
+ removeMessages(ACT);
+ break;
+ case ACT:
+ sendEmptyMessageDelayed(ACT, period);
+ act();
+ }
+ }
+
+ /**
+ * Start the periodic handler.
+ *
+ * Restarting a handler that is already started will only
+ * reset its clock.
+ */
+ public void start() {
+ sendEmptyMessage(START);
+ }
+
+ /**
+ * Stop the periodic handler.
+ *
+ * If this method is called from the looper thread, this call is
+ * guaranteed to be synchronous.
+ */
+ public void stop() {
+ sendMessageAtFrontOfQueue(obtainMessage(STOP));
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/utils/Subject.java b/main/src/cgeo/geocaching/utils/Subject.java
new file mode 100644
index 0000000..b1754cc
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/Subject.java
@@ -0,0 +1,76 @@
+package cgeo.geocaching.utils;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Synchronized implementation of the {@link ISubject} interface.
+ *
+ * @param <T>
+ * the kind of data to observe
+ */
+public class Subject<T> implements ISubject<T> {
+
+ /**
+ * Collection of observers.
+ */
+ protected final Set<IObserver<? super T>> observers = new LinkedHashSet<IObserver<? super T>>();
+
+ @Override
+ public synchronized boolean addObserver(final IObserver<? super T> observer) {
+ final boolean added = observers.add(observer);
+ if (added && observers.size() == 1) {
+ onFirstObserver();
+ }
+ return added;
+ }
+
+ @Override
+ public synchronized boolean deleteObserver(final IObserver<? super T> observer) {
+ final boolean removed = observers.remove(observer);
+ if (removed && observers.isEmpty()) {
+ onLastObserver();
+ }
+ return removed;
+ }
+
+ @Override
+ public synchronized boolean notifyObservers(final T arg) {
+ final boolean nonEmpty = !observers.isEmpty();
+ for (final IObserver<? super T> observer : observers) {
+ observer.update(arg);
+ }
+ return nonEmpty;
+ }
+
+ @Override
+ public synchronized int sizeObservers() {
+ return observers.size();
+ }
+
+ @Override
+ public synchronized boolean clearObservers() {
+ final boolean nonEmpty = !observers.isEmpty();
+ for (final IObserver<? super T> observer : observers) {
+ deleteObserver(observer);
+ }
+ return nonEmpty;
+ }
+
+ /**
+ * Method called when the collection of observers goes from empty to non-empty.
+ * <p/>
+ * The default implementation does nothing and may be overwritten by child classes.
+ */
+ protected void onFirstObserver() {
+ }
+
+ /**
+ * Method called when the collection of observers goes from non-empty to empty.
+ * <p/>
+ * The default implementation does nothing and may be overwritten by child classes.
+ */
+ protected void onLastObserver() {
+ }
+
+}