aboutsummaryrefslogtreecommitdiffstats
path: root/main/src
diff options
context:
space:
mode:
Diffstat (limited to 'main/src')
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java125
-rw-r--r--main/src/cgeo/geocaching/GCConstants.java12
-rw-r--r--main/src/cgeo/geocaching/Settings.java15
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java49
-rw-r--r--main/src/cgeo/geocaching/cgBase.java189
-rw-r--r--main/src/cgeo/geocaching/cgCache.java25
-rw-r--r--main/src/cgeo/geocaching/cgeo.java31
-rw-r--r--main/src/cgeo/geocaching/cgeoadvsearch.java52
-rw-r--r--main/src/cgeo/geocaching/cgeocaches.java16
-rw-r--r--main/src/cgeo/geocaching/cgeoinit.java44
-rw-r--r--main/src/cgeo/geocaching/cgeopopup.java23
-rw-r--r--main/src/cgeo/geocaching/cgeotrackable.java38
-rw-r--r--main/src/cgeo/geocaching/cgeowaypoint.java27
-rw-r--r--main/src/cgeo/geocaching/connector/AbstractConnector.java10
-rw-r--r--main/src/cgeo/geocaching/connector/ConnectorFactory.java18
-rw-r--r--main/src/cgeo/geocaching/connector/GCConnector.java19
-rw-r--r--main/src/cgeo/geocaching/connector/IConnector.java18
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCBase.java72
-rw-r--r--main/src/cgeo/geocaching/connector/gc/UTFGrid.java6
-rw-r--r--main/src/cgeo/geocaching/enumerations/CacheSize.java2
-rw-r--r--main/src/cgeo/geocaching/enumerations/LoadFlags.java4
-rw-r--r--main/src/cgeo/geocaching/filter/SizeFilter.java12
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java16
-rw-r--r--main/src/cgeo/geocaching/utils/BaseUtils.java32
-rw-r--r--main/src/cgeo/geocaching/utils/LogTemplateProvider.java31
25 files changed, 538 insertions, 348 deletions
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index 528b2e2..a9c9dbf 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -65,6 +65,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
+import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
@@ -157,6 +158,13 @@ public class CacheDetailActivity extends AbstractActivity {
// some views that must be available from everywhere // TODO: Reference can block GC?
private TextView cacheDistanceView;
+ private Handler cacheChangeNotificationHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ notifyDataSetChanged();
+ }
+ };
+
public CacheDetailActivity() {
// identifier for manual
super("c:geolocation-cache-details");
@@ -262,6 +270,15 @@ public class CacheDetailActivity extends AbstractActivity {
// nothing, we lost the window
}
+ ImageView defaultNavigationImageView = (ImageView) findViewById(R.id.defaultNavigation);
+ defaultNavigationImageView.setOnLongClickListener(new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ startDefaultNavigation2();
+ return true;
+ }
+ });
+
// initialize ViewPager
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPagerAdapter = new ViewPagerAdapter();
@@ -314,7 +331,9 @@ public class CacheDetailActivity extends AbstractActivity {
if (geolocation == null) {
geolocation = app.startGeo(locationUpdater);
}
-
+ if (cache != null) {
+ cache.setChangeNotificationHandler(cacheChangeNotificationHandler);
+ }
if (refreshOnResume) {
notifyDataSetChanged();
refreshOnResume = false;
@@ -336,6 +355,10 @@ public class CacheDetailActivity extends AbstractActivity {
geolocation = app.removeGeo();
}
+ if (cache != null) {
+ cache.setChangeNotificationHandler(null);
+ }
+
super.onStop();
}
@@ -840,6 +863,19 @@ public class CacheDetailActivity extends AbstractActivity {
}
/**
+ * Tries to navigate to the {@link cgCache} of this activity.
+ */
+ private void startDefaultNavigation2() {
+ if (cache == null || cache.getCoords() == null) {
+ showToast(res.getString(R.string.err_location_unknown));
+ return;
+ }
+
+ //TODO: previously this used also the search argument "search". check if still needed
+ NavigationAppFactory.startDefaultNavigationApplication2(geolocation, this, cache, null, null);
+ }
+
+ /**
* Wrapper for the referenced method in the xml-layout.
*/
public void startDefaultNavigation(@SuppressWarnings("unused") View view) {
@@ -858,7 +894,7 @@ public class CacheDetailActivity extends AbstractActivity {
}
/**
- * Opens a dialog to do actions on an username
+ * Listener for clicks on username
*/
private class UserActionsClickListener implements View.OnClickListener {
@@ -871,36 +907,65 @@ public class CacheDetailActivity extends AbstractActivity {
}
clickedItemText = ((TextView) view).getText().toString();
+ showUserActionsDialog(clickedItemText);
+ }
+ }
- final CharSequence[] items = {res.getString(R.string.user_menu_view_hidden),
- res.getString(R.string.user_menu_view_found),
- res.getString(R.string.user_menu_open_browser)
- };
-
- AlertDialog.Builder builder = new AlertDialog.Builder(CacheDetailActivity.this);
- builder.setTitle(res.getString(R.string.user_menu_title) + " " + clickedItemText);
- builder.setItems(items, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int item) {
- switch (item) {
- case 0:
- cgeocaches.startActivityOwner(CacheDetailActivity.this, clickedItemText.toString());
- return;
- case 1:
- cgeocaches.startActivityUserName(CacheDetailActivity.this, clickedItemText.toString());
- return;
- case 2:
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(clickedItemText.toString()))));
- return;
- default:
- break;
- }
- }
- });
- AlertDialog alert = builder.create();
- alert.show();
+ /**
+ * Listener for clicks on owner name
+ */
+ private class OwnerActionsClickListener implements View.OnClickListener {
+
+ public void onClick(View view) {
+ if (view == null) {
+ return;
+ }
+ if (!cache.supportsUserActions()) {
+ return;
+ }
+
+ // Use real owner name vice the one owner chose to display
+ if (StringUtils.isNotBlank(cache.getOwnerReal())) {
+ clickedItemText = cache.getOwnerReal();
+ } else {
+ clickedItemText = ((TextView) view).getText().toString();
+ }
+ showUserActionsDialog(clickedItemText);
}
}
+ /**
+ * Opens a dialog to do actions on an username
+ */
+ private void showUserActionsDialog(final CharSequence name) {
+ final CharSequence[] items = { res.getString(R.string.user_menu_view_hidden),
+ res.getString(R.string.user_menu_view_found),
+ res.getString(R.string.user_menu_open_browser)
+ };
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(CacheDetailActivity.this);
+ builder.setTitle(res.getString(R.string.user_menu_title) + " " + name);
+ builder.setItems(items, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ switch (item) {
+ case 0:
+ cgeocaches.startActivityOwner(CacheDetailActivity.this, name.toString());
+ return;
+ case 1:
+ cgeocaches.startActivityUserName(CacheDetailActivity.this, name.toString());
+ return;
+ case 2:
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(name.toString()))));
+ return;
+ default:
+ break;
+ }
+ }
+ });
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+
public static void startActivity(final Context context, final String geocode) {
final Intent detailIntent = new Intent(context, CacheDetailActivity.class);
detailIntent.putExtra("geocode", geocode.toUpperCase());
@@ -1394,10 +1459,10 @@ public class CacheDetailActivity extends AbstractActivity {
TextView ownerView = addCacheDetail(R.string.cache_owner, "");
if (StringUtils.isNotBlank(cache.getOwner())) {
ownerView.setText(Html.fromHtml(cache.getOwner()), TextView.BufferType.SPANNABLE);
- } else if (StringUtils.isNotBlank(cache.getOwnerReal())) {
+ } else { // OwnerReal guaranteed to be not blank based on above
ownerView.setText(Html.fromHtml(cache.getOwnerReal()), TextView.BufferType.SPANNABLE);
}
- ownerView.setOnClickListener(new UserActionsClickListener());
+ ownerView.setOnClickListener(new OwnerActionsClickListener());
}
// cache hidden
diff --git a/main/src/cgeo/geocaching/GCConstants.java b/main/src/cgeo/geocaching/GCConstants.java
index fe8c74f..d884380 100644
--- a/main/src/cgeo/geocaching/GCConstants.java
+++ b/main/src/cgeo/geocaching/GCConstants.java
@@ -63,8 +63,8 @@ public final class GCConstants {
// Info box top-right
public static final Pattern PATTERN_LOGIN_NAME = Pattern.compile("\"SignedInProfileLink\">([^<]+)</a>");
public static final Pattern PATTERN_MEMBER_STATUS = Pattern.compile("<span id=\"ctl00_litPMLevel\" style=\"display: block;\">([^<]+)</span>");
- /** Use replaceAll(",","") on the resulting string before converting to an int */
- public static final Pattern PATTERN_CACHES_FOUND = Pattern.compile("title=\"Caches Found\"[\\s\\w=\"/\\.]*/>\\s*([\\d,]+)");
+ /** Use replaceAll("[,.]","") on the resulting string before converting to an int */
+ public static final Pattern PATTERN_CACHES_FOUND = Pattern.compile("title=\"Caches Found\"[\\s\\w=\"/.]*/>\\s*([\\d,.]+)");
public static final Pattern PATTERN_AVATAR_IMAGE_PROFILE_PAGE = Pattern.compile("<img src=\"(http://img.geocaching.com/user/avatar/[0-9a-f-]+\\.jpg)\"[^>]*\\salt=\"Avatar\"");
public static final Pattern PATTERN_LOGIN_NAME_LOGIN_PAGE = Pattern.compile("<span class=\"Success\">You are logged in as[^<]*<strong[^>]*>([^<]+)</strong>[^<]*</span>");
public static final Pattern PATTERN_CUSTOMDATE = Pattern.compile("<option selected=\"selected\" value=\"([ /Mdy-]+)\">");
@@ -92,6 +92,7 @@ public final class GCConstants {
public final static Pattern PATTERN_TRACKABLE_TYPE = Pattern.compile("<img id=\"ctl00_ContentBody_BugTypeImage\" class=\"TravelBugHeaderIcon\" src=\"[^\"]+\" alt=\"([^\"]+)\"[^>]*>");
public final static Pattern PATTERN_TRACKABLE_DISTANCE = Pattern.compile("<h4[^>]*\\W*Tracking History \\(([0-9.,]+(km|mi))[^\\)]*\\)");
public final static Pattern PATTERN_TRACKABLE_LOG = Pattern.compile("<tr class=\"Data.+?src=\"/images/icons/([^.]+)\\.gif[^>]+>&nbsp;([^<]+)</td>.+?guid.+?>([^<]+)</a>.+?(?:guid=([^\"]+)\">(<span class=\"Strike\">)?([^<]+)</.+?)?<td colspan=\"4\">(.+?)(?:<ul.+?ul>)?\\s*</td>\\s*</tr>");
+ public final static Pattern PATTERN_TRACKABLE_LOG_IMAGES = Pattern.compile(".+?<li><a href=\"([^\"]+)\".+?LogImgTitle.+?>([^<]+)</");
/**
* Patterns for parsing the result of a search (next)
@@ -135,11 +136,16 @@ public final class GCConstants {
public final static Pattern PATTERN_MAINTENANCE = Pattern.compile("<span id=\"ctl00_ContentBody_LogBookPanel1_lbConfirm\"[^>]*>([^<]*<font[^>]*>)?([^<]+)(</font>[^<]*)?</span>", Pattern.CASE_INSENSITIVE);
public final static Pattern PATTERN_OK1 = Pattern.compile("<h2[^>]*>[^<]*<span id=\"ctl00_ContentBody_lbHeading\"[^>]*>[^<]*</span>[^<]*</h2>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_OK2 = Pattern.compile("<div id=[\"|']ctl00_ContentBody_LogBookPanel1_ViewLogPanel[\"|']>", Pattern.CASE_INSENSITIVE);
- public final static Pattern PATTERN_USERTOKEN = Pattern.compile("var userToken[^=]*=[^']*'([^']+)';", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_VIEWSTATEFIELDCOUNT = Pattern.compile("id=\"__VIEWSTATEFIELDCOUNT\"[^(value)]+value=\"(\\d+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_VIEWSTATES = Pattern.compile("id=\"__VIEWSTATE(\\d*)\"[^(value)]+value=\"([^\"]+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
public final static Pattern PATTERN_USERTOKEN2 = Pattern.compile("userToken\\s*=\\s*'([^']+)'");
+ /**
+ * Patterns for GC and TB codes
+ */
+ public final static Pattern PATTERN_GC_CODE = Pattern.compile("GC[0-9A-Z]*", Pattern.CASE_INSENSITIVE);
+ public final static Pattern PATTERN_TB_CODE = Pattern.compile("TB[0-9A-Z]*", Pattern.CASE_INSENSITIVE);
+
/** Live Map since 14.02.2012 */
public final static Pattern PATTERN_USERSESSION = Pattern.compile("UserSession\\('([^']+)'");
public final static Pattern PATTERN_SESSIONTOKEN = Pattern.compile("sessionToken:'([^']+)'");
diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java
index 4f9a240..af1ad0a 100644
--- a/main/src/cgeo/geocaching/Settings.java
+++ b/main/src/cgeo/geocaching/Settings.java
@@ -76,6 +76,7 @@ public final class Settings {
private static final String KEY_LAST_DETAILS_PAGE = "lastdetailspage";
private static final String KEY_DEBUG_INFORMATIONS = "debuginfos";
private static final String KEY_DEFAULT_NAVIGATION_TOOL = "defaultNavigationTool";
+ private static final String KEY_DEFAULT_NAVIGATION_TOOL_2 = "defaultNavigationTool2";
private final static int unitsMetric = 1;
private final static int unitsImperial = 2;
@@ -999,4 +1000,18 @@ public final class Settings {
}
});
}
+
+ public static int getDefaultNavigationTool2() {
+ return sharedPrefs.getInt(KEY_DEFAULT_NAVIGATION_TOOL_2, 0);
+ }
+
+ public static void setDefaultNavigationTool2(final int defaultNavigationTool) {
+ editSharedSettings(new PrefRunnable() {
+
+ @Override
+ public void edit(Editor edit) {
+ edit.putInt(KEY_DEFAULT_NAVIGATION_TOOL_2, defaultNavigationTool);
+ }
+ });
+ }
}
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java
index 53240bc..e2a1fc1 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java
@@ -90,7 +90,7 @@ public final class NavigationAppFactory extends AbstractAppFactory {
/**
* Specialized way to handle selection of navigation tool.<br />
* A dialog is created for tool selection and the selected tool is started afterwards.
- *
+ *
* @param geo
* @param activity
* @param cache
@@ -103,7 +103,7 @@ public final class NavigationAppFactory extends AbstractAppFactory {
* should be <code>false</code> only when called from within the internal map
* @param showDefaultNavigation
* should be <code>false</code> by default
- *
+ *
* @see #showNavigationMenu(cgGeo, Activity, cgCache, cgWaypoint, Geopoint)
*/
public static void showNavigationMenu(final cgGeo geo, final Activity activity,
@@ -297,8 +297,31 @@ public final class NavigationAppFactory extends AbstractAppFactory {
}
/**
+ * 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,
+ cgWaypoint waypoint, final Geopoint destination) {
+ final NavigationApp app = getDefaultNavigationApplication2(activity);
+
+ if (app != null) {
+ try {
+ app.invoke(geo, activity, cache, waypoint, destination);
+ } catch (Exception e) {
+ Log.e(Settings.tag, "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>
*/
@@ -316,4 +339,24 @@ public final class NavigationAppFactory extends AbstractAppFactory {
return NavigationAppsEnum.COMPASS.app;
}
+ /**
+ * 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>
+ */
+ public static NavigationApp getDefaultNavigationApplication2(Activity activity) {
+ final int defaultNavigationTool = Settings.getDefaultNavigationTool2();
+
+ final List<NavigationAppsEnum> installedNavigationApps = getInstalledNavigationApps(activity);
+
+ for (NavigationAppsEnum navigationApp : installedNavigationApps) {
+ if (navigationApp.id == defaultNavigationTool) {
+ return navigationApp.app;
+ }
+ }
+ // second default navigation tool wasn't set already or couldn't be found (not installed any more for example)
+ return NavigationAppsEnum.COMPASS.app;
+ }
+
}
diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java
index b05577b..3b057a7 100644
--- a/main/src/cgeo/geocaching/cgBase.java
+++ b/main/src/cgeo/geocaching/cgBase.java
@@ -19,7 +19,6 @@ import cgeo.geocaching.gcvote.GCVoteRating;
import cgeo.geocaching.geopoint.DistanceParser;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter.Format;
-import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.HtmlImage;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.twitter.Twitter;
@@ -41,7 +40,6 @@ 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.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
@@ -79,7 +77,6 @@ import android.widget.LinearLayout;
import java.io.File;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -370,7 +367,7 @@ public class cgBase {
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(",", "")));
+ setActualCachesFound(Integer.parseInt(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "0").replaceAll("[,.]", "")));
return true;
}
@@ -695,101 +692,6 @@ public class cgBase {
return searchResult;
}
- // TODO Valentine Remove with merge
- @Deprecated
- public static SearchResult parseMapJSON(final String uri, final String data) {
- if (StringUtils.isEmpty(data)) {
- Log.e(Settings.tag, "cgeoBase.parseMapJSON: No page given");
- return null;
- }
-
- final SearchResult searchResult = new SearchResult();
- searchResult.setUrl(uri);
-
- try {
- final JSONObject yoDawg = new JSONObject(data);
- final String json = yoDawg.getString("d");
-
- if (StringUtils.isBlank(json)) {
- Log.e(Settings.tag, "cgeoBase.parseMapJSON: No JSON inside JSON");
- return null;
- }
-
- final JSONObject dataJSON = new JSONObject(json);
- final JSONObject extra = dataJSON.getJSONObject("cs");
- if (extra != null && extra.length() > 0) {
- int count = extra.getInt("count");
- // currently unused: 'pm', true for premium members
- // check login status
- boolean li = extra.getBoolean("li");
- if (!li) {
- searchResult.error = StatusCode.NOT_LOGGED_IN;
- }
-
- if (count > 0 && extra.has("cc")) {
- final JSONArray cachesData = extra.getJSONArray("cc");
- if (cachesData != null && cachesData.length() > 0) {
- JSONObject oneCache = null;
- for (int i = 0; i < count; i++) {
- oneCache = cachesData.getJSONObject(i);
- if (oneCache == null) {
- break;
- }
-
- final cgCache cacheToAdd = new cgCache();
- cacheToAdd.setDetailed(false);
- // coords are reliable if we are logged in
- cacheToAdd.setReliableLatLon(li);
- cacheToAdd.setGeocode(oneCache.getString("gc"));
- cacheToAdd.setCoords(new Geopoint(oneCache.getDouble("lat"), oneCache.getDouble("lon")));
- cacheToAdd.setName(oneCache.getString("nn"));
- cacheToAdd.setFound(oneCache.getBoolean("f"));
- cacheToAdd.setOwn(oneCache.getBoolean("o"));
- cacheToAdd.setDisabled(!oneCache.getBoolean("ia"));
- int ctid = oneCache.getInt("ctid");
- if (ctid == 2) {
- cacheToAdd.setType(CacheType.TRADITIONAL);
- } else if (ctid == 3) {
- cacheToAdd.setType(CacheType.MULTI);
- } else if (ctid == 4) {
- cacheToAdd.setType(CacheType.VIRTUAL);
- } else if (ctid == 5) {
- cacheToAdd.setType(CacheType.LETTERBOX);
- } else if (ctid == 6) {
- cacheToAdd.setType(CacheType.EVENT);
- } else if (ctid == 8) {
- cacheToAdd.setType(CacheType.MYSTERY);
- } else if (ctid == 11) {
- cacheToAdd.setType(CacheType.WEBCAM);
- } else if (ctid == 13) {
- cacheToAdd.setType(CacheType.CITO);
- } else if (ctid == 137) {
- cacheToAdd.setType(CacheType.EARTH);
- } else if (ctid == 453) {
- cacheToAdd.setType(CacheType.MEGA_EVENT);
- } else if (ctid == 1858) {
- cacheToAdd.setType(CacheType.WHERIGO);
- } else if (ctid == 3653) {
- cacheToAdd.setType(CacheType.LOSTANDFOUND);
- } else {
- cacheToAdd.setType(CacheType.UNKNOWN);
- }
-
- searchResult.addCache(cacheToAdd);
- }
- }
- } else {
- Log.w(Settings.tag, "There are no caches in viewport. Probably the viewport is too big");
- }
- searchResult.totalCnt = searchResult.getGeocodes().size();
- }
- } catch (Exception e) {
- Log.e(Settings.tag, "cgBase.parseMapJSON", e);
- }
-
- return searchResult;
- }
-
public static SearchResult parseCache(final String page, final int listId, final CancellableHandler handler) {
final SearchResult searchResult = parseCacheFromText(page, listId, handler);
if (searchResult != null && !searchResult.getGeocodes().isEmpty()) {
@@ -1426,7 +1328,7 @@ public class cgBase {
Settings.setMemberStatus(BaseUtils.getMatch(profile, GCConstants.PATTERN_MEMBER_STATUS, true, null));
- setActualCachesFound(Integer.parseInt(BaseUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll(",", "")));
+ setActualCachesFound(Integer.parseInt(BaseUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", "")));
final String avatarURL = BaseUtils.getMatch(profile, GCConstants.PATTERN_AVATAR_IMAGE_PROFILE_PAGE, false, null);
if (null != avatarURL) {
@@ -1598,11 +1500,26 @@ public class cgBase {
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");
+ Log.w(Settings.tag, "cgeoBase.parseCache: Failed to parse cache logs" + e.toString());
}
// trackingcode
@@ -1879,35 +1796,6 @@ public class cgBase {
return searchByAny(thread, cacheType, false, listId, showCaptcha, params);
}
- // TODO Valentine Remove with merge
- @Deprecated
- public static SearchResult searchByViewport(final String userToken, final Viewport viewport) {
-
- String page = null;
-
- final String params = "{\"dto\":{\"data\":{\"c\":1,\"m\":\"\",\"d\":\"" +
- viewport.getLatitudeMax() + "|" + viewport.getLatitudeMin() + "|" +
- viewport.getLongitudeMax() + "|" + viewport.getLongitudeMin() + "\"},\"ut\":\"" +
- StringUtils.defaultString(userToken) + "\"}}";
-
- final String uri = "http://www.geocaching.com/map/default.aspx/MapAction";
- page = requestJSONgc(uri, params);
-
- if (StringUtils.isBlank(page)) {
- Log.e(Settings.tag, "cgeoBase.searchByViewport: No data from server");
- return null;
- }
-
- final SearchResult searchResult = parseMapJSON(Uri.parse(uri).buildUpon().encodedQuery(params).build().toString(), page);
- if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) {
- Log.e(Settings.tag, "cgeoBase.searchByViewport: No cache parsed for viewport " + viewport);
- return null;
- }
-
- final SearchResult search = searchResult.filterSearchResults(Settings.isExcludeDisabledCaches(), Settings.isExcludeMyCaches(), Settings.getCacheType(), StoredList.TEMPORARY_LIST_ID);
- return search;
- }
-
/** Request .png image for a tile. Ignore the image - just load it */
public static void requestMapTile(final String url, final String referer) {
final HttpGet request = new HttpGet(url);
@@ -1928,24 +1816,6 @@ public class cgBase {
return getResponseData(request(request), false);
}
- // TODO Valentine Remove with merge
- @Deprecated
- public static String requestJSONgc(final String uri, final String params) {
- final HttpPost request = new HttpPost("http://www.geocaching.com/map/default.aspx/MapAction");
- try {
- request.setEntity(new StringEntity(params, HTTP.UTF_8));
- } catch (UnsupportedEncodingException e) {
- Log.e(Settings.tag, "cgeoBase.searchByViewport", e);
- }
-
- request.addHeader("Content-Type", "application/json; charset=UTF-8");
- request.addHeader("X-Requested-With", "XMLHttpRequest");
- request.addHeader("Accept", "application/json, text/javascript, */*; q=0.01");
- request.addHeader("Referer", uri);
- String page = getResponseData(request(request));
- return page;
- }
-
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");
@@ -2917,29 +2787,6 @@ public class cgBase {
return false;
}
- // TODO Valentine Remove with merge
- @Deprecated
- public static String getMapUserToken(final Handler noTokenHandler) {
- final HttpResponse response = request("http://www.geocaching.com/map/default.aspx", null, false);
- final String data = getResponseData(response);
- String usertoken = null;
-
- if (StringUtils.isNotBlank(data)) {
- final Matcher matcher = GCConstants.PATTERN_USERTOKEN.matcher(data);
- while (matcher.find()) {
- if (matcher.groupCount() > 0) {
- usertoken = matcher.group(1);
- }
- }
- }
-
- if (noTokenHandler != null && StringUtils.isBlank(usertoken)) {
- noTokenHandler.sendEmptyMessage(0);
- }
-
- return usertoken;
- }
-
public static Double getElevation(final Geopoint coords) {
try {
final String uri = "http://maps.googleapis.com/maps/api/elevation/json";
diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/cgCache.java
index de3680e..f49dffe 100644
--- a/main/src/cgeo/geocaching/cgCache.java
+++ b/main/src/cgeo/geocaching/cgCache.java
@@ -24,6 +24,7 @@ import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
+import android.os.Handler;
import android.text.Spannable;
import android.util.Log;
@@ -102,6 +103,20 @@ public class cgCache implements ICache {
private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");
+ private Handler changeNotificationHandler = null;
+
+ public void setChangeNotificationHandler(Handler newNotificationHandler) {
+ changeNotificationHandler = newNotificationHandler;
+ }
+
+ /**
+ * Sends a change notification to interested parties
+ */
+ private void notifyChange() {
+ if (changeNotificationHandler != null)
+ changeNotificationHandler.sendEmptyMessage(0);
+ }
+
/**
* Gather missing information from another cache object.
*
@@ -254,7 +269,13 @@ public class cgCache implements ICache {
reliableLatLon = other.reliableLatLon;
}
- return isEqualTo(other);
+ boolean isEqual = isEqualTo(other);
+
+ if (!isEqual) {
+ notifyChange();
+ }
+
+ return isEqual;
}
/**
@@ -414,6 +435,8 @@ public class cgCache implements ICache {
cgeoapplication app = (cgeoapplication) ((Activity) fromActivity).getApplication();
final boolean status = app.saveLogOffline(geocode, date.getTime(), logType, log);
+ notifyChange();
+
Resources res = ((Activity) fromActivity).getResources();
if (status) {
fromActivity.showToast(res.getString(R.string.info_log_saved));
diff --git a/main/src/cgeo/geocaching/cgeo.java b/main/src/cgeo/geocaching/cgeo.java
index c012f3a..91cfaf7 100644
--- a/main/src/cgeo/geocaching/cgeo.java
+++ b/main/src/cgeo/geocaching/cgeo.java
@@ -15,6 +15,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import android.app.AlertDialog;
+import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -52,6 +53,8 @@ public class cgeo extends AbstractActivity {
private static final int SCAN_REQUEST_CODE = 1;
private static final int MENU_OPEN_LIST = 100;
+ public static final int SEARCH_REQUEST_CODE = 2;
+
private int version = 0;
private cgGeo geo = null;
private UpdateLocationCallback geoUpdate = null;
@@ -306,17 +309,29 @@ public class cgeo extends AbstractActivity {
if (StringUtils.isBlank(scan)) {
return;
}
- String host = "http://coord.info/";
- if (scan.toLowerCase().startsWith(host)) {
- String geocode = scan.substring(host.length()).trim();
- CacheDetailActivity.startActivity(this, geocode);
- }
- else {
- showToast(res.getString(R.string.unknown_scan));
- }
+
+ Intent searchIntent = new Intent(this, cgeoadvsearch.class);
+ searchIntent.setAction(Intent.ACTION_SEARCH).
+ putExtra(SearchManager.QUERY, scan).
+ putExtra(cgeoadvsearch.EXTRAS_KEYWORDSEARCH, false);
+ startActivityForResult(searchIntent, SEARCH_REQUEST_CODE);
+
} else if (resultCode == RESULT_CANCELED) {
// do nothing
}
+ } else if (requestCode == SEARCH_REQUEST_CODE) {
+ // cgeoadvsearch activity returned without making a search
+ if (resultCode == RESULT_CANCELED) {
+ String query = intent.getStringExtra(SearchManager.QUERY);
+ if (query == null) {
+ query = "";
+ }
+ new AlertDialog.Builder(this)
+ .setMessage(res.getString(R.string.unknown_scan) + "\n\n" + query)
+ .setPositiveButton(getString(android.R.string.ok), null)
+ .create()
+ .show();
+ }
}
}
diff --git a/main/src/cgeo/geocaching/cgeoadvsearch.java b/main/src/cgeo/geocaching/cgeoadvsearch.java
index 754cbdb..7256bb3 100644
--- a/main/src/cgeo/geocaching/cgeoadvsearch.java
+++ b/main/src/cgeo/geocaching/cgeoadvsearch.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.activity.AbstractActivity;
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 org.apache.commons.lang3.StringUtils;
@@ -22,10 +23,10 @@ import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
-import java.util.regex.Pattern;
-
public class cgeoadvsearch extends AbstractActivity {
+ 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();
@@ -48,13 +49,17 @@ public class cgeoadvsearch extends AbstractActivity {
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
final String query = intent.getStringExtra(SearchManager.QUERY);
- final boolean found = instantSearch(query);
-
- if (found) {
- finish();
+ final boolean keywordSearch = intent.getBooleanExtra(EXTRAS_KEYWORDSEARCH, true);
- return;
+ if (instantSearch(query, keywordSearch)) {
+ setResult(RESULT_OK);
+ } else {
+ // send intent back so query string is known
+ setResult(RESULT_CANCELED, intent);
}
+ finish();
+
+ return;
}
setTheme();
@@ -105,28 +110,39 @@ public class cgeoadvsearch extends AbstractActivity {
super.onPause();
}
- private boolean instantSearch(final String queryIn) {
- final String query = queryIn.trim();
-
+ /**
+ * Performs a search for query either as geocode, trackable code or keyword
+ *
+ * @param query
+ * String to search for
+ * @param keywordSearch
+ * Set to true if keyword search should be performed if query isn't GC or TB
+ * @return true if a search was performed, else false
+ */
+ private boolean instantSearch(final String query, final boolean keywordSearch) {
try {
- final Pattern gcCode = Pattern.compile("^GC[0-9A-Z]+$", Pattern.CASE_INSENSITIVE);
- if (gcCode.matcher(query).find()) { // GC-code
+ 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", query.toUpperCase());
+ cachesIntent.putExtra("geocode", result.toUpperCase());
startActivity(cachesIntent);
return true;
} else {
- final Pattern tbCode = Pattern.compile("^TB[0-9A-Z]+$", Pattern.CASE_INSENSITIVE);
- if (tbCode.matcher(query).find()) { // TB-code
+ 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", query.toUpperCase());
+ trackablesIntent.putExtra("geocode", result.toUpperCase());
startActivity(trackablesIntent);
+
return true;
- } else { // keyword (fallback)
- cgeocaches.startActivityKeyword(this, query);
+ } else if (keywordSearch) { // keyword fallback, if desired by caller
+ cgeocaches.startActivityKeyword(this, query.trim());
return true;
+ } else {
+ return false;
}
+
}
} catch (Exception e) {
Log.w(Settings.tag, "cgeoadvsearch.instantSearch: " + e.toString());
diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java
index a7fe4ec..e6978ce 100644
--- a/main/src/cgeo/geocaching/cgeocaches.java
+++ b/main/src/cgeo/geocaching/cgeocaches.java
@@ -8,7 +8,6 @@ import cgeo.geocaching.apps.cachelist.CacheListAppFactory;
import cgeo.geocaching.enumerations.CacheListType;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
-import cgeo.geocaching.enumerations.LoadFlags.LoadFlag;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.files.GPXImporter;
@@ -79,7 +78,6 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -175,9 +173,7 @@ public class cgeocaches extends AbstractListActivity {
setTitle(title + " [" + search.getCount() + "]");
cacheList.clear();
- EnumSet<LoadFlag> loadFlags = LoadFlags.LOAD_CACHE_OR_DB;
- loadFlags.add(LoadFlag.LOAD_OFFLINE_LOG);
- final Set<cgCache> caches = search.getCachesFromSearchResult(loadFlags);
+ final Set<cgCache> caches = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB);
if (CollectionUtils.isNotEmpty(caches)) {
cacheList.addAll(caches);
Collections.sort(cacheList, gcComparator);
@@ -566,7 +562,13 @@ public class cgeocaches extends AbstractListActivity {
title = res.getString(R.string.stored_caches_button);
} else {
final StoredList list = app.getList(listId);
- title = list.title;
+ // Check if list id is still valid
+ if (null == list) {
+ listId = StoredList.STANDARD_LIST_ID;
+ title = res.getString(R.string.stored_caches_button);
+ } else {
+ title = list.title;
+ }
}
setTitle(title);
@@ -1800,7 +1802,7 @@ public class cgeocaches extends AbstractListActivity {
@Override
public void run() {
- search = cgBase.searchByCoords(this, coords, cacheType, 0, Settings.isShowCaptcha());
+ search = cgBase.searchByCoords(this, coords, cacheType, StoredList.TEMPORARY_LIST_ID, Settings.isShowCaptcha());
handler.sendMessage(new Message());
}
diff --git a/main/src/cgeo/geocaching/cgeoinit.java b/main/src/cgeo/geocaching/cgeoinit.java
index 5a601ac..0839f46 100644
--- a/main/src/cgeo/geocaching/cgeoinit.java
+++ b/main/src/cgeo/geocaching/cgeoinit.java
@@ -619,6 +619,50 @@ public class cgeoinit extends AbstractActivity {
}
});
+ // 2nd Default navigation tool settings
+ Spinner defaultNavigationTool2Selector = (Spinner) findViewById(R.id.default_navigation_tool_2);
+ // final List<NavigationAppsEnum> apps = NavigationAppFactory.getInstalledNavigationApps(this);
+ ArrayAdapter<NavigationAppsEnum> navi2Adapter = new ArrayAdapter<NavigationAppsEnum>(this, android.R.layout.simple_spinner_item, apps) {
+ @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;
+ }
+ };
+ navi2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ defaultNavigationTool2Selector.setAdapter(navi2Adapter);
+ int defaultNavigationTool2 = Settings.getDefaultNavigationTool2();
+ int ordinal2 = 0;
+ for (int i = 0; i < apps.size(); i++) {
+ if (apps.get(i).id == defaultNavigationTool2) {
+ ordinal2 = i;
+ break;
+ }
+ }
+ defaultNavigationTool2Selector.setSelection(ordinal2);
+ defaultNavigationTool2Selector.setOnItemSelectedListener(new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ NavigationAppsEnum item = (NavigationAppsEnum) parent.getItemAtPosition(position);
+ if (item != null) {
+ Settings.setDefaultNavigationTool2(item.id);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> arg0) {
+ // noop
+ }
+ });
+
refreshBackupLabel();
}
diff --git a/main/src/cgeo/geocaching/cgeopopup.java b/main/src/cgeo/geocaching/cgeopopup.java
index 0d6195d..4898a40 100644
--- a/main/src/cgeo/geocaching/cgeopopup.java
+++ b/main/src/cgeo/geocaching/cgeopopup.java
@@ -26,6 +26,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -128,6 +129,16 @@ public class cgeopopup extends AbstractActivity {
finish();
return;
}
+
+ ImageView defaultNavigationImageView = (ImageView) findViewById(R.id.defaultNavigation);
+ defaultNavigationImageView.setOnLongClickListener(new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ startDefaultNavigation2();
+ return true;
+ }
+ });
+
}
@Override
@@ -632,6 +643,18 @@ public class cgeopopup extends AbstractActivity {
finish();
}
+ /**
+ * Tries to navigate to the {@link cgCache} of this activity.
+ */
+ private void startDefaultNavigation2() {
+ if (cache == null || cache.getCoords() == null) {
+ showToast(res.getString(R.string.cache_coordinates_no));
+ return;
+ }
+ NavigationAppFactory.startDefaultNavigationApplication2(geo, this, cache, null, null);
+ finish();
+ }
+
@Override
public void goManual(View view) {
super.goManual(view);
diff --git a/main/src/cgeo/geocaching/cgeotrackable.java b/main/src/cgeo/geocaching/cgeotrackable.java
index e40e04f..db533ce 100644
--- a/main/src/cgeo/geocaching/cgeotrackable.java
+++ b/main/src/cgeo/geocaching/cgeotrackable.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.geopoint.HumanDistance;
import cgeo.geocaching.network.HtmlImage;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import android.app.ProgressDialog;
@@ -28,6 +29,7 @@ import android.widget.ScrollView;
import android.widget.TextView;
import java.net.URLEncoder;
+import java.util.ArrayList;
import java.util.Arrays;
public class cgeotrackable extends AbstractActivity {
@@ -441,7 +443,7 @@ public class cgeotrackable extends AbstractActivity {
if (trackable != null && trackable.getLogs() != null) {
for (cgLog log : trackable.getLogs()) {
- rowView = (RelativeLayout) inflater.inflate(R.layout.trackable_logitem, null);
+ 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));
@@ -468,7 +470,39 @@ public class cgeotrackable extends AbstractActivity {
TextView logView = (TextView) rowView.findViewById(R.id.log);
logView.setMovementMethod(LinkMovementMethod.getInstance());
- logView.setText(Html.fromHtml(log.log, new HtmlImage(cgeotrackable.this, null, false, 0, false), null), TextView.BufferType.SPANNABLE);
+ logView.setText(Html.fromHtml(log.log, new HtmlImage(cgeotrackable.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)) {
+
+ final ArrayList<cgImage> logImages = new ArrayList<cgImage>(log.logImages);
+
+ final View.OnClickListener listener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ cgeoimages.startActivityLogImages(cgeotrackable.this, trackable.getGeocode(), logImages);
+ }
+ };
+
+ 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();
+ if (!StringUtils.isBlank(img_title)) {
+ titles.add(img_title);
+ }
+ }
+ if (titles.isEmpty()) {
+ titles.add(res.getString(R.string.cache_log_image_default_title));
+ }
+
+ LinearLayout log_imgView = (LinearLayout) getLayoutInflater().inflate(R.layout.trackable_logs_img, null);
+ TextView log_img_title = (TextView) log_imgView.findViewById(R.id.title);
+ log_img_title.setText(StringUtils.join(titles.toArray(new String[titles.size()]), ", "));
+ log_img_title.setOnClickListener(listener);
+ logLayout.addView(log_imgView);
+ }
((TextView) rowView.findViewById(R.id.author)).setOnClickListener(new userActions());
listView.addView(rowView);
diff --git a/main/src/cgeo/geocaching/cgeowaypoint.java b/main/src/cgeo/geocaching/cgeowaypoint.java
index 84eac46..7fbf14a 100644
--- a/main/src/cgeo/geocaching/cgeowaypoint.java
+++ b/main/src/cgeo/geocaching/cgeowaypoint.java
@@ -18,6 +18,7 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
@@ -54,7 +55,7 @@ public class cgeowaypoint extends AbstractActivity {
} else {
final TextView identification = (TextView) findViewById(R.id.identification);
final TextView coords = (TextView) findViewById(R.id.coordinates);
- final ImageView compass = (ImageView) findViewById(R.id.compass);
+ final ImageView defaultNavigation = (ImageView) findViewById(R.id.defaultNavigation);
final View separator = findViewById(R.id.separator);
final View headline = findViewById(R.id.headline);
@@ -76,11 +77,11 @@ public class cgeowaypoint extends AbstractActivity {
if (waypoint.getCoords() != null) {
coords.setText(Html.fromHtml(waypoint.getCoords().toString()), TextView.BufferType.SPANNABLE);
- compass.setVisibility(View.VISIBLE);
+ defaultNavigation.setVisibility(View.VISIBLE);
separator.setVisibility(View.VISIBLE);
} else {
coords.setText(res.getString(R.string.waypoint_unknown_coordinates));
- compass.setVisibility(View.GONE);
+ defaultNavigation.setVisibility(View.GONE);
separator.setVisibility(View.GONE);
}
registerNavigationMenu(coords);
@@ -163,6 +164,15 @@ public class cgeowaypoint extends AbstractActivity {
waitDialog.setCancelable(true);
(new loadWaypoint()).start();
+
+ ImageView defaultNavigationImageView = (ImageView) findViewById(R.id.defaultNavigation);
+ defaultNavigationImageView.setOnLongClickListener(new OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ startDefaultNavigation2();
+ return true;
+ }
+ });
}
@Override
@@ -341,6 +351,17 @@ public class cgeowaypoint extends AbstractActivity {
NavigationAppFactory.startDefaultNavigationApplication(geo, this, null, waypoint, null);
}
+ /**
+ * Tries to navigate to the {@link cgCache} of this activity.
+ */
+ private void startDefaultNavigation2() {
+ if (!navigationPossible()) {
+ return;
+ }
+
+ NavigationAppFactory.startDefaultNavigationApplication2(geo, this, null, waypoint, null);
+ }
+
private boolean navigationPossible() {
if (waypoint == null || waypoint.getCoords() == null) {
showToast(res.getString(R.string.err_location_unknown));
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java
index 3c0076a..ceaad5e 100644
--- a/main/src/cgeo/geocaching/connector/AbstractConnector.java
+++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.SearchResult;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.utils.CancellableHandler;
public abstract class AbstractConnector implements IConnector {
@@ -53,6 +54,10 @@ public abstract class AbstractConnector implements IConnector {
return null;
}
+ public SearchResult searchByViewport(Viewport viewport, String tokens[]) {
+ return null;
+ }
+
protected static boolean isNumericId(final String string) {
try {
return Integer.parseInt(string) > 0;
@@ -72,4 +77,9 @@ public abstract class AbstractConnector implements IConnector {
// let every cache have reliable coordinates by default
return true;
}
+
+ @Override
+ public String[] getTokens() {
+ return null;
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
index 39e6dee..471d43b 100644
--- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java
+++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
@@ -1,8 +1,11 @@
package cgeo.geocaching.connector;
import cgeo.geocaching.ICache;
+import cgeo.geocaching.SearchResult;
import cgeo.geocaching.connector.opencaching.ApiOpenCachingConnector;
import cgeo.geocaching.connector.opencaching.OpenCachingConnector;
+import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
import org.apache.commons.lang3.StringUtils;
@@ -62,4 +65,19 @@ public final class ConnectorFactory {
private static boolean isInvalidGeocode(final String geocode) {
return StringUtils.isBlank(geocode) || !Character.isLetterOrDigit(geocode.charAt(0));
}
+
+ /** @see IConnector#searchByCoordinate */
+ public static SearchResult searchByCoordinate(final Geopoint center) {
+ // We have only connector capable of doing a 'searchByCoordinate()'
+ // If there is a second connector the information has to be collected from all collectors
+ return GCConnector.getInstance().searchByCoordinate(center);
+ }
+
+ /** @see IConnector#searchByViewport */
+ public static SearchResult searchByViewport(final Viewport viewport, final String[] tokens) {
+ // We have only connector capable of doing a 'searchByViewport()'
+ // If there is a second connector the information has to be collected from all collectors
+ return GCConnector.getInstance().searchByViewport(viewport, tokens);
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/GCConnector.java b/main/src/cgeo/geocaching/connector/GCConnector.java
index 2d6e67b..6b44f82 100644
--- a/main/src/cgeo/geocaching/connector/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/GCConnector.java
@@ -7,7 +7,10 @@ import cgeo.geocaching.Settings;
import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.connector.gc.GCBase;
import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.CancellableHandler;
@@ -133,6 +136,17 @@ public class GCConnector extends AbstractConnector {
}
@Override
+ public SearchResult searchByCoordinate(Geopoint center) {
+ // TODO Auto-generated method stub
+ return super.searchByCoordinate(center);
+ }
+
+ @Override
+ public SearchResult searchByViewport(Viewport viewport, String[] tokens) {
+ return GCBase.searchByViewport(viewport, tokens);
+ }
+
+ @Override
public boolean isZippedGPXFile(final String fileName) {
return gpxZipFilePattern.matcher(fileName).matches();
}
@@ -141,4 +155,9 @@ public class GCConnector extends AbstractConnector {
public boolean isReliableLatLon(boolean cacheHasReliableLatLon) {
return cacheHasReliableLatLon;
}
+
+ @Override
+ public String[] getTokens() {
+ return GCBase.getTokens();
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java
index 21cdb75..bc772c9 100644
--- a/main/src/cgeo/geocaching/connector/IConnector.java
+++ b/main/src/cgeo/geocaching/connector/IConnector.java
@@ -4,6 +4,7 @@ import cgeo.geocaching.SearchResult;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.utils.CancellableHandler;
public interface IConnector {
@@ -86,6 +87,15 @@ public interface IConnector {
public SearchResult searchByCoordinate(final Geopoint center);
/**
+ * Search caches by viewport.
+ *
+ * @param viewport
+ * @param tokens
+ * @return
+ */
+ public SearchResult searchByViewport(final Viewport viewport, final String[] tokens);
+
+ /**
* return true if this is a ZIP file containing a GPX file
*
* @param fileName
@@ -101,4 +111,12 @@ public interface IConnector {
* @return
*/
public boolean isReliableLatLon(boolean cacheHasReliableLatLon);
+
+ /**
+ * Return required tokens for specific following actions
+ *
+ * @return
+ */
+ public String[] getTokens();
+
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCBase.java b/main/src/cgeo/geocaching/connector/gc/GCBase.java
index 72f5d55..eb7603b 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCBase.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCBase.java
@@ -3,6 +3,7 @@ package cgeo.geocaching.connector.gc;
import cgeo.geocaching.GCConstants;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
+import cgeo.geocaching.StoredList;
import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.enumerations.CacheType;
@@ -41,7 +42,6 @@ public class GCBase {
private static final LeastRecentlyUsedCache<String, cgCache> liveMapCache = new LeastRecentlyUsedCache<String, cgCache>(2000); // JSON id, cache
- // TODO Valentine move to connector before merge
/**
* @param viewport
* @param zoomlevel
@@ -54,6 +54,8 @@ public class GCBase {
@SuppressWarnings("null")
public static SearchResult searchByViewport(final Viewport viewport, final String[] tokens) {
+ Log.d(Settings.tag, "GCBase.searchByViewport" + viewport.toString());
+
String referer = GCConstants.URL_LIVE_MAP;
final SearchResult searchResult = new SearchResult();
@@ -66,28 +68,24 @@ public class GCBase {
"?x=" + tile.getX() + // x tile
"&y=" + tile.getY() + // y tile
"&z=" + tile.getZoomlevel(); // zoom level
- /*
- * if (tokens != null) {
- * url += "&k=" + tokens[0]; // user session
- * url += "&st=" + tokens[1]; // session token
- * }
- * url += "&ep=1";
- * /*
- * if (true || Settings.isExcludeMyCaches()) {
- * url += "&hf=1"; // hide found
- * url += "&hh=1"; // hide hidden
- * }
- *
- * if (Settings.getCacheType() == CacheType.TRADITIONAL) {
- * url += "&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 += "&ect=9,5,2,6,453,13,1304,137,11,4,8,1858";
- * }
- * if (Settings.getCacheType() == CacheType.MYSTERY) {
- * url += "&ect=9,5,3,6,453,13,1304,137,11,4,2,1858";
- * }
- */
+ if (tokens != null) {
+ url += "&k=" + tokens[0]; // user session
+ url += "&st=" + tokens[1]; // session token
+ }
+ url += "&ep=1";
+ if (Settings.isExcludeMyCaches()) {
+ url += "&hf=1"; // hide found
+ url += "&hh=1"; // hide hidden
+ }
+ if (Settings.getCacheType() == CacheType.TRADITIONAL) {
+ url += "&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 += "&ect=9,5,2,6,453,13,1304,137,11,4,8,1858";
+ }
+ if (Settings.getCacheType() == CacheType.MYSTERY) {
+ url += "&ect=9,5,3,6,453,13,1304,137,11,4,2,1858";
+ }
if (tile.getZoomlevel() != 14) {
url += "&_=" + String.valueOf(System.currentTimeMillis());
}
@@ -107,6 +105,11 @@ public class GCBase {
}
}
+ if (Settings.isPremiumMember()) {
+ SearchResult search = cgBase.searchByCoords(null, viewport.getCenter(), Settings.getCacheType(), StoredList.TEMPORARY_LIST_ID, Settings.isShowCaptcha());
+ searchResult.addGeocodes(search.getGeocodes());
+ }
+
return searchResult;
}
@@ -149,7 +152,9 @@ public class GCBase {
}
/*
- * // Optimization: the grid can get ignored. The keys are the grid position in the format x_y
+ * Optimization: the grid can get ignored. The keys are the grid position in the format x_y
+ * It's not used at the moment due to optimizations
+ * But maybe we need it some day...
*
* // attach all keys with the cache positions in the tile
* Map<String, UTFGridPosition> keyPositions = new HashMap<String, UTFGridPosition>(); // JSON key, (x/y) in
@@ -239,7 +244,9 @@ public class GCBase {
*/
protected static List<Tile> getTilesForViewport(final Viewport viewport) {
List<Tile> tiles = new ArrayList<Tile>();
- tiles.add(new Tile(viewport.getCenter(), 14)); // precise coords for caches nearby
+ if (!Settings.isPremiumMember()) {
+ tiles.add(new Tile(viewport.getCenter(), 14)); // precise coords for caches nearby
+ }
tiles.add(new Tile(viewport.getCenter(), 12)); // other caches around
return tiles;
}
@@ -340,21 +347,6 @@ public class GCBase {
return GCBase.gcidToGCCode(gcid);
}
- // TODO Valentine
- /** Request further details in the live mapa for a given id */
- public void requestDetailsFromMap(@SuppressWarnings("unused") String id) {
- /**
- * URL http://www.geocaching.com/map/map.details?i=gEaR
- * Response: {"status":"success","data":[{"name":"Spiel & Sport","gc":"GC211WG","g":
- * "872d7eda-7cb9-40d5-890d-5b344bce7302"
- * ,"disabled":false,"subrOnly":false,"li":false,"fp":"0","difficulty":{"text"
- * :3.0,"value":"3"},"terrain":{"text"
- * :2.0,"value":"2"},"hidden":"11/15/2009","container":{"text":"Regular","value"
- * :"regular.gif"},"type":{"text":"Multi-cache"
- * ,"value":3},"owner":{"text":"kai2707","value":"5c4b0915-5cec-4fa1-8afd-4b3ca67e004e"}}]}
- */
- }
-
/** Get user session & session token from the Live Map. Needed for following requests */
public static String[] getTokens() {
final HttpResponse response = cgBase.request(GCConstants.URL_LIVE_MAP, null, false);
diff --git a/main/src/cgeo/geocaching/connector/gc/UTFGrid.java b/main/src/cgeo/geocaching/connector/gc/UTFGrid.java
index 17f61da..cf490ec 100644
--- a/main/src/cgeo/geocaching/connector/gc/UTFGrid.java
+++ b/main/src/cgeo/geocaching/connector/gc/UTFGrid.java
@@ -12,7 +12,11 @@ public final class UTFGrid {
public static final int GRID_MAXX = 63;
public static final int GRID_MAXY = 63;
- /** Convert a value from a JSON grid object into an id that can be used as an index */
+ /**
+ * Convert a value from a JSON grid object into an id that can be used as an index
+ * It's not used at the moment due to optimizations.
+ * But maybe we need it some day...
+ */
public static short getUTFGridId(final char value) {
short result = (short) value;
if (result >= 93) {
diff --git a/main/src/cgeo/geocaching/enumerations/CacheSize.java b/main/src/cgeo/geocaching/enumerations/CacheSize.java
index c0de75b..9b0a559 100644
--- a/main/src/cgeo/geocaching/enumerations/CacheSize.java
+++ b/main/src/cgeo/geocaching/enumerations/CacheSize.java
@@ -20,7 +20,7 @@ public enum CacheSize {
VIRTUAL("virtual", 0, R.string.cache_size_virtual),
NOT_CHOSEN("not chosen", 0, R.string.cache_size_notchosen),
OTHER("other", 0, R.string.cache_size_other),
- UNKNOWN("unknown", 0, R.string.err_unknown); // CacheSize not init. yet
+ UNKNOWN("unknown", 0, R.string.cache_size_unknown); // CacheSize not init. yet
public final String id;
public final int comparable;
diff --git a/main/src/cgeo/geocaching/enumerations/LoadFlags.java b/main/src/cgeo/geocaching/enumerations/LoadFlags.java
index ac1e168..e55a4fc 100644
--- a/main/src/cgeo/geocaching/enumerations/LoadFlags.java
+++ b/main/src/cgeo/geocaching/enumerations/LoadFlags.java
@@ -24,9 +24,9 @@ public class LoadFlags {
/** Retrieve cache from CacheCache only. Do not load from DB */
public final static EnumSet<LoadFlag> LOAD_CACHE_ONLY = EnumSet.of(LoadFlag.LOAD_CACHE_BEFORE);
/** Retrieve cache from CacheCache first. If not found load from DB */
- public final static EnumSet<LoadFlag> LOAD_CACHE_OR_DB = EnumSet.of(LoadFlag.LOAD_CACHE_BEFORE, LoadFlag.LOAD_DB_MINIMAL);
+ public final static EnumSet<LoadFlag> LOAD_CACHE_OR_DB = EnumSet.of(LoadFlag.LOAD_CACHE_BEFORE, LoadFlag.LOAD_DB_MINIMAL, LoadFlag.LOAD_OFFLINE_LOG);
/** Retrieve cache (minimalistic information including waypoints) from DB first. If not found load from CacheCache */
- public final static EnumSet<LoadFlag> LOAD_WAYPOINTS = EnumSet.of(LoadFlag.LOAD_CACHE_AFTER, LoadFlag.LOAD_DB_MINIMAL, LoadFlag.LOAD_WAYPOINTS);
+ public final static EnumSet<LoadFlag> LOAD_WAYPOINTS = EnumSet.of(LoadFlag.LOAD_CACHE_AFTER, LoadFlag.LOAD_DB_MINIMAL, LoadFlag.LOAD_WAYPOINTS, LoadFlag.LOAD_OFFLINE_LOG);
/** Retrieve cache (all stored informations) from DB only. Do not load from CacheCache */
public final static EnumSet<LoadFlag> LOAD_ALL_DB_ONLY = EnumSet.range(LoadFlag.LOAD_DB_MINIMAL, LoadFlag.LOAD_OFFLINE_LOG);
diff --git a/main/src/cgeo/geocaching/filter/SizeFilter.java b/main/src/cgeo/geocaching/filter/SizeFilter.java
index 638a7c9..4f0d830 100644
--- a/main/src/cgeo/geocaching/filter/SizeFilter.java
+++ b/main/src/cgeo/geocaching/filter/SizeFilter.java
@@ -3,6 +3,8 @@ package cgeo.geocaching.filter;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.enumerations.CacheSize;
+import java.util.ArrayList;
+
public class SizeFilter extends AbstractFilter {
private final CacheSize cacheSize;
@@ -23,10 +25,12 @@ public class SizeFilter extends AbstractFilter {
public static AbstractFilter[] getAllFilters() {
final CacheSize[] cacheSizes = CacheSize.values();
- SizeFilter[] filters = new SizeFilter[cacheSizes.length];
- for (int i = 0; i < cacheSizes.length; i++) {
- filters[i] = new SizeFilter(cacheSizes[i]);
+ ArrayList<SizeFilter> filters = new ArrayList<SizeFilter>();
+ for (CacheSize cacheSize : cacheSizes) {
+ if (cacheSize != CacheSize.UNKNOWN) {
+ filters.add(new SizeFilter(cacheSize));
+ }
}
- return filters;
+ return filters.toArray(new SizeFilter[filters.size()]);
}
}
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index 434eb05..0038807 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -15,6 +15,7 @@ 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.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
@@ -1266,8 +1267,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
}
if (tokens == null) {
- // token = cgBase.getMapUserToken(noMapTokenHandler);
tokens = GCBase.getTokens();
+ if (noMapTokenHandler != null && tokens == null) {
+ noMapTokenHandler.sendEmptyMessage(0);
+ }
}
if (stop) {
@@ -1276,7 +1279,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
final Viewport viewport = new Viewport(new Geopoint(latMin, lonMin), new Geopoint(latMax, lonMax));
// search = cgBase.searchByViewport(token, viewport);
- search = GCBase.searchByViewport(viewport, tokens);
+ search = ConnectorFactory.searchByViewport(viewport, tokens);
if (search != null) {
downloaded = true;
if (search.error == StatusCode.NOT_LOGGED_IN) {
@@ -1846,12 +1849,13 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
int hashcode = new HashCodeBuilder()
.append(cache.isReliableLatLon())
.append(cache.getType().id)
- .append(cache.isDisabled())
+ .append(cache.isDisabled() || cache.isArchived())
.append(cache.isOwn())
.append(cache.isFound())
.append(cache.hasUserModifiedCoords())
.append(cache.getPersonalNote())
.append(cache.isLogOffline())
+ .append(cache.getListId() > 0)
.toHashCode();
LayerDrawable ldFromCache = CGeoMap.overlaysCache.get(hashcode);
@@ -1866,7 +1870,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
// background: disabled or not
Drawable marker = getResources().getDrawable(R.drawable.marker);
- if (cache.isDisabled()) {
+ if (cache.isDisabled() || cache.isArchived()) {
marker = getResources().getDrawable(R.drawable.marker_disabled);
}
layers.add(marker);
@@ -1883,6 +1887,10 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
if ( cache.isOwn() ) {
layers.add(getResources().getDrawable(R.drawable.marker_own));
insets.add(INSET_OWN[resolution]);
+ // if not, checked if stored
+ } else if (cache.getListId() > 0) {
+ layers.add(getResources().getDrawable(R.drawable.marker_stored));
+ insets.add(INSET_OWN[resolution]);
}
// found
if (cache.isFound()) {
diff --git a/main/src/cgeo/geocaching/utils/BaseUtils.java b/main/src/cgeo/geocaching/utils/BaseUtils.java
index 0d5e70e..44c35a1 100644
--- a/main/src/cgeo/geocaching/utils/BaseUtils.java
+++ b/main/src/cgeo/geocaching/utils/BaseUtils.java
@@ -31,33 +31,23 @@ public final class BaseUtils {
* @return defaultValue or the n-th group if the pattern matches (trimed if wanted)
*/
public static String getMatch(final String data, final Pattern p, final boolean trim, final int group, final String defaultValue, final boolean last) {
- String result = null;
+ if (data != null) {
- boolean lastInternal = false; // Optimization 1: 'while (matcher.find())' returns the same result as 'mather.find()' (for the tested patterns so far)
+ String result = null;
+ final Matcher matcher = p.matcher(data);
- final Matcher matcher = p.matcher(data);
-
- if (lastInternal) {
- while (matcher.find()) {
- // Optimization 2: 'matcher.find && matcher.groupCount() >= xx' can be shortened to 'matcher.find()'
- // if (matcher.groupCount() >= group) {
- result = matcher.group(group);
- }
- } else {
- // Optimization 2: 'matcher.find && matcher.groupCount() >= xx' can be shortened to 'matcher.find()'
- // if (matcher.find() && matcher.groupCount() >= group) {
if (matcher.find()) {
result = matcher.group(group);
}
- }
- if (null != result) {
- return trim ? new String(result).trim() : new String(result);
- // Java copies the whole page String, when matching with regular expressions
- // later this would block the garbage collector, as we only need tiny parts of the page
- // see http://developer.android.com/reference/java/lang/String.html#backing_array
- // Thus the creating of a new String via String constructor is necessary here!!
+ if (null != result) {
+ return trim ? new String(result).trim() : new String(result);
+ // Java copies the whole page String, when matching with regular expressions
+ // later this would block the garbage collector, as we only need tiny parts of the page
+ // see http://developer.android.com/reference/java/lang/String.html#backing_array
+ // Thus the creating of a new String via String constructor is necessary here!!
- // And BTW: You cannot even see that effect in the debugger, but must use a separate memory profiler!
+ // And BTW: You cannot even see that effect in the debugger, but must use a separate memory profiler!
+ }
}
return defaultValue;
}
diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
index 8606649..bc9b448 100644
--- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
+++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java
@@ -1,16 +1,12 @@
package cgeo.geocaching.utils;
+import cgeo.geocaching.GCConstants;
import cgeo.geocaching.R;
import cgeo.geocaching.Settings;
import cgeo.geocaching.cgBase;
import org.apache.commons.lang3.StringUtils;
-import android.util.Log;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* provides all the available templates for logging
*
@@ -131,29 +127,6 @@ public class LogTemplateProvider {
return -1;
}
- int findCount = -1;
-
- try {
- final Pattern findPattern = Pattern.compile("<strong><img.+?icon_smile.+?title=\"Caches Found\" /> ([,\\d]+)", Pattern.CASE_INSENSITIVE);
- final Matcher findMatcher = findPattern.matcher(page);
- if (findMatcher.find()) {
- if (findMatcher.groupCount() > 0) {
- String count = findMatcher.group(1);
-
- if (count != null) {
- if (count.length() == 0) {
- findCount = 0;
- } else {
- findCount = Integer.parseInt(count.replaceAll("[.,]", ""));
- }
- }
- }
- }
- } catch (Exception e) {
- Log.w(Settings.tag, "cgBase.parseFindCount: " + e.toString());
- }
-
- return findCount;
+ return Integer.parseInt(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", ""));
}
-
}