diff --git a/.hgignore b/.hgignore index 7220e4cb0..3bf9706a8 100644 --- a/.hgignore +++ b/.hgignore @@ -2,5 +2,6 @@ syntax:glob */bin */gen/** +*/proguard/** .metadata MyTracksTest/annotations.log diff --git a/MyTracks/AndroidManifest.xml b/MyTracks/AndroidManifest.xml index e8486bb01..6f3b16692 100755 --- a/MyTracks/AndroidManifest.xml +++ b/MyTracks/AndroidManifest.xml @@ -175,6 +175,7 @@ limitations under the License. - Off + Aus 1 min 2 min 5 min @@ -70,8 +70,8 @@ limitations under the License. - batterie sparend (adaptiv) - hohe genauigkeit (adaptiv) + batteriesparend (adaptiv) + hohe Genauigkeit (adaptiv) maximal (empfohlen) 2 s 3 s @@ -133,12 +133,12 @@ limitations under the License. Nicht zerteilen - 100 meilen - 50 meilen - 25 meilen - 10 meilen - 5 meilen - 1 meile + 100 Meilen + 50 Meilen + 25 Meilen + 10 Meilen + 5 Meilen + 1 Meile 60 min 30 min 15 min @@ -159,7 +159,7 @@ limitations under the License. Laufbahn Geländelauf Gehen - Schnelles Gehen + Gehen (Sport) Wandern Bergwandern Bergsteigen @@ -181,11 +181,11 @@ limitations under the License. Eissegeln Segeln - Kanadierfahren - Kajakfahren + Paddeln + Kajak fahren Kanuwandern Rudern - Motorbootfahren + Motorboot fahren Fähre Ferngesteuertes Boot Surfen @@ -229,13 +229,14 @@ limitations under the License. Bank Kneipe Grill + Imbiss Gebäude Bushaltestelle Straßenbahnhaltestelle Bahnhof S-Bahnhof Café - Lagerfeuer + Feuerstelle Campingplatz Zeltplatz Kirche @@ -278,6 +279,7 @@ limitations under the License. Tunnel Baum Wasserfall + Springbrunnen Wegpunkt diff --git a/MyTracks/res/values-de/strings.xml b/MyTracks/res/values-de/strings.xml index 9514ddec3..a17e5ac0a 100644 --- a/MyTracks/res/values-de/strings.xml +++ b/MyTracks/res/values-de/strings.xml @@ -26,52 +26,54 @@ limitations under the License. Alle Tracks löschen Einstellungen Höhe - Bitte wählen Sie einen Track zur Ansicht aus + Bitte wähle einen Track zur Ansicht aus Aktueller Track Letztes Segment + Sensorstatus + Aggregierte Statistiken - Es wurde kein \'Location Manager\' auf diesem Gerät gefunden. - Konnte keinen GPS-Empfänger auf diesem Gerät finden. - Beim Senden Ihres Tracks an Google My Maps ist ein Fehler aufgetreten. Bitte versuchen Sie es später nochmal. - Beim Senden Ihres Tracks an Google Docs ist ein Fehler aufgetreten. Bitte versuchen Sie es später nochmal. - Aufzeichnen fehlgeschlagen. Bitte versuchen Sie es nochmal. - Anhalten unmöglich. Bitte versuchen Sie es nochmal. - Datei nicht lesbar. + Es wurde kein Dienst zur Positionsermittlung auf diesem Gerät gefunden. + Es wurde kein GPS-Empfänger auf diesem Gerät gefunden. + Beim Senden des Tracks an Google MyMaps ist ein Fehler aufgetreten. Bitte versuche es später noch einmal. + Beim Senden des Tracks an Google Docs ist ein Fehler aufgetreten. Bitte versuche es später noch einmal. + Start der Aufzeichnung fehlgeschlagen. Bitte versuche es noch einmal. + Anhalten unmöglich. Bitte versuche es noch einmal. + Konnte Datei nicht lesen. Datei ist nicht im GPX-Format. - Ein Fehler ist aufgetreten. Bitte versuchen Sie es nochmal. + Ein Fehler ist aufgetreten. Bitte versuche es noch einmal. Track existiert nicht. - Die Datei ist zu groß (Obergrenze sind 500 KB). Operation abgebrochen. + Die Datei ist zu groß (maximal 500 KB). Operation abgebrochen. Der Wegpunkt kann nicht einfügt werden. Keine Positionsbestimmung möglich. - Warten auf ein besseres GPS-Signal. Bitte stellen Sie sicher, dass der Himmel sichtbar ist. + Warte auf ein besseres GPS-Signal. Bitte stelle sicher, dass der Himmel sichtbar ist. Ein neuer Track wird aufgezeichnet. - Die Aufzeichnung wurde beendet. + Die Aufzeichnung wurde angehalten. Eine neue Karte wurde auf maps.google.com erstellt. - Ihr Track wurde auf maps.google.com gespeichert. - Ihr Track wurde in einer neuen Tabelle bei docs.google.com gespeichert. - Ihr Track wurde an docs.google.com gesendet. + Dein Track wurde auf maps.google.com gespeichert. + Dein Track wurde in einer neuen Tabelle bei docs.google.com gespeichert. + Dein Track wurde an docs.google.com gesendet. Manchmal dauert es ein paar Minuten, bis neue Tracks bei maps.google.com erscheinen. - Berühren Sie hier um zu den Sicherheits- und Positionseinstellungen zu gelangen. Aktiviere \'GPS-Satelliten\'. Drücken Sie dann den Zurück-Knopf um zurückzukehren. - Anmerkung: Eine ungefähre Position wird angezeigt, bestimmt mittels Funktürmen und WiFi-Netzwerken. - Ihre Position kann derzeit nicht bestimmt werden. Aktivieren Sie mehr Positionsquellen (siehe Sicherheits- und Positionseinstellungen) und stellen Sie sicher, dass der Himmel sichtbar ist. + Hier berühren, um zu den Sicherheits- und Positionseinstellungen zu gelangen. Aktiviere \'GPS-Satelliten\'. Drücke dann den Zurück-Knopf, um hierher zurückzukehren. + Anmerkung: Eine ungefähre Position wird angezeigt, bestimmt mittels Mobilfunkstationen und WiFi-Netzwerken. + Die Position kann derzeit nicht bestimmt werden. Aktiviere mehr Positionsquellen (siehe Sicherheits- und Positionseinstellungen) und stelle sicher, dass der Himmel sichtbar ist. Ein Wegpunkt wurde eingefügt. Ein Statistikwegpunkt wurde eingefügt. Bitte warten… - Ihr GPS-Track wird an Google gesendet. - Lese Track - Bereite Track vor - Anmelden bei Google Maps - Anmelden bei Google Docs - Track an Google Docs senden - Track an Google Maps senden - Neue \'Meine Karte\' erstellen - Importiere GPS-Track. Das dauert ein wenig. - Schreibe Datei auf SD-Karte. Das dauert ein wenig. - Aktualisiere Trackstatistik + Dein Track wird an Google gesendet... + Lese Track... + Bereite Track vor... + Anmeldung bei Google Maps... + Anmeldung bei Google Docs... + Track wird an Google Docs gesendet... + Track wird an Google Maps gesendet... + Neue \'Meine Karte\' wird erstellt... + Importiere GPS-Track. Das kann ein wenig dauern. + Schreibe Datei auf SD-Karte. Das kann ein wenig dauern. + Aktualisiere Trackstatistik... Bist Du Dir wirklich sicher? @@ -80,17 +82,19 @@ limitations under the License. Dieser Wegpunkt wird endgültig von diesem Gerät gelöscht. + Erstellt von My Tracks für Android. + Erstellt von <a href=\'http://mytracks.appspot.com\'>My Tracks</a> für Android. Neue Karte Punkte Aufgezeichnet am - "Aktivität" - "Art des Wegpunktes" - "(Teil %d)" + Aktivität + Art des Wegpunktes + (Teil %d) - "Ihr Track wird aufgezeichnet…" + Dein Track wird aufgezeichnet… Nein @@ -100,7 +104,7 @@ limitations under the License. Wegpunkt - (Anfang) + (Beginn) (Ende) @@ -114,15 +118,22 @@ limitations under the License. Auf SD-Karte speichern… GPX-Datei exportieren KML-Datei exportieren + CSV-Datei exportieren + TCX-Datei exportieren An Google MyMaps senden Alle Tracks löschen - Eine Track auswählen. Lange berühren für mehr Optionen. - Alle Tracks: + + Alle Tracks exportieren + Exportieren beendet + Einen Track auswählen. Lange berühren für mehr Optionen. + Alle Tracks Dieser Track Mit Freunden teilen… Ein Link zur Google MyMaps-Karte Eine GPX-Datei Eine KML-Datei + Eine CSV-Datei + Eine TCX-Datei Karte zurücksetzen. @@ -150,64 +161,99 @@ limitations under the License. Einstellungen für My Tracks Anzeige - Aufzeichnen - Mit Freunden Teilen + Aufzeichnung + Mit Freunden teilen - Dauer zwischen Ansagen: - Kürzeste Zeit zwichen zwei Ansagen + In dieser Android-Version nicht verfügbar + + Dauer zwischen Ansagen + Kürzeste Zeit zwischen zwei Ansagen - Kleinste Entfernung zwischen Punkten: + Kleinste Entfernung zwischen Punkten Kleinste Entfernung zwischen zwei Positionsaufzeichnungen - Neues Segment wenn Punkte weiter entfernt als: - Der Track wird in Zwei geteilt wenn zwei folgende Punkte weiter entfernt sind als hier angegeben. + Neues Segment, wenn Punkte weiter entfernt als + Der Track wird in zwei geteilt, wenn zwei folgende Punkte weiter entfernt sind als hier angegeben. - Aufzeichnungsfrequenz: - Kürzeste Zeit zwischen zwei Positionsaufzeichnungen. + Aufzeichnungsfrequenz + Kürzeste Zeit zwischen zwei Positionsaufzeichnungen - Aufzeichnung pausieren wenn Genauigkeit kleiner als: - Die Aufzeichnung wird kurzfristig angehalten, wenn Ihre Position nicht genauer als hier angegeben ermittelt werden kann. + Aufzeichnung pausieren, wenn Genauigkeit kleiner als + Die Aufzeichnung wird kurzfristig angehalten, wenn Deine Position nicht genauer als hier angegeben ermittelt werden kann. Entfernungen in metrischen Einheiten anzeigen Alle Entfernungen werden in metrischen Einheiten angezeigt. - Alle Entfernungen werden in britischen Längeneinheiten angezeigt. + Alle Entfernungen werden in imperialen Längeneinheiten angezeigt. Karten auf maps.google.com veröffentlichen Hochgeladene Karten auf maps.google.com sind für alle sichtbar. Hochgeladene Karten auf maps.google.com werden nicht öffentlich sichtbar aufgelistet. - Geschwindigkeitsanzeige: + Geschwindigkeitsanzeige Geschwindigkeit wird angezeigt. - Gangart wird angezeigt. + Pace wird angezeigt. Nur URL als Einladung zum Teilen senden - Beim teilen mit Freunden wird nur die Karten URL gesendet. - Beim teilen mit Freunden wird der GPS Track selbst gesendet. + Beim Teilen mit Freunden wird nur die Karten-URL gesendet. + Beim Teilen mit Freunden wird der GPS-Track selbst gesendet. - Zerteilungs Frequenz - Längste Dauer oder Entfernung nach der automatisch ein Marker eingefügt wird. - Tempo + Zerteilungsfrequenz + Längste Dauer oder Entfernung, nach der automatisch ein Marker eingefügt wird. + + Zeitbegrenzung der Auto-Wiederaufnahme + Maximale Zeit in Minuten, nach der eine abgebrochene Aufzeichnung nach einem Telefonneustart wiederaufgenommen wird. + + Zeitstempel als Trackname + Der Trackname wird aus Datum und Zeit zum Aufzeichnungsbeginn zusammengesetzt. + Tracknamen erhalten eine fortlaufende Nummer. + + Pace + + Wird nur unter Android 2.0 oder höher unterstützt + Sensortyp + Der Typ des zu verbindenden Sensors + Sensor-Id + Die zum Sensor zu sendende Id + Die Id muss eine Ganzzahl sein. + Bluetooth-Sensor + Der zu verbindende Bluetoothsensor + Art der Datenanzeige + + Datensicherung (BETA) + SD-Karten-Sicherung + Jetzt sichern + Eine Kopie aller Deiner Tracks und Einstellungen auf die SD-Karte schreiben + Jetzt wiederherstellen + Alle Tracks und Einstellungen von der SD-Karte holen. + Während ein Track aufgezeichnet wird, kann nicht mit der Datensicherung gearbeitet werden. + + + Eine Wiederherstellung von der SD-Karte ÜBERSCHREIBT alle vorhandenen Tracks und Einstellungen. Willst Du das wirklich? + Wähle die wiederherzustellende Datensicherung aus + Keine Datensicherungen gefunden. + Schreibe alle Tracks und Einstellungen auf die SD-Karte. Dies kann eine Weile dauern... + Lese alle Tracks und Einstellungen von der SD-Karte. Dies kann eine Weile dauern... GPS-Satelliten - Wähle eine Karte von Deinem Konto aus: + Wähle eine Karte von Deinem Konto aus Neue Karte erstellen… An Google My Maps senden Karten werden geladen… - Ihre Karten konnten im Augenblick nicht geladen werden! + Deine Karten konnten im Augenblick nicht geladen werden! Diese Karte auswählen Kartendetails bearbeiten Karte mit Freunden teilen Track mit Freunden teilen Karte vom Konto löschen - Kartentitel: - Trackbeschreibung: - Diese Karte und Ihren Inhalt in Suchergebnissen sichtbar machen. - Diese Karte und Ihren Inhalt nicht in Suchergebnissen sichtbar machen. - Diese Karte und Ihr Inhalt sind in Suchergebnissen sichtbar. - Weder diese Karte noch Ihr Inhalt sind in Suchergebnissen sichtbar, allerdings können Sie trotzdem von anderen durch einen direkten Link angezeigt werden. + Kartentitel + Trackbeschreibung + Diese Karte und ihren Inhalt in Suchergebnissen sichtbar machen. + Diese Karte und ihren Inhalt nicht in Suchergebnissen sichtbar machen. + Diese Karte und ihr Inhalt sind in Suchergebnissen sichtbar. + Weder diese Karte noch ihr Inhalt sind in Suchergebnissen sichtbar, allerdings kann sie trotzdem von anderen durch einen direkten Link angezeigt werden. Schließen Bearbeiten Abbrechen @@ -222,6 +268,8 @@ limitations under the License. Vielleicht interessierst Du Dich für diese Track: %s. + + Öffentlich Nicht in Suchergebnissen enthalten. Du hast noch keine Karten. @@ -229,11 +277,11 @@ limitations under the License. Durchschnitt in Bew. - Durchschnitt in Bew. + Pace in Bew. Durchschnittsgeschw. - Durchschnittstempo + Durchschnitts-Pace Höhenprofil Höhengewinn @@ -244,7 +292,7 @@ limitations under the License. Niedrigste Höhenlage Minimale Steigung - Schnellstes Tempo + Minimaler Pace Höchste Höhenlage @@ -254,14 +302,14 @@ limitations under the License. Lade Track… - Diagram Einstellungen + Diagramm-Einstellungen - X Achse + X-Achse Nach Entfernung Nach Zeit - Y Achse + Y-Achse @@ -282,7 +330,7 @@ limitations under the License. Kilometer pro Stunde pro Kilometer Meilen pro Stunde - pro meile + pro Meile Zeit in Bewegung @@ -290,10 +338,14 @@ limitations under the License. Zeit SD-Karte nicht verfügbar Geschwindigkeit - Sie müssen erst eine Strecke zurücklegen. + Du musst erst eine Aufzeichnung beginnen. Statistik Gesamtentfernung Entfernung + Energie + Kadenz + Herzfrequenz + Höchste Herzfrequenz Bitte warten… @@ -316,22 +368,24 @@ limitations under the License. Kein Konto vorhanden - Kein Konto gefunden um Tracks zu versenden. - Wählen Sei ein Konto + Kein Konto gefunden, um Tracks zu versenden. + Wähle ein Konto - Keine externes Speichermedium verfügbar. Stellen Sie sicher, dass eine SD-Karte vorhanden ist und nicht bereits von einem Computer darauf zugegriffen wird. + Keine externes Speichermedium verfügbar. Stelle sicher, dass eine SD-Karte vorhanden ist und nicht bereits von einem Computer darauf zugegriffen wird. Die Datei kann nicht geschrieben werden. + Die Datei konnte nicht gelesen werden. Das Verzeichnis auf der SD-Karte kann nicht erstellt werden. Der Track wurde auf die SD-Karte geschrieben. + Lesen von der SD-Karte beendet. Suche nach neuer Version Jetzt aktualisieren - Fortfahren ohne zu aktualisieren - Ihre Version von %1$s funktioniert möglicherweise nicht mehr richtig und wird nicht mehr unterstützt. Bitte aktualisieren Sie %1$s. - Ihre Version von %1$s funktioniert möglicherweise nicht mehr richtig. Sie können sie jetzt aktualisieren, oder auf sie auf eigene Gefahr weiterverwenden. Einige Funktionen wie Datenaustausch mit Google-Diensten wird möglicherweise nicht mehr funktionieren, solange Sie die Software nicht aktualisieren. - Eine neue Version von %1$s ist jetzt verfügbar. Sie können Ihre aktuelle Version ohne Probleme weiterverwenden, aber um die neuesten Funktionen in Anspruch nehmen zu können, müssen sie die Software aktualisieren. + Fortfahren, ohne zu aktualisieren + Deine Version von %1$s funktioniert möglicherweise nicht mehr richtig und wird nicht mehr unterstützt. Bitte aktualisiere %1$s. + Deine Version von %1$s funktioniert möglicherweise nicht mehr richtig. Du kannst sie jetzt aktualisieren, oder auf sie auf eigene Gefahr weiterverwenden. Einige Funktionen wie Datenaustausch mit Google-Diensten werden möglicherweise nicht mehr funktionieren, solange Du die Software nicht aktualisierst. + Eine neue Version von %1$s ist jetzt verfügbar. Du kannst Deine installierte Version ohne Probleme weiterverwenden, aber um die neuesten Funktionen in Anspruch nehmen zu können, musst Du die Software aktualisieren. Willkommen @@ -348,4 +402,40 @@ limitations under the License. $6 : Speed units (mph) : Pace units (per mile) --> My Tracks %1$s %2$.2f %3$s in %4$s mit %5$s %6$s + + + Einheitenbenachrichtigung + Voreingestellt sind metrische Einheiten. Willst Du diese Einstellung ändern? + + + Bluetootheinstellungen + Geräteverbindung + Öffnet Androids Bluetootheinstellungen, um Geräte zu verbinden. + Sensoreinstellungen + + + Verbunden mit %s + Verbinde mit Bluetoothsensor ... + Bluetoothsensor nicht verbunden. + + + Sensor Data Time + Energiemessung aktiviert + Herzfrequenzmessung aktiviert + Keine Sensoren verfügbar + Aktiviert + Verbinde... + Verbunden + Getrennt + Kein Sensor-Dienst + Suche... + Sende... + + + Track-Aufzeichnungs-Benachrichtigungen empfangen + Aufgezeichnete Trackdaten lesen + Aufgezeichnete Trackdaten schreiben, Starten/Anhalten des Aufzeichnens von Tracks + Werde benachrichtigt, wenn die Aufzeichnung eines Tracks beginnt oder anhält. + Ermöglicht das Lesen von Trackdaten wie Messpunkten oder Wegpunkten. + Ermöglicht das Schreiben von Trackdaten wie beim Starten der Aufzeichnung oder beim Hinzufügen von Wegpunkten. diff --git a/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java b/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java index 5947f8900..d1fc56029 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java +++ b/MyTracks/src/com/google/android/apps/mytracks/CheckUnits.java @@ -16,6 +16,7 @@ package com.google.android.apps.mytracks; +import com.google.android.apps.mytracks.util.ApiFeatures; import com.google.android.maps.mytracks.R; import android.app.Activity; @@ -82,7 +83,8 @@ class CheckUnits { } private static void recordCheckPerformed(SharedPreferences preferences) { - preferences.edit().putBoolean(PREFERENCE_UNITS_CHECKED, true).commit(); + ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges( + preferences.edit().putBoolean(PREFERENCE_UNITS_CHECKED, true)); } private CheckUnits() { diff --git a/MyTracks/src/com/google/android/apps/mytracks/Eula.java b/MyTracks/src/com/google/android/apps/mytracks/Eula.java index f070e310a..4471d93fc 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/Eula.java +++ b/MyTracks/src/com/google/android/apps/mytracks/Eula.java @@ -15,6 +15,7 @@ */ package com.google.android.apps.mytracks; +import com.google.android.apps.mytracks.util.ApiFeatures; import com.google.android.apps.mytracks.util.ResourceUtils; import com.google.android.maps.mytracks.R; @@ -77,7 +78,8 @@ class Eula { } private static void accept(Activity activity, SharedPreferences preferences) { - preferences.edit().putBoolean(PREFERENCE_EULA_ACCEPTED, true).commit(); + ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges( + preferences.edit().putBoolean(PREFERENCE_EULA_ACCEPTED, true)); Intent startIntent = new Intent(activity, WelcomeActivity.class); activity.startActivityForResult(startIntent, MyTracksConstants.WELCOME); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java index ddf9306eb..c4ed31c11 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java @@ -41,6 +41,7 @@ import com.google.android.apps.mytracks.services.StatusAnnouncerFactory; import com.google.android.apps.mytracks.services.TrackRecordingService; import com.google.android.apps.mytracks.util.ApiFeatures; import com.google.android.apps.mytracks.util.FileUtils; +import com.google.android.apps.mytracks.util.MyTracksUtils; import com.google.android.maps.mytracks.R; import android.app.Activity; @@ -251,6 +252,11 @@ public class MyTracks extends TabActivity implements OnTouchListener, Log.d(MyTracksConstants.TAG, "MyTracks.onCreate"); super.onCreate(savedInstanceState); instance = this; + ApiFeatures apiFeatures = ApiFeatures.getInstance(); + if (!MyTracksUtils.isRelease(this)) { + apiFeatures.getApiPlatformAdapter().enableStrictMode(); + } + providerUtils = MyTracksProviderUtils.Factory.get(this); menuManager = new MenuManager(this); sharedPreferences = getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0); @@ -258,7 +264,7 @@ public class MyTracks extends TabActivity implements OnTouchListener, // The volume we want to control is the Text-To-Speech volume int volumeStream = - new StatusAnnouncerFactory(ApiFeatures.getInstance()).getVolumeStream(); + new StatusAnnouncerFactory(apiFeatures).getVolumeStream(); setVolumeControlStream(volumeStream); // We don't need a window title bar: @@ -1058,10 +1064,10 @@ public class MyTracks extends TabActivity implements OnTouchListener, * @param trackId the id of the track */ public void setSelectedTrackId(final long trackId) { - sharedPreferences - .edit() - .putLong(getString(R.string.selected_track_key), trackId) - .commit(); + ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges( + sharedPreferences + .edit() + .putLong(getString(R.string.selected_track_key), trackId)); } long getSelectedTrackId() { diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java index 8a5f255f1..1e939b144 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java @@ -16,6 +16,7 @@ package com.google.android.apps.mytracks; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; +import com.google.android.apps.mytracks.util.ApiFeatures; import com.google.android.maps.mytracks.R; import android.app.AlertDialog; @@ -63,7 +64,7 @@ public class MyTracksDeleteAllTracks extends Handler { context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0); SharedPreferences.Editor editor = prefs.edit(); editor.putLong(context.getString(R.string.selected_track_key), -1); - editor.commit(); + ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges(editor); if (done != null) { Handler h = new Handler(); h.post(done); diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java b/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java index 06727cd2d..7f1016856 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java @@ -62,24 +62,18 @@ public class ApiFeatures { * Allow subclasses for mocking, but no direct instantiation. */ protected ApiFeatures() { - if (getApiLevel() >= 5) { - try { - Class clazz = Class.forName( - "com.google.android.apps.mytracks.util.EclairPlatformAdapter"); - apiPlatformAdapter = (ApiPlatformAdapter) clazz.newInstance(); - } catch (Exception e) { - Log.i(MyTracksConstants.TAG, "ApiFeatures: Unable to instantiate Eclair" - + " platform adapter", e); - } - } - if (apiPlatformAdapter == null) { + if (getApiLevel() >= 9) { + apiPlatformAdapter = new GingerbreadPlatformAdapter(); + } else if (getApiLevel() >= 5) { + apiPlatformAdapter = new EclairPlatformAdapter(); + } else { Log.i(MyTracksConstants.TAG, "ApiFeatures: Using default platform adapter"); // Cupcake adapter is always supported, so it's safe to do static linkage. apiPlatformAdapter = new CupcakePlatformAdapter(); } } - + public ApiPlatformAdapter getApiPlatformAdapter() { return apiPlatformAdapter; } @@ -107,7 +101,11 @@ public class ApiFeatures { return true; } - + + public boolean hasStrictMode() { + return getApiLevel() >= 9; + } + // Visible for testing. protected int getApiLevel() { return ANDROID_API_LEVEL; diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ApiPlatformAdapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/ApiPlatformAdapter.java index 1e2a5210a..c68832735 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ApiPlatformAdapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ApiPlatformAdapter.java @@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.util; import android.app.Notification; import android.app.NotificationManager; import android.app.Service; +import android.content.SharedPreferences; import android.os.HandlerThread; /** @@ -57,4 +58,15 @@ public interface ApiPlatformAdapter { * @return true whether the handler has been stopped or not. */ boolean stopHandlerThread(HandlerThread handlerThread); + + /** + * Applies all changes done to the given preferences editor. + * Changes may or may not be applied immediately. + */ + void applyPreferenceChanges(SharedPreferences.Editor editor); + + /** + * Enables strict mode where supported, only if this is a development build. + */ + void enableStrictMode(); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/CupcakePlatformAdapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/CupcakePlatformAdapter.java index 272b47218..354f0a307 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/CupcakePlatformAdapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/CupcakePlatformAdapter.java @@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.util; import android.app.Notification; import android.app.NotificationManager; import android.app.Service; +import android.content.SharedPreferences.Editor; import android.os.HandlerThread; /** @@ -50,4 +51,14 @@ public class CupcakePlatformAdapter implements ApiPlatformAdapter { // Do nothing, as Cupcake doesn't provide quit(). return false; } + + @Override + public void applyPreferenceChanges(Editor editor) { + editor.commit(); + } + + @Override + public void enableStrictMode() { + // Not supported + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/EclairPlatformAdapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/EclairPlatformAdapter.java index 9c32946d3..91c1ea1d3 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/EclairPlatformAdapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/EclairPlatformAdapter.java @@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.util; import android.app.Notification; import android.app.NotificationManager; import android.app.Service; +import android.content.SharedPreferences.Editor; import android.os.HandlerThread; /** @@ -45,4 +46,14 @@ public class EclairPlatformAdapter implements ApiPlatformAdapter { public boolean stopHandlerThread(HandlerThread handlerThread) { return handlerThread.quit(); } + + @Override + public void applyPreferenceChanges(Editor editor) { + editor.commit(); + } + + @Override + public void enableStrictMode() { + // Not supported + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/GingerbreadPlatformAdapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/GingerbreadPlatformAdapter.java new file mode 100644 index 000000000..caa73a170 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/util/GingerbreadPlatformAdapter.java @@ -0,0 +1,36 @@ +package com.google.android.apps.mytracks.util; + +import com.google.android.apps.mytracks.MyTracksConstants; + +import android.content.SharedPreferences.Editor; +import android.os.StrictMode; +import android.util.Log; + +/** + * The Gingerbread (API level 9) specific implememntation of the + * {@link ApiPlatformAdapter}. + * + * @author Rodrigo Damazio + */ +public class GingerbreadPlatformAdapter extends EclairPlatformAdapter { + @Override + public void applyPreferenceChanges(Editor editor) { + // Apply asynchronously + editor.apply(); + } + + @Override + public void enableStrictMode() { + Log.d(MyTracksConstants.TAG, "Enabling strict mode"); + StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() + .detectDiskWrites() + .detectNetwork() + .penaltyLog() + .build()); + StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() + .detectAll() + .penaltyLog() + .penaltyDeath() + .build()); + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/MyTracksUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/MyTracksUtils.java index 71caa003c..52f5dee72 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/MyTracksUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/MyTracksUtils.java @@ -21,7 +21,12 @@ import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.maps.GeoPoint; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.Signature; import android.location.Location; +import android.os.StrictMode; import android.util.Log; import java.util.ArrayList; @@ -34,6 +39,7 @@ import java.util.Stack; * @author Leif Hendrik Wilden */ public class MyTracksUtils { + private static final int RELEASE_SIGNATURE_HASHCODE = -1855564782; /** * Computes the distance on the two sphere between the point c0 and the line @@ -246,6 +252,25 @@ public class MyTracksUtils { (int) (location.getLongitude() * 1E6)); } + /** + * Returns whether or not this is a release build. + */ + public static boolean isRelease(Context context) { + try { + Signature [] sigs = context.getPackageManager().getPackageInfo( + context.getPackageName(), PackageManager.GET_SIGNATURES).signatures; + for (Signature sig : sigs) { + if (sig.hashCode() == RELEASE_SIGNATURE_HASHCODE) { + return true; + } + } + } catch (NameNotFoundException e) { + Log.e(MyTracksConstants.TAG, "Unable to get signatures", e); + } + + return false; + } + /** * This is a utility class w/ only static memebers. */ diff --git a/MyTracksLib/default.properties b/MyTracksLib/default.properties index 948be06ed..1694c805b 100644 --- a/MyTracksLib/default.properties +++ b/MyTracksLib/default.properties @@ -8,5 +8,5 @@ # project structure. # Project target. -target=android-8 +target=android-9 android.library=true diff --git a/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java b/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java index 5d134effb..4e90d7227 100644 --- a/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java +++ b/MyTracksLib/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java @@ -861,18 +861,22 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils { String select = TracksColumns._ID + "=" + id; return findTrackBy(select); } - + @Override public List getAllTracks() { Cursor cursor = getTracksCursor(null); - if (cursor == null || !cursor.moveToFirst()) { - return new ArrayList(); - } + ArrayList tracks = new ArrayList(); + if (cursor != null) { + tracks.ensureCapacity(cursor.getCount()); - List tracks = new ArrayList(cursor.getCount()); - do { - tracks.add(createTrack(cursor)); - } while(cursor.moveToNext()); + if (cursor.moveToFirst()) { + do { + tracks.add(createTrack(cursor)); + } while(cursor.moveToNext()); + } + + cursor.close(); + } return tracks; } diff --git a/MyTracksTest/default.properties b/MyTracksTest/default.properties index c4fb0851b..85cbfc4dd 100644 --- a/MyTracksTest/default.properties +++ b/MyTracksTest/default.properties @@ -10,4 +10,4 @@ # Indicates whether an apk should be generated for each density. split.density=false # Project target. -target=Google Inc.:Google APIs:8 +target=Google Inc.:Google APIs:9 diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/PreferenceBackupHelperTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/PreferenceBackupHelperTest.java index 0cdd7c626..e2c8b3b48 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/PreferenceBackupHelperTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/PreferenceBackupHelperTest.java @@ -38,7 +38,7 @@ public class PreferenceBackupHelperTest extends TestCase { */ private class MockPreferenceEditor implements SharedPreferences.Editor { private Map newPreferences = new HashMap(preferenceValues); - + @Override public Editor clear() { newPreferences.clear(); @@ -51,6 +51,11 @@ public class PreferenceBackupHelperTest extends TestCase { return true; } + @Override + public void apply() { + commit(); + } + @Override public Editor putBoolean(String key, boolean value) { return put(key, value); diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java index 9f3e0e186..db0236aa2 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java @@ -502,7 +502,7 @@ public class TrackRecordingServiceTest public void testDeleteAllTracks_trackInProgress() throws Exception { createDummyTrack(123, -1, true); assertEquals(1, providerUtils.getAllTracks().size()); - + ITrackRecordingService service = bindAndGetService(createStartIntent()); assertTrue(service.isRecording()); diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactoryTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactoryTest.java index 8af73b13c..3951aa3c1 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactoryTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactoryTest.java @@ -43,9 +43,9 @@ public class SensorManagerFactoryTest extends AndroidTestCase { private void assertClassForName(Class c, int i) { sharedPreferences.edit() - .putString(getContext().getString(R.string.sensor_type_key), - getContext().getString(i)) - .commit(); + .putString(getContext().getString(R.string.sensor_type_key), + getContext().getString(i)) + .commit(); SensorManager sm = SensorManagerFactory.getSensorManager(getContext()); assertNotNull(sm); assertTrue(c.isInstance(sm)); diff --git a/SignalStrengthSampler/AndroidManifest.xml b/SignalStrengthSampler/AndroidManifest.xml index 03d216a34..9ede9ed88 100644 --- a/SignalStrengthSampler/AndroidManifest.xml +++ b/SignalStrengthSampler/AndroidManifest.xml @@ -54,7 +54,8 @@ limitations under the License. - diff --git a/SignalStrengthSampler/default.properties b/SignalStrengthSampler/default.properties index 45aae789b..903536e41 100644 --- a/SignalStrengthSampler/default.properties +++ b/SignalStrengthSampler/default.properties @@ -8,5 +8,6 @@ # project structure. # Project target. -target=Google Inc.:Google APIs:8 +target=Google Inc.:Google APIs:9 +proguard.config=proguard.cfg android.library.reference.1=../MyTracksLib/ diff --git a/SignalStrengthSamplerTest/default.properties b/SignalStrengthSamplerTest/default.properties index 420db56e3..77f7ad75b 100644 --- a/SignalStrengthSamplerTest/default.properties +++ b/SignalStrengthSamplerTest/default.properties @@ -8,4 +8,4 @@ # project structure. # Project target. -target=Google Inc.:Google APIs:8 +target=Google Inc.:Google APIs:9