diff options
49 files changed, 717 insertions, 373 deletions
diff --git a/main/.settings/org.eclipse.jdt.core.prefs b/main/.settings/org.eclipse.jdt.core.prefs index aaf1455..19b01c3 100644 --- a/main/.settings/org.eclipse.jdt.core.prefs +++ b/main/.settings/org.eclipse.jdt.core.prefs @@ -282,3 +282,4 @@ org.eclipse.jdt.core.formatter.use_on_off_tags=false org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
\ No newline at end of file diff --git a/main/res/layout/init.xml b/main/res/layout/init.xml index ba5b7f3..47e5ae6 100644 --- a/main/res/layout/init.xml +++ b/main/res/layout/init.xml @@ -618,7 +618,8 @@ android:id="@+id/showwaypointsthreshold" android:singleLine="true" android:lines="1" - android:scrollHorizontally="true" /> + android:scrollHorizontally="true" + android:inputType="number" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -643,7 +644,8 @@ android:id="@+id/altitude" android:singleLine="true" android:lines="1" - android:scrollHorizontally="true" /> + android:scrollHorizontally="true" + android:inputType="numberSigned" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml index d4ca1b3..0c20bf7 100644 --- a/main/res/values-de/strings.xml +++ b/main/res/values-de/strings.xml @@ -729,62 +729,62 @@ <string name="attribute_rv_no">Wohnmobile nicht erlaubt</string> <!-- attributes (conditions -> yes, no) --> - <string name="attribute_kids_yes">für Kinder geeignet</string> - <string name="attribute_kids_no">nicht für Kinder geeignet</string> - <string name="attribute_onehour_yes">benötigt weniger als eine Stunde</string> - <string name="attribute_onehour_no">benötigt mehr als eine Stunde</string> - <string name="attribute_scenic_yes">herrliche Aussicht</string> - <string name="attribute_scenic_no">keine besondere Aussicht</string> - <string name="attribute_hiking_yes">anstrengender Marsch</string> - <string name="attribute_hiking_no">kein anstrengender Marsch</string> - <string name="attribute_climbing_yes">schwierige Kletterei</string> - <string name="attribute_climbing_no">keine schwierige Kletterei</string> + <string name="attribute_kids_yes">Für Kinder geeignet</string> + <string name="attribute_kids_no">Nicht für Kinder geeignet</string> + <string name="attribute_onehour_yes">Benötigt weniger als eine Stunde</string> + <string name="attribute_onehour_no">Benötigt mehr als eine Stunde</string> + <string name="attribute_scenic_yes">Besondere Aussicht</string> + <string name="attribute_scenic_no">Keine besondere Aussicht</string> + <string name="attribute_hiking_yes">Anstrengender Marsch</string> + <string name="attribute_hiking_no">Kein anstrengender Marsch</string> + <string name="attribute_climbing_yes">Schwierige Kletterei</string> + <string name="attribute_climbing_no">Keine schwierige Kletterei</string> <string name="attribute_wading_yes">Waten möglicherweise nötig</string> <string name="attribute_wading_no">Waten nicht nötig</string> <string name="attribute_swimming_yes">Schwimmen möglicherweise nötig</string> <string name="attribute_swimming_no">Schwimmen nicht nötig</string> - <string name="attribute_available_yes">zu jeder Zeit erreichbar</string> - <string name="attribute_available_no">nicht zu jeder Zeit erreichbar</string> - <string name="attribute_night_yes">nachts empfohlen</string> - <string name="attribute_night_no">nachts nicht empfohlen</string> - <string name="attribute_winter_yes">im Winter zugänglich</string> - <string name="attribute_winter_no">im Winter nicht zugänglich</string> - <string name="attribute_stealth_yes">heimlich vorgehen</string> + <string name="attribute_available_yes">Zu jeder Zeit erreichbar</string> + <string name="attribute_available_no">Nicht zu jeder Zeit erreichbar</string> + <string name="attribute_night_yes">Nachts empfohlen</string> + <string name="attribute_night_no">Nachts nicht empfohlen</string> + <string name="attribute_winter_yes">Im Winter zugänglich</string> + <string name="attribute_winter_no">Im Winter nicht zugänglich</string> + <string name="attribute_stealth_yes">Heimlich vorgehen</string> <string name="attribute_stealth_no">Heimlichkeit nicht notwendig</string> - <string name="attribute_firstaid_yes">muss gewartet werden</string> - <string name="attribute_firstaid_no">muss nicht gewartet werden</string> + <string name="attribute_firstaid_yes">Muss gewartet werden</string> + <string name="attribute_firstaid_no">Muss nicht gewartet werden</string> <string name="attribute_cow_yes">Achtung, Tierzucht</string> - <string name="attribute_cow_no">keine Tierzucht</string> + <string name="attribute_cow_no">Keine Tierzucht</string> <string name="attribute_field_puzzle_yes">Geländerätsel</string> - <string name="attribute_field_puzzle_no">kein Geländerätsel</string> + <string name="attribute_field_puzzle_no">Kein Geländerätsel</string> <string name="attribute_nightcache_yes">Nacht-Cache</string> - <string name="attribute_nightcache_no">kein Nacht-Cache</string> - <string name="attribute_parkngrab_yes">halten und mitnehmen</string> - <string name="attribute_parkngrab_no">kein halten und mitnehmen</string> - <string name="attribute_abandonedbuilding_yes">leerstehendes Gebäude</string> - <string name="attribute_abandonedbuilding_no">kein leerstehendes Gebäude</string> - <string name="attribute_hike_short_yes">kurzer Marsch (weniger als 1 km)</string> - <string name="attribute_hike_short_no">kein kurzer Marsch</string> - <string name="attribute_hike_med_yes">mittlerer Marsch (1 bis 10 km)</string> - <string name="attribute_hike_med_no">kein mittlerer Marsch</string> - <string name="attribute_hike_long_yes">langer Marsch (mehr als 10 km)</string> - <string name="attribute_hike_long_no">kein langer Marsch</string> + <string name="attribute_nightcache_no">Kein Nacht-Cache</string> + <string name="attribute_parkngrab_yes">Halten und Mitnehmen</string> + <string name="attribute_parkngrab_no">Kein Halten und Mitnehmen</string> + <string name="attribute_abandonedbuilding_yes">Leerstehendes Gebäude</string> + <string name="attribute_abandonedbuilding_no">Kein leerstehendes Gebäude</string> + <string name="attribute_hike_short_yes">Kurzer Marsch (weniger als 1 km)</string> + <string name="attribute_hike_short_no">Kein kurzer Marsch</string> + <string name="attribute_hike_med_yes">Mittlerer Marsch (1 bis 10 km)</string> + <string name="attribute_hike_med_no">Kein mittlerer Marsch</string> + <string name="attribute_hike_long_yes">Langer Marsch (mehr als 10 km)</string> + <string name="attribute_hike_long_no">Kein langer Marsch</string> <string name="attribute_seasonal_yes">Saisonabhängiger Zugang</string> <string name="attribute_seasonal_no">Zugang nicht saisonabhängig</string> - <string name="attribute_touristok_yes">touristenfreundlich</string> - <string name="attribute_touristok_no">nicht touristenfreundlich</string> + <string name="attribute_touristok_yes">Touristenfreundlich</string> + <string name="attribute_touristok_no">Nicht Touristenfreundlich</string> <string name="attribute_frontyard_yes">Privatgrundstück</string> - <string name="attribute_frontyard_no">kein Privatgrundstück</string> + <string name="attribute_frontyard_no">Kein Privatgrundstück</string> <string name="attribute_teamwork_yes">Teamwork notwendig</string> <string name="attribute_teamwork_no">Teamwork nicht notwendig</string> <string name="attribute_landf_yes">\'Lost and found\' Tour</string> - <string name="attribute_landf_no">keine \'Lost and found\' Tour</string> + <string name="attribute_landf_no">Keine \'Lost and found\' Tour</string> <string name="attribute_partnership_yes">Partnerschafts-Cache</string> <string name="attribute_partnership_no">kein Partnerschafts-Cache</string> <!-- attributes (equipment -> required, not required) --> <string name="attribute_fee_yes">Eintrittsgeld notwendig</string> - <string name="attribute_fee_no">kein Eintrittsgeld notwendig</string> + <string name="attribute_fee_no">Kein Eintrittsgeld notwendig</string> <string name="attribute_rappelling_yes">Kletterausrüstung notwendig</string> <string name="attribute_rappelling_no">Kletterausrüstung nicht notwendig</string> <string name="attribute_boat_yes">Boot notwendig</string> @@ -802,51 +802,51 @@ <string name="attribute_s_tool_yes">Besondere Werkzeuge notwendig</string> <string name="attribute_s_tool_no">Besondere Werkzeuge nicht notwendig</string> <string name="attribute_wirelessbeacon_yes">Radiosignal</string> - <string name="attribute_wirelessbeacon_no">kein Radiosignal</string> - <string name="attribute_treeclimbing_yes">auf Bäume klettern notwendig</string> - <string name="attribute_treeclimbing_no">auf Bäume klettern nicht notwendig</string> + <string name="attribute_wirelessbeacon_no">Kein Radiosignal</string> + <string name="attribute_treeclimbing_yes">Auf Bäume klettern notwendig</string> + <string name="attribute_treeclimbing_no">Auf Bäume klettern nicht notwendig</string> <!-- attributes (hazards -> present, not present) --> - <string name="attribute_poisonoak_yes">giftige Pflanzen</string> - <string name="attribute_poisonoak_no">keine giftige Pflanzen</string> - <string name="attribute_dangerousanimals_yes">gefährliche Tiere</string> - <string name="attribute_dangerousanimals_no">keine gefährlichen Tiere</string> + <string name="attribute_poisonoak_yes">Giftige Pflanzen</string> + <string name="attribute_poisonoak_no">Keine giftigen Pflanzen</string> + <string name="attribute_dangerousanimals_yes">Gefährliche Tiere</string> + <string name="attribute_dangerousanimals_no">Keine gefährlichen Tiere</string> <string name="attribute_ticks_yes">Zecken</string> - <string name="attribute_ticks_no">keine Zecken</string> - <string name="attribute_mine_yes">verlassene Minen</string> - <string name="attribute_mine_no">keine verlassenen Minen</string> + <string name="attribute_ticks_no">Keine Zecken</string> + <string name="attribute_mine_yes">Verlassene Minen</string> + <string name="attribute_mine_no">Keine verlassenen Minen</string> <string name="attribute_cliff_yes">Kliff/Abhang</string> - <string name="attribute_cliff_no">kein Kliff/Abhang</string> + <string name="attribute_cliff_no">Kein Kliff/Abhang</string> <string name="attribute_hunting_yes">Jagdgebiet</string> - <string name="attribute_hunting_no">kein Jagdgebiet</string> + <string name="attribute_hunting_no">Kein Jagdgebiet</string> <string name="attribute_danger_yes">Gefährliches Gebiet</string> - <string name="attribute_danger_no">kein gefährliches Gebiet</string> + <string name="attribute_danger_no">Kein gefährliches Gebiet</string> <string name="attribute_thorn_yes">Dornen</string> - <string name="attribute_thorn_no">keine Dornen</string> + <string name="attribute_thorn_no">Keine Dornen</string> <!-- attributes (facilities -> yes, no) --> - <string name="attribute_wheelchair_yes">rollstuhlgängig</string> - <string name="attribute_wheelchair_no">nicht rollstuhlgängig</string> + <string name="attribute_wheelchair_yes">Rollstuhlgängig</string> + <string name="attribute_wheelchair_no">Nicht Rollstuhlgängig</string> <string name="attribute_parking_yes">Parkplatz vorhanden</string> - <string name="attribute_parking_no">kein Parkplatz vorhanden</string> - <string name="attribute_public_yes">öffentliche Verkehrsmittel</string> - <string name="attribute_public_no">keine öffentlichen Verkehrsmittel</string> + <string name="attribute_parking_no">Kein Parkplatz vorhanden</string> + <string name="attribute_public_yes">Öffentliche Verkehrsmittel</string> + <string name="attribute_public_no">Keine öffentlichen Verkehrsmittel</string> <string name="attribute_water_yes">Trinkwasser in der Nähe</string> - <string name="attribute_water_no">kein Trinkwasser in der Nähe</string> - <string name="attribute_restrooms_yes">öffentliche Toiletten in der Nähe</string> - <string name="attribute_restrooms_no">keine öffentliche Toiletten in der Nähe</string> + <string name="attribute_water_no">Kein Trinkwasser in der Nähe</string> + <string name="attribute_restrooms_yes">Öffentliche Toiletten in der Nähe</string> + <string name="attribute_restrooms_no">Keine öffentliche Toiletten in der Nähe</string> <string name="attribute_phone_yes">Telefon in der Nähe</string> - <string name="attribute_phone_no">kein Telefon in der Nähe</string> + <string name="attribute_phone_no">Kein Telefon in der Nähe</string> <string name="attribute_picnic_yes">Picknicktische in der Nähe</string> - <string name="attribute_picnic_no">keine Picknicktische in der Nähe</string> + <string name="attribute_picnic_no">Keine Picknicktische in der Nähe</string> <string name="attribute_camping_yes">Camping möglich</string> <string name="attribute_camping_no">Camping nicht möglich</string> - <string name="attribute_stroller_yes">mit Kinderwagen erreichbar</string> - <string name="attribute_stroller_no">nicht mit Kinderwagen erreichbar</string> + <string name="attribute_stroller_yes">Mit Kinderwagen erreichbar</string> + <string name="attribute_stroller_no">Nicht mit Kinderwagen erreichbar</string> <string name="attribute_fuel_yes">Tankstelle in der Nähe</string> - <string name="attribute_fuel_no">keine Tankstelle in der Nähe</string> + <string name="attribute_fuel_no">Keine Tankstelle in der Nähe</string> <string name="attribute_food_yes">Lebensmittel in der Nähe</string> - <string name="attribute_food_no">keine Lebensmittel in der Nähe</string> + <string name="attribute_food_no">Keine Lebensmittel in der Nähe</string> <!-- next things --> <string name="legal_note">Um die Dienste von Geocaching.com nutzen zu können, müssen die <a href="http://www.geocaching.com/about/termsofuse.aspx">Groundspeak-Nutzungsbedingungen</a> (englisch) akzeptiert werden.</string> diff --git a/main/res/values-sv/strings.xml b/main/res/values-sv/strings.xml index a034f57..556c8bd 100644..100755 --- a/main/res/values-sv/strings.xml +++ b/main/res/values-sv/strings.xml @@ -35,6 +35,7 @@ <string name="ape">Projekt APE cache</string> <string name="gchq">Groundspeak HQ</string> <string name="gps">GPS cache utställning</string> + <string name="unknown">Okänd cache</string> <!-- cache sizes --> <string name="cache_size_micro">micro</string> @@ -124,6 +125,7 @@ <string name="err_comm">Okänt kommunikationsfel</string> <string name="err_missing_auth">Användarnamn och/eller lösenord saknas.</string> <string name="err_wrong">felaktiga inloggningsuppgifter</string> + <string name="err_maintenance">Arbete pågår med servern Geocaching.com, försök igen senare. c:geo fungerar under tiden i offline läge.</string> <string name="err_license">användaren inte har bekräftat licensavtalet med Geocaching.com</string> <string name="err_unpublished">Den sökta cachen är opubliserad.</string> <string name="err_premium_only">Cachen är enbart för premium medlemmar på Geocaching.com</string> @@ -235,6 +237,7 @@ <string name="menu_settings">Inställningar</string> <string name="menu_history">Loggade cacher</string> <string name="menu_filter">Filter</string> + <string name="menu_scan_geo">Scanna geokod</string> <!-- main screen --> <string name="live_map_button">Live karta</string> @@ -249,6 +252,7 @@ <string name="caches_more_caches">Ladda fler cacher</string> <string name="caches_more_caches_no">Inga fler cacher att ladda</string> <string name="caches_more_caches_loading">Laddar fler cacher…</string> + <string name="caches_more_caches_currently">samtidigt</string> <string name="caches_downloading">Laddar ner cacher…\nTid kvar: </string> <string name="caches_eta_ltm">mindre än en minut</string> <string name="caches_eta_mins"> minuter</string> @@ -362,6 +366,10 @@ <string name="init_signature_template_datetime">Datum & Tid</string> <string name="init_signature_template_user">Namn</string> <string name="init_signature_template_number">Nummer</string> + <string name="init_details">Cacheinformation</string> + <string name="init_ratingwanted">Ladda cache betyg från GCvote.com</string> + <string name="init_elevationwanted">Ladda höjddata för cacher</string> + <string name="init_autoload">Ladda full beskrivning automatiskt</string> <string name="init_other">Övriga inställningar</string> <string name="init_skin">Vitt skal (kräver omstart av c:geo)</string> <string name="init_address">Visa adress på huvudskärmen</string> @@ -375,7 +383,6 @@ <string name="init_save_log_img">Spara bilder från loggar</string> <string name="init_units">Använd amerikanska enheter för avstånd</string> <string name="init_nav">Använd Google Navigering</string> - <string name="init_autoload">Ladda full beskrivning automatiskt</string> <string name="init_log_offline">Vid loggning: spara bara loggen lokalt (visa inte loggningfönster och skicka inte loggen till gc.com)</string> <string name="init_livelist">Visa riktning till cacher i listan</string> <string name="init_browser">Identifiera c:geo som normal webbläsare</string> @@ -474,12 +481,13 @@ <string name="cache_hint">Tips</string> <string name="cache_logs">Loggbok</string> <string name="cache_dialog_loading_details">Laddar detaljer om cachen…</string> - <string name="cache_dialog_loading_details_status_loadpage">Laddar ner från gc.com</string> + <string name="cache_dialog_loading_details_status_loadpage">Hämtar från gc.com</string> <string name="cache_dialog_loading_details_status_details">Analyserar cacheinformation</string> - <string name="cache_dialog_loading_details_status_spoilers">Laddar ner spoilerbilder</string> - <string name="cache_dialog_loading_details_status_logs">Laddar ner tidgare loggar</string> + <string name="cache_dialog_loading_details_status_spoilers">Hämtar spoilerbilder</string> + <string name="cache_dialog_loading_details_status_logs">Hämtar tidgare loggar</string> <string name="cache_dialog_loading_details_status_waypoints">Analyserar punkter</string> - <string name="cache_dialog_loading_details_status_gcvote">Hämtar betyg från GCVote</string> + <string name="cache_dialog_loading_details_status_gcvote">Hämtar betyg från GCVote.com</string> + <string name="cache_dialog_loading_details_status_elevation">Hämtar höjddata</string> <string name="cache_dialog_loading_details_status_render">Förbereder för visning</string> <string name="cache_dialog_loading_description">Laddar beskrivning om cachen…</string> <string name="cache_dialog_offline_save_title">Offline</string> @@ -522,6 +530,7 @@ <string name="cache_geocode">GC-kod</string> <string name="cache_name">Namn</string> <string name="cache_type">Typ</string> + <string name="cache_size">Storlek</string> <string name="cache_distance">Avstånd</string> <string name="cache_difficulty">Svårighet</string> <string name="cache_terrain">Terräng</string> @@ -557,6 +566,11 @@ <string name="gpx_import_title">Importera GPX</string> <string name="gpx_import_title_reading_file">Läser fil</string> <string name="gpx_import_title_caches_imported">Resultat</string> + <string name="gpx_import_title_caches_import_failed">Importeringen misslyckades</string> + <string name="gpx_import_error_io">Kan inte läsa filen</string> + <string name="gpx_import_error_parser">Filens format är felaktigt</string> + <string name="gpx_import_error_unexpected">Oväntat fel</string> + <string name="gpx_import_confirm">Vill du importera GPX filen till c:geo?</string> <!-- map file select --> <string name="map_file_select_title">Välj kartfil</string> @@ -592,6 +606,8 @@ <string name="waypoint_loading">Laddar punkt…</string> <string name="waypoint_unknown_coordinates">Koordinaterna ogiltiga</string> <string name="waypoint_done">Klar</string> + <string name="waypoint_duplicate">Duplicera</string> + <string name="waypoint_copy_of">Kopia av</string> <string name="search_history">Historik</string> <string name="search_history_empty">Inga tidigare destinationer</string> <string name="search_remove_destination">Destinationen borttagen</string> @@ -616,6 +632,7 @@ <string name="map_static_title">Sparade kartor</string> <string name="map_static_loading">Laddar sparade kartor…</string> <string name="map_token_err">Eftersom c:geo bara kunde hämta en del av informationen så kan positionen för cacher vara felaktig.</string> + <string name="map_as_list">Visa som lista</string> <!-- search --> <string name="search_bar_hint">Sök cache/TB</string> diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index 519f5c0..a5b1178 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -401,6 +401,7 @@ <string name="init_restore_success">Restoration completed.</string> <string name="init_restore_failed">Restoration failed.</string> <string name="init_restore_running">Restoring cache database…</string> + <string name="init_restore_confirm">Database is empty. Do you want to restore the database backup?</string> <string name="init_backup_last">Available backup from</string> <string name="init_backup_last_no">There is no file with backup.</string> <string name="init_mapsources">Map Sources</string> @@ -559,7 +560,10 @@ <string name="cache_clear_history">Clear history</string> <string name="cache_remove_from_history">Remove from history</string> <string name="cache_license">License</string> - + <string name="cache_image">Image</string> + <string name="cache_image_open_file">Open as file</string> + <string name="cache_image_open_browser">Open in browser</string> + <!-- file list base --> <string name="file_searching_in">Searching for files\nin</string> <string name="file_list_no_files">Sorry, c:geo found no appropriate files.</string> diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java index 3d96baf..2007493 100644 --- a/main/src/cgeo/geocaching/Settings.java +++ b/main/src/cgeo/geocaching/Settings.java @@ -812,7 +812,11 @@ public final class Settings { } public static CacheType getCacheType() { - return CacheType.getById(sharedPrefs.getString(KEY_CACHE_TYPE, null)); + String cacheFilterType = sharedPrefs.getString(KEY_CACHE_TYPE, null); + if (cacheFilterType == null) { + return null; + } + return CacheType.getById(cacheFilterType); } public static int getWayPointsThreshold() { diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java index 5792fbe..ba3db88 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java @@ -60,7 +60,7 @@ public abstract class AbstractActivity extends Activity implements IAbstractActi } public final void helpDialog(final String title, final String message) { - ActivityMixin.helpDialog(this, title, message, null); + ActivityMixin.helpDialog(this, title, message); } public final void helpDialog(final String title, final String message, final Drawable icon) { diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java index d4f9edb..5561cc7 100644 --- a/main/src/cgeo/geocaching/activity/ActivityMixin.java +++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java @@ -122,6 +122,10 @@ public final class ActivityMixin { alert.show(); } + public static void helpDialog(Activity activity, String title, String message) { + helpDialog(activity, title, message, null); + } + protected static void addVisitMenu(IAbstractActivity activity, Menu menu, cgCache cache) { if (cache == null) { return; @@ -145,5 +149,4 @@ public final class ActivityMixin { } } } - } diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java index 17a7835..a615ae7 100644 --- a/main/src/cgeo/geocaching/cgBase.java +++ b/main/src/cgeo/geocaching/cgBase.java @@ -449,8 +449,8 @@ public class cgBase { } HttpResponse loginResponse = request("https://www.geocaching.com/login/default.aspx", null, false, false, false); - String loginData = getResponseDataOnError(loginResponse); - if (loginResponse.getStatusLine().getStatusCode() == 503 && patternMaintenance.matcher(loginData).find()) { + String loginData = getResponseData(loginResponse); + if (loginResponse != null && loginResponse.getStatusLine().getStatusCode() == 503 && patternMaintenance.matcher(loginData).find()) { return StatusCode.MAINTENANCE; } @@ -1231,15 +1231,17 @@ public class cgBase { final Matcher matcherSpoilersInside = GCConstants.PATTERN_SPOILERSINSIDE.matcher(spoilers); while (matcherSpoilersInside.find()) { - final cgImage spoiler = new cgImage(); - spoiler.url = matcherSpoilersInside.group(1); + String url = matcherSpoilersInside.group(1); + String title = null; if (matcherSpoilersInside.group(2) != null) { - spoiler.title = matcherSpoilersInside.group(2); + title = matcherSpoilersInside.group(2); } + String description = null; if (matcherSpoilersInside.group(3) != null) { - spoiler.description = matcherSpoilersInside.group(3); + description = matcherSpoilersInside.group(3); } + final cgImage spoiler = new cgImage(url, title, description); if (cache.getSpoilers() == null) { cache.setSpoilers(new ArrayList<cgImage>()); @@ -1356,7 +1358,7 @@ public class cgBase { try { final Matcher matcherWpType = patternWpType.matcher(wp[3]); if (matcherWpType.find() && matcherWpType.groupCount() > 0) { - waypoint.setWaypointType(WaypointType.FIND_BY_ID.get(matcherWpType.group(1).trim())); + waypoint.setWaypointType(WaypointType.findById(matcherWpType.group(1).trim())); } } catch (Exception e) { // failed to parse type @@ -1551,9 +1553,9 @@ public class cgBase { final JSONArray images = entry.getJSONArray("Images"); for (int i = 0; i < images.length(); i++) { final JSONObject image = images.getJSONObject(i); - final cgImage logImage = new cgImage(); - logImage.url = "http://img.geocaching.com/cache/log/" + image.getString("FileName"); - logImage.title = image.getString("Name"); + 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>(); } @@ -2935,7 +2937,7 @@ public class cgBase { // store spoilers if (CollectionUtils.isNotEmpty(cache.getSpoilers())) { for (cgImage oneSpoiler : cache.getSpoilers()) { - imgGetter.getDrawable(oneSpoiler.url); + imgGetter.getDrawable(oneSpoiler.getUrl()); } } @@ -2948,7 +2950,7 @@ public class cgBase { for (cgLog log : cache.getLogs()) { if (CollectionUtils.isNotEmpty(log.logImages)) { for (cgImage oneLogImg : log.logImages) { - imgGetter.getDrawable(oneLogImg.url); + imgGetter.getDrawable(oneLogImg.getUrl()); } } } diff --git a/main/src/cgeo/geocaching/cgData.java b/main/src/cgeo/geocaching/cgData.java index 37b20ad..1724fdd 100644 --- a/main/src/cgeo/geocaching/cgData.java +++ b/main/src/cgeo/geocaching/cgData.java @@ -221,6 +221,7 @@ public class cgData { public boolean initialized = false; private SQLiteStatement statementDescription; private SQLiteStatement statementLogCount; + private static boolean newlyCreatedDatabase = false; public cgData(Context contextIn) { context = contextIn; @@ -385,6 +386,7 @@ public class cgData { @Override public void onCreate(SQLiteDatabase db) { + newlyCreatedDatabase = true; db.execSQL(dbCreateCaches); db.execSQL(dbCreateLists); db.execSQL(dbCreateAttributes); @@ -1554,9 +1556,9 @@ public class cgData { values.clear(); values.put("geocode", geocode); values.put("updated", timeStamp); - values.put("url", oneSpoiler.url); - values.put("title", oneSpoiler.title); - values.put("description", oneSpoiler.description); + values.put("url", oneSpoiler.getUrl()); + values.put("title", oneSpoiler.getTitle()); + values.put("description", oneSpoiler.getDescription()); databaseRW.insert(dbTableSpoilers, null, values); } @@ -1608,8 +1610,8 @@ public class cgData { for (cgImage img : log.logImages) { values.clear(); values.put("log_id", log_id); - values.put("title", img.title); - values.put("url", img.url); + values.put("title", img.getTitle()); + values.put("url", img.getUrl()); databaseRW.insert(dbTableLogImages, null, values); } } @@ -2226,7 +2228,7 @@ public class cgData { waypoint.setId(cursor.getInt(cursor.getColumnIndex("_id"))); waypoint.setGeocode(cursor.getString(cursor.getColumnIndex("geocode"))); - waypoint.setWaypointType(WaypointType.FIND_BY_ID.get(cursor.getString(cursor.getColumnIndex("type")))); + waypoint.setWaypointType(WaypointType.findById(cursor.getString(cursor.getColumnIndex("type")))); waypoint.setPrefix(cursor.getString(cursor.getColumnIndex("prefix"))); waypoint.setLookup(cursor.getString(cursor.getColumnIndex("lookup"))); waypoint.setName(cursor.getString(cursor.getColumnIndex("name"))); @@ -2263,10 +2265,7 @@ public class cgData { int indexDescription = cursor.getColumnIndex("description"); do { - cgImage spoiler = new cgImage(); - spoiler.url = cursor.getString(indexUrl); - spoiler.title = cursor.getString(indexTitle); - spoiler.description = cursor.getString(indexDescription); + cgImage spoiler = new cgImage(cursor.getString(indexUrl), cursor.getString(indexTitle), cursor.getString(indexDescription)); spoilers.add(spoiler); } while (cursor.moveToNext()); @@ -2382,18 +2381,12 @@ public class cgData { logs.add(log); } if (!cursor.isNull(indexLogImagesId)) { - final cgImage log_img = new cgImage(); - log_img.title = cursor.getString(indexTitle); - if (log_img.title == null) { - log_img.title = ""; - } - log_img.url = cursor.getString(indexUrl); - if (log_img.url == null) { - log_img.url = ""; - } + 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); } } @@ -3373,4 +3366,20 @@ public class cgData { return null; } + + /** + * checks if this is a newly created database + * + * @return + */ + public static boolean isNewlyCreatedDatebase() { + return newlyCreatedDatabase; + } + + /** + * resets flag for newly created database to avoid asking the user multiple times + */ + public static void resetNewlyCreatedDatabase() { + newlyCreatedDatabase = false; + } } diff --git a/main/src/cgeo/geocaching/cgGeo.java b/main/src/cgeo/geocaching/cgGeo.java index 180a7a4..ebd6525 100644 --- a/main/src/cgeo/geocaching/cgGeo.java +++ b/main/src/cgeo/geocaching/cgGeo.java @@ -1,6 +1,7 @@ package cgeo.geocaching; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.go4cache.Go4Cache; import android.content.Context; import android.content.SharedPreferences; diff --git a/main/src/cgeo/geocaching/cgImage.java b/main/src/cgeo/geocaching/cgImage.java index 3dba437..2be27b2 100644 --- a/main/src/cgeo/geocaching/cgImage.java +++ b/main/src/cgeo/geocaching/cgImage.java @@ -1,14 +1,26 @@ package cgeo.geocaching; +import org.apache.commons.lang3.StringUtils; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; public class cgImage implements Parcelable { - public String url = ""; - public String title = ""; - public String description = ""; + private final String url; + private final String title; + private final String description; + + public cgImage(final String url, final String title, final String description) { + this.url = url; + this.title = title; + this.description = description; + } - public cgImage() { + public cgImage(final String url, final String title) { + this(url, title, null); } public cgImage(final Parcel in) { @@ -39,4 +51,24 @@ public class cgImage implements Parcelable { return new cgImage[size]; } }; + + public String getUrl() { + return url; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public void openInBrowser(final Context fromActivity) { + if (StringUtils.isBlank(url)) { + return; + } + final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + fromActivity.startActivity(browserIntent); + } } diff --git a/main/src/cgeo/geocaching/cgUser.java b/main/src/cgeo/geocaching/cgUser.java deleted file mode 100644 index 2249133..0000000 --- a/main/src/cgeo/geocaching/cgUser.java +++ /dev/null @@ -1,13 +0,0 @@ -package cgeo.geocaching; - -import cgeo.geocaching.geopoint.Geopoint; - -import java.util.Date; - -public class cgUser { - public Date located = null; - public String username = null; - public Geopoint coords = null; - public String action = null; - public String client = null; -} diff --git a/main/src/cgeo/geocaching/cgeo.java b/main/src/cgeo/geocaching/cgeo.java index 2a4fb13..6be2e98 100644 --- a/main/src/cgeo/geocaching/cgeo.java +++ b/main/src/cgeo/geocaching/cgeo.java @@ -11,7 +11,9 @@ import cgeo.geocaching.maps.CGeoMap; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; @@ -446,7 +448,7 @@ public class cgeo extends AbstractActivity { (new firstLogin()).start(); } - (new countBubbleUpdate()).start(); + updateCacheCounter(); (new cleanDatabase()).start(); if (Settings.getCacheType() != null && !cgBase.cacheTypesInv.containsKey(Settings.getCacheType())) { @@ -478,7 +480,7 @@ public class cgeo extends AbstractActivity { }); registerForContextMenu(findByOffline); - (new countBubbleUpdate()).start(); + updateCacheCounter(); final View advanced = findViewById(R.id.advanced_button); advanced.setClickable(true); @@ -506,6 +508,37 @@ public class cgeo extends AbstractActivity { }); setFilterTitle(); + checkRestore(); + } + + private void updateCacheCounter() { + (new countBubbleUpdate()).start(); + } + + private void checkRestore() { + if (!cgData.isNewlyCreatedDatebase() || null == cgData.isRestoreFile()) { + return; + } + new AlertDialog.Builder(this) + .setTitle(res.getString(R.string.init_backup_restore)) + .setMessage(res.getString(R.string.init_restore_confirm)) + .setCancelable(false) + .setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + cgData.resetNewlyCreatedDatabase(); + app.restoreDatabase(cgeo.this); + updateCacheCounter(); + } + }) + .setNegativeButton(getString(android.R.string.no), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + cgData.resetNewlyCreatedDatabase(); + } + }) + .create() + .show(); } private class update extends cgUpdateLoc { diff --git a/main/src/cgeo/geocaching/cgeoapplication.java b/main/src/cgeo/geocaching/cgeoapplication.java index 486665a..7ae1575 100644 --- a/main/src/cgeo/geocaching/cgeoapplication.java +++ b/main/src/cgeo/geocaching/cgeoapplication.java @@ -1,5 +1,6 @@ package cgeo.geocaching; +import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.geopoint.Geopoint; @@ -7,8 +8,13 @@ import cgeo.geocaching.geopoint.Geopoint; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import android.app.Activity; import android.app.Application; +import android.app.ProgressDialog; 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; @@ -17,6 +23,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; public class cgeoapplication extends Application { @@ -81,8 +88,33 @@ public class cgeoapplication extends Application { return cgData.isRestoreFile(); } - public boolean restoreDatabase() { - return storage.restoreDatabase(); + /** + * restore the database in a new thread, showing a progress window + * + * @param fromActivity + * calling activity + */ + public void restoreDatabase(final Activity fromActivity) { + final Resources res = this.getResources(); + final ProgressDialog dialog = ProgressDialog.show(fromActivity, res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_running), true, false); + final AtomicBoolean atomic = new AtomicBoolean(false); + Thread restoreThread = new Thread() { + final Handler handler = new Handler() { + public void handleMessage(Message msg) { + dialog.dismiss(); + boolean restored = atomic.get(); + String message = restored ? res.getString(R.string.init_restore_success) : res.getString(R.string.init_restore_failed); + ActivityMixin.helpDialog(fromActivity, res.getString(R.string.init_backup_restore), message); + } + }; + + @Override + public void run() { + atomic.set(storage.restoreDatabase()); + handler.sendMessage(handler.obtainMessage()); + } + }; + restoreThread.start(); } public void cleanGeo() { diff --git a/main/src/cgeo/geocaching/cgeodetail.java b/main/src/cgeo/geocaching/cgeodetail.java index 84c208b..a818859 100644 --- a/main/src/cgeo/geocaching/cgeodetail.java +++ b/main/src/cgeo/geocaching/cgeodetail.java @@ -77,6 +77,12 @@ import java.util.Map.Entry; */ public class cgeodetail extends AbstractActivity { + private static final int MENU_SHARE = 12; + private static final int MENU_CALENDAR = 11; + private static final int MENU_CACHES_AROUND = 10; + private static final int MENU_BROWSER = 7; + private static final int MENU_SPOILERS = 5; + private static final int MENU_NAVIGATE = 2; private static final int CONTEXT_MENU_WAYPOINT_DELETE = 1235; private static final int CONTEXT_MENU_WAYPOINT_DUPLICATE = 1234; @@ -580,33 +586,30 @@ public class cgeodetail extends AbstractActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { - if (cache != null && cache.getCoords() != null) { - menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass - SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_mapmode); + if (null != cache) { + menu.add(0, MENU_NAVIGATE, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass + final SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_mapmode); addNavigationMenuItems(subMenu); + menu.add(1, MENU_CALENDAR, 0, res.getString(R.string.cache_menu_event)).setIcon(android.R.drawable.ic_menu_agenda); // add event to calendar + addVisitMenu(menu, cache); + menu.add(1, MENU_SPOILERS, 0, res.getString(R.string.cache_menu_spoilers)).setIcon(android.R.drawable.ic_menu_gallery); // spoiler images + menu.add(0, MENU_CACHES_AROUND, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around + menu.add(1, MENU_BROWSER, 0, res.getString(R.string.cache_menu_browser)).setIcon(R.drawable.ic_menu_globe); // browser + menu.add(0, MENU_SHARE, 0, res.getString(R.string.cache_menu_share)).setIcon(android.R.drawable.ic_menu_share); // share cache } - - if (cache != null && cache.canBeAddedToCalendar()) { - menu.add(1, 11, 0, res.getString(R.string.cache_menu_event)).setIcon(android.R.drawable.ic_menu_agenda); // add event to calendar - } - addVisitMenu(menu, cache); - - if (cache != null && CollectionUtils.isNotEmpty(cache.getSpoilers())) { - menu.add(1, 5, 0, res.getString(R.string.cache_menu_spoilers)).setIcon(android.R.drawable.ic_menu_gallery); // spoiler images - } - - if (cache != null && cache.getCoords() != null && cache.supportsCachesAround()) { - menu.add(0, 10, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // caches around - } - - if (cache != null && cache.canOpenInBrowser()) { - menu.add(1, 7, 0, res.getString(R.string.cache_menu_browser)).setIcon(R.drawable.ic_menu_globe); // browser - } - menu.add(0, 12, 0, res.getString(R.string.cache_menu_share)).setIcon(android.R.drawable.ic_menu_share); // share cache - return true; } + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + menu.findItem(MENU_NAVIGATE).setVisible(null != cache.getCoords()); + menu.findItem(MENU_CALENDAR).setVisible(cache.canBeAddedToCalendar()); + menu.findItem(MENU_SPOILERS).setVisible(CollectionUtils.isNotEmpty(cache.getSpoilers())); + menu.findItem(MENU_CACHES_AROUND).setVisible(null != cache.getCoords() && cache.supportsCachesAround()); + menu.findItem(MENU_BROWSER).setVisible(cache.canOpenInBrowser()); + return super.onPrepareOptionsMenu(menu); + } + private void addNavigationMenuItems(final Menu menu) { NavigationAppFactory.addMenuItems(menu, this, res); GeneralAppsFactory.addMenuItems(menu, this, res, cache); @@ -621,25 +624,25 @@ public class cgeodetail extends AbstractActivity { return false; } - if (menuItem == 2) { + if (menuItem == MENU_NAVIGATE) { navigateTo(); return true; } else if (menuItem == MENU_LOG_VISIT) { logVisit(); return true; - } else if (menuItem == 5) { + } else if (menuItem == MENU_SPOILERS) { showSpoilers(); return true; - } else if (menuItem == 7) { + } else if (menuItem == MENU_BROWSER) { cache.openInBrowser(this); return true; - } else if (menuItem == 10) { + } else if (menuItem == MENU_CACHES_AROUND) { cachesAround(); return true; - } else if (menuItem == 11) { + } else if (menuItem == MENU_CALENDAR) { addToCalendar(); return true; - } else if (menuItem == 12) { + } else if (menuItem == MENU_SHARE) { if (cache != null) { cache.shareCache(this, res); return true; @@ -1306,17 +1309,13 @@ public class cgeodetail extends AbstractActivity { final View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { - Intent logImgIntent = new Intent(cgeodetail.this, cgeoimages.class); - logImgIntent.putExtra("geocode", geocode.toUpperCase()); - logImgIntent.putExtra("type", cgeoimages.LOG_IMAGES); - logImgIntent.putParcelableArrayListExtra("images", logImages); - startActivity(logImgIntent); + cgeoimages.startActivityLogImages(cgeodetail.this, geocode, 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).title; + String img_title = log.logImages.get(i_img_cnt).getTitle(); if (!StringUtils.isBlank(img_title)) { titles.add(img_title); } @@ -1647,11 +1646,7 @@ public class cgeodetail extends AbstractActivity { showToast(res.getString(R.string.err_detail_no_spoiler)); } - Intent spoilersIntent = new Intent(this, cgeoimages.class); - spoilersIntent.putExtra("geocode", geocode.toUpperCase()); - spoilersIntent.putExtra("type", cgeoimages.SPOILER_IMAGES); - spoilersIntent.putParcelableArrayListExtra("images", cache.getSpoilers()); - startActivity(spoilersIntent); + cgeoimages.startActivitySpoilerImages(cgeodetail.this, geocode, cache.getSpoilers()); } public class codeHint implements View.OnClickListener { diff --git a/main/src/cgeo/geocaching/cgeoimages.java b/main/src/cgeo/geocaching/cgeoimages.java index 48b7985..a6f1740 100644 --- a/main/src/cgeo/geocaching/cgeoimages.java +++ b/main/src/cgeo/geocaching/cgeoimages.java @@ -8,6 +8,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import android.app.ProgressDialog; +import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; @@ -18,7 +19,10 @@ import android.os.AsyncTask; import android.os.Bundle; import android.text.Html; import android.util.Log; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; @@ -30,13 +34,16 @@ 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 { + private static final int MENU_BROWSER = 2; + private static final int MENU_FILE = 1; private static final int UNKNOWN_TYPE = 0; - public static final int LOG_IMAGES = 1; - public static final int SPOILER_IMAGES = 2; + private static final int LOG_IMAGES = 1; + private static final int SPOILER_IMAGES = 2; private String geocode = null; private LayoutInflater inflater = null; @@ -44,8 +51,11 @@ 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 BitmapDrawable currentDrawable; + private cgImage currentImage; - static private Collection<Bitmap> bitmaps = Collections.synchronizedCollection(new ArrayList<Bitmap>()); + static private final Collection<Bitmap> bitmaps = Collections.synchronizedCollection(new ArrayList<Bitmap>()); private void loadImages(final List<cgImage> images, final int progressMessage, final boolean offline) { @@ -61,11 +71,11 @@ public class cgeoimages extends AbstractActivity { for (final cgImage img : images) { rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null); - ((TextView) rowView.findViewById(R.id.title)).setText(Html.fromHtml(img.title)); + ((TextView) rowView.findViewById(R.id.title)).setText(Html.fromHtml(img.getTitle())); - if (StringUtils.isNotBlank(img.description)) { + if (StringUtils.isNotBlank(img.getDescription())) { final TextView descView = (TextView) rowView.findViewById(R.id.description); - descView.setText(Html.fromHtml(img.description), TextView.BufferType.SPANNABLE); + descView.setText(Html.fromHtml(img.getDescription()), TextView.BufferType.SPANNABLE); descView.setVisibility(View.VISIBLE); } @@ -89,7 +99,7 @@ public class cgeoimages extends AbstractActivity { @Override protected BitmapDrawable doInBackground(Void... params) { final HtmlImage imgGetter = new HtmlImage(cgeoimages.this, geocode, true, offline ? 1 : 0, false); - return imgGetter.getDrawable(img.url); + return imgGetter.getDrawable(img.getUrl()); } @Override @@ -105,30 +115,17 @@ public class cgeoimages extends AbstractActivity { image_view.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { - final File file = LocalStorage.getStorageFile(null, "temp.jpg", false); - try { - final FileOutputStream fos = new FileOutputStream(file); - image.getBitmap().compress(CompressFormat.JPEG, 100, fos); - fos.close(); - } catch (Exception e) { - Log.e(Settings.tag, "cgeoimages.handleMessage.onClick: " + e.toString()); - return; - } - - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(file), "image/jpg"); - startActivity(intent); - - if (file.exists()) - file.deleteOnExit(); + viewImageInStandardApp(image); } }); + cgeoimages.this.registerForContextMenu(image_view); image_view.setImageDrawable(image); image_view.setScaleType(ImageView.ScaleType.CENTER_CROP); image_view.setLayoutParams(new LayoutParams(bounds.width(), bounds.height())); view.addView(image_view); + + images.put(image_view.getId(), img); } synchronized (cgeoimages.this) { @@ -146,7 +143,7 @@ public class cgeoimages extends AbstractActivity { super.onCreate(savedInstanceState); // get parameters - Bundle extras = getIntent().getExtras(); + final Bundle extras = getIntent().getExtras(); // try to get data from extras int img_type = UNKNOWN_TYPE; @@ -200,10 +197,68 @@ public class cgeoimages extends AbstractActivity { super.onDestroy(); } - @Override - public void onResume() { - super.onResume(); + private void viewImageInStandardApp(final BitmapDrawable image) { + final File file = LocalStorage.getStorageFile(null, "temp.jpg", false); + try { + final FileOutputStream fos = new FileOutputStream(file); + image.getBitmap().compress(CompressFormat.JPEG, 100, fos); + fos.close(); + } catch (Exception e) { + Log.e(Settings.tag, "cgeoimages.handleMessage.onClick: " + e.toString()); + return; + } + + final Intent intent = new Intent(); + intent.setAction(android.content.Intent.ACTION_VIEW); + intent.setDataAndType(Uri.fromFile(file), "image/jpg"); + startActivity(intent); + + if (file.exists()) { + file.deleteOnExit(); + } + } + + public static void startActivityLogImages(final Context fromActivity, final String geocode, ArrayList<cgImage> logImages) { + startActivity(fromActivity, geocode, logImages, cgeoimages.LOG_IMAGES); + } + private static void startActivity(final Context fromActivity, final String geocode, ArrayList<cgImage> logImages, int imageType) { + final Intent logImgIntent = new Intent(fromActivity, cgeoimages.class); + logImgIntent.putExtra("geocode", geocode.toUpperCase()); + logImgIntent.putExtra("type", imageType); + logImgIntent.putParcelableArrayListExtra("images", logImages); + fromActivity.startActivity(logImgIntent); } + public static void startActivitySpoilerImages(final Context fromActivity, String geocode, ArrayList<cgImage> spoilers) { + startActivity(fromActivity, geocode, spoilers, cgeoimages.SPOILER_IMAGES); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + menu.setHeaderTitle(res.getString(R.string.cache_image)); + menu.add(0, MENU_FILE, 0, res.getString(R.string.cache_image_open_file)); + menu.add(0, MENU_BROWSER, 0, res.getString(R.string.cache_image_open_browser)); + final ImageView view = (ImageView) v; + currentDrawable = (BitmapDrawable) view.getDrawable(); + currentImage = images.get(view.getId()); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + switch (item.getItemId()) { + case MENU_FILE: + viewImageInStandardApp(currentDrawable); + return true; + case MENU_BROWSER: + if (currentImage != null) { + currentImage.openInBrowser(this); + } + return true; + default: + break; + } + return super.onContextItemSelected(item); + } } diff --git a/main/src/cgeo/geocaching/cgeoinit.java b/main/src/cgeo/geocaching/cgeoinit.java index 8391f15..13a358c 100644 --- a/main/src/cgeo/geocaching/cgeoinit.java +++ b/main/src/cgeo/geocaching/cgeoinit.java @@ -33,7 +33,6 @@ import android.widget.Spinner; import android.widget.TextView; import java.io.File; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; public class cgeoinit extends AbstractActivity { @@ -603,28 +602,7 @@ public class cgeoinit extends AbstractActivity { * unused here but needed since this method is referenced from XML layout */ public void restore(View view) { - final ProgressDialog dialog = ProgressDialog.show(this, res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_running), true, false); - final AtomicBoolean atomic = new AtomicBoolean(false); - Thread restoreThread = new Thread() { - final Handler handler = new Handler() { - public void handleMessage(Message msg) { - dialog.dismiss(); - boolean restored = atomic.get(); - if (restored) { - helpDialog(res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_success)); - } else { - helpDialog(res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_failed)); - } - } - }; - - @Override - public void run() { - atomic.set(app.restoreDatabase()); - handler.sendMessage(handler.obtainMessage()); - } - }; - restoreThread.start(); + app.restoreDatabase(this); } public boolean saveValues() { diff --git a/main/src/cgeo/geocaching/cgeovisit.java b/main/src/cgeo/geocaching/cgeovisit.java index a07dfeb..3544054 100644 --- a/main/src/cgeo/geocaching/cgeovisit.java +++ b/main/src/cgeo/geocaching/cgeovisit.java @@ -674,7 +674,6 @@ public class cgeovisit extends cgLogForm { types.addAll(typesPre); types.remove(Integer.valueOf(cgBase.LOG_UPDATE_COORDINATES)); } - typesPre.clear(); } catch (Exception e) { Log.e(Settings.tag, "cgeovisit.loadData.run: " + e.toString()); } diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java index 7b0326c..39e6dee 100644 --- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java +++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java @@ -1,6 +1,6 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.ICache; import cgeo.geocaching.connector.opencaching.ApiOpenCachingConnector; import cgeo.geocaching.connector.opencaching.OpenCachingConnector; @@ -9,7 +9,7 @@ import org.apache.commons.lang3.StringUtils; public final class ConnectorFactory { private static final UnknownConnector UNKNOWN_CONNECTOR = new UnknownConnector(); private static final IConnector[] connectors = new IConnector[] { - new GCConnector(), + GCConnector.getInstance(), new OpenCachingConnector("OpenCaching.DE", "www.opencaching.de", "OC"), new OpenCachingConnector("OpenCaching.CZ", "www.opencaching.cz", "OZ"), new ApiOpenCachingConnector("OpenCaching.CO.UK", "www.opencaching.org.uk", "OK", "arU4okouc4GEjMniE2fq"), @@ -42,7 +42,7 @@ public final class ConnectorFactory { return false; } - public static IConnector getConnector(cgCache cache) { + public static IConnector getConnector(ICache cache) { return getConnector(cache.getGeocode()); } @@ -60,6 +60,6 @@ public final class ConnectorFactory { } private static boolean isInvalidGeocode(final String geocode) { - return StringUtils.isBlank(geocode); + return StringUtils.isBlank(geocode) || !Character.isLetterOrDigit(geocode.charAt(0)); } } diff --git a/main/src/cgeo/geocaching/connector/GCConnector.java b/main/src/cgeo/geocaching/connector/GCConnector.java index f81176e..8419e56 100644 --- a/main/src/cgeo/geocaching/connector/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/GCConnector.java @@ -19,6 +19,19 @@ import java.util.List; public class GCConnector extends AbstractConnector { + private static GCConnector instance; + + private GCConnector() { + // singleton + } + + public static GCConnector getInstance() { + if (instance == null) { + instance = new GCConnector(); + } + return instance; + } + @Override public boolean canHandle(String geocode) { return StringUtils.startsWithIgnoreCase(geocode, "GC"); diff --git a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java index a0af45c..c1d4586 100644 --- a/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/opencaching/OkapiClient.java @@ -111,13 +111,12 @@ final public class OkapiClient { final JSONArray images = response.getJSONArray(CACHE_IMAGES); if (images != null) { JSONObject imageResponse; - cgImage image; for (int i = 0; i < images.length(); i++) { imageResponse = images.getJSONObject(i); if (imageResponse.getBoolean(CACHE_IMAGE_IS_SPOILER)) { - image = new cgImage(); - image.title = imageResponse.getString(CACHE_IMAGE_CAPTION); - image.url = absoluteUrl(imageResponse.getString(CACHE_IMAGE_URL), cache.getGeocode()); + final String title = imageResponse.getString(CACHE_IMAGE_CAPTION); + final String url = absoluteUrl(imageResponse.getString(CACHE_IMAGE_URL), cache.getGeocode()); + final cgImage image = new cgImage(url, title); if (cache.getSpoilers() == null) { cache.setSpoilers(new ArrayList<cgImage>()); } diff --git a/main/src/cgeo/geocaching/enumerations/CacheType.java b/main/src/cgeo/geocaching/enumerations/CacheType.java index e2d3d98..ccea7c8 100644 --- a/main/src/cgeo/geocaching/enumerations/CacheType.java +++ b/main/src/cgeo/geocaching/enumerations/CacheType.java @@ -56,7 +56,7 @@ public enum CacheType { public final static CacheType getById(final String id) { if (id == null) { - return null; + return UNKNOWN; } final CacheType result = CacheType.FIND_BY_ID.get(id.toLowerCase().trim()); if (result == null) { diff --git a/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java b/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java index 359e4e8..13b8d03 100644 --- a/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java +++ b/main/src/cgeo/geocaching/enumerations/LogTypeTrackable.java @@ -23,7 +23,7 @@ public enum LogTypeTrackable { return logType; } } - return null; + return DO_NOTHING; } } diff --git a/main/src/cgeo/geocaching/enumerations/WaypointType.java b/main/src/cgeo/geocaching/enumerations/WaypointType.java index ac1cf1e..9fd783d 100644 --- a/main/src/cgeo/geocaching/enumerations/WaypointType.java +++ b/main/src/cgeo/geocaching/enumerations/WaypointType.java @@ -32,7 +32,11 @@ public enum WaypointType { this.markerId = markerId; } - public static final Map<String, WaypointType> FIND_BY_ID; + /** + * inverse lookup of waypoint IDs<br/> + * 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; static { final HashMap<String, WaypointType> mapping = new HashMap<String, WaypointType>(); for (WaypointType wt : values()) { @@ -41,4 +45,19 @@ public enum WaypointType { FIND_BY_ID = Collections.unmodifiableMap(mapping); } + /** + * inverse lookup of waypoint IDs<br/> + * here the <code>null</code> handling shall be done + */ + public static WaypointType findById(final String id) { + if (null == id) { + return WAYPOINT; + } + WaypointType waypointType = FIND_BY_ID.get(id); + if (null == waypointType) { + return WAYPOINT; + } + return waypointType; + } + } diff --git a/main/src/cgeo/geocaching/Go4Cache.java b/main/src/cgeo/geocaching/go4cache/Go4Cache.java index d2ed032..ffd5974 100644 --- a/main/src/cgeo/geocaching/Go4Cache.java +++ b/main/src/cgeo/geocaching/go4cache/Go4Cache.java @@ -1,5 +1,9 @@ -package cgeo.geocaching; +package cgeo.geocaching.go4cache; +import cgeo.geocaching.Parameters; +import cgeo.geocaching.Settings; +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter.Format; import cgeo.geocaching.geopoint.Viewport; @@ -15,6 +19,7 @@ import android.util.Log; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; @@ -35,7 +40,7 @@ public class Go4Cache extends Thread { final private cgBase base; private static Go4Cache getInstance(final cgeoapplication app) { - if (instance == null) { + if (null == instance) { synchronized(Go4Cache.class) { instance = new Go4Cache(app); instance.start(); @@ -45,6 +50,7 @@ public class Go4Cache extends Thread { } private Go4Cache(final cgeoapplication app) { + super("Go4Cache"); this.app = app; base = cgBase.getInstance(app); setPriority(Thread.MIN_PRIORITY); @@ -77,7 +83,7 @@ public class Go4Cache extends Thread { // If we are too close and we haven't changed our current action, no need // to update our situation. - if (latestCoords != null && latestCoords.distanceTo(currentCoords) < 0.75 && StringUtils.equals(latestAction, currentAction)) { + if (null != latestCoords && latestCoords.distanceTo(currentCoords) < 0.75 && StringUtils.equals(latestAction, currentAction)) { continue; } @@ -94,13 +100,13 @@ public class Go4Cache extends Thread { "ln", lonStr, "a", currentAction, "s", (CryptUtils.sha1(username + "|" + latStr + "|" + lonStr + "|" + currentAction + "|" + CryptUtils.md5("carnero: developing your dreams"))).toLowerCase()); - if (base.version != null) { + if (null != base.version) { params.put("v", base.version); } cgBase.postRequest("http://api.go4cache.com/", params); - // Update our coordinates even if the request was not succesful, as not to hammer the server + // Update our coordinates even if the request was not successful, as not to hammer the server // with invalid requests for every new GPS position. latestCoords = currentCoords; latestAction = currentAction; @@ -119,10 +125,10 @@ public class Go4Cache extends Thread { * the current viewport * @return the list of users present in the viewport */ - public static List<cgUser> getGeocachersInViewport(final String username, final Viewport viewport) { - final List<cgUser> users = new ArrayList<cgUser>(); + public static List<Go4CacheUser> getGeocachersInViewport(final String username, final Viewport viewport) { + final List<Go4CacheUser> users = new ArrayList<Go4CacheUser>(); - if (username == null) { + if (null == username) { return users; } @@ -157,7 +163,7 @@ public class Go4Cache extends Thread { /** * Parse user information from go4cache.com. * - * @param oneUser + * @param user * a JSON object * @return a cgCache user filled with information * @throws JSONException @@ -165,14 +171,13 @@ public class Go4Cache extends Thread { * @throws ParseException * if the date could not be parsed as expected */ - private static cgUser parseUser(final JSONObject oneUser) throws JSONException, ParseException { - final cgUser user = new cgUser(); - final String located = oneUser.getString("located"); - user.located = cgBase.dateSqlIn.parse(located); - user.username = oneUser.getString("user"); - user.coords = new Geopoint(oneUser.getDouble("latitude"), oneUser.getDouble("longitude")); - user.action = oneUser.getString("action"); - user.client = oneUser.getString("client"); - return user; + private static Go4CacheUser parseUser(final JSONObject user) throws JSONException, ParseException { + final String located = user.getString("located"); + final Date userlocated = cgBase.dateSqlIn.parse(located); + final String username = user.getString("user"); + final Geopoint coords = new Geopoint(user.getDouble("latitude"), user.getDouble("longitude")); + final String action = user.getString("action"); + final String client = user.getString("client"); + return new Go4CacheUser(username, coords, userlocated, action, client); } } diff --git a/main/src/cgeo/geocaching/go4cache/Go4CacheUser.java b/main/src/cgeo/geocaching/go4cache/Go4CacheUser.java new file mode 100644 index 0000000..931bdaf --- /dev/null +++ b/main/src/cgeo/geocaching/go4cache/Go4CacheUser.java @@ -0,0 +1,91 @@ +package cgeo.geocaching.go4cache; + +import cgeo.geocaching.R; +import cgeo.geocaching.geopoint.Geopoint; + +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Go4CacheUser { + private static final Pattern patternGeocode = Pattern.compile("^(GC[A-Z0-9]+)(\\: ?(.+))?$", Pattern.CASE_INSENSITIVE); + + private final Date located; + private final String username; + private final Geopoint coords; + private final String action; + private final String client; + + private String actionForDisplay; + private String geocode; + + public Go4CacheUser(final String username, final Geopoint coords, final Date located, final String action, final String client) { + this.username = username; + this.coords = coords; + this.located = located; + this.action = action; + this.client = client; + } + + public Date getLocated() { + return located; + } + + public String getUsername() { + return username; + } + + public Geopoint getCoords() { + return coords; + } + + public int getIconId() { + if (null == client) { + return -1; + } + if (client.equalsIgnoreCase("c:geo")) { + return R.drawable.client_cgeo; + } else if (client.equalsIgnoreCase("preCaching")) { + return R.drawable.client_precaching; + } else if (client.equalsIgnoreCase("Handy Geocaching")) { + return R.drawable.client_handygeocaching; + } + return -1; + } + + private void getGeocodeAndAction() { + final Matcher matcherGeocode = patternGeocode.matcher(action.trim()); + + geocode = ""; + if (0 == action.length() || action.equalsIgnoreCase("pending")) { + actionForDisplay = "Looking around"; + } else if (action.equalsIgnoreCase("tweeting")) { + actionForDisplay = "Tweeting"; + } else if (matcherGeocode.find()) { + if (null != matcherGeocode.group(1)) { + geocode = matcherGeocode.group(1).trim().toUpperCase(); + } + if (null != matcherGeocode.group(3)) { + actionForDisplay = "Heading to " + geocode + " (" + matcherGeocode.group(3).trim() + ")"; + } else { + actionForDisplay = "Heading to " + geocode; + } + } else { + actionForDisplay = action; + } + } + + public String getAction() { + if (null == actionForDisplay) { + getGeocodeAndAction(); + } + return actionForDisplay; + } + + public String getGeocode() { + if (null == geocode) { + getGeocodeAndAction(); + } + return geocode; + } +} diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index 85e916c..f59ddf0 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -1,6 +1,5 @@ package cgeo.geocaching.maps; -import cgeo.geocaching.Go4Cache; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.Settings.mapSourceEnum; @@ -12,7 +11,6 @@ import cgeo.geocaching.cgGeo; import cgeo.geocaching.cgSearch; import cgeo.geocaching.cgUpdateDir; import cgeo.geocaching.cgUpdateLoc; -import cgeo.geocaching.cgUser; import cgeo.geocaching.cgWaypoint; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.cgeocaches; @@ -22,6 +20,8 @@ import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.Viewport; +import cgeo.geocaching.go4cache.Go4Cache; +import cgeo.geocaching.go4cache.Go4CacheUser; import cgeo.geocaching.maps.interfaces.CachesOverlayItemImpl; import cgeo.geocaching.maps.interfaces.GeoPointImpl; import cgeo.geocaching.maps.interfaces.MapActivityImpl; @@ -156,7 +156,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory /** List of caches in the viewport */ private List<cgCache> caches = new ArrayList<cgCache>(); /** List of users in the viewport */ - private List<cgUser> users = new ArrayList<cgUser>(); + private List<Go4CacheUser> users = new ArrayList<Go4CacheUser>(); private List<cgCoord> coordinates = new ArrayList<cgCoord>(); // storing for offline private ProgressDialog waitDialog = null; @@ -372,7 +372,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory final double latitudeIntent = extras.getDouble(EXTRAS_LATITUDE); final double longitudeIntent = extras.getDouble(EXTRAS_LONGITUDE); coordsIntent = new Geopoint(latitudeIntent, longitudeIntent); - waypointTypeIntent = WaypointType.FIND_BY_ID.get(extras.getString(EXTRAS_WPTTYPE)); + waypointTypeIntent = WaypointType.findById(extras.getString(EXTRAS_WPTTYPE)); mapStateIntent = extras.getIntArray(EXTRAS_MAPSTATE); mapTitle = extras.getString(EXTRAS_MAP_TITLE); @@ -1529,9 +1529,9 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory */ private class DisplayUsersThread extends DoThread { - private List<cgUser> users = null; + private List<Go4CacheUser> users = null; - public DisplayUsersThread(List<cgUser> usersIn, long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { + public DisplayUsersThread(List<Go4CacheUser> usersIn, long centerLatIn, long centerLonIn, long spanLatIn, long spanLonIn) { super(centerLatIn, centerLonIn, spanLatIn, spanLonIn); setName("Display Users"); users = usersIn; @@ -1553,12 +1553,12 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory int counter = 0; OtherCachersOverlayItemImpl item = null; - for (cgUser userOne : users) { + for (Go4CacheUser userOne : users) { if (stop) { return; } - if (userOne.coords == null) { + if (userOne.getCoords() == null) { continue; } diff --git a/main/src/cgeo/geocaching/maps/CachesOverlay.java b/main/src/cgeo/geocaching/maps/CachesOverlay.java index 40da6f2..f6e3660 100644 --- a/main/src/cgeo/geocaching/maps/CachesOverlay.java +++ b/main/src/cgeo/geocaching/maps/CachesOverlay.java @@ -311,7 +311,7 @@ public class CachesOverlay extends AbstractItemizedOverlay { } else { dialog.setTitle("waypoint"); - String waypointL10N = cgBase.waypointTypes.get(WaypointType.FIND_BY_ID.get(coordinate.getTypeSpec())); + String waypointL10N = cgBase.waypointTypes.get(WaypointType.findById(coordinate.getTypeSpec())); if (waypointL10N == null) { waypointL10N = cgBase.waypointTypes.get(WaypointType.WAYPOINT); } diff --git a/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java b/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java index 33274ba..8498b29 100644 --- a/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java +++ b/main/src/cgeo/geocaching/maps/OtherCachersOverlay.java @@ -1,9 +1,8 @@ package cgeo.geocaching.maps; -import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgUser; import cgeo.geocaching.cgeodetail; +import cgeo.geocaching.go4cache.Go4CacheUser; import cgeo.geocaching.maps.interfaces.ItemizedOverlayImpl; import cgeo.geocaching.maps.interfaces.MapProjectionImpl; import cgeo.geocaching.maps.interfaces.MapViewImpl; @@ -21,14 +20,11 @@ import android.util.Log; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class OtherCachersOverlay extends AbstractItemizedOverlay { private List<OtherCachersOverlayItemImpl> items = new ArrayList<OtherCachersOverlayItemImpl>(); private Context context = null; - private final Pattern patternGeocode = Pattern.compile("^(GC[A-Z0-9]+)(\\: ?(.+))?$", Pattern.CASE_INSENSITIVE); public OtherCachersOverlay(ItemizedOverlayImpl ovlImplIn, Context contextIn) { super(ovlImplIn); @@ -71,45 +67,20 @@ public class OtherCachersOverlay extends AbstractItemizedOverlay { } final OtherCachersOverlayItemImpl item = items.get(index); - final cgUser user = item.getUser(); + final Go4CacheUser user = item.getUser(); // set action - String action = null; - String geocode = null; - final Matcher matcherGeocode = patternGeocode.matcher(user.action.trim()); - - if (user.action.length() == 0 || user.action.equalsIgnoreCase("pending")) { - action = "Looking around"; - } else if (user.action.equalsIgnoreCase("tweeting")) { - action = "Tweeting"; - } else if (matcherGeocode.find()) { - if (matcherGeocode.group(1) != null) { - geocode = matcherGeocode.group(1).trim().toUpperCase(); - } - if (matcherGeocode.group(3) != null) { - action = "Heading to " + geocode + " (" + matcherGeocode.group(3).trim() + ")"; - } else { - action = "Heading to " + geocode; - } - } else { - action = user.action; - } + String action = user.getAction(); + String geocode = user.getGeocode(); // set icon - int icon = -1; - if (user.client.equalsIgnoreCase("c:geo")) { - icon = R.drawable.client_cgeo; - } else if (user.client.equalsIgnoreCase("preCaching")) { - icon = R.drawable.client_precaching; - } else if (user.client.equalsIgnoreCase("Handy Geocaching")) { - icon = R.drawable.client_handygeocaching; - } + int icon = user.getIconId(); final AlertDialog.Builder dialog = new AlertDialog.Builder(context); if (icon > -1) { dialog.setIcon(icon); } - dialog.setTitle(user.username); + dialog.setTitle(user.getUsername()); dialog.setMessage(action); dialog.setCancelable(true); if (StringUtils.isNotBlank(geocode)) { diff --git a/main/src/cgeo/geocaching/maps/google/GoogleMapFactory.java b/main/src/cgeo/geocaching/maps/google/GoogleMapFactory.java index 55f6837..d4ac68b 100644 --- a/main/src/cgeo/geocaching/maps/google/GoogleMapFactory.java +++ b/main/src/cgeo/geocaching/maps/google/GoogleMapFactory.java @@ -2,9 +2,9 @@ package cgeo.geocaching.maps.google; import cgeo.geocaching.R; import cgeo.geocaching.cgCoord; -import cgeo.geocaching.cgUser; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.go4cache.Go4CacheUser; import cgeo.geocaching.maps.interfaces.CachesOverlayItemImpl; import cgeo.geocaching.maps.interfaces.GeoPointImpl; import cgeo.geocaching.maps.interfaces.MapFactory; @@ -43,7 +43,7 @@ public class GoogleMapFactory implements MapFactory { } @Override - public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context, cgUser userOne) { + public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context, Go4CacheUser userOne) { GoogleOtherCachersOverlayItem baseItem = new GoogleOtherCachersOverlayItem(context, userOne); return baseItem; } diff --git a/main/src/cgeo/geocaching/maps/google/GoogleOtherCachersOverlayItem.java b/main/src/cgeo/geocaching/maps/google/GoogleOtherCachersOverlayItem.java index f6fbcec..ac8e725 100644 --- a/main/src/cgeo/geocaching/maps/google/GoogleOtherCachersOverlayItem.java +++ b/main/src/cgeo/geocaching/maps/google/GoogleOtherCachersOverlayItem.java @@ -1,7 +1,7 @@ package cgeo.geocaching.maps.google; import cgeo.geocaching.R; -import cgeo.geocaching.cgUser; +import cgeo.geocaching.go4cache.Go4CacheUser; import cgeo.geocaching.maps.interfaces.OtherCachersOverlayItemImpl; import com.google.android.maps.GeoPoint; @@ -12,10 +12,10 @@ import android.graphics.drawable.Drawable; public class GoogleOtherCachersOverlayItem extends OverlayItem implements OtherCachersOverlayItemImpl { private Context context = null; - private cgUser user = null; + private Go4CacheUser user = null; - public GoogleOtherCachersOverlayItem(Context contextIn, cgUser userIn) { - super(new GeoPoint(userIn.coords.getLatitudeE6(), userIn.coords.getLongitudeE6()), userIn.username, ""); + public GoogleOtherCachersOverlayItem(Context contextIn, Go4CacheUser userIn) { + super(new GeoPoint(userIn.getCoords().getLatitudeE6(), userIn.getCoords().getLongitudeE6()), userIn.getUsername(), ""); context = contextIn; user = userIn; @@ -25,7 +25,7 @@ public class GoogleOtherCachersOverlayItem extends OverlayItem implements OtherC public Drawable getMarker(int state) { Drawable marker = null; - if (user != null && user.located != null && user.located.getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { + if (user != null && user.getLocated() != null && user.getLocated().getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { marker = context.getResources().getDrawable(R.drawable.user_location_active); } else { marker = context.getResources().getDrawable(R.drawable.user_location); @@ -38,7 +38,7 @@ public class GoogleOtherCachersOverlayItem extends OverlayItem implements OtherC return marker; } - public cgUser getUser() { + public Go4CacheUser getUser() { return user; } } diff --git a/main/src/cgeo/geocaching/maps/interfaces/MapFactory.java b/main/src/cgeo/geocaching/maps/interfaces/MapFactory.java index 814703c..3bc6b8f 100644 --- a/main/src/cgeo/geocaching/maps/interfaces/MapFactory.java +++ b/main/src/cgeo/geocaching/maps/interfaces/MapFactory.java @@ -1,9 +1,9 @@ package cgeo.geocaching.maps.interfaces; import cgeo.geocaching.cgCoord; -import cgeo.geocaching.cgUser; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.go4cache.Go4CacheUser; import android.app.Activity; import android.content.Context; @@ -28,6 +28,6 @@ public interface MapFactory { public CachesOverlayItemImpl getCachesOverlayItem(final cgCoord coordinate, final CacheType type); public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context, - cgUser userOne); + Go4CacheUser userOne); } diff --git a/main/src/cgeo/geocaching/maps/interfaces/OtherCachersOverlayItemImpl.java b/main/src/cgeo/geocaching/maps/interfaces/OtherCachersOverlayItemImpl.java index 43fc58e..cc611ed 100644 --- a/main/src/cgeo/geocaching/maps/interfaces/OtherCachersOverlayItemImpl.java +++ b/main/src/cgeo/geocaching/maps/interfaces/OtherCachersOverlayItemImpl.java @@ -1,6 +1,6 @@ package cgeo.geocaching.maps.interfaces; -import cgeo.geocaching.cgUser; +import cgeo.geocaching.go4cache.Go4CacheUser; /** * Common functions of the provider-specific @@ -11,5 +11,5 @@ import cgeo.geocaching.cgUser; */ public interface OtherCachersOverlayItemImpl extends OverlayItemImpl { - public cgUser getUser(); + public Go4CacheUser getUser(); } diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapFactory.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapFactory.java index dabd91b..3499c1d 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapFactory.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeMapFactory.java @@ -2,9 +2,9 @@ package cgeo.geocaching.maps.mapsforge; import cgeo.geocaching.R; import cgeo.geocaching.cgCoord; -import cgeo.geocaching.cgUser; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.go4cache.Go4CacheUser; import cgeo.geocaching.maps.interfaces.CachesOverlayItemImpl; import cgeo.geocaching.maps.interfaces.GeoPointImpl; import cgeo.geocaching.maps.interfaces.MapFactory; @@ -42,7 +42,7 @@ public class MapsforgeMapFactory implements MapFactory { } @Override - public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context, cgUser userOne) { + public OtherCachersOverlayItemImpl getOtherCachersOverlayItemBase(Context context, Go4CacheUser userOne) { MapsforgeOtherCachersOverlayItem baseItem = new MapsforgeOtherCachersOverlayItem(context, userOne); return baseItem; } diff --git a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOtherCachersOverlayItem.java b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOtherCachersOverlayItem.java index 6a83c16..f2cae3a 100644 --- a/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOtherCachersOverlayItem.java +++ b/main/src/cgeo/geocaching/maps/mapsforge/MapsforgeOtherCachersOverlayItem.java @@ -1,7 +1,7 @@ package cgeo.geocaching.maps.mapsforge; import cgeo.geocaching.R; -import cgeo.geocaching.cgUser; +import cgeo.geocaching.go4cache.Go4CacheUser; import cgeo.geocaching.maps.interfaces.OtherCachersOverlayItemImpl; import org.mapsforge.android.maps.GeoPoint; @@ -12,10 +12,10 @@ import android.graphics.drawable.Drawable; public class MapsforgeOtherCachersOverlayItem extends OverlayItem implements OtherCachersOverlayItemImpl { private Context context = null; - private cgUser user = null; + private Go4CacheUser user = null; - public MapsforgeOtherCachersOverlayItem(Context contextIn, cgUser userIn) { - super(new GeoPoint(userIn.coords.getLatitudeE6(), userIn.coords.getLongitudeE6()), userIn.username, ""); + public MapsforgeOtherCachersOverlayItem(Context contextIn, Go4CacheUser userIn) { + super(new GeoPoint(userIn.getCoords().getLatitudeE6(), userIn.getCoords().getLongitudeE6()), userIn.getUsername(), ""); context = contextIn; user = userIn; @@ -25,7 +25,7 @@ public class MapsforgeOtherCachersOverlayItem extends OverlayItem implements Oth public Drawable getMarker(int state) { Drawable marker = null; - if (user != null && user.located != null && user.located.getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { + if (user != null && user.getLocated() != null && user.getLocated().getTime() >= (System.currentTimeMillis() - (20 * 60 * 1000))) { marker = context.getResources().getDrawable(R.drawable.user_location_active); } else { marker = context.getResources().getDrawable(R.drawable.user_location); @@ -38,7 +38,7 @@ public class MapsforgeOtherCachersOverlayItem extends OverlayItem implements Oth return marker; } - public cgUser getUser() { + public Go4CacheUser getUser() { return user; } } diff --git a/tests/src/cgeo/geocaching/ParserTest.java b/tests/src/cgeo/geocaching/ParserTest.java index ca4a171..18a11df 100644 --- a/tests/src/cgeo/geocaching/ParserTest.java +++ b/tests/src/cgeo/geocaching/ParserTest.java @@ -1,18 +1,9 @@ package cgeo.geocaching; +import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase; import cgeo.geocaching.test.R; -import android.test.InstrumentationTestCase; - -import java.io.InputStream; -import java.util.Scanner; - -public class ParserTest extends InstrumentationTestCase { - - private String getFileContent(int resourceId) { - InputStream ins = getInstrumentation().getContext().getResources().openRawResource(resourceId); - return new Scanner(ins).useDelimiter("\\A").next(); - } +public class ParserTest extends AbstractResourceInstrumentationTestCase { public void testOwnerDecoding() { cgCacheWrap caches = cgBase.parseCacheFromText(getFileContent(R.raw.gc1zxez), 0, null); diff --git a/tests/src/cgeo/geocaching/TrackablesTest.java b/tests/src/cgeo/geocaching/TrackablesTest.java index da4afa3..f66d33c 100644 --- a/tests/src/cgeo/geocaching/TrackablesTest.java +++ b/tests/src/cgeo/geocaching/TrackablesTest.java @@ -1,15 +1,12 @@ package cgeo.geocaching; +import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase; import cgeo.geocaching.test.R; import cgeo.geocaching.utils.BaseUtils; -import android.test.InstrumentationTestCase; - -import java.io.InputStream; import java.util.List; -import java.util.Scanner; -public class TrackablesTest extends InstrumentationTestCase { +public class TrackablesTest extends AbstractResourceInstrumentationTestCase { public void testLogPageWithTrackables() { List<cgTrackableLog> tbLogs = cgBase.parseTrackableLog(getFileContent(R.raw.log_with_2tb)); @@ -52,11 +49,6 @@ public class TrackablesTest extends InstrumentationTestCase { assertNull(trackable.getOrigin()); } - private String getFileContent(int resourceId) { - InputStream ins = getInstrumentation().getContext().getResources().openRawResource(resourceId); - return new Scanner(ins).useDelimiter("\\A").next(); - } - private cgTrackable getTB2R124() { return cgBase.parseTrackable(BaseUtils.replaceWhitespace(getFileContent(R.raw.trackable_tb2r124)), null); } diff --git a/tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java b/tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java new file mode 100644 index 0000000..043a6b1 --- /dev/null +++ b/tests/src/cgeo/geocaching/connector/ConnectorFactoryTest.java @@ -0,0 +1,31 @@ +package cgeo.geocaching.connector; + +import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase; +import cgeo.geocaching.test.mock.GC1ZXX2; + +public class ConnectorFactoryTest extends AbstractResourceInstrumentationTestCase { + + public void testGetConnectors() { + IConnector[] connectors = ConnectorFactory.getConnectors(); + assertNotNull(connectors); + assertTrue(connectors.length > 0); // unknown connector must exist + } + + public void testCanHandle() { + assertFalse(ConnectorFactory.canHandle("")); + assertTrue(ConnectorFactory.canHandle("GC12345")); + assertTrue(ConnectorFactory.canHandle("some string")); // using unknown connector + assertFalse(ConnectorFactory.canHandle("[/start with special char")); + } + + public void testGetConnectorCgCache() { + assertEquals(GCConnector.getInstance(), ConnectorFactory.getConnector(new GC1ZXX2())); + } + + public void testGetConnectorString() { + IConnector connector = ConnectorFactory.getConnector("GC12345"); + assertNotNull(connector); + assertEquals(GCConnector.getInstance().getName(), connector.getName()); + } + +} diff --git a/tests/src/cgeo/geocaching/connector/opencaching/OkapiClientTest.java b/tests/src/cgeo/geocaching/connector/opencaching/OkapiClientTest.java new file mode 100644 index 0000000..ea9dcae --- /dev/null +++ b/tests/src/cgeo/geocaching/connector/opencaching/OkapiClientTest.java @@ -0,0 +1,17 @@ +package cgeo.geocaching.connector.opencaching; + +import cgeo.geocaching.cgCache; + +import android.test.AndroidTestCase; + +public class OkapiClientTest extends AndroidTestCase { + + public void testGetOCCache() { + String geoCode = "OU0331"; + cgCache cache = OkapiClient.getCache(geoCode); + assertNotNull(cache); + assertEquals(geoCode, cache.getGeocode()); + assertEquals("Oshkosh Municipal Tank", cache.getName()); + } + +} diff --git a/tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java b/tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java new file mode 100644 index 0000000..8617629 --- /dev/null +++ b/tests/src/cgeo/geocaching/enumerations/CacheSizeTest.java @@ -0,0 +1,11 @@ +package cgeo.geocaching.enumerations; + +import android.test.AndroidTestCase; + +public class CacheSizeTest extends AndroidTestCase { + public void testOrder() { + assertTrue(CacheSize.MICRO.comparable < CacheSize.SMALL.comparable); + assertTrue(CacheSize.SMALL.comparable < CacheSize.REGULAR.comparable); + assertTrue(CacheSize.REGULAR.comparable < CacheSize.LARGE.comparable); + } +} diff --git a/tests/src/cgeo/geocaching/enumerations/CacheTypeTest.java b/tests/src/cgeo/geocaching/enumerations/CacheTypeTest.java new file mode 100644 index 0000000..52c8fe1 --- /dev/null +++ b/tests/src/cgeo/geocaching/enumerations/CacheTypeTest.java @@ -0,0 +1,13 @@ +package cgeo.geocaching.enumerations; + +import android.test.AndroidTestCase; + +public class CacheTypeTest extends AndroidTestCase { + + public void testGetById() { + assertEquals(CacheType.UNKNOWN, CacheType.getById("")); + assertEquals(CacheType.UNKNOWN, CacheType.getById(null)); + assertEquals(CacheType.UNKNOWN, CacheType.getById("random garbage")); + } + +} diff --git a/tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java b/tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java new file mode 100644 index 0000000..7f26db6 --- /dev/null +++ b/tests/src/cgeo/geocaching/enumerations/LogTypeTrackableTest.java @@ -0,0 +1,11 @@ +package cgeo.geocaching.enumerations; + +import android.test.AndroidTestCase; + +public class LogTypeTrackableTest extends AndroidTestCase { + + public void testFindById() { + assertEquals(LogTypeTrackable.DO_NOTHING, LogTypeTrackable.findById(12345)); + } + +} diff --git a/tests/src/cgeo/geocaching/enumerations/WaypointTypeTest.java b/tests/src/cgeo/geocaching/enumerations/WaypointTypeTest.java new file mode 100644 index 0000000..0363205 --- /dev/null +++ b/tests/src/cgeo/geocaching/enumerations/WaypointTypeTest.java @@ -0,0 +1,11 @@ +package cgeo.geocaching.enumerations; + +import android.test.AndroidTestCase; + +public class WaypointTypeTest extends AndroidTestCase { + + public void testFindById() { + assertEquals(WaypointType.WAYPOINT, WaypointType.findById("random garbage")); + } + +} diff --git a/tests/src/cgeo/geocaching/files/GPXImporterTest.java b/tests/src/cgeo/geocaching/files/GPXImporterTest.java index 182e5e9..d23521b 100644 --- a/tests/src/cgeo/geocaching/files/GPXImporterTest.java +++ b/tests/src/cgeo/geocaching/files/GPXImporterTest.java @@ -3,21 +3,19 @@ package cgeo.geocaching.files; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgSearch; import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase; import cgeo.geocaching.test.R; import cgeo.geocaching.utils.CancellableHandler; import android.os.Message; -import android.test.InstrumentationTestCase; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class GPXImporterTest extends InstrumentationTestCase { +public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { private TestHandler importStepHandler = new TestHandler(); private TestHandler progressHandler = new TestHandler(); private int listId; @@ -132,22 +130,6 @@ public class GPXImporterTest extends InstrumentationTestCase { assertEquals(GPXImporter.IMPORT_STEP_CANCELED, importStepHandler.messages.get(1).what); } - private void copyResourceToFile(int resourceId, File file) throws IOException { - final InputStream is = getInstrumentation().getContext().getResources().openRawResource(resourceId); - final FileOutputStream os = new FileOutputStream(file); - - try { - byte[] buffer = new byte[4096]; - int byteCount; - while ((byteCount = is.read(buffer)) >= 0) { - os.write(buffer, 0, byteCount); - } - } finally { - os.close(); - is.close(); - } - } - static class TestHandler extends CancellableHandler { private final List<Message> messages = new ArrayList<Message>(); private long lastMessage = System.currentTimeMillis(); diff --git a/tests/src/cgeo/geocaching/files/GPXParserTest.java b/tests/src/cgeo/geocaching/files/GPXParserTest.java index 6f585b3..11d0161 100644 --- a/tests/src/cgeo/geocaching/files/GPXParserTest.java +++ b/tests/src/cgeo/geocaching/files/GPXParserTest.java @@ -8,11 +8,9 @@ import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; +import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase; import cgeo.geocaching.test.R; -import android.content.res.Resources; -import android.test.InstrumentationTestCase; - import java.io.IOException; import java.io.InputStream; import java.text.ParseException; @@ -21,7 +19,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class GPXParserTest extends InstrumentationTestCase { +public class GPXParserTest extends AbstractResourceInstrumentationTestCase { private static final SimpleDateFormat LOG_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); // 2010-04-20T07:00:00Z public void testGPXVersion100() throws Exception { @@ -186,8 +184,7 @@ public class GPXParserTest extends InstrumentationTestCase { private List<cgCache> readVersionedGPX(final GPXParser parser, int... resourceIds) throws IOException, ParserException { Collection<cgCache> caches = null; for (int resourceId : resourceIds) { - final Resources res = getInstrumentation().getContext().getResources(); - final InputStream instream = res.openRawResource(resourceId); + final InputStream instream = getResourceStream(resourceId); try { caches = parser.parse(instream, null); assertNotNull(caches); diff --git a/tests/src/cgeo/geocaching/files/LocParserTest.java b/tests/src/cgeo/geocaching/files/LocParserTest.java index 31e8e13..8facfe4 100644 --- a/tests/src/cgeo/geocaching/files/LocParserTest.java +++ b/tests/src/cgeo/geocaching/files/LocParserTest.java @@ -3,23 +3,20 @@ package cgeo.geocaching.files; import cgeo.geocaching.cgCache; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase; import cgeo.geocaching.test.R; -import android.content.res.Resources; -import android.test.InstrumentationTestCase; - import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class LocParserTest extends InstrumentationTestCase { +public class LocParserTest extends AbstractResourceInstrumentationTestCase { private List<cgCache> readLoc(int resourceId) throws IOException, ParserException { LocParser parser = new LocParser(1); Collection<cgCache> caches = null; - final Resources res = getInstrumentation().getContext().getResources(); - final InputStream instream = res.openRawResource(resourceId); + final InputStream instream = getResourceStream(resourceId); try { caches = parser.parse(instream, null); assertNotNull(caches); diff --git a/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java b/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java new file mode 100644 index 0000000..906b414 --- /dev/null +++ b/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java @@ -0,0 +1,38 @@ +package cgeo.geocaching.test; + +import android.content.res.Resources; +import android.test.InstrumentationTestCase; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Scanner; + +public abstract class AbstractResourceInstrumentationTestCase extends InstrumentationTestCase { + protected InputStream getResourceStream(int resourceId) { + final Resources res = getInstrumentation().getContext().getResources(); + return res.openRawResource(resourceId); + } + + protected String getFileContent(int resourceId) { + InputStream ins = getInstrumentation().getContext().getResources().openRawResource(resourceId); + return new Scanner(ins).useDelimiter("\\A").next(); + } + + protected void copyResourceToFile(int resourceId, File file) throws IOException { + final InputStream is = getResourceStream(resourceId); + final FileOutputStream os = new FileOutputStream(file); + + try { + byte[] buffer = new byte[4096]; + int byteCount; + while ((byteCount = is.read(buffer)) >= 0) { + os.write(buffer, 0, byteCount); + } + } finally { + os.close(); + is.close(); + } + } +} diff --git a/tests/src/cgeo/geocaching/test/mock/GC2JVEH.java b/tests/src/cgeo/geocaching/test/mock/GC2JVEH.java index 1c7ac5b..5ff95b3 100644 --- a/tests/src/cgeo/geocaching/test/mock/GC2JVEH.java +++ b/tests/src/cgeo/geocaching/test/mock/GC2JVEH.java @@ -97,7 +97,7 @@ public class GC2JVEH extends MockedCache { @Override public List<String> getAttributes() { - String[] attributes = new String[] { + final String[] attributes = new String[] { "winter_yes", "flashlight_yes", "stealth_yes", @@ -111,7 +111,7 @@ public class GC2JVEH extends MockedCache { @Override public Map<Integer, Integer> getLogCounts() { - Map<Integer, Integer> logCounts = new HashMap<Integer, Integer>(); + final Map<Integer, Integer> logCounts = new HashMap<Integer, Integer>(); logCounts.put(cgBase.LOG_FOUND_IT, 59); logCounts.put(cgBase.LOG_NOTE, 7); logCounts.put(cgBase.LOG_TEMP_DISABLE_LISTING, 1); @@ -122,7 +122,7 @@ public class GC2JVEH extends MockedCache { @Override public Integer getFavoritePoints() { - return new Integer(21); + return 21; } @Override @@ -132,17 +132,18 @@ public class GC2JVEH extends MockedCache { @Override public List<cgTrackable> getInventory() { - ArrayList<cgTrackable> inventory = new ArrayList<cgTrackable>(); + final ArrayList<cgTrackable> inventory = new ArrayList<cgTrackable>(); inventory.add(new cgTrackable()); return inventory; } @Override public List<cgImage> getSpoilers() { - ArrayList<cgImage> spoilers = new ArrayList<cgImage>(); - spoilers.add(new cgImage()); - spoilers.add(new cgImage()); - spoilers.add(new cgImage()); + final ArrayList<cgImage> spoilers = new ArrayList<cgImage>(); + final cgImage mockedImage = new cgImage(null, null, null); + spoilers.add(mockedImage); + spoilers.add(mockedImage); + spoilers.add(mockedImage); return spoilers; } } |
