mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 09:33:06 +02:00
Merging to Sandor's renaming.
This commit is contained in:
@@ -5,4 +5,3 @@ syntax:glob
|
||||
*/proguard/**
|
||||
.metadata
|
||||
MyTracksTest/annotations.log
|
||||
MyTracks/src/com/google/android/apps/mytracks/io/mymaps
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry exported="true" kind="lib" path="/MyTracksLib/libs/protobuf-java-2.3.0-lite.jar"/>
|
||||
<classpathentry kind="lib" path="libs/libmymaps.jar"/>
|
||||
<classpathentry kind="src" path="MyTracksLib_src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -17,8 +17,8 @@ limitations under the License.
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.google.android.maps.mytracks"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="25"
|
||||
android:versionName="1.1.3rc1">
|
||||
android:versionCode="26"
|
||||
android:versionName="1.1.4rc1">
|
||||
<application android:icon="@drawable/arrow_icon"
|
||||
android:label="@string/app_name"
|
||||
android:backupAgent="com.google.android.apps.mytracks.io.backup.MyTracksBackupAgent">
|
||||
@@ -61,16 +61,16 @@ limitations under the License.
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale"
|
||||
android:exported="false" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyTracksList"
|
||||
<activity android:name="com.google.android.apps.mytracks.TrackList"
|
||||
android:label="Recorded Tracks" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyTracksWaypointsList"
|
||||
<activity android:name="com.google.android.apps.mytracks.WaypointsList"
|
||||
android:label="Recorded Waypoints" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyTracksDetails"
|
||||
<activity android:name="com.google.android.apps.mytracks.TrackDetails"
|
||||
android:label="@string/trackdetails_title" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyTracksWaypointDetails"
|
||||
<activity android:name="com.google.android.apps.mytracks.WaypointDetails"
|
||||
android:label="@string/waypointdetails_title" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyTracksSettings"
|
||||
|
||||
Binary file not shown.
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2010 Google Inc.
|
||||
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -31,7 +31,7 @@ limitations under the License.
|
||||
<string name="current_segment">Letztes Segment</string>
|
||||
<string name="sensor_state">Sensorstatus</string>
|
||||
<string name="aggregated_stats">Aggregierte Statistiken</string>
|
||||
|
||||
|
||||
<!-- Error messages -->
|
||||
<string name="error_no_location_manager">Es wurde kein Dienst zur Positionsermittlung auf diesem Gerät gefunden.</string>
|
||||
<string name="error_no_gps_location_provider">Es wurde kein GPS-Empfänger auf diesem Gerät gefunden.</string>
|
||||
@@ -45,7 +45,7 @@ limitations under the License.
|
||||
<string name="error_track_does_not_exist">Track existiert nicht.</string>
|
||||
<string name="error_out_of_memory">Die Datei ist zu groß (maximal 500 KB). Operation abgebrochen.</string>
|
||||
<string name="error_unable_to_insert_marker">Der Wegpunkt kann nicht einfügt werden. Keine Positionsbestimmung möglich.</string>
|
||||
|
||||
|
||||
<!-- Status messages -->
|
||||
<string name="wait_for_fix">Warte auf ein besseres GPS-Signal. Bitte stelle sicher, dass der Himmel sichtbar ist.</string>
|
||||
<string name="status_now_recording">Ein neuer Track wird aufgezeichnet.</string>
|
||||
@@ -59,7 +59,7 @@ limitations under the License.
|
||||
<string name="status_no_location">Die Position kann derzeit nicht bestimmt werden. Aktiviere mehr Positionsquellen (siehe Sicherheits- und Positionseinstellungen) und stelle sicher, dass der Himmel sichtbar ist.</string>
|
||||
<string name="status_waypoint_inserted">Ein Wegpunkt wurde eingefügt.</string>
|
||||
<string name="status_statistics_inserted">Ein Statistikwegpunkt wurde eingefügt.</string>
|
||||
|
||||
|
||||
<!-- Progress dialog -->
|
||||
<string name="progress_title">Bitte warten…</string>
|
||||
<string name="progress_message">Dein Track wird an Google gesendet...</string>
|
||||
@@ -73,28 +73,28 @@ limitations under the License.
|
||||
<string name="import_progress_message">Importiere GPS-Track. Das kann ein wenig dauern.</string>
|
||||
<string name="write_progress_message">Schreibe Datei auf SD-Karte. Das kann ein wenig dauern.</string>
|
||||
<string name="progress_message_updating_track">Aktualisiere Trackstatistik...</string>
|
||||
|
||||
|
||||
<!-- Used by DeleteAllDataHandler -->
|
||||
<string name="are_you_sure_question">Bist Du Dir wirklich sicher?</string>
|
||||
<string name="all_data_will_be_permanently_deleted">Alle Tracks und Wegpunkte werden endgültig von diesem Gerät gelöscht.</string>
|
||||
<string name="track_will_be_permanently_deleted">Dieser Track und seine Wegpunkte werden endgültig von diesem Gerät gelöscht.</string>
|
||||
<string name="marker_will_be_permanently_deleted">Dieser Wegpunkt wird endgültig von diesem Gerät gelöscht.</string>
|
||||
|
||||
|
||||
<!-- Text and links when uploading to Google Fusion Tables -->
|
||||
<string name="new_map_description">Erstellt von My Tracks für Android.</string>
|
||||
<string name="fusiontable_link">Erstellt von <a href=\'http://mytracks.appspot.com\'>My Tracks</a> für Android.</string>
|
||||
|
||||
|
||||
<!-- Formatting of track and marker descriptions -->
|
||||
<string name="points">Punkte</string>
|
||||
<string name="recorded_date">Aufgezeichnet am</string>
|
||||
<string name="category">Aktivität</string>
|
||||
<string name="waypoint_category">Art des Wegpunktes</string>
|
||||
<string name="part">(Teil %d)</string>
|
||||
|
||||
|
||||
<!-- Used by the track recording service -->
|
||||
<string name="recording_your_track">Dein Track wird aufgezeichnet…</string>
|
||||
<!--string name="new_track">Track %d</string-->
|
||||
|
||||
|
||||
<!-- Common -->
|
||||
<string name="no">Nein</string>
|
||||
<string name="yes">Ja</string>
|
||||
@@ -111,7 +111,7 @@ limitations under the License.
|
||||
<!-- Placemark labels for start and end of track -->
|
||||
<!--string name="start">(Start)</string-->
|
||||
<string name="end">(Ende)</string>
|
||||
|
||||
|
||||
<!-- TrackList -->
|
||||
<string name="tracklist_show_track">Anzeigen</string>
|
||||
<string name="tracklist_send_to_fusiontables">An eine Google Fusion Tables-Karte senden</string>
|
||||
@@ -140,7 +140,7 @@ limitations under the License.
|
||||
<string name="tracklist_share_csv_file">Eine CSV-Datei</string>
|
||||
<string name="tracklist_share_tcx_file">Eine TCX-Datei</string>
|
||||
<string name="tracklist_clear_map">Karte zurücksetzen.</string>
|
||||
|
||||
|
||||
<!-- Waypoints list -->
|
||||
<string name="waypointslist_btn_delete_all">Alle Wegpunkte löschen</string>
|
||||
<string name="waypointslist_this_waypoint">Dieser Wegpunkt</string>
|
||||
@@ -150,70 +150,70 @@ limitations under the License.
|
||||
<string name="waypointslist_btn_insert_waypoint">Wegpunkt einfügen</string>
|
||||
<string name="waypointslist_btn_insert_statistics">Statistik einfügen</string>
|
||||
<string name="waypointslist_pick_one">Wegpunkt auswählen. Lange berühren für mehr Optionen.</string>
|
||||
|
||||
|
||||
<!-- MyTracks Details -->
|
||||
<string name="trackdetails_title">Trackdetails</string>
|
||||
<string name="trackdetails_name">Name</string>
|
||||
<string name="trackdetails_description">Beschreibung</string>
|
||||
<string name="trackdetails_category">Aktivität (z. B. Wandern, Fahrradfahren, Laufen, Klettern…)</string>
|
||||
|
||||
|
||||
<!-- MyTracks Waypoint Details -->
|
||||
<string name="waypointdetails_title">Wegpunktdetails</string>
|
||||
<string name="waypointdetails_name">Wegpunktname</string>
|
||||
<string name="waypointdetails_description">Wegpunktbeschreibung</string>
|
||||
<string name="waypointdetails_category">Art des Wegpunktes (z. B. Gebäude, Schlagloch, Sehenswürdigkeit…)</string>
|
||||
|
||||
|
||||
<!-- MyTracks Settings -->
|
||||
<string name="mytracks_settings">Einstellungen für My Tracks</string>
|
||||
<string name="settings_display">Anzeige</string>
|
||||
<string name="settings_recording">Aufzeichnung</string>
|
||||
<string name="settings_sharing">Mit Freunden teilen</string>
|
||||
|
||||
|
||||
<string name="settings_not_available_summary">In dieser Android-Version nicht verfügbar</string>
|
||||
|
||||
|
||||
<string name="settings_announcement_frequency">Dauer zwischen Ansagen</string>
|
||||
<string name="settings_announcement_frequency_summary">Kürzeste Zeit zwischen zwei Ansagen</string>
|
||||
|
||||
|
||||
<string name="settings_min_recording_distance">Kleinste Entfernung zwischen Punkten</string>
|
||||
<string name="settings_min_recording_distance_summary">Kleinste Entfernung zwischen zwei Positionsaufzeichnungen</string>
|
||||
|
||||
|
||||
<string name="settings_max_recording_distance">Neues Segment, wenn Punkte weiter entfernt als</string>
|
||||
<string name="settings_max_recording_distance_summary">Der Track wird in zwei geteilt, wenn zwei folgende Punkte weiter entfernt sind als hier angegeben.</string>
|
||||
|
||||
|
||||
<string name="settings_min_recording_interval">Aufzeichnungsfrequenz</string>
|
||||
<string name="settings_min_recording_interval_summary">Kürzeste Zeit zwischen zwei Positionsaufzeichnungen</string>
|
||||
|
||||
|
||||
<string name="settings_min_required_accuracy">Aufzeichnung pausieren, wenn Genauigkeit kleiner als</string>
|
||||
<string name="settings_min_required_accuracy_summary">Die Aufzeichnung wird kurzfristig angehalten, wenn Deine Position nicht genauer als hier angegeben ermittelt werden kann.</string>
|
||||
|
||||
|
||||
<string name="settings_metric_units">Entfernungen in metrischen Einheiten anzeigen</string>
|
||||
<string name="settings_metric_units_summary_on">Alle Entfernungen werden in metrischen Einheiten angezeigt.</string>
|
||||
<string name="settings_metric_units_summary_off">Alle Entfernungen werden in imperialen Längeneinheiten angezeigt.</string>
|
||||
|
||||
|
||||
<string name="settings_map_public">Karten auf maps.google.com veröffentlichen</string>
|
||||
<string name="settings_map_public_summary_on">Hochgeladene Karten auf maps.google.com sind für alle sichtbar.</string>
|
||||
<string name="settings_map_public_summary_off">Hochgeladene Karten auf maps.google.com werden nicht öffentlich sichtbar aufgelistet.</string>
|
||||
|
||||
|
||||
<string name="settings_report_speed_or_pace">Geschwindigkeitsanzeige</string>
|
||||
<string name="settings_report_speed_or_pace_summary_on">Geschwindigkeit wird angezeigt.</string>
|
||||
<string name="settings_report_speed_or_pace_summary_off">Pace wird angezeigt.</string>
|
||||
|
||||
|
||||
<string name="settings_share_url_only">Nur URL als Einladung zum Teilen senden</string>
|
||||
<string name="settings_share_url_only_summary_on">Beim Teilen mit Freunden wird nur die Karten-URL gesendet.</string>
|
||||
<string name="settings_share_url_only_summary_off">Beim Teilen mit Freunden wird der GPS-Track selbst gesendet.</string>
|
||||
|
||||
|
||||
<string name="settings_split_frequency">Zerteilungsfrequenz</string>
|
||||
<string name="settings_split_frequency_summary">Längste Dauer oder Entfernung, nach der automatisch ein Marker eingefügt wird.</string>
|
||||
|
||||
|
||||
<string name="settings_auto_resume_track_timeout">Zeitbegrenzung der Auto-Wiederaufnahme</string>
|
||||
<string name="settings_auto_resume_track_timeout_summary">Maximale Zeit in Minuten, nach der eine abgebrochene Aufzeichnung nach einem Telefonneustart wiederaufgenommen wird.</string>
|
||||
|
||||
|
||||
<string name="settings_timestamp_track_name">Zeitstempel als Trackname</string>
|
||||
<string name="settings_timestamp_track_name_summary_on">Der Trackname wird aus Datum und Zeit zum Aufzeichnungsbeginn zusammengesetzt.</string>
|
||||
<string name="settings_timestamp_track_name_summary_off">Tracknamen erhalten eine fortlaufende Nummer.</string>
|
||||
|
||||
|
||||
<string name="pace_label">Pace</string>
|
||||
|
||||
|
||||
<string name="eclair_required">Wird nur unter Android 2.0 oder höher unterstützt</string>
|
||||
<string name="settings_sensor_type">Sensortyp</string>
|
||||
<string name="settings_sensor_type_summary">Der Typ des zu verbindenden Sensors</string>
|
||||
@@ -225,7 +225,7 @@ limitations under the License.
|
||||
<string name="bluetooth_sensor_title">Bluetooth-Sensor</string>
|
||||
<string name="bluetooth_sensor_summary">Der zu verbindende Bluetoothsensor</string>
|
||||
<string name="settings_modular_stats_display_title">Art der Datenanzeige</string>
|
||||
|
||||
|
||||
<!-- Backups -->
|
||||
<string name="settings_backup">Datensicherung (BETA)</string>
|
||||
<string name="settings_sd_backup">SD-Karten-Sicherung</string>
|
||||
@@ -234,13 +234,13 @@ limitations under the License.
|
||||
<string name="settings_restore_from_sd">Jetzt wiederherstellen</string>
|
||||
<string name="settings_restore_from_sd_summary">Alle Tracks und Einstellungen von der SD-Karte holen.</string>
|
||||
<string name="settings_no_backup_while_recording">Während ein Track aufgezeichnet wird, kann nicht mit der Datensicherung gearbeitet werden.</string>
|
||||
|
||||
|
||||
<string name="restore_overwrites_warning">Eine Wiederherstellung von der SD-Karte ÜBERSCHREIBT alle vorhandenen Tracks und Einstellungen. Willst Du das wirklich?</string>
|
||||
<string name="select_backup_to_restore">Wähle die wiederherzustellende Datensicherung aus</string>
|
||||
<string name="no_backups">Keine Datensicherungen gefunden.</string>
|
||||
<string name="backup_write_progress_message">Schreibe alle Tracks und Einstellungen auf die SD-Karte. Dies kann eine Weile dauern...</string>
|
||||
<string name="backup_import_progress_message">Lese alle Tracks und Einstellungen von der SD-Karte. Dies kann eine Weile dauern...</string>
|
||||
|
||||
|
||||
<!-- MyTracksSky -->
|
||||
<string name="mytracks_sky">GPS-Satelliten</string>
|
||||
|
||||
@@ -248,12 +248,12 @@ limitations under the License.
|
||||
<string name="share_map">Karte mit Freunden teilen</string>
|
||||
<string name="share_map_subject">Ich möchte gerne eine Karte mit Dir teilen.</string>
|
||||
<string name="share_map_body_format">Vielleicht interessierst Du Dich für diese Karte:
|
||||
|
||||
|
||||
%s</string>
|
||||
<string name="send_track_subject">Ich möchte einen GPS-Track mit Dir teilen</string>
|
||||
<string name="send_track_body_format">Vielleicht interessierst Du Dich für diese Track:
|
||||
|
||||
%s.</string>
|
||||
|
||||
Der Track kann mit Google Earth oder anderer Karten-Software visualisiert werden.</string>
|
||||
<string name="share_track">Track mit Freunden teilen</string>
|
||||
|
||||
<!-- Visibility -->
|
||||
@@ -265,39 +265,39 @@ limitations under the License.
|
||||
<!-- Average Moving -->
|
||||
<string name="average_moving_speed_label">Durchschnitt in Bew.</string>
|
||||
<string name="average_moving_pace_label">Pace in Bew.</string>
|
||||
|
||||
|
||||
<!-- Average -->
|
||||
<string name="average_speed_label">Durchschnittsgeschw.</string>
|
||||
<string name="average_pace_label">Durchschnitts-Pace</string>
|
||||
|
||||
|
||||
<string name="elevation_chart_name">Höhenprofil</string>
|
||||
<string name="elevation_gain_label">Höhengewinn</string>
|
||||
<string name="elevation_label">Höhe</string>
|
||||
<string name="latitude_label">Breitengrad</string>
|
||||
<string name="longitude_label">Längengrad</string>
|
||||
|
||||
|
||||
<!-- Min -->
|
||||
<string name="min_elevation_label">Niedrigste Höhenlage</string>
|
||||
<string name="min_grade_label">Minimale Steigung</string>
|
||||
<string name="min_pace_label">Minimaler Pace</string>
|
||||
|
||||
|
||||
<!-- Max -->
|
||||
<string name="max_elevation_label">Höchste Höhenlage</string>
|
||||
<string name="max_grade_label">Maximale Steigung</string>
|
||||
<string name="max_speed_label">Max. Geschwindigkeit</string>
|
||||
|
||||
|
||||
<string name="loading_track">Lade Track…</string>
|
||||
|
||||
|
||||
<!-- Chart Settings -->
|
||||
<string name="chart_settings">Diagramm-Einstellungen</string>
|
||||
<!-- X Axis -->
|
||||
<string name="x_axis">X-Achse</string>
|
||||
<string name="by_distance">Nach Entfernung</string>
|
||||
<string name="by_time">Nach Zeit</string>
|
||||
|
||||
|
||||
<!-- Y Axis -->
|
||||
<string name="y_axis">Y-Achse</string>
|
||||
|
||||
|
||||
<!-- Units -->
|
||||
<!-- Time -->
|
||||
<string name="hour">Stunde</string>
|
||||
@@ -309,7 +309,7 @@ limitations under the License.
|
||||
<string name="second">Sekunde</string>
|
||||
<string name="seconds">Sekunden</string>
|
||||
<!--string name="milliseconds">ms</string-->
|
||||
|
||||
|
||||
<!-- Distance -->
|
||||
<!--string name="meter">m</string-->
|
||||
<!--string name="kilometer">km</string-->
|
||||
@@ -317,7 +317,7 @@ limitations under the License.
|
||||
<string name="feet">Fuß</string>
|
||||
<!--string name="mile">mi</string-->
|
||||
<string name="miles_long">Meilen</string>
|
||||
|
||||
|
||||
<!-- Speed and Pace -->
|
||||
<!--string name="kilometer_per_hour">km/h</string-->
|
||||
<string name="kilometer_per_hour_long">Kilometer pro Stunde</string>
|
||||
@@ -350,12 +350,12 @@ limitations under the License.
|
||||
<string name="max_heart_rate">Höchste Herzfrequenz</string>
|
||||
<!--string name="unknown">-</string-->
|
||||
<string name="waiting">Bitte warten…</string>
|
||||
|
||||
|
||||
<!-- End User License Agreement -->
|
||||
<string name="eula_title">Lizenzvereinbarung für Endverbraucher</string>
|
||||
<string name="accept">Akzeptieren</string>
|
||||
<string name="decline">Ablehnen</string>
|
||||
|
||||
|
||||
<!-- About -->
|
||||
<string name="about">Über</string>
|
||||
<string name="help">Hilfe</string>
|
||||
@@ -363,7 +363,7 @@ limitations under the License.
|
||||
<!--string name="about_version">Version:</string-->
|
||||
<string name="about_support">Unterstützung:</string>
|
||||
<string name="about_privacy">Datenschutz:</string>
|
||||
|
||||
|
||||
<!-- Send to Google -->
|
||||
<string name="sendtogoogle_title">Senden an…</string>
|
||||
<!--string name="sendtogoogle_google_fusiontables">Google Fusion Tables</string-->
|
||||
@@ -371,12 +371,12 @@ limitations under the License.
|
||||
<string name="sendtogoogle_send_now">Jetzt senden</string>
|
||||
<string name="sendtogoogle_send_stats">Trackstatistik senden</string>
|
||||
<string name="sendtogoogle_send_stats_and_points">Statistik und Punkte senden</string>
|
||||
|
||||
|
||||
<!-- Getting the account to upload to. -->
|
||||
<string name="no_account_found_title">Kein Konto vorhanden</string>
|
||||
<string name="no_account_found">Kein Konto gefunden, um Tracks zu versenden.</string>
|
||||
<string name="choose_account_title">Wähle ein Konto</string>
|
||||
|
||||
|
||||
<!-- SD card -->
|
||||
<string name="io_no_external_storage_found">Keine externes Speichermedium verfügbar. Stelle sicher, dass eine SD-Karte vorhanden ist und nicht bereits von einem Computer darauf zugegriffen wird.</string>
|
||||
<string name="io_write_failed">Die Datei kann nicht geschrieben werden.</string>
|
||||
@@ -384,7 +384,7 @@ limitations under the License.
|
||||
<string name="io_create_dir_failed">Das Verzeichnis auf der SD-Karte kann nicht erstellt werden.</string>
|
||||
<string name="io_write_finished">Der Track wurde auf die SD-Karte geschrieben.</string>
|
||||
<string name="io_read_finished">Lesen von der SD-Karte beendet.</string>
|
||||
|
||||
|
||||
<!-- VersionChecker -->
|
||||
<string name="version_check_title">Suche nach neuer Version</string>
|
||||
<string name="version_check_upgrade_button">Jetzt aktualisieren</string>
|
||||
@@ -392,12 +392,12 @@ limitations under the License.
|
||||
<string name="upgrade_required">Deine Version von %1$s funktioniert möglicherweise nicht mehr richtig und wird nicht mehr unterstützt. Bitte aktualisiere %1$s.</string>
|
||||
<string name="upgrade_recommended">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.</string>
|
||||
<string name="upgrade_available">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.</string>
|
||||
|
||||
|
||||
<!-- Welcome -->
|
||||
<string name="welcome">Willkommen</string>
|
||||
<string name="welcome_read_later">OK</string>
|
||||
<string name="welcome_about">Über My Tracks</string>
|
||||
|
||||
|
||||
<!-- Announcement -->
|
||||
<string name="announce_no_distance">My Tracks keine Entfernung</string>
|
||||
<!-- Format:
|
||||
@@ -409,11 +409,11 @@ limitations under the License.
|
||||
$6 : Speed units (mph) : Pace units (per mile)
|
||||
-->
|
||||
<string name="announce_template">My Tracks %1$s %2$.2f %3$s in %4$s mit %5$s %6$s</string>
|
||||
|
||||
|
||||
<!-- Check Units -->
|
||||
<string name="check_units_title">Einheitenbenachrichtigung</string>
|
||||
<string name="check_units_message">Voreingestellt sind metrische Einheiten. Willst Du diese Einstellung ändern?</string>
|
||||
|
||||
|
||||
<!-- Fake preference keys - never saved, but show options in the preferences screen -->
|
||||
<string name="method_bluetooth">Bluetooth</string>
|
||||
<string name="bluetooth_options">Bluetooth-Einstellungen</string>
|
||||
@@ -421,12 +421,12 @@ limitations under the License.
|
||||
<string name="bluetooth_pairing_summary">Öffnet Androids Bluetooth-Einstellungen, um Geräte zu verbinden.</string>
|
||||
<!--string name="sensor_bluetooth_options_key">bluetoothSensorsEnabled</string-->
|
||||
<string name="sensor_options">Sensor-Einstellungen</string>
|
||||
|
||||
|
||||
<!-- Bluetooth Sensor -->
|
||||
<string name="bluetooth_connected">Verbunden mit %s</string>
|
||||
<string name="bluetooth_connecting">Verbinde mit Bluetooth-Sensor ...</string>
|
||||
<string name="bluetooth_not_connected">Bluetooth-Sensor nicht verbunden.</string>
|
||||
|
||||
|
||||
<!-- Sensor State -->
|
||||
<string name="sensor_data_time">Uhrzeit</string>
|
||||
<string name="power_meter_enabled">Kraftmesser aktiviert</string>
|
||||
@@ -439,7 +439,7 @@ limitations under the License.
|
||||
<string name="no_sensor_service">Kein Sensor-Dienst</string>
|
||||
<string name="searching">Suche...</string>
|
||||
<string name="sending">Sende...</string>
|
||||
|
||||
|
||||
<!-- Manifest description (not seen inside the app) -->
|
||||
<string name="notification_permission_label">Track-Aufzeichnungs-Benachrichtigungen empfangen</string>
|
||||
<string name="read_tracks_permission_label">Aufgezeichnete Trackdaten lesen</string>
|
||||
|
||||
@@ -59,7 +59,7 @@ public class AccountChooser {
|
||||
public void chooseAccount(final Activity activity,
|
||||
final AccountHandler handler) {
|
||||
final Account[] accounts = AccountManager.get(activity)
|
||||
.getAccountsByType(MyTracksConstants.ACCOUNT_TYPE);
|
||||
.getAccountsByType(Constants.ACCOUNT_TYPE);
|
||||
if (accounts.length < 1) {
|
||||
alertNoAccounts(activity, handler);
|
||||
return;
|
||||
@@ -76,7 +76,7 @@ public class AccountChooser {
|
||||
}
|
||||
|
||||
// Let the user choose.
|
||||
Log.e(MyTracksConstants.TAG, "Multiple matching accounts found.");
|
||||
Log.e(Constants.TAG, "Multiple matching accounts found.");
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setTitle(R.string.choose_account_title);
|
||||
builder.setCancelable(false);
|
||||
@@ -112,7 +112,7 @@ public class AccountChooser {
|
||||
*/
|
||||
private void alertNoAccounts(final Activity activity,
|
||||
final AccountHandler handler) {
|
||||
Log.e(MyTracksConstants.TAG, "No matching accounts found.");
|
||||
Log.e(Constants.TAG, "No matching accounts found.");
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setTitle(R.string.no_account_found_title);
|
||||
builder.setMessage(R.string.no_account_found);
|
||||
|
||||
@@ -40,7 +40,7 @@ public class AggregatedStatsActivity extends Activity implements
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
|
||||
String key) {
|
||||
Log.d(MyTracksConstants.TAG, "StatsActivity: onSharedPreferences changed "
|
||||
Log.d(Constants.TAG, "StatsActivity: onSharedPreferences changed "
|
||||
+ key);
|
||||
if (key != null) {
|
||||
if (key.equals(R.string.metric_units_key)) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.ChartView.Mode;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
@@ -55,9 +55,9 @@ import java.util.ArrayList;
|
||||
public class ChartActivity extends Activity implements TrackDataListener {
|
||||
|
||||
private final DoubleBuffer elevationBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
private final DoubleBuffer speedBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.SPEED_SMOOTHING_FACTOR);
|
||||
new DoubleBuffer(Constants.SPEED_SMOOTHING_FACTOR);
|
||||
private final ArrayList<double[]> pendingPoints = new ArrayList<double[]>();
|
||||
|
||||
private TrackDataHub dataHub;
|
||||
@@ -186,7 +186,7 @@ public class ChartActivity extends Activity implements TrackDataListener {
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
chartSettingsMenuItem =
|
||||
menu.add(0, MyTracksConstants.MENU_CHART_SETTINGS, 0,
|
||||
menu.add(0, Constants.MENU_CHART_SETTINGS, 0,
|
||||
R.string.chart_settings);
|
||||
chartSettingsMenuItem.setIcon(R.drawable.chart_settings);
|
||||
return true;
|
||||
@@ -195,7 +195,7 @@ public class ChartActivity extends Activity implements TrackDataListener {
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MyTracksConstants.MENU_CHART_SETTINGS:
|
||||
case Constants.MENU_CHART_SETTINGS:
|
||||
MyTracks.getInstance().getDialogManager().showDialogSafely(
|
||||
DialogManager.DIALOG_CHART_SETTINGS);
|
||||
return true;
|
||||
|
||||
@@ -527,7 +527,7 @@ public class ChartView extends View {
|
||||
}
|
||||
if (nearestWaypoint != null && dmin < 100) {
|
||||
Intent intent =
|
||||
new Intent(getContext(), MyTracksWaypointDetails.class);
|
||||
new Intent(getContext(), WaypointDetails.class);
|
||||
intent.putExtra("waypointid", nearestWaypoint.getId());
|
||||
getContext().startActivity(intent);
|
||||
return true;
|
||||
|
||||
+28
-28
@@ -20,7 +20,7 @@ package com.google.android.apps.mytracks;
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public abstract class MyTracksConstants {
|
||||
public abstract class Constants {
|
||||
|
||||
/**
|
||||
* Should be used by all log statements
|
||||
@@ -188,32 +188,32 @@ public abstract class MyTracksConstants {
|
||||
|
||||
public static int getActionFromMenuId(int menuId) {
|
||||
switch (menuId) {
|
||||
case MyTracksConstants.MENU_SEND_TO_GOOGLE:
|
||||
return MyTracksConstants.SEND_TO_GOOGLE_DIALOG;
|
||||
case MyTracksConstants.MENU_EDIT:
|
||||
return MyTracksConstants.EDIT_DETAILS;
|
||||
case MyTracksConstants.MENU_DELETE:
|
||||
return MyTracksConstants.DELETE_TRACK;
|
||||
case MyTracksConstants.MENU_SHARE_LINK:
|
||||
return MyTracksConstants.SHARE_LINK;
|
||||
case MyTracksConstants.MENU_SHARE_KML_FILE:
|
||||
return MyTracksConstants.SHARE_KML_FILE;
|
||||
case MyTracksConstants.MENU_SHARE_GPX_FILE:
|
||||
return MyTracksConstants.SHARE_GPX_FILE;
|
||||
case MyTracksConstants.MENU_SHARE_CSV_FILE:
|
||||
return MyTracksConstants.SHARE_CSV_FILE;
|
||||
case MyTracksConstants.MENU_SHARE_TCX_FILE:
|
||||
return MyTracksConstants.SHARE_TCX_FILE;
|
||||
case MyTracksConstants.MENU_SAVE_GPX_FILE:
|
||||
return MyTracksConstants.SAVE_GPX_FILE;
|
||||
case MyTracksConstants.MENU_SAVE_KML_FILE:
|
||||
return MyTracksConstants.SAVE_KML_FILE;
|
||||
case MyTracksConstants.MENU_SAVE_CSV_FILE:
|
||||
return MyTracksConstants.SAVE_CSV_FILE;
|
||||
case MyTracksConstants.MENU_SAVE_TCX_FILE:
|
||||
return MyTracksConstants.SAVE_TCX_FILE;
|
||||
case MyTracksConstants.MENU_CLEAR_MAP:
|
||||
return MyTracksConstants.CLEAR_MAP;
|
||||
case Constants.MENU_SEND_TO_GOOGLE:
|
||||
return Constants.SEND_TO_GOOGLE_DIALOG;
|
||||
case Constants.MENU_EDIT:
|
||||
return Constants.EDIT_DETAILS;
|
||||
case Constants.MENU_DELETE:
|
||||
return Constants.DELETE_TRACK;
|
||||
case Constants.MENU_SHARE_LINK:
|
||||
return Constants.SHARE_LINK;
|
||||
case Constants.MENU_SHARE_KML_FILE:
|
||||
return Constants.SHARE_KML_FILE;
|
||||
case Constants.MENU_SHARE_GPX_FILE:
|
||||
return Constants.SHARE_GPX_FILE;
|
||||
case Constants.MENU_SHARE_CSV_FILE:
|
||||
return Constants.SHARE_CSV_FILE;
|
||||
case Constants.MENU_SHARE_TCX_FILE:
|
||||
return Constants.SHARE_TCX_FILE;
|
||||
case Constants.MENU_SAVE_GPX_FILE:
|
||||
return Constants.SAVE_GPX_FILE;
|
||||
case Constants.MENU_SAVE_KML_FILE:
|
||||
return Constants.SAVE_KML_FILE;
|
||||
case Constants.MENU_SAVE_CSV_FILE:
|
||||
return Constants.SAVE_CSV_FILE;
|
||||
case Constants.MENU_SAVE_TCX_FILE:
|
||||
return Constants.SAVE_TCX_FILE;
|
||||
case Constants.MENU_CLEAR_MAP:
|
||||
return Constants.CLEAR_MAP;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -225,5 +225,5 @@ public abstract class MyTracksConstants {
|
||||
/**
|
||||
* This is an abstract utility class.
|
||||
*/
|
||||
protected MyTracksConstants() { }
|
||||
protected Constants() { }
|
||||
}
|
||||
+3
-3
@@ -34,12 +34,12 @@ import android.util.Log;
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksDeleteAllTracks extends Handler {
|
||||
public class DeleteAllTracks extends Handler {
|
||||
|
||||
private final Context context;
|
||||
private final Runnable done;
|
||||
|
||||
public MyTracksDeleteAllTracks(Context context, Runnable done) {
|
||||
public DeleteAllTracks(Context context, Runnable done) {
|
||||
this.context = context;
|
||||
this.done = done;
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public class MyTracksDeleteAllTracks extends Handler {
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int i) {
|
||||
dialog.dismiss();
|
||||
Log.w(MyTracksConstants.TAG, "deleting all!");
|
||||
Log.w(Constants.TAG, "deleting all!");
|
||||
MyTracksProviderUtils.Factory.get(context).deleteAllTracks();
|
||||
SharedPreferences prefs =
|
||||
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendDialog;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
@@ -96,7 +98,7 @@ public class DialogManager {
|
||||
activity.resetSendToGoogleStatus();
|
||||
break;
|
||||
case DIALOG_CHART_SETTINGS:
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks.onPrepare chart dialog");
|
||||
Log.d(TAG, "MyTracks.onPrepare chart dialog");
|
||||
chartSettingsDialog.setup(activity.getChartActivity());
|
||||
break;
|
||||
}
|
||||
@@ -170,11 +172,9 @@ public class DialogManager {
|
||||
try {
|
||||
activity.showDialog(id);
|
||||
} catch (BadTokenException e) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"Could not display dialog with id " + id, e);
|
||||
Log.w(TAG, "Could not display dialog with id " + id, e);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"Could not display dialog with id " + id, e);
|
||||
Log.w(TAG, "Could not display dialog with id " + id, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -190,9 +190,9 @@ public class DialogManager {
|
||||
try {
|
||||
dialog.show();
|
||||
} catch (BadTokenException e) {
|
||||
Log.w(MyTracksConstants.TAG, "Could not display dialog", e);
|
||||
Log.w(TAG, "Could not display dialog", e);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.w(MyTracksConstants.TAG, "Could not display dialog", e);
|
||||
Log.w(TAG, "Could not display dialog", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -98,7 +98,7 @@ class Eula {
|
||||
ApiFeatures.getInstance().getApiPlatformAdapter().applyPreferenceChanges(
|
||||
preferences.edit().putBoolean(PREFERENCE_EULA_ACCEPTED, true));
|
||||
Intent startIntent = new Intent(activity, WelcomeActivity.class);
|
||||
activity.startActivityForResult(startIntent, MyTracksConstants.WELCOME);
|
||||
activity.startActivityForResult(startIntent, Constants.WELCOME);
|
||||
}
|
||||
|
||||
private static void refuse(Activity activity) {
|
||||
|
||||
@@ -71,14 +71,14 @@ public class ExportAllTracks {
|
||||
format = TrackFileFormat.TCX;
|
||||
break;
|
||||
default:
|
||||
Log.w(MyTracksConstants.TAG, "Unknown export format: " + which);
|
||||
Log.w(Constants.TAG, "Unknown export format: " + which);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public ExportAllTracks(Activity activity) {
|
||||
this.activity = activity;
|
||||
Log.i(MyTracksConstants.TAG, "ExportAllTracks: Starting");
|
||||
Log.i(Constants.TAG, "ExportAllTracks: Starting");
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setSingleChoiceItems(R.array.export_formats, 0, itemClick);
|
||||
@@ -130,9 +130,9 @@ public class ExportAllTracks {
|
||||
// TODO check what happens if we started recording after getting this lock.
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
wakeLock.release();
|
||||
Log.i(MyTracksConstants.TAG, "ExportAllTracks: Releasing wake lock.");
|
||||
Log.i(Constants.TAG, "ExportAllTracks: Releasing wake lock.");
|
||||
}
|
||||
Log.i(MyTracksConstants.TAG, "ExportAllTracks: Done");
|
||||
Log.i(Constants.TAG, "ExportAllTracks: Done");
|
||||
Toast.makeText(activity, R.string.export_done, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public class ExportAllTracks {
|
||||
}
|
||||
|
||||
final int trackCount = cursor.getCount();
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"ExportAllTracks: Exporting: " + cursor.getCount() + " tracks.");
|
||||
int idxTrackId = cursor.getColumnIndexOrThrow(TracksColumns._ID);
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@@ -186,7 +186,7 @@ public class ExportAllTracks {
|
||||
});
|
||||
|
||||
long id = cursor.getLong(idxTrackId);
|
||||
Log.i(MyTracksConstants.TAG, "ExportAllTracks: exporting: " + id);
|
||||
Log.i(Constants.TAG, "ExportAllTracks: exporting: " + id);
|
||||
TrackWriter writer =
|
||||
TrackWriterFactory.newWriter(activity, providerUtils, id, format);
|
||||
writer.writeTrack();
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ImportAllTracks {
|
||||
|
||||
public ImportAllTracks(Activity activity) {
|
||||
this.activity = activity;
|
||||
Log.i(MyTracksConstants.TAG, "ImportAllTracks: Starting");
|
||||
Log.i(Constants.TAG, "ImportAllTracks: Starting");
|
||||
fileUtils = new FileUtils();
|
||||
gpxPath = fileUtils.buildExternalDirectoryPath("gpx");
|
||||
HandlerThread handlerThread;
|
||||
@@ -98,10 +98,10 @@ public class ImportAllTracks {
|
||||
// TODO check what happens if we started recording after getting this lock.
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
wakeLock.release();
|
||||
Log.i(MyTracksConstants.TAG, "ImportAllTracks: Releasing wake lock.");
|
||||
Log.i(Constants.TAG, "ImportAllTracks: Releasing wake lock.");
|
||||
}
|
||||
|
||||
Log.i(MyTracksConstants.TAG, "ImportAllTracks: Done");
|
||||
Log.i(Constants.TAG, "ImportAllTracks: Done");
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
if (gpxFileCount == 0) {
|
||||
builder.setMessage(activity.getString(R.string.import_empty, gpxPath + "/"));
|
||||
@@ -141,7 +141,7 @@ public class ImportAllTracks {
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(MyTracksConstants.TAG, "ImportAllTracks: Importing: " + gpxFileCount + " tracks.");
|
||||
Log.i(Constants.TAG, "ImportAllTracks: Importing: " + gpxFileCount + " tracks.");
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
makeProgressDialog(gpxFileCount);
|
||||
@@ -180,19 +180,19 @@ public class ImportAllTracks {
|
||||
* notifications and returns false on failure.
|
||||
*/
|
||||
private boolean importFile(File gpxFile, MyTracksProviderUtils providerUtils) {
|
||||
Log.i(MyTracksConstants.TAG, "ImportAllTracks: importing: " + gpxFile.getName());
|
||||
Log.i(Constants.TAG, "ImportAllTracks: importing: " + gpxFile.getName());
|
||||
try {
|
||||
GpxImporter.importGPXFile(new FileInputStream(gpxFile), providerUtils);
|
||||
return true;
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(MyTracksConstants.TAG, "GPX file wasn't found/went missing: "
|
||||
Log.w(Constants.TAG, "GPX file wasn't found/went missing: "
|
||||
+ gpxFile.getAbsolutePath(), e);
|
||||
} catch (ParserConfigurationException e) {
|
||||
Log.w(MyTracksConstants.TAG, "Error parsing file: " + gpxFile.getAbsolutePath(), e);
|
||||
Log.w(Constants.TAG, "Error parsing file: " + gpxFile.getAbsolutePath(), e);
|
||||
} catch (SAXException e) {
|
||||
Log.w(MyTracksConstants.TAG, "Error parsing file: " + gpxFile.getAbsolutePath(), e);
|
||||
Log.w(Constants.TAG, "Error parsing file: " + gpxFile.getAbsolutePath(), e);
|
||||
} catch (IOException e) {
|
||||
Log.w(MyTracksConstants.TAG, "Error reading file: " + gpxFile.getAbsolutePath(), e);
|
||||
Log.w(Constants.TAG, "Error reading file: " + gpxFile.getAbsolutePath(), e);
|
||||
}
|
||||
Toast.makeText(activity, activity.getString(R.string.import_error, gpxFile.getName()),
|
||||
Toast.LENGTH_LONG).show();
|
||||
|
||||
@@ -64,14 +64,14 @@ class MenuManager {
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_list_tracks: {
|
||||
activity.startActivityForResult(new Intent(activity, MyTracksList.class),
|
||||
MyTracksConstants.SHOW_TRACK);
|
||||
activity.startActivityForResult(new Intent(activity, TrackList.class),
|
||||
Constants.SHOW_TRACK);
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_list_markers: {
|
||||
Intent startIntent = new Intent(activity, MyTracksWaypointsList.class);
|
||||
Intent startIntent = new Intent(activity, WaypointsList.class);
|
||||
startIntent.putExtra("trackid", activity.getSelectedTrackId());
|
||||
activity.startActivityForResult(startIntent, MyTracksConstants.SHOW_WAYPOINT);
|
||||
activity.startActivityForResult(startIntent, Constants.SHOW_WAYPOINT);
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_sensor_state: {
|
||||
@@ -86,7 +86,7 @@ class MenuManager {
|
||||
case R.id.menu_help: {
|
||||
return startActivity(WelcomeActivity.class);
|
||||
}
|
||||
case MyTracksConstants.MENU_CLEAR_MAP: {
|
||||
case Constants.MENU_CLEAR_MAP: {
|
||||
activity.clearSelectedTrack();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,8 @@ package com.google.android.apps.mytracks;
|
||||
import com.google.android.accounts.Account;
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
import com.google.android.apps.mytracks.io.AuthManagerFactory;
|
||||
import com.google.android.apps.mytracks.io.MyMapsFactory;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsService;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MyMapsConstants;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
@@ -84,7 +83,7 @@ public class MyMapsList extends Activity implements MapsFacade.MapsListCallback
|
||||
super.onCreate(icicle);
|
||||
|
||||
auth = AuthManagerFactory.getAuthManager(this, GET_LOGIN, null, true,
|
||||
MapsService.getServiceName());
|
||||
MyMapsConstants.SERVICE_NAME);
|
||||
|
||||
setContentView(R.layout.list);
|
||||
|
||||
@@ -125,7 +124,7 @@ public class MyMapsList extends Activity implements MapsFacade.MapsListCallback
|
||||
auth.doLogin(new Runnable() {
|
||||
public void run() {
|
||||
// Runs in UI thread.
|
||||
mapsClient = MyMapsFactory.newMapsClient(MyMapsList.this, auth);
|
||||
mapsClient = new MapsFacade(MyMapsList.this, auth);
|
||||
|
||||
startLookup();
|
||||
}
|
||||
@@ -200,7 +199,7 @@ public class MyMapsList extends Activity implements MapsFacade.MapsListCallback
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, String.format(
|
||||
getText(R.string.share_map_body_format).toString(),
|
||||
listItem[1],
|
||||
MapsService.buildMapUrl(listItem[0])));
|
||||
MapsFacade.buildMapUrl(listItem[0])));
|
||||
startActivity(Intent.createChooser(shareIntent,
|
||||
getText(R.string.share_map).toString()));
|
||||
return true;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import static com.google.android.apps.mytracks.DialogManager.DIALOG_IMPORT_PROGRESS;
|
||||
import static com.google.android.apps.mytracks.DialogManager.DIALOG_PROGRESS;
|
||||
import static com.google.android.apps.mytracks.DialogManager.DIALOG_SEND_TO_GOOGLE;
|
||||
@@ -35,7 +36,8 @@ import com.google.android.apps.mytracks.io.TempFileCleaner;
|
||||
import com.google.android.apps.mytracks.io.TrackWriter;
|
||||
import com.google.android.apps.mytracks.io.TrackWriterFactory;
|
||||
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsService;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MyMapsConstants;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.ResultDialogFactory;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendDialog;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendResult;
|
||||
@@ -163,7 +165,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
private final ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks: Service now connected.");
|
||||
Log.d(Constants.TAG, "MyTracks: Service now connected.");
|
||||
// Delay setting the service until we are done with initialization.
|
||||
ITrackRecordingService trackRecordingService =
|
||||
ITrackRecordingService.Stub.asInterface(service);
|
||||
@@ -181,7 +183,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks: Service now disconnected.");
|
||||
Log.d(TAG, "MyTracks: Service now disconnected.");
|
||||
trackRecordingService = null;
|
||||
}
|
||||
};
|
||||
@@ -226,7 +228,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
// TODO: We catch Exception, because after eliminating the service process
|
||||
// all exceptions it may throw are no longer wrapped in a RemoteException.
|
||||
} catch (Exception e) {
|
||||
Log.e(MyTracksConstants.TAG, "MyTracks: Remote exception.", e);
|
||||
Log.e(TAG, "MyTracks: Remote exception.", e);
|
||||
|
||||
// Fall back to alternative check method.
|
||||
return dataHub.isRecording();
|
||||
@@ -240,7 +242,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks.onCreate");
|
||||
Log.d(TAG, "MyTracks.onCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
instance = this;
|
||||
ApiFeatures apiFeatures = ApiFeatures.getInstance();
|
||||
@@ -303,34 +305,32 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
// Do nothing.
|
||||
} else if (action.equals(Intent.ACTION_VIEW)) {
|
||||
if (intent.getScheme() != null && intent.getScheme().equals("file")) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"Received a VIEW intent with file scheme. Importing.");
|
||||
Log.w(TAG, "Received a VIEW intent with file scheme. Importing.");
|
||||
importGpxFile(intent.getData().getPath());
|
||||
} else {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"Received a VIEW intent with unsupported scheme "
|
||||
+ intent.getScheme());
|
||||
Log.w(TAG, "Received a VIEW intent with unsupported scheme " + intent.getScheme());
|
||||
}
|
||||
} else {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"Received an intent with unsupported action " + action);
|
||||
Log.w(TAG, "Received an intent with unsupported action " + action);
|
||||
}
|
||||
} else {
|
||||
Log.d(MyTracksConstants.TAG, "Received an intent with no action.");
|
||||
Log.d(TAG, "Received an intent with no action.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks.onDestroy");
|
||||
Log.d(TAG, "MyTracks.onDestroy");
|
||||
|
||||
dataHub.destroy();
|
||||
|
||||
tryUnbindTrackRecordingService();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks.onStop");
|
||||
Log.d(TAG, "MyTracks.onStop");
|
||||
|
||||
dataHub.stop();
|
||||
|
||||
@@ -343,7 +343,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
protected void onPause() {
|
||||
// Called when activity is going into the background, but has not (yet) been
|
||||
// killed. Shouldn't block longer than approx. 2 seconds.
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks.onPause");
|
||||
Log.d(TAG, "MyTracks.onPause");
|
||||
tryUnbindTrackRecordingService();
|
||||
super.onPause();
|
||||
}
|
||||
@@ -352,14 +352,14 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
protected void onResume() {
|
||||
// Called when the current activity is being displayed or re-displayed
|
||||
// to the user.
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks.onResume");
|
||||
Log.d(TAG, "MyTracks.onResume");
|
||||
tryBindTrackRecordingService();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks.onStart");
|
||||
Log.d(TAG, "MyTracks.onStart");
|
||||
super.onStart();
|
||||
dataHub.start();
|
||||
}
|
||||
@@ -422,9 +422,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
try {
|
||||
insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert statistics marker.", e);
|
||||
Log.e(TAG, "Cannot insert statistics marker.", e);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert statistics marker.", e);
|
||||
Log.e(TAG, "Cannot insert statistics marker.", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -437,13 +437,13 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
final Intent results) {
|
||||
TrackFileFormat exportFormat = null;
|
||||
switch (requestCode) {
|
||||
case MyTracksConstants.GET_LOGIN: {
|
||||
case Constants.GET_LOGIN: {
|
||||
if (resultCode != RESULT_OK || auth == null || !auth.authResult(resultCode, results)) {
|
||||
dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SHOW_TRACK: {
|
||||
case Constants.SHOW_TRACK: {
|
||||
if (results != null) {
|
||||
final long trackId = results.getLongExtra("trackid", -1);
|
||||
if (trackId >= 0) {
|
||||
@@ -451,14 +451,14 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
|
||||
// The track list passed the requested action as result code. Hand
|
||||
// it off to the onAcitivtyResult for further processing:
|
||||
if (resultCode != MyTracksConstants.SHOW_TRACK) {
|
||||
if (resultCode != Constants.SHOW_TRACK) {
|
||||
onActivityResult(resultCode, Activity.RESULT_OK, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SHOW_WAYPOINT: {
|
||||
case Constants.SHOW_WAYPOINT: {
|
||||
if (results != null) {
|
||||
final long waypointId = results.getLongExtra("waypointid", -1);
|
||||
if (waypointId >= 0) {
|
||||
@@ -472,28 +472,28 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.DELETE_TRACK: {
|
||||
case Constants.DELETE_TRACK: {
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
final long trackId = results.getLongExtra("trackid", dataHub.getSelectedTrackId());
|
||||
deleteTrack(trackId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.EDIT_DETAILS: {
|
||||
case Constants.EDIT_DETAILS: {
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
final long trackId = results.getLongExtra("trackid", dataHub.getSelectedTrackId());
|
||||
Intent intent = new Intent(this, MyTracksDetails.class);
|
||||
Intent intent = new Intent(this, TrackDetails.class);
|
||||
intent.putExtra("trackid", trackId);
|
||||
startActivity(intent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SEND_TO_GOOGLE_DIALOG: {
|
||||
case Constants.SEND_TO_GOOGLE_DIALOG: {
|
||||
shareRequested = false;
|
||||
dialogManager.showDialogSafely(DIALOG_SEND_TO_GOOGLE);
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.GET_MAP: {
|
||||
case Constants.GET_MAP: {
|
||||
// User picked a map to upload to
|
||||
if (resultCode == RESULT_OK) {
|
||||
results.putExtra("trackid", dataHub.getSelectedTrackId());
|
||||
@@ -506,7 +506,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_MY_MAPS: {
|
||||
case Constants.AUTHENTICATE_TO_MY_MAPS: {
|
||||
// Authenticated with Google My Maps
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
final String mapId;
|
||||
@@ -528,7 +528,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_FUSION_TABLES: {
|
||||
case Constants.AUTHENTICATE_TO_FUSION_TABLES: {
|
||||
// Authenticated with Google Fusion Tables
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
final long trackId;
|
||||
@@ -544,7 +544,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_DOCLIST: {
|
||||
case Constants.AUTHENTICATE_TO_DOCLIST: {
|
||||
// Authenticated with Google Docs
|
||||
if (resultCode == RESULT_OK) {
|
||||
authenticateToGoogleTrix();
|
||||
@@ -553,7 +553,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.AUTHENTICATE_TO_TRIX: {
|
||||
case Constants.AUTHENTICATE_TO_TRIX: {
|
||||
// Authenticated with Trix
|
||||
if (resultCode == RESULT_OK) {
|
||||
final long trackId = results.getLongExtra("trackid", dataHub.getSelectedTrackId());
|
||||
@@ -563,16 +563,16 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SAVE_GPX_FILE:
|
||||
case Constants.SAVE_GPX_FILE:
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.GPX; }
|
||||
//$FALL-THROUGH$
|
||||
case MyTracksConstants.SAVE_KML_FILE:
|
||||
case Constants.SAVE_KML_FILE:
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
|
||||
//$FALL-THROUGH$
|
||||
case MyTracksConstants.SAVE_CSV_FILE:
|
||||
case Constants.SAVE_CSV_FILE:
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
|
||||
//$FALL-THROUGH$
|
||||
case MyTracksConstants.SAVE_TCX_FILE:
|
||||
case Constants.SAVE_TCX_FILE:
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
|
||||
|
||||
if (results != null && resultCode == Activity.RESULT_OK) {
|
||||
@@ -582,11 +582,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MyTracksConstants.SHARE_LINK: {
|
||||
case Constants.SHARE_LINK: {
|
||||
Track selectedTrack = providerUtils.getTrack(dataHub.getSelectedTrackId());
|
||||
if (selectedTrack != null) {
|
||||
if (!TextUtils.isEmpty(selectedTrack.getMapId())) {
|
||||
shareLinkToMap(MapsService.buildMapUrl(selectedTrack.getMapId()));
|
||||
shareLinkToMap(MapsFacade.buildMapUrl(selectedTrack.getMapId()));
|
||||
} else if (!TextUtils.isEmpty(selectedTrack.getTableId())) {
|
||||
shareLinkToMap(getFusionTablesUrl(dataHub.getSelectedTrackId()));
|
||||
} else {
|
||||
@@ -596,16 +596,16 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.SHARE_GPX_FILE:
|
||||
case Constants.SHARE_GPX_FILE:
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.GPX; }
|
||||
//$FALL-THROUGH$
|
||||
case MyTracksConstants.SHARE_KML_FILE:
|
||||
case Constants.SHARE_KML_FILE:
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
|
||||
//$FALL-THROUGH$
|
||||
case MyTracksConstants.SHARE_CSV_FILE:
|
||||
case Constants.SHARE_CSV_FILE:
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
|
||||
//$FALL-THROUGH$
|
||||
case MyTracksConstants.SHARE_TCX_FILE: {
|
||||
case Constants.SHARE_TCX_FILE: {
|
||||
if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
|
||||
|
||||
if (results != null && resultCode == Activity.RESULT_OK) {
|
||||
@@ -616,18 +616,17 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.CLEAR_MAP: {
|
||||
case Constants.CLEAR_MAP: {
|
||||
dataHub.unloadCurrentTrack();
|
||||
break;
|
||||
}
|
||||
case MyTracksConstants.WELCOME: {
|
||||
case Constants.WELCOME: {
|
||||
CheckUnits.check(this);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"Warning unhandled request code: " + requestCode);
|
||||
Log.w(TAG, "Warning unhandled request code: " + requestCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -668,19 +667,19 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
InputStream is = new FileInputStream(fileName);
|
||||
trackIdsImported = GpxImporter.importGPXFile(is, providerUtils);
|
||||
} catch (SAXException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
Log.e(TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_generic;
|
||||
} catch (ParserConfigurationException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
Log.e(TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_generic;
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
Log.e(TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_unable_to_read_file;
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
Log.e(TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_invalid_gpx_format;
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
Log.e(TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_out_of_memory;
|
||||
}
|
||||
if (trackIdsImported != null && trackIdsImported.length > 0) {
|
||||
@@ -803,16 +802,15 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
final String service) {
|
||||
auth = authMap.get(service);
|
||||
if (auth == null) {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
"Creating a new authentication for service: " + service);
|
||||
Log.i(TAG, "Creating a new authentication for service: " + service);
|
||||
auth = AuthManagerFactory.getAuthManager(this,
|
||||
MyTracksConstants.GET_LOGIN,
|
||||
Constants.GET_LOGIN,
|
||||
null,
|
||||
true,
|
||||
service);
|
||||
authMap.put(service, auth);
|
||||
}
|
||||
Log.d(MyTracksConstants.TAG, "Logging in to " + service + "...");
|
||||
Log.d(TAG, "Logging in to " + service + "...");
|
||||
if (AuthManagerFactory.useModernAuthManager()) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
@@ -839,7 +837,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
final String service, final Account account) {
|
||||
auth.doLogin(new Runnable() {
|
||||
public void run() {
|
||||
Log.d(MyTracksConstants.TAG, "Loggin success for " + service + "!");
|
||||
Log.d(TAG, "Loggin success for " + service + "!");
|
||||
onActivityResult(requestCode, RESULT_OK, results);
|
||||
}
|
||||
}, account);
|
||||
@@ -859,7 +857,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
Toast.makeText(this,
|
||||
getString(R.string.error_unable_to_start_recording),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
Log.w(MyTracksConstants.TAG, "Unable to start recording.", e);
|
||||
Log.w(TAG, "Unable to start recording.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -891,11 +889,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
// TODO: We catch Exception, because after eliminating the service process
|
||||
// all exceptions it may throw are no longer wrapped in a RemoteException.
|
||||
} catch (Exception e) {
|
||||
Log.e(MyTracksConstants.TAG, "Unable to stop recording.", e);
|
||||
Log.e(TAG, "Unable to stop recording.", e);
|
||||
}
|
||||
|
||||
if (currentTrackId > 0) {
|
||||
Intent intent = new Intent(MyTracks.this, MyTracksDetails.class);
|
||||
Intent intent = new Intent(MyTracks.this, TrackDetails.class);
|
||||
intent.putExtra("trackid", currentTrackId);
|
||||
intent.putExtra("hasCancelButton", false);
|
||||
startActivity(intent);
|
||||
@@ -905,8 +903,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
try {
|
||||
stopService(new Intent(MyTracks.this, TrackRecordingService.class));
|
||||
} catch (SecurityException e) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
"Encountered a security exception when trying to stop service.", e);
|
||||
Log.e(TAG, "Encountered a security exception when trying to stop service.", e);
|
||||
}
|
||||
trackRecordingService = null;
|
||||
}
|
||||
@@ -915,7 +912,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
* Initiates the process to send tracks to google.
|
||||
* This is called once the user has selected sending options via the
|
||||
* SendToGoogleDialog.
|
||||
*
|
||||
*
|
||||
* TODO: Change this whole flow to an actual state machine.
|
||||
*/
|
||||
public void sendToGoogle() {
|
||||
@@ -935,7 +932,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
} else if (sendToGoogleDialog.getSendToDocs()) {
|
||||
authenticateToGoogleDocs();
|
||||
} else {
|
||||
Log.w(MyTracksConstants.TAG, "Nowhere to upload to");
|
||||
Log.w(TAG, "Nowhere to upload to");
|
||||
onSendToGoogleDone();
|
||||
}
|
||||
}
|
||||
@@ -944,7 +941,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
if (!sendToGoogleDialog.getCreateNewMap()) {
|
||||
// Ask the user to choose a map to upload into
|
||||
Intent listIntent = new Intent(this, MyMapsList.class);
|
||||
startActivityForResult(listIntent, MyTracksConstants.GET_MAP);
|
||||
startActivityForResult(listIntent, Constants.GET_MAP);
|
||||
// The callback for GET_MAP calls authenticateToGoogleMaps
|
||||
} else {
|
||||
authenticateToGoogleMaps(null);
|
||||
@@ -957,8 +954,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
setProgressValue(0);
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_mymaps);
|
||||
authenticate(results, MyTracksConstants.AUTHENTICATE_TO_MY_MAPS,
|
||||
MapsService.getServiceName());
|
||||
authenticate(results, Constants.AUTHENTICATE_TO_MY_MAPS,
|
||||
MyMapsConstants.SERVICE_NAME);
|
||||
// AUTHENTICATE_TO_MY_MAPS callback calls sendToGoogleMaps
|
||||
}
|
||||
|
||||
@@ -978,7 +975,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
} catch (RuntimeException e) {
|
||||
// If that fails whatever reasons we'll just log an error, but
|
||||
// continue.
|
||||
Log.w(MyTracksConstants.TAG, "Updating map id failed.", e);
|
||||
Log.w(TAG, "Updating map id failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1010,7 +1007,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
|
||||
setProgressValue(0);
|
||||
setProgressMessage(R.string.progress_message_authenticating_fusiontables);
|
||||
authenticate(results, MyTracksConstants.AUTHENTICATE_TO_FUSION_TABLES,
|
||||
authenticate(results, Constants.AUTHENTICATE_TO_FUSION_TABLES,
|
||||
SendToFusionTables.SERVICE_ID);
|
||||
// AUTHENTICATE_TO_FUSION_TABLES callback calls sendToFusionTables
|
||||
}
|
||||
@@ -1032,10 +1029,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
} catch (RuntimeException e) {
|
||||
// If that fails whatever reasons we'll just log an error, but
|
||||
// continue.
|
||||
Log.w(MyTracksConstants.TAG, "Updating table id failed.", e);
|
||||
Log.w(TAG, "Updating table id failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onSendToFusionTablesDone();
|
||||
}
|
||||
};
|
||||
@@ -1063,7 +1060,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(new Intent(),
|
||||
MyTracksConstants.AUTHENTICATE_TO_DOCLIST,
|
||||
Constants.AUTHENTICATE_TO_DOCLIST,
|
||||
SendToDocs.GDATA_SERVICE_NAME_DOCLIST);
|
||||
// AUTHENTICATE_TO_DOCLIST callback calls authenticateToGoogleTrix
|
||||
}
|
||||
@@ -1073,16 +1070,16 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(new Intent(),
|
||||
MyTracksConstants.AUTHENTICATE_TO_TRIX,
|
||||
Constants.AUTHENTICATE_TO_TRIX,
|
||||
SendToDocs.GDATA_SERVICE_NAME_TRIX);
|
||||
// AUTHENTICATE_TO_TRIX callback calls sendToGoogleDocs
|
||||
}
|
||||
|
||||
private void sendToGoogleDocs(final long trackId) {
|
||||
Log.d(MyTracksConstants.TAG, "Sending to Docs....");
|
||||
Log.d(TAG, "Sending to Docs....");
|
||||
setProgressValue(50);
|
||||
setProgressMessage(R.string.progress_message_sending_docs);
|
||||
final SendToDocs sender = new SendToDocs(this,
|
||||
final SendToDocs sender = new SendToDocs(this,
|
||||
authMap.get(SendToDocs.GDATA_SERVICE_NAME_TRIX),
|
||||
authMap.get(SendToDocs.GDATA_SERVICE_NAME_DOCLIST), trackId);
|
||||
sendToTrackId = trackId;
|
||||
@@ -1151,11 +1148,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
DialogManager.showDialogSafely(this, sendToGoogleResultDialog);
|
||||
}
|
||||
|
||||
private boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
|
||||
boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
|
||||
String url = null;
|
||||
if (sentToMyMaps && sendToMyMapsSuccess) {
|
||||
// Prefer a link to My Maps
|
||||
url = MapsService.buildMapUrl(sendToMyMapsMapId);
|
||||
url = MapsFacade.buildMapUrl(sendToMyMapsMapId);
|
||||
} else if (sentToFusionTables && sendToFusionTablesSuccess) {
|
||||
// Otherwise try using the link to fusion tables
|
||||
url = getFusionTablesUrl(sendToTrackId);
|
||||
@@ -1206,11 +1203,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
* Binds to track recording service if it is running.
|
||||
*/
|
||||
private void tryBindTrackRecordingService() {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"MyTracks: Trying to bind to track recording service...");
|
||||
bindService(new Intent(this, TrackRecordingService.class),
|
||||
serviceConnection, 0);
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks: ...bind finished!");
|
||||
Log.d(TAG, "MyTracks: ...bind finished!");
|
||||
isBound = true;
|
||||
}
|
||||
|
||||
@@ -1220,14 +1217,12 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
*/
|
||||
private void tryUnbindTrackRecordingService() {
|
||||
if (isBound) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"MyTracks: Trying to unbind from track recording service...");
|
||||
Log.d(TAG, "MyTracks: Trying to unbind from track recording service...");
|
||||
try {
|
||||
unbindService(serviceConnection);
|
||||
Log.d(MyTracksConstants.TAG, "MyTracks: ...unbind finished!");
|
||||
Log.d(TAG, "MyTracks: ...unbind finished!");
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"MyTracks: Tried unbinding, but service was not registered.", e);
|
||||
Log.d(TAG, "MyTracks: Tried unbinding, but service was not registered.", e);
|
||||
}
|
||||
isBound = false;
|
||||
}
|
||||
@@ -1319,24 +1314,24 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
|
||||
public boolean getSendToGoogleSuccess() {
|
||||
return sendToMyMapsSuccess && sendToFusionTablesSuccess && sendToDocsSuccess;
|
||||
return sendToFusionTablesSuccess && sendToDocsSuccess;
|
||||
}
|
||||
|
||||
// @VisibleForTesting
|
||||
long getRecordingTrackId() {
|
||||
return sharedPreferences.getLong(getString(R.string.recording_track_key), -1);
|
||||
}
|
||||
|
||||
|
||||
// @VisibleForTesting
|
||||
SharedPreferences getSharedPreferences() {
|
||||
return sharedPreferences;
|
||||
}
|
||||
|
||||
|
||||
// @VisibleForTesting
|
||||
static void clearInstance() {
|
||||
instance = null;
|
||||
}
|
||||
|
||||
|
||||
// @VisibleForTesting
|
||||
ITrackRecordingService getTrackRecordingService() {
|
||||
return trackRecordingService;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
@@ -343,37 +343,37 @@ public class MyTracksMap extends MapActivity
|
||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
||||
ContextMenuInfo menuInfo) {
|
||||
menu.setHeaderTitle(R.string.tracklist_this_track);
|
||||
menu.add(0, MyTracksConstants.MENU_EDIT, 0,
|
||||
menu.add(0, Constants.MENU_EDIT, 0,
|
||||
R.string.tracklist_edit_track);
|
||||
if (!dataHub.isRecordingSelected()) {
|
||||
menu.add(0, MyTracksConstants.MENU_SEND_TO_GOOGLE, 0,
|
||||
menu.add(0, Constants.MENU_SEND_TO_GOOGLE, 0,
|
||||
R.string.tracklist_send_to_google);
|
||||
SubMenu share = menu.addSubMenu(0, MyTracksConstants.MENU_SHARE, 0,
|
||||
SubMenu share = menu.addSubMenu(0, Constants.MENU_SHARE, 0,
|
||||
R.string.tracklist_share_track);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_LINK, 0,
|
||||
share.add(0, Constants.MENU_SHARE_LINK, 0,
|
||||
R.string.tracklist_share_link);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_GPX_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_GPX_FILE, 0,
|
||||
R.string.tracklist_share_gpx_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_KML_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_KML_FILE, 0,
|
||||
R.string.tracklist_share_kml_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_CSV_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_CSV_FILE, 0,
|
||||
R.string.tracklist_share_csv_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_TCX_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_TCX_FILE, 0,
|
||||
R.string.tracklist_share_tcx_file);
|
||||
SubMenu save = menu.addSubMenu(0,
|
||||
MyTracksConstants.MENU_WRITE_TO_SD_CARD, 0,
|
||||
Constants.MENU_WRITE_TO_SD_CARD, 0,
|
||||
R.string.tracklist_write_to_sd);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_GPX_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_GPX_FILE, 0,
|
||||
R.string.tracklist_save_as_gpx);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_KML_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_KML_FILE, 0,
|
||||
R.string.tracklist_save_as_kml);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_CSV_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_CSV_FILE, 0,
|
||||
R.string.tracklist_save_as_csv);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_TCX_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_TCX_FILE, 0,
|
||||
R.string.tracklist_save_as_tcx);
|
||||
menu.add(0, MyTracksConstants.MENU_CLEAR_MAP, 0,
|
||||
menu.add(0, Constants.MENU_CLEAR_MAP, 0,
|
||||
R.string.tracklist_clear_map);
|
||||
menu.add(0, MyTracksConstants.MENU_DELETE, 0,
|
||||
menu.add(0, Constants.MENU_DELETE, 0,
|
||||
R.string.tracklist_delete_track);
|
||||
}
|
||||
}
|
||||
@@ -383,7 +383,7 @@ public class MyTracksMap extends MapActivity
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
if (!super.onMenuItemSelected(featureId, item)) {
|
||||
MyTracks.getInstance().onActivityResult(
|
||||
MyTracksConstants.getActionFromMenuId(item.getItemId()), RESULT_OK,
|
||||
Constants.getActionFromMenuId(item.getItemId()), RESULT_OK,
|
||||
new Intent());
|
||||
return true;
|
||||
}
|
||||
@@ -393,10 +393,10 @@ public class MyTracksMap extends MapActivity
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
myLocation = menu.add(0, MyTracksConstants.MENU_MY_LOCATION, 0,
|
||||
myLocation = menu.add(0, Constants.MENU_MY_LOCATION, 0,
|
||||
R.string.mylocation);
|
||||
myLocation.setIcon(android.R.drawable.ic_menu_mylocation);
|
||||
toggleLayers = menu.add(0, MyTracksConstants.MENU_TOGGLE_LAYERS, 0,
|
||||
toggleLayers = menu.add(0, Constants.MENU_TOGGLE_LAYERS, 0,
|
||||
R.string.switch_to_sat);
|
||||
toggleLayers.setIcon(android.R.drawable.ic_menu_mapmode);
|
||||
return true;
|
||||
@@ -412,7 +412,7 @@ public class MyTracksMap extends MapActivity
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MyTracksConstants.MENU_MY_LOCATION: {
|
||||
case Constants.MENU_MY_LOCATION: {
|
||||
dataHub.forceUpdateLocation();
|
||||
keepMyLocationVisible = true;
|
||||
if (mapView.getZoomLevel() < 18) {
|
||||
@@ -420,7 +420,7 @@ public class MyTracksMap extends MapActivity
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case MyTracksConstants.MENU_TOGGLE_LAYERS: {
|
||||
case Constants.MENU_TOGGLE_LAYERS: {
|
||||
mapView.setSatellite(!mapView.isSatellite());
|
||||
return true;
|
||||
}
|
||||
@@ -497,7 +497,7 @@ public class MyTracksMap extends MapActivity
|
||||
|
||||
@Override
|
||||
public void onCurrentLocationChanged(Location location) {
|
||||
if (!location.getProvider().equals(MyTracksConstants.GPS_PROVIDER)) {
|
||||
if (!location.getProvider().equals(Constants.GPS_PROVIDER)) {
|
||||
Log.d(TAG,
|
||||
"MyTracksMap: Network location update received (provider '" + location.getProvider() + "'.");
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class MyTracksOverlay extends Overlay {
|
||||
this.waypoints = new ArrayList<Waypoint>();
|
||||
this.points = new ArrayList<CachedLocation>(1024);
|
||||
this.pendingPoints = new ArrayBlockingQueue<CachedLocation>(
|
||||
MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS, true);
|
||||
Constants.MAX_DISPLAYED_TRACK_POINTS, true);
|
||||
|
||||
// TODO: Can we use a FrameAnimation or similar here rather
|
||||
// than individual resources for each arrow direction?
|
||||
@@ -460,7 +460,7 @@ public class MyTracksOverlay extends Overlay {
|
||||
|
||||
if (waypoint != null &&
|
||||
dmin < 15000000 / Math.pow(2, mapView.getZoomLevel())) {
|
||||
Intent intent = new Intent(context, MyTracksWaypointDetails.class);
|
||||
Intent intent = new Intent(context, WaypointDetails.class);
|
||||
intent.putExtra("waypointid", waypoint.getId());
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static android.content.Intent.ACTION_BOOT_COMPLETED;
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.RESUME_TRACK_EXTRA_NAME;
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingService;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.io.backup.BackupActivityHelper;
|
||||
import com.google.android.apps.mytracks.io.backup.BackupPreferencesListener;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||
import com.google.android.apps.mytracks.services.sensors.SensorUtils;
|
||||
@@ -103,7 +103,7 @@ public class SensorStateActivity extends Activity {
|
||||
ITrackRecordingService service =
|
||||
mt == null ? null : mt.getTrackRecordingService();
|
||||
if (service == null) {
|
||||
Log.d(MyTracksConstants.TAG, "Could not get track recording service.");
|
||||
Log.d(Constants.TAG, "Could not get track recording service.");
|
||||
updateSensorState(Sensor.SensorState.NONE);
|
||||
updateSensorData(null);
|
||||
return;
|
||||
@@ -116,9 +116,9 @@ public class SensorStateActivity extends Activity {
|
||||
updateSensorData(sds);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Could not read sensor data.", e);
|
||||
Log.e(Constants.TAG, "Could not read sensor data.", e);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Could not read sensor data.", e);
|
||||
Log.e(Constants.TAG, "Could not read sensor data.", e);
|
||||
}
|
||||
updateSensorData(sds);
|
||||
|
||||
@@ -126,7 +126,7 @@ public class SensorStateActivity extends Activity {
|
||||
int i = service.getSensorState();
|
||||
updateSensorState(Sensor.SensorState.valueOf(i));
|
||||
} catch (RemoteException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Could not read sensor state.", e);
|
||||
Log.e(Constants.TAG, "Could not read sensor state.", e);
|
||||
updateSensorState(Sensor.SensorState.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
@@ -175,14 +175,14 @@ public class StatsActivity extends Activity implements TrackDataListener {
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
MenuItem currentSegment = menu.add(0,
|
||||
MyTracksConstants.MENU_CURRENT_SEGMENT, 0, R.string.current_segment);
|
||||
Constants.MENU_CURRENT_SEGMENT, 0, R.string.current_segment);
|
||||
currentSegment.setIcon(R.drawable.ic_menu_lastsegment);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
MenuItem item = menu.findItem(MyTracksConstants.MENU_CURRENT_SEGMENT);
|
||||
MenuItem item = menu.findItem(Constants.MENU_CURRENT_SEGMENT);
|
||||
if (item != null) {
|
||||
item.setTitle(showCurrentSegment
|
||||
? getString(R.string.current_track)
|
||||
@@ -194,7 +194,7 @@ public class StatsActivity extends Activity implements TrackDataListener {
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MyTracksConstants.MENU_CURRENT_SEGMENT:
|
||||
case Constants.MENU_CURRENT_SEGMENT:
|
||||
showCurrentSegment = !showCurrentSegment;
|
||||
// TODO: Re-read only the data that interests us
|
||||
return true;
|
||||
|
||||
@@ -235,7 +235,7 @@ public class StatsUtilities {
|
||||
}
|
||||
|
||||
public void setSpeedLabel(int id, int speedString, int paceString) {
|
||||
Log.w(MyTracksConstants.TAG, "Setting view " + id +
|
||||
Log.w(Constants.TAG, "Setting view " + id +
|
||||
" to " + reportSpeed +
|
||||
" speed: " + speedString +
|
||||
" pace: " + paceString);
|
||||
@@ -243,7 +243,7 @@ public class StatsUtilities {
|
||||
if (tv != null) {
|
||||
tv.setText(reportSpeed ? speedString : paceString);
|
||||
} else {
|
||||
Log.w(MyTracksConstants.TAG, "Could not find id: " + id);
|
||||
Log.w(Constants.TAG, "Could not find id: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackDataListener.ProviderState;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
@@ -359,7 +359,7 @@ public class TrackDataHub {
|
||||
|
||||
final long now = System.currentTimeMillis();
|
||||
Location loc = locationManager.getLastKnownLocation(
|
||||
MyTracksConstants.GPS_PROVIDER);
|
||||
Constants.GPS_PROVIDER);
|
||||
if (loc == null || loc.getTime() < now - MAX_LOCATION_AGE_MS) {
|
||||
// We don't have a recent GPS fix, just use cell towers if available
|
||||
loc = locationManager.getLastKnownLocation(
|
||||
@@ -502,25 +502,25 @@ public class TrackDataHub {
|
||||
// Listen to compass
|
||||
Sensor compass = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
|
||||
if (compass != null) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"TrackDataHub: Now registering sensor listeners.");
|
||||
sensorManager.registerListener(compassListener, compass, SensorManager.SENSOR_DELAY_UI);
|
||||
}
|
||||
|
||||
// Listen to GPS
|
||||
LocationProvider gpsProvider =
|
||||
locationManager.getProvider(MyTracksConstants.GPS_PROVIDER);
|
||||
locationManager.getProvider(Constants.GPS_PROVIDER);
|
||||
if (gpsProvider == null) {
|
||||
Toast.makeText(context, R.string.error_no_gps_location_provider, Toast.LENGTH_LONG).show();
|
||||
hasProviderEnabled = false;
|
||||
return;
|
||||
} else {
|
||||
Log.d(MyTracksConstants.TAG, "TrackDataHub: Using location provider "
|
||||
Log.d(Constants.TAG, "TrackDataHub: Using location provider "
|
||||
+ gpsProvider.getName());
|
||||
}
|
||||
locationManager.requestLocationUpdates(gpsProvider.getName(),
|
||||
0 /*minTime*/, 0 /*minDist*/, locationListener);
|
||||
hasProviderEnabled = locationManager.isProviderEnabled(MyTracksConstants.GPS_PROVIDER);
|
||||
hasProviderEnabled = locationManager.isProviderEnabled(Constants.GPS_PROVIDER);
|
||||
|
||||
// Listen to network location
|
||||
try {
|
||||
@@ -529,7 +529,7 @@ public class TrackDataHub {
|
||||
} catch (RuntimeException e) {
|
||||
// If anything at all goes wrong with getting a cell location do not
|
||||
// abort. Cell location is not essential to this app.
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(Constants.TAG,
|
||||
"Could not register network location listener.");
|
||||
}
|
||||
}
|
||||
@@ -777,7 +777,7 @@ public class TrackDataHub {
|
||||
private void notifyWaypointUpdated(final TrackDataListener... listeners) {
|
||||
// Always reload all the waypoints.
|
||||
final Cursor cursor = providerUtils.getWaypointsCursor(
|
||||
selectedTrackId, 0, MyTracksConstants.MAX_DISPLAYED_WAYPOINTS_POINTS);
|
||||
selectedTrackId, 0, Constants.MAX_DISPLAYED_WAYPOINTS_POINTS);
|
||||
|
||||
listenerHandler.post(new Runnable() {
|
||||
@Override
|
||||
@@ -857,7 +857,7 @@ public class TrackDataHub {
|
||||
long minPointId = keepState ? lastSeenLocationId + 1 : 0;
|
||||
long maxPointId = keepState ? -1 : lastSeenLocationId;
|
||||
|
||||
if (numLoadedPoints >= MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS) {
|
||||
if (numLoadedPoints >= Constants.MAX_DISPLAYED_TRACK_POINTS) {
|
||||
// We're about to exceed the maximum allowed number of points, so reload
|
||||
// the whole track with fewer points (the sampling frequency will be
|
||||
// lower). We do this for every listener even if we were loading just for
|
||||
@@ -931,7 +931,7 @@ public class TrackDataHub {
|
||||
// frequency.
|
||||
long numTotalPoints = lastStoredLocationId - localFirstSeenLocationId;
|
||||
pointSamplingFrequency =
|
||||
(int) (1 + numTotalPoints / MyTracksConstants.TARGET_DISPLAYED_TRACK_POINTS);
|
||||
(int) (1 + numTotalPoints / Constants.TARGET_DISPLAYED_TRACK_POINTS);
|
||||
}
|
||||
|
||||
// Include a point if it fits one of the following criteria:
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ import android.widget.EditText;
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksDetails extends Activity implements OnClickListener {
|
||||
public class TrackDetails extends Activity implements OnClickListener {
|
||||
|
||||
/**
|
||||
* The id of the track being edited (taken from bundle, "trackid")
|
||||
@@ -56,7 +56,7 @@ public class MyTracksDetails extends Activity implements OnClickListener {
|
||||
// Required extra when launching this intent:
|
||||
trackId = getIntent().getLongExtra("trackid", -1);
|
||||
if (trackId < 0) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"MyTracksDetails intent was launched w/o track id.");
|
||||
finish();
|
||||
return;
|
||||
+25
-25
@@ -45,7 +45,7 @@ import android.widget.TextView;
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksList extends ListActivity
|
||||
public class TrackList extends ListActivity
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener,
|
||||
View.OnClickListener {
|
||||
|
||||
@@ -70,40 +70,40 @@ public class MyTracksList extends ListActivity
|
||||
AdapterView.AdapterContextMenuInfo info =
|
||||
(AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
contextPosition = info.position;
|
||||
trackId = MyTracksList.this.listView.getAdapter().getItemId(
|
||||
trackId = TrackList.this.listView.getAdapter().getItemId(
|
||||
contextPosition);
|
||||
menu.add(0, MyTracksConstants.MENU_SHOW, 0,
|
||||
menu.add(0, Constants.MENU_SHOW, 0,
|
||||
R.string.tracklist_show_track);
|
||||
menu.add(0, MyTracksConstants.MENU_EDIT, 0,
|
||||
menu.add(0, Constants.MENU_EDIT, 0,
|
||||
R.string.tracklist_edit_track);
|
||||
if (!MyTracks.getInstance().isRecording()
|
||||
|| trackId != recordingTrackId) {
|
||||
menu.add(0, MyTracksConstants.MENU_SEND_TO_GOOGLE, 0,
|
||||
menu.add(0, Constants.MENU_SEND_TO_GOOGLE, 0,
|
||||
R.string.tracklist_send_to_google);
|
||||
SubMenu share = menu.addSubMenu(0, MyTracksConstants.MENU_SHARE, 0,
|
||||
SubMenu share = menu.addSubMenu(0, Constants.MENU_SHARE, 0,
|
||||
R.string.tracklist_share_track);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_LINK, 0,
|
||||
share.add(0, Constants.MENU_SHARE_LINK, 0,
|
||||
R.string.tracklist_share_link);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_GPX_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_GPX_FILE, 0,
|
||||
R.string.tracklist_share_gpx_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_KML_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_KML_FILE, 0,
|
||||
R.string.tracklist_share_kml_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_CSV_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_CSV_FILE, 0,
|
||||
R.string.tracklist_share_csv_file);
|
||||
share.add(0, MyTracksConstants.MENU_SHARE_TCX_FILE, 0,
|
||||
share.add(0, Constants.MENU_SHARE_TCX_FILE, 0,
|
||||
R.string.tracklist_share_tcx_file);
|
||||
SubMenu save = menu.addSubMenu(0,
|
||||
MyTracksConstants.MENU_WRITE_TO_SD_CARD, 0,
|
||||
Constants.MENU_WRITE_TO_SD_CARD, 0,
|
||||
R.string.tracklist_write_to_sd);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_GPX_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_GPX_FILE, 0,
|
||||
R.string.tracklist_save_as_gpx);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_KML_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_KML_FILE, 0,
|
||||
R.string.tracklist_save_as_kml);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_CSV_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_CSV_FILE, 0,
|
||||
R.string.tracklist_save_as_csv);
|
||||
save.add(0, MyTracksConstants.MENU_SAVE_TCX_FILE, 0,
|
||||
save.add(0, Constants.MENU_SAVE_TCX_FILE, 0,
|
||||
R.string.tracklist_save_as_tcx);
|
||||
menu.add(0, MyTracksConstants.MENU_DELETE, 0,
|
||||
menu.add(0, Constants.MENU_DELETE, 0,
|
||||
R.string.tracklist_delete_track);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ public class MyTracksList extends ListActivity
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
Intent result = new Intent();
|
||||
result.putExtra("trackid", id);
|
||||
setResult(MyTracksConstants.SHOW_TRACK, result);
|
||||
setResult(Constants.SHOW_TRACK, result);
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -140,24 +140,24 @@ public class MyTracksList extends ListActivity
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
if (!super.onMenuItemSelected(featureId, item)) {
|
||||
switch (item.getItemId()) {
|
||||
case MyTracksConstants.MENU_SHOW: {
|
||||
case Constants.MENU_SHOW: {
|
||||
onListItemClick(null, null, 0, trackId);
|
||||
return true;
|
||||
}
|
||||
case MyTracksConstants.MENU_EDIT: {
|
||||
Intent intent = new Intent(this, MyTracksDetails.class);
|
||||
case Constants.MENU_EDIT: {
|
||||
Intent intent = new Intent(this, TrackDetails.class);
|
||||
intent.putExtra("trackid", trackId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
case MyTracksConstants.MENU_SHARE:
|
||||
case MyTracksConstants.MENU_WRITE_TO_SD_CARD:
|
||||
case Constants.MENU_SHARE:
|
||||
case Constants.MENU_WRITE_TO_SD_CARD:
|
||||
return false;
|
||||
default: {
|
||||
Intent result = new Intent();
|
||||
result.putExtra("trackid", trackId);
|
||||
setResult(
|
||||
MyTracksConstants.getActionFromMenuId(item.getItemId()), result);
|
||||
Constants.getActionFromMenuId(item.getItemId()), result);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
@@ -170,7 +170,7 @@ public class MyTracksList extends ListActivity
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()) {
|
||||
case R.id.tracklist_btn_delete_all: {
|
||||
Handler h = new MyTracksDeleteAllTracks(this, null);
|
||||
Handler h = new DeleteAllTracks(this, null);
|
||||
h.handleMessage(null);
|
||||
break;
|
||||
}
|
||||
+2
-2
@@ -39,7 +39,7 @@ import android.widget.ImageView;
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksWaypointDetails extends Activity
|
||||
public class WaypointDetails extends Activity
|
||||
implements OnClickListener {
|
||||
|
||||
public static final String WAYPOINT_ID_EXTRA = "com.google.android.apps.mytracks.WAYPOINT_ID";
|
||||
@@ -82,7 +82,7 @@ public class MyTracksWaypointDetails extends Activity
|
||||
// Required extra when launching this intent:
|
||||
waypointId = getIntent().getLongExtra(WAYPOINT_ID_EXTRA, -1);
|
||||
if (waypointId < 0) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"MyTracksWaypointsDetails intent was launched w/o waypoint id.");
|
||||
finish();
|
||||
return;
|
||||
+18
-18
@@ -49,7 +49,7 @@ import android.widget.TextView;
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class MyTracksWaypointsList extends ListActivity
|
||||
public class WaypointsList extends ListActivity
|
||||
implements View.OnClickListener {
|
||||
|
||||
private int contextPosition = -1;
|
||||
@@ -71,14 +71,14 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
AdapterView.AdapterContextMenuInfo info =
|
||||
(AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
contextPosition = info.position;
|
||||
waypointId = MyTracksWaypointsList.this.listView.getAdapter()
|
||||
waypointId = WaypointsList.this.listView.getAdapter()
|
||||
.getItemId(contextPosition);
|
||||
int type = providerUtils.getWaypoint(info.id).getType();
|
||||
menu.add(0, MyTracksConstants.MENU_SHOW, 0,
|
||||
menu.add(0, Constants.MENU_SHOW, 0,
|
||||
R.string.waypointslist_show_waypoint);
|
||||
menu.add(0, MyTracksConstants.MENU_EDIT, 0,
|
||||
menu.add(0, Constants.MENU_EDIT, 0,
|
||||
R.string.waypointslist_edit_waypoint);
|
||||
menu.add(0, MyTracksConstants.MENU_DELETE, 0,
|
||||
menu.add(0, Constants.MENU_DELETE, 0,
|
||||
R.string.waypointslist_delete_waypoint).setEnabled(
|
||||
recordingTrackId < 0 || type == Waypoint.TYPE_WAYPOINT ||
|
||||
info.id != providerUtils.getLastWaypointId(recordingTrackId));
|
||||
@@ -89,8 +89,8 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
Intent result = new Intent();
|
||||
result.putExtra("trackid", trackId);
|
||||
result.putExtra(MyTracksWaypointDetails.WAYPOINT_ID_EXTRA, id);
|
||||
setResult(MyTracksConstants.EDIT_WAYPOINT, result);
|
||||
result.putExtra(WaypointDetails.WAYPOINT_ID_EXTRA, id);
|
||||
setResult(Constants.EDIT_WAYPOINT, result);
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -98,18 +98,18 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
if (!super.onMenuItemSelected(featureId, item)) {
|
||||
switch (item.getItemId()) {
|
||||
case MyTracksConstants.MENU_SHOW: {
|
||||
case Constants.MENU_SHOW: {
|
||||
onListItemClick(null, null, 0, waypointId);
|
||||
return true;
|
||||
}
|
||||
case MyTracksConstants.MENU_EDIT: {
|
||||
Intent intent = new Intent(this, MyTracksWaypointDetails.class);
|
||||
case Constants.MENU_EDIT: {
|
||||
Intent intent = new Intent(this, WaypointDetails.class);
|
||||
intent.putExtra("trackid", trackId);
|
||||
intent.putExtra(MyTracksWaypointDetails.WAYPOINT_ID_EXTRA, waypointId);
|
||||
intent.putExtra(WaypointDetails.WAYPOINT_ID_EXTRA, waypointId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
case MyTracksConstants.MENU_DELETE: {
|
||||
case Constants.MENU_DELETE: {
|
||||
deleteWaypoint(waypointId);
|
||||
}
|
||||
}
|
||||
@@ -185,18 +185,18 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
try {
|
||||
id = MyTracks.getInstance().insertWaypoint(request);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert marker.", e);
|
||||
Log.e(Constants.TAG, "Cannot insert marker.", e);
|
||||
return;
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Cannot insert marker.", e);
|
||||
Log.e(Constants.TAG, "Cannot insert marker.", e);
|
||||
return;
|
||||
}
|
||||
if (id < 0) {
|
||||
Log.e(MyTracksConstants.TAG, "Failed to insert marker.");
|
||||
Log.e(Constants.TAG, "Failed to insert marker.");
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent(this, MyTracksWaypointDetails.class);
|
||||
intent.putExtra(MyTracksWaypointDetails.WAYPOINT_ID_EXTRA, id);
|
||||
Intent intent = new Intent(this, WaypointDetails.class);
|
||||
intent.putExtra(WaypointDetails.WAYPOINT_ID_EXTRA, id);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ public class MyTracksWaypointsList extends ListActivity
|
||||
public void onClick(DialogInterface dialog, int i) {
|
||||
dialog.dismiss();
|
||||
providerUtils.deleteWaypoint(waypointId,
|
||||
new StringUtils(MyTracksWaypointsList.this));
|
||||
new StringUtils(WaypointsList.this));
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.no),
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
@@ -382,7 +382,7 @@ public class MyTracksProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
if (ApiFeatures.getInstance().canReuseSQLiteQueryBuilder()) {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"Build query: " + qb.buildQuery(projection, selection, selectionArgs,
|
||||
null, null, sortOrder, null));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Build;
|
||||
@@ -46,11 +46,11 @@ public class AuthManagerFactory {
|
||||
public static AuthManager getAuthManager(Activity activity, int code,
|
||||
Bundle extras, boolean requireGoogle, String service) {
|
||||
if (useModernAuthManager()) {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"Creating modern auth manager: " + service);
|
||||
return new ModernAuthManager(activity, code, extras, requireGoogle, service);
|
||||
} else {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"Creating legacy auth manager: " + service);
|
||||
return new AuthManagerOld(activity, code, extras, requireGoogle, service);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
|
||||
@@ -174,7 +174,7 @@ public class GpxImporter extends DefaultHandler {
|
||||
parser.parse(is, handler);
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
Log.d(MyTracksConstants.TAG, "Total import time: " + (end - start) + "ms");
|
||||
Log.d(Constants.TAG, "Total import time: " + (end - start) + "ms");
|
||||
|
||||
trackIds = handler.getImportedTrackIds();
|
||||
} finally {
|
||||
@@ -462,7 +462,7 @@ public class GpxImporter extends DefaultHandler {
|
||||
|
||||
// check for negative time change
|
||||
if (timeDifference < 0) {
|
||||
Log.w(MyTracksConstants.TAG, "Found negative time change.");
|
||||
Log.w(Constants.TAG, "Found negative time change.");
|
||||
} else {
|
||||
|
||||
// We don't have a speed and bearing in GPX, make something up from
|
||||
|
||||
@@ -23,7 +23,7 @@ import com.google.android.accounts.AuthenticatorException;
|
||||
import com.google.android.accounts.OperationCanceledException;
|
||||
import com.google.android.apps.mytracks.AccountChooser;
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
@@ -104,20 +104,20 @@ public class ModernAuthManager implements AuthManager {
|
||||
if (result.containsKey(AccountManager.KEY_INTENT)) {
|
||||
Intent intent = (Intent) result.get(AccountManager.KEY_INTENT);
|
||||
clearNewTaskFlag(intent);
|
||||
activity.startActivityForResult(intent, MyTracksConstants.GET_LOGIN);
|
||||
activity.startActivityForResult(intent, Constants.GET_LOGIN);
|
||||
return;
|
||||
}
|
||||
|
||||
authToken = result.getString(
|
||||
AccountManager.KEY_AUTHTOKEN);
|
||||
Log.e(MyTracksConstants.TAG, "Got auth token.");
|
||||
Log.e(Constants.TAG, "Got auth token.");
|
||||
runWhenFinished();
|
||||
} catch (OperationCanceledException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Operation Canceled", e);
|
||||
Log.e(Constants.TAG, "Operation Canceled", e);
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "IOException", e);
|
||||
Log.e(Constants.TAG, "IOException", e);
|
||||
} catch (AuthenticatorException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Authentication Failed", e);
|
||||
Log.e(Constants.TAG, "Authentication Failed", e);
|
||||
}
|
||||
}
|
||||
}, null /* handler */);
|
||||
@@ -149,9 +149,9 @@ public class ModernAuthManager implements AuthManager {
|
||||
if (results != null) {
|
||||
authToken = results.getStringExtra(
|
||||
AccountManager.KEY_AUTHTOKEN);
|
||||
Log.w(MyTracksConstants.TAG, "authResult: " + authToken);
|
||||
Log.w(Constants.TAG, "authResult: " + authToken);
|
||||
} else {
|
||||
Log.e(MyTracksConstants.TAG, "No auth result results!!");
|
||||
Log.e(Constants.TAG, "No auth result results!!");
|
||||
}
|
||||
runWhenFinished();
|
||||
return authToken != null;
|
||||
@@ -181,7 +181,7 @@ public class ModernAuthManager implements AuthManager {
|
||||
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
accountManager.invalidateAuthToken(MyTracksConstants.ACCOUNT_TYPE,
|
||||
accountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE,
|
||||
authToken);
|
||||
MyTracks.getInstance().getAccountChooser().chooseAccount(activity,
|
||||
new AccountChooser.AccountHandler() {
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.io.gdata.GDataClientFactory;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsService;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsStringsProvider;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade.AuthenticationRefresher;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Factory to easily instantiate a {@link MapsFacade}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class MyMapsFactory {
|
||||
|
||||
/**
|
||||
* Simple provider for reading strings from resources.
|
||||
*/
|
||||
private static class MyMapsStringProvider implements MapsStringsProvider {
|
||||
private final Context context;
|
||||
|
||||
public MyMapsStringProvider(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNewMapDescription() {
|
||||
return context.getString(R.string.new_map_description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStart() {
|
||||
return context.getString(R.string.start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEnd() {
|
||||
return context.getString(R.string.end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Maps fa�ade interface instance.
|
||||
*
|
||||
* @param context current context
|
||||
* @param auth a valid authentication manager
|
||||
* @return the fa�ade
|
||||
*/
|
||||
public static MapsFacade newMapsClient(Activity context, final AuthManager auth) {
|
||||
MapsFacade client = MapsService.newClient(context,
|
||||
GDataClientFactory.getGDataClient(context),
|
||||
new MyMapsStringProvider(context),
|
||||
auth.getAuthToken());
|
||||
client.setAuthenticationRefresher(new AuthenticationRefresher() {
|
||||
@Override
|
||||
public void invalidateAndRefresh(Runnable done) {
|
||||
auth.invalidateAndRefresh(done);
|
||||
}
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
private MyMapsFactory() {}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
@@ -82,7 +82,7 @@ public class SendToDocs {
|
||||
metricUnits = true;
|
||||
}
|
||||
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"Sending to Google Docs: trackId = " + trackId);
|
||||
handlerThread = new HandlerThread("SendToGoogleDocs");
|
||||
handlerThread.start();
|
||||
@@ -105,7 +105,7 @@ public class SendToDocs {
|
||||
|
||||
try {
|
||||
if (trackId == -1) {
|
||||
Log.w(MyTracksConstants.TAG, "Cannot get track id.");
|
||||
Log.w(Constants.TAG, "Cannot get track id.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,14 +113,14 @@ public class SendToDocs {
|
||||
Track track =
|
||||
MyTracksProviderUtils.Factory.get(activity).getTrack(trackId);
|
||||
if (track == null) {
|
||||
Log.w(MyTracksConstants.TAG, "Cannot get track.");
|
||||
Log.w(Constants.TAG, "Cannot get track.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Transmit track stats via GData feed:
|
||||
// -------------------------------
|
||||
|
||||
Log.d(MyTracksConstants.TAG, "SendToDocs: Uploading to spreadsheet");
|
||||
Log.d(Constants.TAG, "SendToDocs: Uploading to spreadsheet");
|
||||
success = uploadToDocs(track);
|
||||
if (success) {
|
||||
if (createdNewSpreadSheet) {
|
||||
@@ -133,7 +133,7 @@ public class SendToDocs {
|
||||
} else {
|
||||
statusMessage = activity.getString(R.string.error_sending_to_docs);
|
||||
}
|
||||
Log.d(MyTracksConstants.TAG, "SendToDocs: Done.");
|
||||
Log.d(Constants.TAG, "SendToDocs: Done.");
|
||||
} finally {
|
||||
if (onCompletion != null) {
|
||||
activity.runOnUiThread(onCompletion);
|
||||
@@ -176,7 +176,7 @@ public class SendToDocs {
|
||||
SpreadsheetsClient gdataClient = new SpreadsheetsClient(androidClient,
|
||||
new XmlDocsGDataParserFactory(new AndroidXmlParserFactory()));
|
||||
trixWrapper.setClient(gdataClient);
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"GData connection prepared: " + this.docListAuth);
|
||||
String sheetTitle = "My Tracks";
|
||||
|
||||
@@ -194,7 +194,7 @@ public class SendToDocs {
|
||||
spreadsheetId = docsHelper.requestSpreadsheetId(docListWrapper,
|
||||
sheetTitle);
|
||||
} catch (IOException e) {
|
||||
Log.i(MyTracksConstants.TAG, "Spreadsheet lookup failed.", e);
|
||||
Log.i(Constants.TAG, "Spreadsheet lookup failed.", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -205,14 +205,14 @@ public class SendToDocs {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Sleep interrupted", e);
|
||||
Log.e(Constants.TAG, "Sleep interrupted", e);
|
||||
}
|
||||
|
||||
try {
|
||||
spreadsheetId = docsHelper.requestSpreadsheetId(docListWrapper,
|
||||
sheetTitle);
|
||||
} catch (IOException e) {
|
||||
Log.i(MyTracksConstants.TAG, "2nd spreadsheet lookup failed.", e);
|
||||
Log.i(Constants.TAG, "2nd spreadsheet lookup failed.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -220,13 +220,13 @@ public class SendToDocs {
|
||||
// We were unable to find an existing spreadsheet, so create a new one.
|
||||
MyTracks.getInstance().setProgressValue(70);
|
||||
if (spreadsheetId == null) {
|
||||
Log.i(MyTracksConstants.TAG, "Creating new spreadsheet: " + sheetTitle);
|
||||
Log.i(Constants.TAG, "Creating new spreadsheet: " + sheetTitle);
|
||||
|
||||
try {
|
||||
spreadsheetId = docsHelper.createSpreadsheet(activity, docListWrapper,
|
||||
sheetTitle);
|
||||
} catch (IOException e) {
|
||||
Log.i(MyTracksConstants.TAG, "Failed to create new spreadsheet "
|
||||
Log.i(Constants.TAG, "Failed to create new spreadsheet "
|
||||
+ sheetTitle, e);
|
||||
return false;
|
||||
}
|
||||
@@ -239,19 +239,19 @@ public class SendToDocs {
|
||||
// reported an error. Seems to be a know bug,
|
||||
// see http://code.google.com/p/gdata-issues/issues/detail?id=929
|
||||
// Try to find the created spreadsheet:
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(Constants.TAG,
|
||||
"Create might have failed. Trying to find created document.");
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Sleep interrupted", e);
|
||||
Log.e(Constants.TAG, "Sleep interrupted", e);
|
||||
}
|
||||
|
||||
try {
|
||||
spreadsheetId = docsHelper.requestSpreadsheetId(docListWrapper,
|
||||
sheetTitle);
|
||||
} catch (IOException e) {
|
||||
Log.i(MyTracksConstants.TAG, "Failed create-failed lookup", e);
|
||||
Log.i(Constants.TAG, "Failed create-failed lookup", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -261,19 +261,19 @@ public class SendToDocs {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Sleep interrupted", e);
|
||||
Log.e(Constants.TAG, "Sleep interrupted", e);
|
||||
}
|
||||
|
||||
try {
|
||||
spreadsheetId = docsHelper.requestSpreadsheetId(docListWrapper,
|
||||
sheetTitle);
|
||||
} catch (IOException e) {
|
||||
Log.i(MyTracksConstants.TAG, "Failed create-failed relookup", e);
|
||||
Log.i(Constants.TAG, "Failed create-failed relookup", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (spreadsheetId == null) {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"Creating new spreadsheet really failed.");
|
||||
return false;
|
||||
}
|
||||
@@ -287,7 +287,7 @@ public class SendToDocs {
|
||||
throw new IOException("Worksheet ID lookup returned empty");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.i(MyTracksConstants.TAG, "Looking up worksheet id failed.", e);
|
||||
Log.i(Constants.TAG, "Looking up worksheet id failed.", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -295,9 +295,9 @@ public class SendToDocs {
|
||||
|
||||
docsHelper.addTrackRow(activity, trixAuth, spreadsheetId, worksheetId,
|
||||
track, metricUnits);
|
||||
Log.i(MyTracksConstants.TAG, "Done uploading to docs.");
|
||||
Log.i(Constants.TAG, "Done uploading to docs.");
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Unable to upload docs.", e);
|
||||
Log.e(Constants.TAG, "Unable to upload docs.", e);
|
||||
return false;
|
||||
} finally {
|
||||
if (androidClient != null) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
@@ -151,7 +151,7 @@ public class SendToFusionTables implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(MyTracksConstants.TAG, "Sending to Fusion tables: trackId = " + trackId);
|
||||
Log.d(Constants.TAG, "Sending to Fusion tables: trackId = " + trackId);
|
||||
doUpload();
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ public class SendToFusionTables implements Runnable {
|
||||
private void doUpload() {
|
||||
((GoogleHeaders) transport.defaultHeaders).setGoogleLogin(auth.getAuthToken());
|
||||
int statusMessageId = R.string.error_sending_to_fusiontables;
|
||||
boolean success = false;
|
||||
boolean success = true;
|
||||
try {
|
||||
progressIndicator.setProgressValue(PROGRESS_INITIALIZATION);
|
||||
progressIndicator.setProgressMessage(R.string.progress_message_reading_track);
|
||||
@@ -204,11 +204,10 @@ public class SendToFusionTables implements Runnable {
|
||||
}
|
||||
|
||||
statusMessageId = R.string.status_new_fusiontable_has_been_created;
|
||||
success = true;
|
||||
Log.d(MyTracksConstants.TAG, "SendToFusionTables: Done: " + success);
|
||||
Log.d(Constants.TAG, "SendToFusionTables: Done: " + success);
|
||||
progressIndicator.setProgressValue(PROGRESS_COMPLETE);
|
||||
|
||||
} finally {
|
||||
|
||||
final boolean finalSuccess = success;
|
||||
final int finalStatusMessageId = statusMessageId;
|
||||
context.runOnUiThread(new Runnable() {
|
||||
@@ -229,14 +228,14 @@ public class SendToFusionTables implements Runnable {
|
||||
* @return true in case of success.
|
||||
*/
|
||||
private boolean createNewTable(Track track) {
|
||||
Log.d(MyTracksConstants.TAG, "Creating a new fusion table.");
|
||||
Log.d(Constants.TAG, "Creating a new fusion table.");
|
||||
String query = "CREATE TABLE '" + sqlEscape(track.getName()) +
|
||||
"' (name:STRING,description:STRING,geometry:LOCATION,marker:STRING)";
|
||||
return runUpdate(query);
|
||||
}
|
||||
|
||||
private boolean makeTableUnlisted(String tableId) {
|
||||
Log.d(MyTracksConstants.TAG, "Setting visibility to unlisted.");
|
||||
Log.d(Constants.TAG, "Setting visibility to unlisted.");
|
||||
String query = "UPDATE TABLE " + tableId + " SET VISIBILITY = UNLISTED";
|
||||
return runUpdate(query);
|
||||
}
|
||||
@@ -275,7 +274,7 @@ public class SendToFusionTables implements Runnable {
|
||||
*/
|
||||
private boolean createNewPoint(String name, String description, Location location,
|
||||
String marker) {
|
||||
Log.d(MyTracksConstants.TAG, "Creating a new row with a point.");
|
||||
Log.d(Constants.TAG, "Creating a new row with a point.");
|
||||
String query = "INSERT INTO " + tableId + " (name,description,geometry,marker) VALUES "
|
||||
+ values(name, description, getKmlPoint(location), marker);
|
||||
return runUpdate(query);
|
||||
@@ -288,7 +287,7 @@ public class SendToFusionTables implements Runnable {
|
||||
* @return true in case of success.
|
||||
*/
|
||||
private boolean createNewLineString(Track track) {
|
||||
Log.d(MyTracksConstants.TAG, "Creating a new row with a point.");
|
||||
Log.d(Constants.TAG, "Creating a new row with a point.");
|
||||
String query = "INSERT INTO " + tableId
|
||||
+ " (name,description,geometry) VALUES "
|
||||
+ values(track.getName(), track.getDescription(), getKmlLineString(track));
|
||||
@@ -306,7 +305,7 @@ public class SendToFusionTables implements Runnable {
|
||||
Cursor locationsCursor = providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
||||
try {
|
||||
if (!locationsCursor.moveToFirst()) {
|
||||
Log.w(MyTracksConstants.TAG, "Unable to get any points to upload");
|
||||
Log.w(Constants.TAG, "Unable to get any points to upload");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -319,14 +318,14 @@ public class SendToFusionTables implements Runnable {
|
||||
// Limit the number of elevation readings. Ideally we would want around 250.
|
||||
int elevationSamplingFrequency =
|
||||
Math.max(1, (int) (totalLocations / 250.0));
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"Using elevation sampling factor: " + elevationSamplingFrequency
|
||||
+ " on " + totalLocations);
|
||||
double totalDistance = 0;
|
||||
|
||||
Vector<Double> distances = new Vector<Double>();
|
||||
Vector<Double> elevations = new Vector<Double>();
|
||||
DoubleBuffer elevationBuffer = new DoubleBuffer(MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
DoubleBuffer elevationBuffer = new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
||||
Location lastLocation = null;
|
||||
@@ -448,7 +447,7 @@ public class SendToFusionTables implements Runnable {
|
||||
|
||||
int numLocations = locations.size();
|
||||
if (numLocations < 2) {
|
||||
Log.d(MyTracksConstants.TAG, "Not preparing/uploading too few points");
|
||||
Log.d(Constants.TAG, "Not preparing/uploading too few points");
|
||||
totalLocationsUploaded += numLocations;
|
||||
return true;
|
||||
}
|
||||
@@ -464,16 +463,16 @@ public class SendToFusionTables implements Runnable {
|
||||
context.getString(R.string.part), totalSegmentsUploaded));
|
||||
}
|
||||
totalSegmentsUploaded++;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"SendToFusionTables: Prepared feature for upload w/ "
|
||||
+ splitTrack.getLocations().size() + " points.");
|
||||
|
||||
// Transmit tracks via GData feed:
|
||||
// -------------------------------
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"SendToFusionTables: Uploading to table " + tableId + " w/ auth " + auth);
|
||||
if (!uploadTrackPoints(splitTrack)) {
|
||||
Log.e(MyTracksConstants.TAG, "Uploading failed");
|
||||
Log.e(Constants.TAG, "Uploading failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -519,7 +518,7 @@ public class SendToFusionTables implements Runnable {
|
||||
// Close up the last segment.
|
||||
prepareTrackSegment(segment, splitTracks);
|
||||
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"MyTracksSendToFusionTables: Starting new track segment...");
|
||||
startNewTrackSegment = false;
|
||||
segment = new Track();
|
||||
@@ -582,7 +581,7 @@ public class SendToFusionTables implements Runnable {
|
||||
int numLocations = splitTrack.getLocations().size();
|
||||
if (numLocations < 2) {
|
||||
// Need at least two points for a polyline:
|
||||
Log.w(MyTracksConstants.TAG, "Not uploading too few points");
|
||||
Log.w(Constants.TAG, "Not uploading too few points");
|
||||
return true;
|
||||
}
|
||||
return createNewLineString(splitTrack);
|
||||
@@ -605,14 +604,14 @@ public class SendToFusionTables implements Runnable {
|
||||
try {
|
||||
c = providerUtils.getWaypointsCursor(
|
||||
track.getId(), 0,
|
||||
MyTracksConstants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (c != null) {
|
||||
if (c.moveToFirst()) {
|
||||
// This will skip the 1st waypoint (it carries the stats for the
|
||||
// last segment).
|
||||
while (c.moveToNext()) {
|
||||
Waypoint wpt = providerUtils.createWaypoint(c);
|
||||
Log.d(MyTracksConstants.TAG, "SendToFusionTables: Creating waypoint.");
|
||||
Log.d(Constants.TAG, "SendToFusionTables: Creating waypoint.");
|
||||
success = createNewPoint(wpt.getName(), wpt.getDescription(), wpt.getLocation(),
|
||||
MARKER_TYPE_WAYPOINT);
|
||||
if (!success) {
|
||||
@@ -622,7 +621,7 @@ public class SendToFusionTables implements Runnable {
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
Log.w(MyTracksConstants.TAG, "SendToFusionTables: upload waypoints failed.");
|
||||
Log.w(Constants.TAG, "SendToFusionTables: upload waypoints failed.");
|
||||
}
|
||||
return success;
|
||||
} finally {
|
||||
@@ -657,7 +656,7 @@ public class SendToFusionTables implements Runnable {
|
||||
wrapper.setAuthManager(auth);
|
||||
wrapper.setRetryOnAuthFailure(true);
|
||||
wrapper.setClient(transport);
|
||||
Log.d(MyTracksConstants.TAG, "GData connection prepared: " + this.auth);
|
||||
Log.d(Constants.TAG, "GData connection prepared: " + this.auth);
|
||||
wrapper.runQuery(new QueryFunction<HttpTransport>() {
|
||||
@Override
|
||||
public void query(HttpTransport client)
|
||||
@@ -672,7 +671,7 @@ public class SendToFusionTables implements Runnable {
|
||||
isc.inputStream = new ByteArrayInputStream(Strings.toBytesUtf8(sql));
|
||||
request.content = isc;
|
||||
|
||||
Log.d(MyTracksConstants.TAG, "Running update query " + url.toString() + ": " + sql);
|
||||
Log.d(Constants.TAG, "Running update query " + url.toString() + ": " + sql);
|
||||
HttpResponse response;
|
||||
try {
|
||||
response = request.execute();
|
||||
@@ -687,12 +686,12 @@ public class SendToFusionTables implements Runnable {
|
||||
String[] lines = s.split(Strings.LINE_SEPARATOR);
|
||||
if (lines[0].equals("tableid")) {
|
||||
tableId = lines[1];
|
||||
Log.d(MyTracksConstants.TAG, "tableId = " + tableId);
|
||||
Log.d(Constants.TAG, "tableId = " + tableId);
|
||||
} else {
|
||||
Log.w(MyTracksConstants.TAG, "Unrecognized response: " + lines[0]);
|
||||
Log.w(Constants.TAG, "Unrecognized response: " + lines[0]);
|
||||
}
|
||||
} else {
|
||||
Log.d(MyTracksConstants.TAG, "Query failed: " + response.statusMessage + " (" +
|
||||
Log.d(Constants.TAG, "Query failed: " + response.statusMessage + " (" +
|
||||
response.statusCode + ")");
|
||||
throw new GDataWrapper.HttpException(response.statusCode, response.statusMessage);
|
||||
}
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade.WaypointData;
|
||||
import com.google.android.apps.mytracks.stats.DoubleBuffer;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.MyTracksUtils;
|
||||
@@ -93,7 +93,7 @@ public class SendToMyMaps implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(MyTracksConstants.TAG, "Sending to MyMaps: trackId = " + trackId);
|
||||
Log.d(TAG, "Sending to MyMaps: trackId = " + trackId);
|
||||
doUpload();
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class SendToMyMaps implements Runnable {
|
||||
track.setDescription("<p>" + track.getDescription() + "</p><p>"
|
||||
+ stringUtils.generateTrackDescription(track, null, null) + "</p>");
|
||||
|
||||
mapsClient = MyMapsFactory.newMapsClient(context, auth);
|
||||
mapsClient = new MapsFacade(context, auth);
|
||||
|
||||
// Create a new map if necessary:
|
||||
boolean isNewMap = mapId.equals(NEW_MAP_ID);
|
||||
@@ -142,17 +142,16 @@ public class SendToMyMaps implements Runnable {
|
||||
if (success) {
|
||||
Cursor c = providerUtils.getWaypointsCursor(
|
||||
track.getId(), 0,
|
||||
MyTracksConstants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (c != null) {
|
||||
try {
|
||||
if (c.getCount() > 1 && c.moveToFirst()) {
|
||||
// This will skip the 1st waypoint (it carries the stats for the
|
||||
// last segment).
|
||||
ArrayList<WaypointData> waypoints = new ArrayList<WaypointData>(c.getCount() - 1);
|
||||
ArrayList<Waypoint> waypoints = new ArrayList<Waypoint>(c.getCount() - 1);
|
||||
while (c.moveToNext()) {
|
||||
Waypoint wpt = providerUtils.createWaypoint(c);
|
||||
waypoints.add(new WaypointData(
|
||||
wpt.getName(), wpt.getDescription(), wpt.getIcon(), wpt.getLocation()));
|
||||
waypoints.add(wpt);
|
||||
}
|
||||
|
||||
success = mapsClient.uploadWaypoints(mapId, waypoints);
|
||||
@@ -165,8 +164,7 @@ public class SendToMyMaps implements Runnable {
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: upload waypoints failed.");
|
||||
Log.w(TAG, "SendToMyMaps: upload waypoints failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +173,7 @@ public class SendToMyMaps implements Runnable {
|
||||
? R.string.status_new_mymap_has_been_created
|
||||
: R.string.status_tracks_have_been_uploaded;
|
||||
}
|
||||
Log.d(MyTracksConstants.TAG, "SendToMyMaps: Done: " + success);
|
||||
Log.d(TAG, "SendToMyMaps: Done: " + success);
|
||||
progressIndicator.setProgressValue(100);
|
||||
} finally {
|
||||
if (mapsClient != null) {
|
||||
@@ -210,7 +208,7 @@ public class SendToMyMaps implements Runnable {
|
||||
providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
||||
try {
|
||||
if (!locationsCursor.moveToFirst()) {
|
||||
Log.w(MyTracksConstants.TAG, "Unable to get any points to upload");
|
||||
Log.w(TAG, "Unable to get any points to upload");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -223,7 +221,7 @@ public class SendToMyMaps implements Runnable {
|
||||
// Limit the number of elevation readings. Ideally we would want around 250.
|
||||
int elevationSamplingFrequency =
|
||||
Math.max(1, (int) (totalLocations / 250.0));
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Using elevation sampling factor: " + elevationSamplingFrequency
|
||||
+ " on " + totalLocations);
|
||||
double totalDistance = 0;
|
||||
@@ -231,7 +229,7 @@ public class SendToMyMaps implements Runnable {
|
||||
Vector<Double> distances = new Vector<Double>();
|
||||
Vector<Double> elevations = new Vector<Double>();
|
||||
DoubleBuffer elevationBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
||||
progressIndicator.setProgressMessage(
|
||||
@@ -312,7 +310,7 @@ public class SendToMyMaps implements Runnable {
|
||||
|
||||
int numLocations = locations.size();
|
||||
if (numLocations < 2) {
|
||||
Log.d(MyTracksConstants.TAG, "Not preparing/uploading too few points");
|
||||
Log.d(TAG, "Not preparing/uploading too few points");
|
||||
totalLocationsUploaded += numLocations;
|
||||
return true;
|
||||
}
|
||||
@@ -330,16 +328,16 @@ public class SendToMyMaps implements Runnable {
|
||||
context.getString(R.string.part), totalSegmentsUploaded));
|
||||
}
|
||||
totalSegmentsUploaded++;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"SendToMyMaps: Prepared feature for upload w/ "
|
||||
+ splitTrack.getLocations().size() + " points.");
|
||||
|
||||
// Transmit tracks via GData feed:
|
||||
// -------------------------------
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"SendToMyMaps: Uploading to map " + mapId + " w/ auth " + auth);
|
||||
if (!mapsClient.uploadTrackPoints(mapId, splitTrack.getName(), splitTrack.getLocations())) {
|
||||
Log.e(MyTracksConstants.TAG, "Uploading failed");
|
||||
Log.e(TAG, "Uploading failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -385,7 +383,7 @@ public class SendToMyMaps implements Runnable {
|
||||
// Close up the last segment.
|
||||
prepareTrackSegment(segment, splitTracks);
|
||||
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"MyTracksSendToMyMaps: Starting new track segment...");
|
||||
startNewTrackSegment = false;
|
||||
segment = new Track();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
@@ -17,11 +17,13 @@ package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
|
||||
import com.google.android.apps.mytracks.util.MyTracksUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
|
||||
@@ -30,6 +32,7 @@ import java.io.PrintWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
@@ -37,20 +40,35 @@ import java.util.TimeZone;
|
||||
* As defined by:
|
||||
* http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2
|
||||
*
|
||||
* The TCX file written by this class has been verified as compatible with
|
||||
* Garmin Training Center 3.5.3.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class TcxTrackWriter implements TrackFormatWriter {
|
||||
protected static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
|
||||
// These are the only sports allowed by the TCX v2 specification for fields
|
||||
// of type Sport_t.
|
||||
private static final String TCX_SPORT_BIKING = "Biking";
|
||||
private static final String TCX_SPORT_RUNNING = "Running";
|
||||
private static final String TCX_SPORT_OTHER = "Other";
|
||||
|
||||
// Values for fields of type Build_t/Type.
|
||||
private static final String TCX_TYPE_RELEASE = "Release";
|
||||
private static final String TCX_TYPE_INTERNAL = "Internal";
|
||||
|
||||
private final SimpleDateFormat timestampFormatter;
|
||||
private final Context context;
|
||||
|
||||
private PrintWriter pw = null;
|
||||
private Track track;
|
||||
|
||||
static final SimpleDateFormat TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
static {
|
||||
TIMESTAMP_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
public TcxTrackWriter(Context context) {
|
||||
this.context = context;
|
||||
|
||||
public TcxTrackWriter() {
|
||||
timestampFormatter = new SimpleDateFormat(TIMESTAMP_FORMAT);
|
||||
timestampFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,16 +111,13 @@ public class TcxTrackWriter implements TrackFormatWriter {
|
||||
if (pw == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String startTime = timestampFormatter.format(track.getStatistics().getStartTime());
|
||||
|
||||
pw.println(" <Activities>");
|
||||
pw.print(" <Activity Sport=\"");
|
||||
if (track.getCategory() != null) {
|
||||
pw.print(track.getCategory());
|
||||
}
|
||||
pw.println("\">");
|
||||
pw.print(" <Id>");
|
||||
pw.print(TIMESTAMP_FORMAT.format(track.getStatistics().getStartTime()));
|
||||
pw.println("</Id>");
|
||||
pw.println(" <Lap>");
|
||||
pw.format(" <Activity Sport=\"%s\">\n", categoryToTcxSport(track.getCategory()));
|
||||
pw.format(" <Id>%s</Id>\n", startTime);
|
||||
pw.format(" <Lap StartTime=\"%s\">\n", startTime);
|
||||
pw.print(" <TotalTimeSeconds>");
|
||||
pw.print(track.getStatistics().getTotalTime() / 1000);
|
||||
pw.println("</TotalTimeSeconds>");
|
||||
@@ -113,7 +128,7 @@ public class TcxTrackWriter implements TrackFormatWriter {
|
||||
// Calories are a required element just put in 0.
|
||||
pw.print("<Calories>0</Calories>");
|
||||
pw.println("<Intensity>Active</Intensity>");
|
||||
pw.println("<TriggerMethod>Manual</TriggerMethod>)");
|
||||
pw.println("<TriggerMethod>Manual</TriggerMethod>");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,7 +145,7 @@ public class TcxTrackWriter implements TrackFormatWriter {
|
||||
}
|
||||
pw.println(" <Trackpoint>");
|
||||
Date d = new Date(location.getTime());
|
||||
pw.println(" <Time>" + TIMESTAMP_FORMAT.format(d) + "</Time>");
|
||||
pw.println(" <Time>" + timestampFormatter.format(d) + "</Time>");
|
||||
pw.println(" <Position>");
|
||||
|
||||
pw.print(" <LatitudeDegrees>");
|
||||
@@ -194,10 +209,18 @@ public class TcxTrackWriter implements TrackFormatWriter {
|
||||
}
|
||||
pw.println(" </Lap>");
|
||||
pw.print(" <Creator xsi:type=\"Device_t\">");
|
||||
pw.print("<Name>");
|
||||
pw.print(Build.MODEL);
|
||||
pw.print("</Name>");
|
||||
pw.println("</Creator>)");
|
||||
pw.format("<Name>%s</Name>\n", Build.MODEL);
|
||||
|
||||
// The following code is correct. ID is inconsistently capitalized in the
|
||||
// TCX schema.
|
||||
pw.println("<UnitId>0</UnitId>");
|
||||
pw.println("<ProductID>0</ProductID>");
|
||||
|
||||
pw.println("<Version>");
|
||||
pw.println("<VersionMajor>0</VersionMajor>");
|
||||
pw.println("<VersionMinor>0</VersionMinor>");
|
||||
pw.println("</Version>");
|
||||
pw.println("</Creator>");
|
||||
pw.println(" </Activity>");
|
||||
pw.println(" </Activities>");
|
||||
}
|
||||
@@ -207,8 +230,31 @@ public class TcxTrackWriter implements TrackFormatWriter {
|
||||
if (pw == null) {
|
||||
return;
|
||||
}
|
||||
pw.print(" <Author xsi:type=\"Application_t\">");
|
||||
pw.print("<Name>My Tracks by Google</Name>");
|
||||
pw.println(" <Author xsi:type=\"Application_t\">");
|
||||
|
||||
// We put the version in the name because there isn't a better place for
|
||||
// it. The TCX schema tightly defined the Version tag, so we can't put it
|
||||
// there. They've similarly constrained the PartNumber tag, so it can't go
|
||||
// there either.
|
||||
pw.format("<Name>My Tracks %s by Google</Name>\n", MyTracksUtils.getMyTracksVersion(context));
|
||||
|
||||
pw.println("<Build>");
|
||||
|
||||
// The TCX spec for the Version tag is too strict to allow us to use our
|
||||
// user-visible version number, so we use our version code instead. We
|
||||
// also set the minor version to 1 if this is a development build to
|
||||
// signify that this build is newer than the one associated with the
|
||||
// version code given in VersionMajor.
|
||||
pw.println("<Version>");
|
||||
pw.format("<VersionMajor>%d</VersionMajor>\n", MyTracksUtils.getMyTracksVersion(context));
|
||||
pw.format("<VersionMinor>%d</VersionMinor>\n", MyTracksUtils.isRelease(context) ? 0 : 1);
|
||||
pw.println("</Version>");
|
||||
|
||||
pw.format("<Type>%s</Type>\n", MyTracksUtils.isRelease(context) ? TCX_TYPE_RELEASE
|
||||
: TCX_TYPE_INTERNAL);
|
||||
pw.println("</Build>");
|
||||
pw.format("<LangID>%s</LangID>\n", Locale.getDefault().getLanguage());
|
||||
pw.println("<PartNumber>000-00000-00</PartNumber>");
|
||||
pw.println("</Author>");
|
||||
pw.println("</TrainingCenterDatabase>");
|
||||
}
|
||||
@@ -217,4 +263,15 @@ public class TcxTrackWriter implements TrackFormatWriter {
|
||||
public void writeWaypoint(Waypoint waypoint) {
|
||||
// TODO Write out the waypoints somewhere.
|
||||
}
|
||||
|
||||
private String categoryToTcxSport(String category) {
|
||||
category = category.trim();
|
||||
if (category.equalsIgnoreCase(TCX_SPORT_RUNNING)) {
|
||||
return TCX_SPORT_RUNNING;
|
||||
} else if (category.equalsIgnoreCase(TCX_SPORT_BIKING)) {
|
||||
return TCX_SPORT_BIKING;
|
||||
} else {
|
||||
return TCX_SPORT_OTHER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
@@ -160,16 +160,16 @@ public class TrackWriter {
|
||||
String fileName = fileUtils.buildUniqueFileName(
|
||||
directory, track.getName(), writer.getExtension());
|
||||
if (fileName == null) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(Constants.TAG,
|
||||
"Unable to get a unique filename for " + fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.i(MyTracksConstants.TAG, "Writing track to: " + fileName);
|
||||
Log.i(Constants.TAG, "Writing track to: " + fileName);
|
||||
try {
|
||||
writer.prepare(track, newOutputStream(fileName));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Failed to open output file.", e);
|
||||
Log.e(Constants.TAG, "Failed to open output file.", e);
|
||||
errorMessage = R.string.io_write_failed;
|
||||
return false;
|
||||
}
|
||||
@@ -187,12 +187,12 @@ public class TrackWriter {
|
||||
}
|
||||
|
||||
if (!fileUtils.isSdCardAvailable()) {
|
||||
Log.i(MyTracksConstants.TAG, "Could not find SD card.");
|
||||
Log.i(Constants.TAG, "Could not find SD card.");
|
||||
errorMessage = R.string.io_no_external_storage_found;
|
||||
return false;
|
||||
}
|
||||
if (!fileUtils.ensureDirectoryExists(directory)) {
|
||||
Log.i(MyTracksConstants.TAG, "Could not create export directory.");
|
||||
Log.i(Constants.TAG, "Could not create export directory.");
|
||||
errorMessage = R.string.io_create_dir_failed;
|
||||
return false;
|
||||
}
|
||||
@@ -230,7 +230,7 @@ public class TrackWriter {
|
||||
// same time.
|
||||
Cursor cursor = null;
|
||||
cursor = providerUtils.getWaypointsCursor(trackId, 0,
|
||||
MyTracksConstants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
@@ -253,14 +253,14 @@ public class TrackWriter {
|
||||
* Does the actual work of writing the track to the now open file.
|
||||
*/
|
||||
void writeDocument() {
|
||||
Log.d(MyTracksConstants.TAG, "Started writing track.");
|
||||
Log.d(Constants.TAG, "Started writing track.");
|
||||
writer.writeHeader();
|
||||
writeWaypoints(track.getId());
|
||||
writeLocations();
|
||||
writer.writeFooter();
|
||||
writer.close();
|
||||
success = true;
|
||||
Log.d(MyTracksConstants.TAG, "Done writing track.");
|
||||
Log.d(Constants.TAG, "Done writing track.");
|
||||
errorMessage = R.string.io_write_finished;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ public class TrackWriter {
|
||||
locationFactory);
|
||||
try {
|
||||
if (!it.hasNext()) {
|
||||
Log.w(MyTracksConstants.TAG, "Unable to get any points to write");
|
||||
Log.w(Constants.TAG, "Unable to get any points to write");
|
||||
return;
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
@@ -53,7 +53,7 @@ public class TrackWriterFactory {
|
||||
TCX {
|
||||
@Override
|
||||
public TrackFormatWriter newFormatWriter(Context context) {
|
||||
return new TcxTrackWriter();
|
||||
return new TcxTrackWriter(context);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.google.android.apps.mytracks.io.backup;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
@@ -97,7 +97,7 @@ public class BackupActivityHelper {
|
||||
backup.writeToDefaultFile();
|
||||
showToast(R.string.io_write_finished);
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Failed to write backup", e);
|
||||
Log.e(Constants.TAG, "Failed to write backup", e);
|
||||
showToast(R.string.io_write_failed);
|
||||
} finally {
|
||||
dismissDialog(progressDialog);
|
||||
@@ -199,7 +199,7 @@ public class BackupActivityHelper {
|
||||
backup.restoreFromDate(date);
|
||||
showToast(R.string.io_read_finished);
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Failed to restore backup", e);
|
||||
Log.e(Constants.TAG, "Failed to restore backup", e);
|
||||
showToast(R.string.io_read_failed);
|
||||
} finally {
|
||||
dismissDialog(progressDialog);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.backup;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.TrackPointsColumns;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
@@ -88,7 +88,7 @@ class ExternalFileBackup {
|
||||
private File getBackupsDirectory(boolean create) {
|
||||
String dirName = fileUtils.buildExternalDirectoryPath(BACKUPS_SUBDIR);
|
||||
final File dir = new File(dirName);
|
||||
Log.d(MyTracksConstants.TAG, "Dir: " + dir.getAbsolutePath());
|
||||
Log.d(Constants.TAG, "Dir: " + dir.getAbsolutePath());
|
||||
if (create) {
|
||||
// Try to create - if that fails, return null
|
||||
return fileUtils.ensureDirectoryExists(dir) ? dir : null;
|
||||
@@ -147,7 +147,7 @@ class ExternalFileBackup {
|
||||
* Synchronously writes a backup to the given file.
|
||||
*/
|
||||
private void writeToFile(File outputFile) throws IOException {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"Writing backup to file " + outputFile.getAbsolutePath());
|
||||
|
||||
// Create all the auxiliary classes that will do the writing
|
||||
@@ -219,7 +219,7 @@ class ExternalFileBackup {
|
||||
* Synchronously restores the backup from the given file.
|
||||
*/
|
||||
private void restoreFromFile(File inputFile) throws IOException {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"Restoring from file " + inputFile.getAbsolutePath());
|
||||
|
||||
PreferenceBackupHelper preferencesHelper = new PreferenceBackupHelper();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.backup;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
|
||||
import android.app.backup.BackupAgent;
|
||||
@@ -40,12 +40,12 @@ public class MyTracksBackupAgent extends BackupAgent {
|
||||
@Override
|
||||
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
|
||||
ParcelFileDescriptor newState) throws IOException {
|
||||
Log.i(MyTracksConstants.TAG, "Performing backup");
|
||||
Log.i(Constants.TAG, "Performing backup");
|
||||
SharedPreferences preferences = this.getSharedPreferences(
|
||||
MyTracksSettings.SETTINGS_NAME, 0);
|
||||
|
||||
backupPreferences(data, preferences);
|
||||
Log.i(MyTracksConstants.TAG, "Backup complete");
|
||||
Log.i(Constants.TAG, "Backup complete");
|
||||
}
|
||||
|
||||
private void backupPreferences(BackupDataOutput data,
|
||||
@@ -63,18 +63,18 @@ public class MyTracksBackupAgent extends BackupAgent {
|
||||
@Override
|
||||
public void onRestore(BackupDataInput data, int appVersionCode,
|
||||
ParcelFileDescriptor newState) throws IOException {
|
||||
Log.i(MyTracksConstants.TAG, "Restoring from backup");
|
||||
Log.i(Constants.TAG, "Restoring from backup");
|
||||
while (data.readNextHeader()) {
|
||||
String key = data.getKey();
|
||||
Log.d(MyTracksConstants.TAG, "Restoring entity " + key);
|
||||
Log.d(Constants.TAG, "Restoring entity " + key);
|
||||
if (key.equals(PREFERENCES_ENTITY)) {
|
||||
restorePreferences(data);
|
||||
} else {
|
||||
Log.e(MyTracksConstants.TAG, "Found unknown backup entity: " + key);
|
||||
Log.e(Constants.TAG, "Found unknown backup entity: " + key);
|
||||
data.skipEntityData();
|
||||
}
|
||||
}
|
||||
Log.i(MyTracksConstants.TAG, "Done restoring from backup");
|
||||
Log.i(Constants.TAG, "Done restoring from backup");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.docs;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
import com.google.android.apps.mytracks.io.gdata.GDataWrapper;
|
||||
@@ -144,7 +144,7 @@ public class DocsHelper {
|
||||
|
||||
String id = result.substring(
|
||||
idStringStart + DOCS_SPREADSHEET_URL.length(), idTagCloseIndex);
|
||||
Log.i(MyTracksConstants.TAG, "Created new spreadsheet: " + id);
|
||||
Log.i(Constants.TAG, "Created new spreadsheet: " + id);
|
||||
idSaver.set(id);
|
||||
}});
|
||||
|
||||
@@ -184,7 +184,7 @@ public class DocsHelper {
|
||||
while (listParser.hasMoreData()) {
|
||||
Entry entry = listParser.readNextEntry(null);
|
||||
String entryTitle = entry.getTitle();
|
||||
Log.i(MyTracksConstants.TAG, "Found docs entry: " + entryTitle);
|
||||
Log.i(Constants.TAG, "Found docs entry: " + entryTitle);
|
||||
if (entryTitle.equals(title)) {
|
||||
String entryId = entry.getId();
|
||||
int lastSlash = entryId.lastIndexOf('/');
|
||||
@@ -233,7 +233,7 @@ public class DocsHelper {
|
||||
trixWrapper.getAuthManager().getAuthToken());
|
||||
sheetParser.init();
|
||||
if (!sheetParser.hasMoreData()) {
|
||||
Log.i(MyTracksConstants.TAG, "Found no worksheets");
|
||||
Log.i(Constants.TAG, "Found no worksheets");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ public class DocsHelper {
|
||||
|
||||
if (track.getMapId().length() > 0) {
|
||||
tagBuilder.append("map", String.format("%s?msa=0&msid=%s",
|
||||
MyTracksConstants.MAPSHOP_BASE_URL, track.getMapId()));
|
||||
Constants.MAPSHOP_BASE_URL, track.getMapId()));
|
||||
}
|
||||
|
||||
String postText = new StringBuilder()
|
||||
@@ -319,14 +319,14 @@ public class DocsHelper {
|
||||
.append("</entry>")
|
||||
.toString();
|
||||
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"Inserting at: " + spreadsheetId + " => " + worksheetUri);
|
||||
|
||||
Log.i(MyTracksConstants.TAG, postText);
|
||||
Log.i(Constants.TAG, postText);
|
||||
|
||||
writeRowData(trixAuth, worksheetUri, postText);
|
||||
|
||||
Log.i(MyTracksConstants.TAG, "Post finished.");
|
||||
Log.i(Constants.TAG, "Post finished.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,7 +358,7 @@ public class DocsHelper {
|
||||
String line;
|
||||
while ((line = rd.readLine()) != null) {
|
||||
// Process line.
|
||||
Log.i(MyTracksConstants.TAG, "r: " + line);
|
||||
Log.i(Constants.TAG, "r: " + line);
|
||||
}
|
||||
wr.close();
|
||||
rd.close();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.gdata;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.wireless.gdata.client.GDataClient;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -43,7 +43,7 @@ public class GDataClientFactory {
|
||||
} catch (LinkageError e) {
|
||||
// On all other platforms use the client implementation packaged in the
|
||||
// apk.
|
||||
Log.i(MyTracksConstants.TAG, "Using mytracks AndroidGDataClient.", e);
|
||||
Log.i(Constants.TAG, "Using mytracks AndroidGDataClient.", e);
|
||||
return new com.google.android.apps.mytracks.io.gdata.AndroidGDataClient();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.gdata;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
|
||||
import android.util.Log;
|
||||
@@ -173,14 +173,14 @@ public class GDataWrapper<C> {
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.d(MyTracksConstants.TAG, "GData error encountered: " + errorMessage);
|
||||
Log.d(Constants.TAG, "GData error encountered: " + errorMessage);
|
||||
if (errorType == ERROR_AUTH && auth != null) {
|
||||
if (!retryOnAuthFailure || !invalidateAndRefreshAuthToken()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(MyTracksConstants.TAG, "retrying function/query");
|
||||
Log.d(Constants.TAG, "retrying function/query");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -206,11 +206,11 @@ public class GDataWrapper<C> {
|
||||
errorMessage = null;
|
||||
|
||||
} catch (AuthenticationException e) {
|
||||
Log.e(MyTracksConstants.TAG, "AuthenticationException", e);
|
||||
Log.e(Constants.TAG, "AuthenticationException", e);
|
||||
errorType = ERROR_AUTH;
|
||||
errorMessage = e.getMessage();
|
||||
} catch (HttpException e) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(Constants.TAG,
|
||||
"HttpException, code " + e.getStatusCode() + " message " + e.getMessage(), e);
|
||||
errorMessage = e.getMessage();
|
||||
if (e.getStatusCode() == 401) {
|
||||
@@ -219,11 +219,11 @@ public class GDataWrapper<C> {
|
||||
errorType = ERROR_CONNECTION;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Exception", e);
|
||||
Log.e(Constants.TAG, "Exception", e);
|
||||
errorType = ERROR_AUTH;
|
||||
errorMessage = e.getMessage();
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Exception", e);
|
||||
Log.e(Constants.TAG, "Exception", e);
|
||||
errorMessage = e.getMessage();
|
||||
if (errorMessage != null && errorMessage.contains("503")) {
|
||||
errorType = ERROR_INTERNAL;
|
||||
@@ -231,11 +231,11 @@ public class GDataWrapper<C> {
|
||||
errorType = ERROR_CONNECTION;
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Exception", e);
|
||||
Log.e(Constants.TAG, "Exception", e);
|
||||
errorType = ERROR_LOCAL;
|
||||
errorMessage = e.getMessage();
|
||||
} catch (ConflictDetectedException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Exception", e);
|
||||
Log.e(Constants.TAG, "Exception", e);
|
||||
errorType = ERROR_CONFLICT;
|
||||
errorMessage = e.getMessage();
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public class GDataWrapper<C> {
|
||||
* times out.
|
||||
*/
|
||||
private boolean invalidateAndRefreshAuthToken() {
|
||||
Log.d(MyTracksConstants.TAG, "Retrying due to auth failure");
|
||||
Log.d(Constants.TAG, "Retrying due to auth failure");
|
||||
// This FutureTask doesn't do anything -- it exists simply to be
|
||||
// blocked upon using get().
|
||||
FutureTask<?> whenFinishedFuture = new FutureTask<Object>(new Runnable() {
|
||||
@@ -259,18 +259,18 @@ public class GDataWrapper<C> {
|
||||
auth.invalidateAndRefresh(whenFinishedFuture);
|
||||
|
||||
try {
|
||||
Log.d(MyTracksConstants.TAG, "waiting for invalidate");
|
||||
Log.d(Constants.TAG, "waiting for invalidate");
|
||||
whenFinishedFuture.get(AUTH_TOKEN_INVALIDATE_REFRESH_TIMEOUT,
|
||||
TimeUnit.MILLISECONDS);
|
||||
Log.d(MyTracksConstants.TAG, "invalidate finished");
|
||||
Log.d(Constants.TAG, "invalidate finished");
|
||||
return true;
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Failed to invalidate", e);
|
||||
Log.e(Constants.TAG, "Failed to invalidate", e);
|
||||
} catch (ExecutionException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Failed to invalidate", e);
|
||||
Log.e(Constants.TAG, "Failed to invalidate", e);
|
||||
} catch (TimeoutException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Invalidate didn't complete in time", e);
|
||||
Log.e(Constants.TAG, "Invalidate didn't complete in time", e);
|
||||
} finally {
|
||||
whenFinishedFuture.cancel(false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.android.maps.GeoPoint;
|
||||
|
||||
/**
|
||||
* A rectangle in geographical space.
|
||||
*/
|
||||
class GeoRect {
|
||||
public int top;
|
||||
public int left;
|
||||
public int bottom;
|
||||
public int right;
|
||||
|
||||
public GeoRect() {
|
||||
top = 0;
|
||||
left = 0;
|
||||
bottom = 0;
|
||||
right = 0;
|
||||
}
|
||||
|
||||
public GeoRect(GeoPoint center, int latSpan, int longSpan) {
|
||||
top = center.getLatitudeE6() - latSpan / 2;
|
||||
left = center.getLongitudeE6() - longSpan / 2;
|
||||
bottom = center.getLatitudeE6() + latSpan / 2;
|
||||
right = center.getLongitudeE6() + longSpan / 2;
|
||||
}
|
||||
|
||||
public GeoPoint getCenter() {
|
||||
return new GeoPoint(top / 2 + bottom / 2, left / 2 + right / 2);
|
||||
}
|
||||
|
||||
public int getLatSpan() {
|
||||
return bottom - top;
|
||||
}
|
||||
|
||||
public int getLongSpan() {
|
||||
return right - left;
|
||||
}
|
||||
|
||||
public boolean contains(GeoPoint geoPoint) {
|
||||
if (geoPoint.getLatitudeE6() >= top
|
||||
&& geoPoint.getLatitudeE6() <= bottom
|
||||
&& geoPoint.getLongitudeE6() >= left
|
||||
&& geoPoint.getLongitudeE6() <= right) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* GData entry for a map feature.
|
||||
*/
|
||||
class MapFeatureEntry extends Entry {
|
||||
|
||||
private String mPrivacy = null;
|
||||
private Map<String, String> mAttributes = new HashMap<String, String>();
|
||||
|
||||
public void setPrivacy(String privacy) {
|
||||
mPrivacy = privacy;
|
||||
}
|
||||
|
||||
public String getPrivacy() {
|
||||
return mPrivacy;
|
||||
}
|
||||
|
||||
public void setAttribute(String name, String value) {
|
||||
mAttributes.put(name, value);
|
||||
}
|
||||
|
||||
public void removeAttribute(String name) {
|
||||
mAttributes.remove(name);
|
||||
}
|
||||
|
||||
public Map<String, String> getAllAttributes() {
|
||||
return mAttributes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.wireless.gdata.client.GDataClient;
|
||||
import com.google.wireless.gdata.client.GDataParserFactory;
|
||||
import com.google.wireless.gdata.client.GDataServiceClient;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Client to talk to Google Maps via GData.
|
||||
*/
|
||||
class MapsClient extends GDataServiceClient {
|
||||
private static final boolean DEBUG = false;
|
||||
public static final boolean LOG_COMMUNICATION = false;
|
||||
|
||||
private static final String MAPS_BASE_FEED_URL =
|
||||
"http://maps.google.com/maps/feeds/";
|
||||
private static final String MAPS_MAP_FEED_PATH = "maps/default/full";
|
||||
private static final String MAPS_FEATURE_FEED_PATH_BEFORE_MAPID = "features/";
|
||||
private static final String MAPS_FEATURE_FEED_PATH_AFTER_MAPID = "/full";
|
||||
private static final String MAPS_VERSION_FEED_PATH_FORMAT =
|
||||
"%smaps/%s/versions/%s/full/%s";
|
||||
|
||||
private static final String MAP_ENTRY_ID_BEFORE_USER_ID = "maps/feeds/maps/";
|
||||
private static final String MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID = "/";
|
||||
private static final String V2_ONLY_PARAM = "?v=2.0";
|
||||
|
||||
public MapsClient(GDataClient dataClient,
|
||||
GDataParserFactory dataParserFactory) {
|
||||
super(dataClient, dataParserFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return MyMapsConstants.SERVICE_NAME;
|
||||
}
|
||||
|
||||
public static String buildMapUrl(String mapId) {
|
||||
return MyMapsConstants.MAPSHOP_BASE_URL + "?msa=0&msid=" + mapId;
|
||||
}
|
||||
|
||||
public static String getMapsFeed() {
|
||||
if (DEBUG) {
|
||||
Log.d("Maps Client", "Requesting map feed:");
|
||||
}
|
||||
return MAPS_BASE_FEED_URL + MAPS_MAP_FEED_PATH + V2_ONLY_PARAM;
|
||||
}
|
||||
|
||||
public static String getFeaturesFeed(String mapid) {
|
||||
StringBuilder feed = new StringBuilder();
|
||||
feed.append(MAPS_BASE_FEED_URL);
|
||||
feed.append(MAPS_FEATURE_FEED_PATH_BEFORE_MAPID);
|
||||
feed.append(mapid);
|
||||
feed.append(MAPS_FEATURE_FEED_PATH_AFTER_MAPID);
|
||||
feed.append(V2_ONLY_PARAM);
|
||||
return feed.toString();
|
||||
}
|
||||
|
||||
public static String getMapIdFromMapEntryId(String entryId) {
|
||||
String userId = null;
|
||||
String mapId = null;
|
||||
if (DEBUG) {
|
||||
Log.d("Maps GData Client", "Getting mapid from entry id: " + entryId);
|
||||
}
|
||||
int userIdStart =
|
||||
entryId.indexOf(MAP_ENTRY_ID_BEFORE_USER_ID)
|
||||
+ MAP_ENTRY_ID_BEFORE_USER_ID.length();
|
||||
int userIdEnd =
|
||||
entryId.indexOf(MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID, userIdStart);
|
||||
if (userIdStart >= 0 && userIdEnd < entryId.length()
|
||||
&& userIdStart <= userIdEnd) {
|
||||
userId = entryId.substring(userIdStart, userIdEnd);
|
||||
}
|
||||
int mapIdStart =
|
||||
entryId.indexOf(MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID, userIdEnd)
|
||||
+ MAP_ENTRY_ID_BETWEEN_USER_ID_AND_MAP_ID.length();
|
||||
if (mapIdStart >= 0 && mapIdStart < entryId.length()) {
|
||||
mapId = entryId.substring(mapIdStart);
|
||||
}
|
||||
if (userId == null) {
|
||||
userId = "";
|
||||
}
|
||||
if (mapId == null) {
|
||||
mapId = "";
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d("Maps GData Client", "Got user id: " + userId);
|
||||
Log.d("Maps GData Client", "Got map id: " + mapId);
|
||||
}
|
||||
return userId + "." + mapId;
|
||||
}
|
||||
|
||||
public static String getVersionFeed(String versionUserId,
|
||||
String versionClient, String currentVersion) {
|
||||
return String.format(MAPS_VERSION_FEED_PATH_FORMAT,
|
||||
MAPS_BASE_FEED_URL, versionUserId,
|
||||
versionClient, currentVersion);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
// Copyright 2011 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
import com.google.android.maps.GeoPoint;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
import com.google.wireless.gdata.client.HttpException;
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.parser.GDataParser;
|
||||
import com.google.wireless.gdata.parser.ParseException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
/**
|
||||
* Single interface which abstracts all access to the Google Maps service.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class MapsFacade {
|
||||
|
||||
/**
|
||||
* Interface for receiving data back from getMapsList.
|
||||
* All calls to the interface will happen before getMapsList returns.
|
||||
*/
|
||||
public interface MapsListCallback {
|
||||
void onReceivedMapListing(String mapId, String title, String description,
|
||||
boolean isPublic);
|
||||
}
|
||||
|
||||
private static final String END_ICON_URL =
|
||||
"http://maps.google.com/mapfiles/ms/micons/red-dot.png";
|
||||
private static final String START_ICON_URL =
|
||||
"http://maps.google.com/mapfiles/ms/micons/green-dot.png";
|
||||
|
||||
private final Context context;
|
||||
private final MyMapsGDataWrapper wrapper;
|
||||
private final MyMapsGDataConverter gdataConverter;
|
||||
private final String authToken;
|
||||
|
||||
public MapsFacade(Context context, AuthManager auth) {
|
||||
this.context = context;
|
||||
this.authToken = auth.getAuthToken();
|
||||
|
||||
wrapper = new MyMapsGDataWrapper(context, auth);
|
||||
wrapper.setRetryOnAuthFailure(true);
|
||||
|
||||
try {
|
||||
gdataConverter = new MyMapsGDataConverter();
|
||||
} catch (XmlPullParserException e) {
|
||||
throw new IllegalStateException("Unable to create maps data converter", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String buildMapUrl(String mapId) {
|
||||
return MapsClient.buildMapUrl(mapId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all maps for the current user.
|
||||
*
|
||||
* @param callback callback to call for each map returned
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
public boolean getMapsList(final MapsListCallback callback) {
|
||||
return wrapper.runQuery(new MyMapsGDataWrapper.QueryFunction() {
|
||||
@Override
|
||||
public void query(MapsClient client) throws IOException, Exception {
|
||||
GDataParser listParser = client.getParserForFeed(
|
||||
MapFeatureEntry.class, MapsClient.getMapsFeed(), authToken);
|
||||
listParser.init();
|
||||
while (listParser.hasMoreData()) {
|
||||
MapFeatureEntry entry =
|
||||
(MapFeatureEntry) listParser.readNextEntry(null);
|
||||
MyMapsMapMetadata metadata =
|
||||
MyMapsGDataConverter.getMapMetadataForEntry(entry);
|
||||
String mapId = MyMapsGDataConverter.getMapidForEntry(entry);
|
||||
|
||||
callback.onReceivedMapListing(
|
||||
mapId, metadata.getTitle(), metadata.getDescription(), metadata.getSearchable());
|
||||
}
|
||||
listParser.close();
|
||||
listParser = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new map for the current user.
|
||||
*
|
||||
* @param title title of the map
|
||||
* @param category category of the map
|
||||
* @param description description for the map
|
||||
* @param isPublic whether the map should be public
|
||||
* @param mapIdBuilder builder to append the map ID to
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
public boolean createNewMap(
|
||||
final String title, final String category, final String description,
|
||||
final boolean isPublic, final StringBuilder mapIdBuilder) {
|
||||
if (mapIdBuilder.length() > 0) {
|
||||
throw new IllegalArgumentException("mapIdBuilder should be empty");
|
||||
}
|
||||
|
||||
return wrapper.runQuery(new MyMapsGDataWrapper.QueryFunction() {
|
||||
@Override
|
||||
public void query(MapsClient client) throws IOException, Exception {
|
||||
Log.d(MyMapsConstants.TAG, "Creating a new map.");
|
||||
String mapFeed = MapsClient.getMapsFeed();
|
||||
Log.d(MyMapsConstants.TAG, "Map feed is " + mapFeed);
|
||||
MyMapsMapMetadata metaData = new MyMapsMapMetadata();
|
||||
metaData.setTitle(title);
|
||||
metaData.setDescription(description + " - "
|
||||
+ category + " - " + context.getString(R.string.new_map_description));
|
||||
metaData.setSearchable(isPublic);
|
||||
Entry entry = MyMapsGDataConverter.getMapEntryForMetadata(metaData);
|
||||
Log.d(MyMapsConstants.TAG, "Title: " + entry.getTitle());
|
||||
Entry map = client.createEntry(mapFeed, authToken, entry);
|
||||
|
||||
String mapId = MapsClient.getMapIdFromMapEntryId(map.getId());
|
||||
mapIdBuilder.append(mapId);
|
||||
Log.d(MyMapsConstants.TAG, "New map id is: " + mapId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a single start or end marker to the given map.
|
||||
*
|
||||
* @param mapId ID of the map to upload to
|
||||
* @param trackName name of the track being started/ended
|
||||
* @param trackDescription description of the track being started/ended
|
||||
* @param location the location of the marker
|
||||
* @param isStart true to add a start marker, false to add an end marker
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
public boolean uploadMarker(final String mapId, final String trackName,
|
||||
final String trackDescription, final Location loc, final boolean isStart) {
|
||||
return wrapper.runQuery(new MyMapsGDataWrapper.QueryFunction() {
|
||||
@Override
|
||||
public void query(MapsClient client)
|
||||
throws IOException, Exception {
|
||||
String featureFeed = MapsClient.getFeaturesFeed(mapId);
|
||||
GeoPoint geoPoint = getGeoPoint(loc);
|
||||
insertMarker(client, featureFeed, trackName, trackDescription, geoPoint, isStart);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a place mark. Second try if 1st try fails. Will throw exception on
|
||||
* 2nd failure.
|
||||
*/
|
||||
private void insertMarker(MapsClient client,
|
||||
String featureFeed,
|
||||
String trackName, String trackDescription,
|
||||
GeoPoint geoPoint,
|
||||
boolean isStart) throws IOException, Exception {
|
||||
MyMapsFeature feature =
|
||||
buildMyMapsPlacemarkFeature(trackName, trackDescription, geoPoint, isStart);
|
||||
Entry entry = gdataConverter.getEntryForFeature(feature);
|
||||
Log.d(MyMapsConstants.TAG, "SendToMyMaps: Creating placemark "
|
||||
+ entry.getTitle());
|
||||
try {
|
||||
client.createEntry(featureFeed, authToken, entry);
|
||||
Log.d(MyMapsConstants.TAG, "SendToMyMaps: createEntry success!");
|
||||
} catch (IOException e) {
|
||||
Log.w(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: createEntry 1st try failed. Trying again.");
|
||||
// Retry once (often IOException is thrown on a timeout):
|
||||
client.createEntry(featureFeed, authToken, entry);
|
||||
Log.d(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: createEntry success on 2nd try!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a placemark MyMapsFeature from a track.
|
||||
*
|
||||
* @param track the track
|
||||
* @param isStart true if it's the start of the track, or false for end
|
||||
* @return a MyMapsFeature
|
||||
*/
|
||||
private MyMapsFeature buildMyMapsPlacemarkFeature(
|
||||
String trackName, String trackDescription,
|
||||
GeoPoint geoPoint, boolean isStart) {
|
||||
String iconUrl;
|
||||
if (isStart) {
|
||||
iconUrl = START_ICON_URL;
|
||||
} else {
|
||||
iconUrl = END_ICON_URL;
|
||||
}
|
||||
String title = trackName + " "
|
||||
+ (isStart ? context.getString(R.string.start)
|
||||
: context.getString(R.string.end));
|
||||
String description = isStart ? "" : trackDescription;
|
||||
return buildMyMapsPlacemarkFeature(title, description, iconUrl, geoPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a MyMapsFeature from a track.
|
||||
*
|
||||
* @param wpt the waypoint
|
||||
* @return a MyMapsFeature
|
||||
*/
|
||||
private static MyMapsFeature buildMyMapsPlacemarkFeature(
|
||||
String title, String description, String iconUrl, GeoPoint geoPoint) {
|
||||
MyMapsFeature myMapsFeature = new MyMapsFeature();
|
||||
myMapsFeature.generateAndroidId();
|
||||
myMapsFeature.setType(MyMapsFeature.MARKER);
|
||||
myMapsFeature.setIconUrl(iconUrl);
|
||||
myMapsFeature.setDescription(description);
|
||||
myMapsFeature.addPoint(geoPoint);
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
// Features must have a name (otherwise GData upload may fail):
|
||||
myMapsFeature.setTitle("-");
|
||||
} else {
|
||||
myMapsFeature.setTitle(title);
|
||||
}
|
||||
myMapsFeature.setDescription(description.replaceAll("\n", "<br>"));
|
||||
return myMapsFeature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a series of waypoints to the given map.
|
||||
*
|
||||
* @param mapId ID of the map to upload to
|
||||
* @param waypoints the waypoints to upload
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
public boolean uploadWaypoints(
|
||||
final String mapId, final Iterable<Waypoint> waypoints) {
|
||||
return wrapper.runQuery(new MyMapsGDataWrapper.QueryFunction() {
|
||||
public void query(MapsClient client) {
|
||||
// TODO(rdamazio): Stream through the waypoints in chunks.
|
||||
// I am leaving the number of waypoints very high which should not be a
|
||||
// problem because we don't try to load them into objects all at the
|
||||
// same time.
|
||||
String featureFeed = MapsClient.getFeaturesFeed(mapId);
|
||||
|
||||
try {
|
||||
for (Waypoint waypoint : waypoints) {
|
||||
MyMapsFeature feature = buildMyMapsPlacemarkFeature(
|
||||
waypoint.getName(), waypoint.getDescription(), waypoint.getIcon(),
|
||||
getGeoPoint(waypoint.getLocation()));
|
||||
Entry entry = gdataConverter.getEntryForFeature(feature);
|
||||
|
||||
Log.d(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: Creating waypoint.");
|
||||
try {
|
||||
client.createEntry(featureFeed, authToken, entry);
|
||||
Log.d(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: createEntry success!");
|
||||
} catch (IOException e) {
|
||||
Log.w(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: createEntry 1st try failed. Retrying.");
|
||||
|
||||
// Retry once (often IOException is thrown on a timeout):
|
||||
client.createEntry(featureFeed, authToken, entry);
|
||||
Log.d(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: createEntry success on 2nd try!");
|
||||
}
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
Log.w(MyMapsConstants.TAG, "ParseException caught.", e);
|
||||
} catch (HttpException e) {
|
||||
Log.w(MyMapsConstants.TAG, "HttpException caught.", e);
|
||||
} catch (IOException e) {
|
||||
Log.w(MyMapsConstants.TAG, "IOException caught.", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a series of points to the given map.
|
||||
*
|
||||
* @param mapId ID of the map to upload to
|
||||
* @param trackName the name of the track
|
||||
* @param locations the locations to upload
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
public boolean uploadTrackPoints(
|
||||
final String mapId, final String trackName, final Collection<Location> locations) {
|
||||
return wrapper.runQuery(new MyMapsGDataWrapper.QueryFunction() {
|
||||
@Override
|
||||
public void query(MapsClient client)
|
||||
throws IOException, Exception {
|
||||
String featureFeed = MapsClient.getFeaturesFeed(mapId);
|
||||
Log.d(MyMapsConstants.TAG, "Feature feed url: " + featureFeed);
|
||||
uploadTrackPoints(client, featureFeed, trackName, locations);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean uploadTrackPoints(
|
||||
MapsClient client,
|
||||
String featureFeed,
|
||||
String trackName, Collection<Location> locations)
|
||||
throws IOException, Exception {
|
||||
Entry entry = null;
|
||||
int numLocations = locations.size();
|
||||
if (numLocations < 2) {
|
||||
// Need at least two points for a polyline:
|
||||
Log.w(MyMapsConstants.TAG, "Not uploading too few points");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Put the line:
|
||||
entry = gdataConverter.getEntryForFeature(
|
||||
buildMyMapsLineFeature(trackName, locations));
|
||||
Log.d(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: Creating line " + entry.getTitle());
|
||||
try {
|
||||
client.createEntry(featureFeed, authToken, entry);
|
||||
Log.d(MyMapsConstants.TAG, "SendToMyMaps: createEntry success!");
|
||||
} catch (IOException e) {
|
||||
Log.w(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: createEntry 1st try failed. Trying again.");
|
||||
// Retry once (often IOException is thrown on a timeout):
|
||||
client.createEntry(featureFeed, authToken, entry);
|
||||
Log.d(MyMapsConstants.TAG,
|
||||
"SendToMyMaps: createEntry success on 2nd try!");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a MyMapsFeature from a track.
|
||||
*
|
||||
* @param track the track
|
||||
* @return a MyMapsFeature
|
||||
*/
|
||||
private static MyMapsFeature buildMyMapsLineFeature(String trackName,
|
||||
Iterable<Location> locations) {
|
||||
MyMapsFeature myMapsFeature = new MyMapsFeature();
|
||||
myMapsFeature.generateAndroidId();
|
||||
myMapsFeature.setType(MyMapsFeature.LINE);
|
||||
if (TextUtils.isEmpty(trackName)) {
|
||||
// Features must have a name (otherwise GData upload may fail):
|
||||
myMapsFeature.setTitle("-");
|
||||
} else {
|
||||
myMapsFeature.setTitle(trackName);
|
||||
}
|
||||
myMapsFeature.setColor(0x80FF0000);
|
||||
for (Location loc : locations) {
|
||||
myMapsFeature.addPoint(getGeoPoint(loc));
|
||||
}
|
||||
return myMapsFeature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up after a series of uploads.
|
||||
* This closes the connection to Maps and resets retry counters.
|
||||
*/
|
||||
public void cleanUp() {
|
||||
wrapper.cleanUp();
|
||||
}
|
||||
|
||||
private static GeoPoint getGeoPoint(Location location) {
|
||||
return new GeoPoint((int) (location.getLatitude() * 1E6),
|
||||
(int) (location.getLongitude() * 1E6));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
/**
|
||||
* Constants for My Maps.
|
||||
*/
|
||||
public class MyMapsConstants {
|
||||
static final String TAG = "MapsApi";
|
||||
static final String MAPSHOP_BASE_URL =
|
||||
"http://maps.google.com/maps/ms";
|
||||
public static final String SERVICE_NAME = "local";
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private MyMapsConstants() { }
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.android.maps.GeoPoint;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* MyMapsFeature contains all of the data associated with a feature in My Maps,
|
||||
* where a feature is a marker, line, or shape. Some of the data is stored in a
|
||||
* {@link MyMapsFeatureMetadata} object so that it can be more efficiently
|
||||
* transmitted to other activities.
|
||||
*/
|
||||
class MyMapsFeature implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8439035544430497236L;
|
||||
|
||||
/** A marker feature displays an icon at a single point on the map. */
|
||||
public static final int MARKER = 0;
|
||||
|
||||
/**
|
||||
* A line feature displays a line connecting a set of points on the map.
|
||||
*/
|
||||
public static final int LINE = 1;
|
||||
|
||||
/**
|
||||
* A shape feature displays a border defined by connecting a set of points,
|
||||
* including connecting the last to the first, and displays the area
|
||||
* confined by this border.
|
||||
*/
|
||||
public static final int SHAPE = 2;
|
||||
|
||||
/** The local feature id for this feature, if needed. */
|
||||
private String androidId;
|
||||
|
||||
/**
|
||||
* The latitudes of the points of this feature in order, specified in
|
||||
* millionths of a degree north.
|
||||
*/
|
||||
private final Vector<Integer> latitudeE6 = new Vector<Integer>();
|
||||
|
||||
/**
|
||||
* The longitudes of the points of this feature in order, specified in
|
||||
* millionths of a degree east.
|
||||
*/
|
||||
private final Vector<Integer> longitudeE6 = new Vector<Integer>();
|
||||
|
||||
/** The metadata of this feature in a format efficient for transmission. */
|
||||
private MyMapsFeatureMetadata featureInfo = new MyMapsFeatureMetadata();
|
||||
|
||||
/**
|
||||
* Initializes a valid but empty feature. It will default to a
|
||||
* {@link #MARKER} with a blue placemark with a dot as an icon at the
|
||||
* location (0, 0).
|
||||
*/
|
||||
public MyMapsFeature() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new point to the end of this feature.
|
||||
*
|
||||
* @param point The new point to add
|
||||
*/
|
||||
public synchronized void addPoint(GeoPoint point) {
|
||||
latitudeE6.add(point.getLatitudeE6());
|
||||
longitudeE6.add(point.getLongitudeE6());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new local id for this feature based on the current time and
|
||||
* a random number.
|
||||
*/
|
||||
public synchronized void generateAndroidId() {
|
||||
Long time = System.currentTimeMillis();
|
||||
Integer random = (int) (Math.random() * 10000);
|
||||
androidId = time.toString() + "." + random.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current local id for this feature if one is available.
|
||||
*
|
||||
* @return The local id for this feature
|
||||
*/
|
||||
public String getAndroidId() {
|
||||
return androidId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current (html) description of this feature. The description
|
||||
* is stored in the feature metadata.
|
||||
*
|
||||
* @return The description of this feature
|
||||
*/
|
||||
public String getDescription() {
|
||||
return featureInfo.getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description of this feature. That description is stored in the
|
||||
* feature metadata.
|
||||
*
|
||||
* @param description The new description of this feature
|
||||
*/
|
||||
public synchronized void setDescription(String description) {
|
||||
featureInfo.setDescription(description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the point at the given index for this feature.
|
||||
*
|
||||
* @param index The index of the point desired
|
||||
* @return A {@link GeoPoint} representing the point or null if that point
|
||||
* doesn't exist
|
||||
*/
|
||||
public GeoPoint getPoint(int index) {
|
||||
if (latitudeE6.size() <= index) {
|
||||
return null;
|
||||
}
|
||||
return new GeoPoint(latitudeE6.get(index), longitudeE6.get(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of points in this feature and return that count.
|
||||
*
|
||||
* @return The number of points in this feature
|
||||
*/
|
||||
public int getPointCount() {
|
||||
return latitudeE6.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the title of this feature. That title is stored in the feature
|
||||
* metadata.
|
||||
*
|
||||
* @return the current title of this feature
|
||||
*/
|
||||
public String getTitle() {
|
||||
return featureInfo.getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the type of this feature. That type is stored in the feature
|
||||
* metadata.
|
||||
*
|
||||
* @return One of {@link #MARKER}, {@link #LINE}, or {@link #SHAPE}
|
||||
* identifying the type of this feature
|
||||
*/
|
||||
public int getType() {
|
||||
return featureInfo.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current color of this feature as an ARGB color integer.
|
||||
* That color is stored in the feature metadata.
|
||||
*
|
||||
* @return The ARGB color of this feature
|
||||
*/
|
||||
public int getColor() {
|
||||
return featureInfo.getColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current line width of this feature. That line width is
|
||||
* stored in the feature metadata.
|
||||
*
|
||||
* @return The line width of this feature
|
||||
*/
|
||||
public int getLineWidth() {
|
||||
return featureInfo.getLineWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current fill color of this feature as an ARGB color
|
||||
* integer. That color is stored in the feature metadata.
|
||||
*
|
||||
* @return The ARGB fill color of this feature
|
||||
*/
|
||||
public int getFillColor() {
|
||||
return featureInfo.getFillColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current icon url of this feature. That icon url is stored
|
||||
* in the feature metadata.
|
||||
*
|
||||
* @return The icon url for this feature
|
||||
*/
|
||||
public String getIconUrl() {
|
||||
return featureInfo.getIconUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title of this feature. That title is stored in the feature
|
||||
* metadata.
|
||||
*
|
||||
* @param title The new title of this feature
|
||||
*/
|
||||
public synchronized void setTitle(String title) {
|
||||
featureInfo.setTitle(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this feature. That type is stored in the feature
|
||||
* metadata.
|
||||
*
|
||||
* @param type The new type of the feature. That type must be one of
|
||||
* {@link #MARKER}, {@link #LINE}, or {@link #SHAPE}
|
||||
*/
|
||||
public synchronized void setType(int type) {
|
||||
featureInfo.setType(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ARGB color of this feature. That color is stored in the feature
|
||||
* metadata.
|
||||
*
|
||||
* @param color The new ARGB color of this feature
|
||||
*/
|
||||
public synchronized void setColor(int color) {
|
||||
featureInfo.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the icon url of this feature. That icon url is stored in the feature
|
||||
* metadata.
|
||||
*
|
||||
* @param url The new icon url of the feature
|
||||
*/
|
||||
public synchronized void setIconUrl(String url) {
|
||||
featureInfo.setIconUrl(url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
/**
|
||||
* Metadata about a maps feature.
|
||||
*/
|
||||
class MyMapsFeatureMetadata {
|
||||
|
||||
private static final String BLUE_DOT_URL =
|
||||
"http://maps.google.com/mapfiles/ms/micons/blue-dot.png";
|
||||
private static final int DEFAULT_COLOR = 0x800000FF;
|
||||
private static final int DEFAULT_FILL_COLOR = 0xC00000FF;
|
||||
|
||||
private String title;
|
||||
private String description;
|
||||
private int type;
|
||||
private int color;
|
||||
private int lineWidth;
|
||||
private int fillColor;
|
||||
private String iconUrl;
|
||||
|
||||
public MyMapsFeatureMetadata() {
|
||||
title = "";
|
||||
description = "";
|
||||
type = MyMapsFeature.MARKER;
|
||||
color = DEFAULT_COLOR;
|
||||
lineWidth = 5;
|
||||
fillColor = DEFAULT_FILL_COLOR;
|
||||
iconUrl = BLUE_DOT_URL;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public int getLineWidth() {
|
||||
return lineWidth;
|
||||
}
|
||||
|
||||
public void setLineWidth(int width) {
|
||||
lineWidth = width;
|
||||
}
|
||||
|
||||
public int getFillColor() {
|
||||
return fillColor;
|
||||
}
|
||||
|
||||
public void setFillColor(int color) {
|
||||
fillColor = color;
|
||||
}
|
||||
|
||||
public String getIconUrl() {
|
||||
return iconUrl;
|
||||
}
|
||||
|
||||
public void setIconUrl(String url) {
|
||||
iconUrl = new String(url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.data.StringUtils;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Converter from GData objects to MyMaps objects.
|
||||
*/
|
||||
class MyMapsGDataConverter {
|
||||
|
||||
private final XmlSerializer xmlSerializer;
|
||||
|
||||
public MyMapsGDataConverter() throws XmlPullParserException {
|
||||
xmlSerializer = XmlPullParserFactory.newInstance().newSerializer();
|
||||
}
|
||||
|
||||
public static MyMapsMapMetadata getMapMetadataForEntry(
|
||||
MapFeatureEntry entry) {
|
||||
MyMapsMapMetadata metadata = new MyMapsMapMetadata();
|
||||
if ("public".equals(entry.getPrivacy())) {
|
||||
metadata.setSearchable(true);
|
||||
} else {
|
||||
metadata.setSearchable(false);
|
||||
}
|
||||
metadata.setTitle(entry.getTitle());
|
||||
|
||||
String desc = entry.getContent();
|
||||
if (desc.length() > 12) {
|
||||
metadata.setDescription(desc.substring(9, desc.length() - 3));
|
||||
}
|
||||
|
||||
String editUri = entry.getEditUri();
|
||||
if (editUri != null) {
|
||||
metadata.setGDataEditUri(editUri);
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public static String getMapidForEntry(Entry entry) {
|
||||
return MapsClient.getMapIdFromMapEntryId(entry.getId());
|
||||
}
|
||||
|
||||
public static Entry getMapEntryForMetadata(MyMapsMapMetadata metadata) {
|
||||
MapFeatureEntry entry = new MapFeatureEntry();
|
||||
entry.setEditUri(metadata.getGDataEditUri());
|
||||
entry.setTitle(metadata.getTitle());
|
||||
entry.setContent(metadata.getDescription());
|
||||
entry.setPrivacy(metadata.getSearchable() ? "public" : "unlisted");
|
||||
entry.setAuthor("android");
|
||||
entry.setEmail("nobody@google.com");
|
||||
return entry;
|
||||
}
|
||||
|
||||
public MapFeatureEntry getEntryForFeature(MyMapsFeature feature) {
|
||||
MapFeatureEntry entry = new MapFeatureEntry();
|
||||
entry.setTitle(feature.getTitle());
|
||||
entry.setAuthor("android");
|
||||
entry.setEmail("nobody@google.com");
|
||||
entry.setCategoryScheme("http://schemas.google.com/g/2005#kind");
|
||||
entry.setCategory("http://schemas.google.com/g/2008#mapfeature");
|
||||
entry.setEditUri("");
|
||||
if (!StringUtils.isEmpty(feature.getAndroidId())) {
|
||||
entry.setAttribute("_androidId", feature.getAndroidId());
|
||||
}
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
xmlSerializer.setOutput(writer);
|
||||
xmlSerializer.startTag(null, "Placemark");
|
||||
xmlSerializer.attribute(null, "xmlns", "http://earth.google.com/kml/2.2");
|
||||
xmlSerializer.startTag(null, "Style");
|
||||
if (feature.getType() == MyMapsFeature.MARKER) {
|
||||
xmlSerializer.startTag(null, "IconStyle");
|
||||
xmlSerializer.startTag(null, "Icon");
|
||||
xmlSerializer.startTag(null, "href");
|
||||
xmlSerializer.text(feature.getIconUrl());
|
||||
xmlSerializer.endTag(null, "href");
|
||||
xmlSerializer.endTag(null, "Icon");
|
||||
xmlSerializer.endTag(null, "IconStyle");
|
||||
} else {
|
||||
xmlSerializer.startTag(null, "LineStyle");
|
||||
xmlSerializer.startTag(null, "color");
|
||||
int color = feature.getColor();
|
||||
// Reverse the color because KML is ABGR and Android is ARGB
|
||||
xmlSerializer.text(Integer.toHexString(
|
||||
Color.argb(Color.alpha(color), Color.blue(color),
|
||||
Color.green(color), Color.red(color))));
|
||||
xmlSerializer.endTag(null, "color");
|
||||
xmlSerializer.startTag(null, "width");
|
||||
xmlSerializer.text(Integer.toString(feature.getLineWidth()));
|
||||
xmlSerializer.endTag(null, "width");
|
||||
xmlSerializer.endTag(null, "LineStyle");
|
||||
|
||||
if (feature.getType() == MyMapsFeature.SHAPE) {
|
||||
xmlSerializer.startTag(null, "PolyStyle");
|
||||
xmlSerializer.startTag(null, "color");
|
||||
int fcolor = feature.getFillColor();
|
||||
// Reverse the color because KML is ABGR and Android is ARGB
|
||||
xmlSerializer.text(Integer.toHexString(Color.argb(Color.alpha(fcolor),
|
||||
Color.blue(fcolor), Color.green(fcolor), Color.red(fcolor))));
|
||||
xmlSerializer.endTag(null, "color");
|
||||
xmlSerializer.startTag(null, "fill");
|
||||
xmlSerializer.text("1");
|
||||
xmlSerializer.endTag(null, "fill");
|
||||
xmlSerializer.startTag(null, "outline");
|
||||
xmlSerializer.text("1");
|
||||
xmlSerializer.endTag(null, "outline");
|
||||
xmlSerializer.endTag(null, "PolyStyle");
|
||||
}
|
||||
}
|
||||
xmlSerializer.endTag(null, "Style");
|
||||
xmlSerializer.startTag(null, "name");
|
||||
xmlSerializer.text(feature.getTitle());
|
||||
xmlSerializer.endTag(null, "name");
|
||||
xmlSerializer.startTag(null, "description");
|
||||
xmlSerializer.cdsect(feature.getDescription());
|
||||
xmlSerializer.endTag(null, "description");
|
||||
StringBuilder pointBuilder = new StringBuilder();
|
||||
for (int i = 0; i < feature.getPointCount(); ++i) {
|
||||
if (i > 0) {
|
||||
pointBuilder.append('\n');
|
||||
}
|
||||
pointBuilder.append(feature.getPoint(i).getLongitudeE6() / 1e6);
|
||||
pointBuilder.append(',');
|
||||
pointBuilder.append(feature.getPoint(i).getLatitudeE6() / 1e6);
|
||||
pointBuilder.append(",0.000000");
|
||||
}
|
||||
String pointString = pointBuilder.toString();
|
||||
if (feature.getType() == MyMapsFeature.MARKER) {
|
||||
xmlSerializer.startTag(null, "Point");
|
||||
xmlSerializer.startTag(null, "coordinates");
|
||||
xmlSerializer.text(pointString);
|
||||
xmlSerializer.endTag(null, "coordinates");
|
||||
xmlSerializer.endTag(null, "Point");
|
||||
} else if (feature.getType() == MyMapsFeature.LINE) {
|
||||
xmlSerializer.startTag(null, "LineString");
|
||||
xmlSerializer.startTag(null, "tessellate");
|
||||
xmlSerializer.text("1");
|
||||
xmlSerializer.endTag(null, "tessellate");
|
||||
xmlSerializer.startTag(null, "coordinates");
|
||||
xmlSerializer.text(pointString);
|
||||
xmlSerializer.endTag(null, "coordinates");
|
||||
xmlSerializer.endTag(null, "LineString");
|
||||
} else {
|
||||
xmlSerializer.startTag(null, "Polygon");
|
||||
xmlSerializer.startTag(null, "outerBoundaryIs");
|
||||
xmlSerializer.startTag(null, "LinearRing");
|
||||
xmlSerializer.startTag(null, "tessellate");
|
||||
xmlSerializer.text("1");
|
||||
xmlSerializer.endTag(null, "tessellate");
|
||||
xmlSerializer.startTag(null, "coordinates");
|
||||
xmlSerializer.text(pointString + "\n"
|
||||
+ Double.toString(feature.getPoint(0).getLongitudeE6() / 1e6)
|
||||
+ ","
|
||||
+ Double.toString(feature.getPoint(0).getLatitudeE6() / 1e6)
|
||||
+ ",0.000000");
|
||||
xmlSerializer.endTag(null, "coordinates");
|
||||
xmlSerializer.endTag(null, "LinearRing");
|
||||
xmlSerializer.endTag(null, "outerBoundaryIs");
|
||||
xmlSerializer.endTag(null, "Polygon");
|
||||
}
|
||||
xmlSerializer.endTag(null, "Placemark");
|
||||
xmlSerializer.flush();
|
||||
entry.setContent(writer.toString());
|
||||
Log.d("My Google Maps", "Generated kml:\n" + entry.getContent());
|
||||
Log.d("My Google Maps", "Edit URI: " + entry.getEditUri());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
import com.google.android.apps.mytracks.io.gdata.GDataClientFactory;
|
||||
import com.google.android.common.gdata.AndroidXmlParserFactory;
|
||||
import com.google.wireless.gdata.client.GDataClient;
|
||||
import com.google.wireless.gdata.client.HttpException;
|
||||
import com.google.wireless.gdata.parser.xml.SimplePullParser.ParseException;
|
||||
import com.google.wireless.gdata2.ConflictDetectedException;
|
||||
import com.google.wireless.gdata2.client.AuthenticationException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* MyMapsGDataWrapper provides a wrapper around GData operations that maintains
|
||||
* the GData client, and provides a method to run gdata queries with proper
|
||||
* error handling. After a query is run, the wrapper can be queried about the
|
||||
* error that occurred.
|
||||
*/
|
||||
class MyMapsGDataWrapper {
|
||||
/**
|
||||
* A QueryFunction is passed in when executing a query. The query function
|
||||
* of the class is called with the GData client as a parameter. The
|
||||
* function should execute whatever operations it desires on the client
|
||||
* without concern for whether the client will throw an error.
|
||||
*/
|
||||
interface QueryFunction {
|
||||
public abstract void query(MapsClient client)
|
||||
throws AuthenticationException, IOException, ParseException,
|
||||
ConflictDetectedException, Exception;
|
||||
}
|
||||
|
||||
// The types of error that may be encountered
|
||||
/** No error occurred. */
|
||||
public static final int ERROR_NO_ERROR = 0;
|
||||
/** There was an authentication error, the auth token may be invalid. */
|
||||
public static final int ERROR_AUTH = 1;
|
||||
/** There was an internal error on the server side. */
|
||||
public static final int ERROR_INTERNAL = 2;
|
||||
/** There was an error connecting to the server. */
|
||||
public static final int ERROR_CONNECTION = 3;
|
||||
/** The item queried did not exit. */
|
||||
public static final int ERROR_NOT_FOUND = 4;
|
||||
/** There was an error parsing or serializing locally. */
|
||||
public static final int ERROR_LOCAL = 5;
|
||||
/** There was a conflict, update the entry and try again. */
|
||||
public static final int ERROR_CONFLICT = 6;
|
||||
/**
|
||||
* A query was run after cleaning up the wrapper, so the client was invalid.
|
||||
*/
|
||||
public static final int ERROR_CLEANED_UP = 7;
|
||||
/** An unknown error occurred. */
|
||||
public static final int ERROR_UNKNOWN = 100;
|
||||
|
||||
private final GDataClient androidGdataClient;
|
||||
private final AuthManager auth;
|
||||
private final MapsClient client;
|
||||
|
||||
private String errorMessage;
|
||||
private int errorType;
|
||||
private boolean retryOnAuthFailure;
|
||||
private int retriesPending;
|
||||
private boolean cleanupCalled;
|
||||
|
||||
public MyMapsGDataWrapper(Context context, AuthManager auth) {
|
||||
androidGdataClient = GDataClientFactory.getGDataClient(context);
|
||||
this.auth = auth;
|
||||
client =
|
||||
new MapsClient(androidGdataClient, new XmlMapsGDataParserFactory(
|
||||
new AndroidXmlParserFactory()));
|
||||
errorType = ERROR_NO_ERROR;
|
||||
errorMessage = null;
|
||||
retryOnAuthFailure = false;
|
||||
retriesPending = 0;
|
||||
cleanupCalled = false;
|
||||
}
|
||||
|
||||
public boolean runQuery(final QueryFunction query) {
|
||||
if (client == null) {
|
||||
errorType = ERROR_CLEANED_UP;
|
||||
errorMessage = "GData Wrapper has already been cleaned up!";
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
query.query(client);
|
||||
errorType = ERROR_NO_ERROR;
|
||||
errorMessage = null;
|
||||
return true;
|
||||
} catch (AuthenticationException e) {
|
||||
Log.e(MyMapsConstants.TAG, "Exception", e);
|
||||
errorType = ERROR_AUTH;
|
||||
errorMessage = e.getMessage();
|
||||
} catch (HttpException e) {
|
||||
Log.e(MyMapsConstants.TAG, "HttpException", e);
|
||||
errorMessage = e.getMessage();
|
||||
if (errorMessage != null && errorMessage.contains("401")) {
|
||||
errorType = ERROR_AUTH;
|
||||
} else {
|
||||
errorType = ERROR_CONNECTION;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(MyMapsConstants.TAG, "Exception", e);
|
||||
errorMessage = e.getMessage();
|
||||
if (errorMessage != null && errorMessage.contains("503")) {
|
||||
errorType = ERROR_INTERNAL;
|
||||
} else {
|
||||
errorType = ERROR_CONNECTION;
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
Log.e(MyMapsConstants.TAG, "Exception", e);
|
||||
errorType = ERROR_LOCAL;
|
||||
errorMessage = e.getMessage();
|
||||
} catch (ConflictDetectedException e) {
|
||||
Log.e(MyMapsConstants.TAG, "Exception", e);
|
||||
errorType = ERROR_CONFLICT;
|
||||
errorMessage = e.getMessage();
|
||||
} catch (Exception e) {
|
||||
Log.e(MyMapsConstants.TAG, "Exception", e);
|
||||
errorType = ERROR_UNKNOWN;
|
||||
errorMessage = e.getMessage();
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.d(MyMapsConstants.TAG, "GData error encountered: " + errorMessage);
|
||||
if (errorType == ERROR_AUTH && auth != null) {
|
||||
Runnable whenFinished = null;
|
||||
if (retryOnAuthFailure) {
|
||||
retriesPending++;
|
||||
whenFinished = new Runnable() {
|
||||
public void run() {
|
||||
retriesPending--;
|
||||
retryOnAuthFailure = false;
|
||||
runQuery(query);
|
||||
if (cleanupCalled && retriesPending == 0) {
|
||||
cleanUp();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
auth.invalidateAndRefresh(whenFinished);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getErrorType() {
|
||||
return errorType;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
// cleanUp must be called when done using this wrapper to close the client.
|
||||
// Note that the cleanup will be delayed if auth failure retries were
|
||||
// requested and there is a pending retry.
|
||||
public void cleanUp() {
|
||||
if (retriesPending == 0 && !cleanupCalled) {
|
||||
androidGdataClient.close();
|
||||
}
|
||||
cleanupCalled = true;
|
||||
}
|
||||
|
||||
public void setRetryOnAuthFailure(boolean retry) {
|
||||
retryOnAuthFailure = retry;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
/**
|
||||
* Metadata about a "my maps" map.
|
||||
*/
|
||||
class MyMapsMapMetadata {
|
||||
|
||||
private String title;
|
||||
private String description;
|
||||
private String gdataEditUri;
|
||||
private boolean searchable;
|
||||
|
||||
public MyMapsMapMetadata() {
|
||||
title = "";
|
||||
description = "";
|
||||
gdataEditUri = "";
|
||||
searchable = false;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = new String(title);
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = new String(description);
|
||||
}
|
||||
|
||||
public boolean getSearchable() {
|
||||
return searchable;
|
||||
}
|
||||
|
||||
public void setSearchable(boolean searchable) {
|
||||
this.searchable = searchable;
|
||||
}
|
||||
|
||||
public String getGDataEditUri() {
|
||||
return gdataEditUri;
|
||||
}
|
||||
|
||||
public void setGDataEditUri(String editUri) {
|
||||
this.gdataEditUri = new String(editUri);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.data.Feed;
|
||||
import com.google.wireless.gdata.data.XmlUtils;
|
||||
import com.google.wireless.gdata.parser.ParseException;
|
||||
import com.google.wireless.gdata.parser.xml.XmlGDataParser;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Parser for XML gdata maps data.
|
||||
*/
|
||||
class XmlMapsGDataParser extends XmlGDataParser {
|
||||
|
||||
public XmlMapsGDataParser(InputStream is, XmlPullParser xpp)
|
||||
throws ParseException {
|
||||
super(is, xpp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Feed createFeed() {
|
||||
return new Feed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Entry createEntry() {
|
||||
return new MapFeatureEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleExtraElementInFeed(Feed feed) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleExtraLinkInEntry(
|
||||
String rel, String type, String href, Entry entry)
|
||||
throws XmlPullParserException, IOException {
|
||||
if (!(entry instanceof MapFeatureEntry)) {
|
||||
throw new IllegalArgumentException("Expected MapFeatureEntry!");
|
||||
}
|
||||
if (rel.endsWith("#view")) {
|
||||
return;
|
||||
}
|
||||
super.handleExtraLinkInEntry(rel, type, href, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current entry in the XML document. Assumes that the parser is
|
||||
* currently pointing just after an <entry>.
|
||||
*
|
||||
* @param plainEntry The entry that will be filled.
|
||||
* @throws XmlPullParserException Thrown if the XML cannot be parsed.
|
||||
* @throws IOException Thrown if the underlying inputstream cannot be read.
|
||||
*/
|
||||
@Override
|
||||
protected void handleEntry(Entry plainEntry)
|
||||
throws XmlPullParserException, IOException, ParseException {
|
||||
XmlPullParser parser = getParser();
|
||||
if (!(plainEntry instanceof MapFeatureEntry)) {
|
||||
throw new IllegalArgumentException("Expected MapFeatureEntry!");
|
||||
}
|
||||
MapFeatureEntry entry = (MapFeatureEntry) plainEntry;
|
||||
|
||||
int eventType = parser.getEventType();
|
||||
entry.setPrivacy("public");
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
switch (eventType) {
|
||||
case XmlPullParser.START_TAG:
|
||||
String name = parser.getName();
|
||||
if ("entry".equals(name)) {
|
||||
// stop parsing here.
|
||||
return;
|
||||
} else if ("id".equals(name)) {
|
||||
entry.setId(XmlUtils.extractChildText(parser));
|
||||
} else if ("title".equals(name)) {
|
||||
entry.setTitle(XmlUtils.extractChildText(parser));
|
||||
} else if ("link".equals(name)) {
|
||||
String rel = parser.getAttributeValue(null /* ns */, "rel");
|
||||
String type = parser.getAttributeValue(null /* ns */, "type");
|
||||
String href = parser.getAttributeValue(null /* ns */, "href");
|
||||
if ("edit".equals(rel)) {
|
||||
entry.setEditUri(href);
|
||||
} else if ("alternate".equals(rel) && "text/html".equals(type)) {
|
||||
entry.setHtmlUri(href);
|
||||
} else {
|
||||
handleExtraLinkInEntry(rel, type, href, entry);
|
||||
}
|
||||
} else if ("summary".equals(name)) {
|
||||
entry.setSummary(XmlUtils.extractChildText(parser));
|
||||
} else if ("content".equals(name)) {
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
int parentDepth = parser.getDepth();
|
||||
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
|
||||
int etype = parser.next();
|
||||
switch (etype) {
|
||||
case XmlPullParser.START_TAG:
|
||||
contentBuilder.append('<');
|
||||
contentBuilder.append(parser.getName());
|
||||
contentBuilder.append('>');
|
||||
break;
|
||||
case XmlPullParser.TEXT:
|
||||
contentBuilder.append("<![CDATA[");
|
||||
contentBuilder.append(parser.getText());
|
||||
contentBuilder.append("]]>");
|
||||
break;
|
||||
case XmlPullParser.END_TAG:
|
||||
if (parser.getDepth() > parentDepth) {
|
||||
contentBuilder.append("</");
|
||||
contentBuilder.append(parser.getName());
|
||||
contentBuilder.append('>');
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (etype == XmlPullParser.END_TAG
|
||||
&& parser.getDepth() == parentDepth) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
entry.setContent(contentBuilder.toString());
|
||||
} else if ("category".equals(name)) {
|
||||
String category = parser.getAttributeValue(null /* ns */, "term");
|
||||
if (category != null && category.length() > 0) {
|
||||
entry.setCategory(category);
|
||||
}
|
||||
String categoryScheme =
|
||||
parser.getAttributeValue(null /* ns */, "scheme");
|
||||
if (categoryScheme != null && category.length() > 0) {
|
||||
entry.setCategoryScheme(categoryScheme);
|
||||
}
|
||||
} else if ("published".equals(name)) {
|
||||
entry.setPublicationDate(XmlUtils.extractChildText(parser));
|
||||
} else if ("updated".equals(name)) {
|
||||
entry.setUpdateDate(XmlUtils.extractChildText(parser));
|
||||
} else if ("deleted".equals(name)) {
|
||||
entry.setDeleted(true);
|
||||
} else if ("draft".equals(name)) {
|
||||
String draft = XmlUtils.extractChildText(parser);
|
||||
entry.setPrivacy("yes".equals(draft) ? "unlisted" : "public");
|
||||
} else if ("customProperty".equals(name)) {
|
||||
String attrName = parser.getAttributeValue(null, "name");
|
||||
String attrValue = XmlUtils.extractChildText(parser);
|
||||
entry.setAttribute(attrName, attrValue);
|
||||
} else if ("deleted".equals(name)) {
|
||||
entry.setDeleted(true);
|
||||
} else {
|
||||
handleExtraElementInEntry(entry);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.wireless.gdata.client.GDataParserFactory;
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.parser.GDataParser;
|
||||
import com.google.wireless.gdata.parser.ParseException;
|
||||
import com.google.wireless.gdata.parser.xml.XmlGDataParser;
|
||||
import com.google.wireless.gdata.parser.xml.XmlParserFactory;
|
||||
import com.google.wireless.gdata.serializer.GDataSerializer;
|
||||
import com.google.wireless.gdata.serializer.xml.XmlEntryGDataSerializer;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Factory of Xml parsers for gdata maps data.
|
||||
*/
|
||||
class XmlMapsGDataParserFactory implements GDataParserFactory {
|
||||
private XmlParserFactory xmlFactory;
|
||||
|
||||
public XmlMapsGDataParserFactory(XmlParserFactory xmlFactory) {
|
||||
this.xmlFactory = xmlFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GDataParser createParser(InputStream is) throws ParseException {
|
||||
is = maybeLogCommunication(is);
|
||||
try {
|
||||
return new XmlGDataParser(is, xmlFactory.createParser());
|
||||
} catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public GDataParser createParser(Class cls, InputStream is)
|
||||
throws ParseException {
|
||||
is = maybeLogCommunication(is);
|
||||
try {
|
||||
return createParserForClass(cls, is);
|
||||
} catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream maybeLogCommunication(InputStream is)
|
||||
throws ParseException {
|
||||
if (MapsClient.LOG_COMMUNICATION) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
byte[] buffer = new byte[2048];
|
||||
try {
|
||||
for (int n = is.read(buffer); n >= 0; n = is.read(buffer)) {
|
||||
String part = new String(buffer, 0, n);
|
||||
builder.append(part);
|
||||
Log.d("Response part", part);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ParseException("Could not read stream", e);
|
||||
}
|
||||
String whole = builder.toString();
|
||||
Log.d("Response", whole);
|
||||
is = new ByteArrayInputStream(whole.getBytes());
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
private GDataParser createParserForClass(
|
||||
Class<? extends Entry> cls, InputStream is)
|
||||
throws ParseException, XmlPullParserException {
|
||||
if (cls == MapFeatureEntry.class) {
|
||||
return new XmlMapsGDataParser(is, xmlFactory.createParser());
|
||||
} else {
|
||||
return new XmlGDataParser(is, xmlFactory.createParser());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GDataSerializer createSerializer(Entry en) {
|
||||
if (en.getClass() == MapFeatureEntry.class) {
|
||||
return new XmlMapsGDataSerializer(xmlFactory, en);
|
||||
} else {
|
||||
return new XmlEntryGDataSerializer(xmlFactory, en);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.mymaps;
|
||||
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
import com.google.wireless.gdata.data.StringUtils;
|
||||
import com.google.wireless.gdata.parser.ParseException;
|
||||
import com.google.wireless.gdata.parser.xml.XmlGDataParser;
|
||||
import com.google.wireless.gdata.parser.xml.XmlParserFactory;
|
||||
import com.google.wireless.gdata.serializer.xml.XmlEntryGDataSerializer;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Serializer of maps data for GData.
|
||||
*/
|
||||
class XmlMapsGDataSerializer extends XmlEntryGDataSerializer {
|
||||
|
||||
private static final String APP_NAMESPACE = "http://www.w3.org/2007/app";
|
||||
|
||||
private MapFeatureEntry entry;
|
||||
private XmlParserFactory factory;
|
||||
private OutputStream stream;
|
||||
|
||||
public XmlMapsGDataSerializer(XmlParserFactory factory, Entry entry) {
|
||||
super(factory, entry);
|
||||
|
||||
this.factory = factory;
|
||||
this.entry = (MapFeatureEntry) entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(OutputStream out, int format)
|
||||
throws IOException, ParseException {
|
||||
XmlSerializer serializer = null;
|
||||
try {
|
||||
serializer = factory.createSerializer();
|
||||
} catch (XmlPullParserException e) {
|
||||
throw new ParseException("Unable to create XmlSerializer.", e);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream printStream;
|
||||
|
||||
if (MapsClient.LOG_COMMUNICATION) {
|
||||
printStream = new ByteArrayOutputStream();
|
||||
|
||||
serializer.setOutput(printStream, "UTF-8");
|
||||
} else {
|
||||
serializer.setOutput(out, "UTF-8");
|
||||
}
|
||||
|
||||
serializer.startDocument("UTF-8", Boolean.FALSE);
|
||||
|
||||
declareEntryNamespaces(serializer);
|
||||
serializer.startTag(XmlGDataParser.NAMESPACE_ATOM_URI, "entry");
|
||||
|
||||
stream = MapsClient.LOG_COMMUNICATION ? printStream : out;
|
||||
serializeEntryContents(serializer, format);
|
||||
|
||||
serializer.endTag(XmlGDataParser.NAMESPACE_ATOM_URI, "entry");
|
||||
serializer.endDocument();
|
||||
serializer.flush();
|
||||
|
||||
if (MapsClient.LOG_COMMUNICATION) {
|
||||
Log.d("Request", printStream.toString());
|
||||
out.write(printStream.toByteArray());
|
||||
stream = out;
|
||||
}
|
||||
}
|
||||
|
||||
private final void declareEntryNamespaces(XmlSerializer serializer)
|
||||
throws IOException {
|
||||
serializer.setPrefix(
|
||||
"" /* default ns */, XmlGDataParser.NAMESPACE_ATOM_URI);
|
||||
serializer.setPrefix(
|
||||
XmlGDataParser.NAMESPACE_GD, XmlGDataParser.NAMESPACE_GD_URI);
|
||||
declareExtraEntryNamespaces(serializer);
|
||||
}
|
||||
|
||||
private final void serializeEntryContents(XmlSerializer serializer,
|
||||
int format) throws IOException {
|
||||
if (format != FORMAT_CREATE) {
|
||||
serializeId(serializer, entry.getId());
|
||||
}
|
||||
|
||||
serializeTitle(serializer, entry.getTitle());
|
||||
|
||||
if (format != FORMAT_CREATE) {
|
||||
serializeLink(serializer,
|
||||
"edit" /* rel */, entry.getEditUri(), null /* type */);
|
||||
serializeLink(serializer,
|
||||
"alternate" /* rel */, entry.getHtmlUri(), "text/html" /* type */);
|
||||
}
|
||||
|
||||
serializeSummary(serializer, entry.getSummary());
|
||||
serializeContent(serializer, entry.getContent());
|
||||
serializeAuthor(serializer, entry.getAuthor(), entry.getEmail());
|
||||
serializeCategory(serializer,
|
||||
entry.getCategory(), entry.getCategoryScheme());
|
||||
|
||||
if (format == FORMAT_FULL) {
|
||||
serializePublicationDate(serializer, entry.getPublicationDate());
|
||||
}
|
||||
|
||||
if (format != FORMAT_CREATE) {
|
||||
serializeUpdateDate(serializer, entry.getUpdateDate());
|
||||
}
|
||||
|
||||
serializeExtraEntryContents(serializer, format);
|
||||
}
|
||||
|
||||
private static void serializeId(XmlSerializer serializer, String id)
|
||||
throws IOException {
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "id");
|
||||
serializer.text(id);
|
||||
serializer.endTag(null /* ns */, "id");
|
||||
}
|
||||
|
||||
private static void serializeTitle(XmlSerializer serializer, String title)
|
||||
throws IOException {
|
||||
if (StringUtils.isEmpty(title)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "title");
|
||||
serializer.text(title);
|
||||
serializer.endTag(null /* ns */, "title");
|
||||
}
|
||||
|
||||
public static void serializeLink(XmlSerializer serializer, String rel,
|
||||
String href, String type) throws IOException {
|
||||
if (StringUtils.isEmpty(href)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "link");
|
||||
serializer.attribute(null /* ns */, "rel", rel);
|
||||
serializer.attribute(null /* ns */, "href", href);
|
||||
if (!StringUtils.isEmpty(type)) {
|
||||
serializer.attribute(null /* ns */, "type", type);
|
||||
}
|
||||
serializer.endTag(null /* ns */, "link");
|
||||
}
|
||||
|
||||
private static void serializeSummary(XmlSerializer serializer, String summary)
|
||||
throws IOException {
|
||||
if (StringUtils.isEmpty(summary)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "summary");
|
||||
serializer.text(summary);
|
||||
serializer.endTag(null /* ns */, "summary");
|
||||
}
|
||||
|
||||
private void serializeContent(XmlSerializer serializer, String content)
|
||||
throws IOException {
|
||||
if (content == null) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "content");
|
||||
if (content.contains("</Placemark>")) {
|
||||
serializer.attribute(
|
||||
null /* ns */, "type", "application/vnd.google-earth.kml+xml");
|
||||
serializer.flush();
|
||||
stream.write(content.getBytes());
|
||||
} else {
|
||||
serializer.text(content);
|
||||
}
|
||||
serializer.endTag(null /* ns */, "content");
|
||||
}
|
||||
|
||||
private static void serializeAuthor(XmlSerializer serializer, String author,
|
||||
String email) throws IOException {
|
||||
if (StringUtils.isEmpty(author) || StringUtils.isEmpty(email)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "author");
|
||||
serializer.startTag(null /* ns */, "name");
|
||||
serializer.text(author);
|
||||
serializer.endTag(null /* ns */, "name");
|
||||
serializer.startTag(null /* ns */, "email");
|
||||
serializer.text(email);
|
||||
serializer.endTag(null /* ns */, "email");
|
||||
serializer.endTag(null /* ns */, "author");
|
||||
}
|
||||
|
||||
private static void serializeCategory(XmlSerializer serializer,
|
||||
String category, String categoryScheme) throws IOException {
|
||||
if (StringUtils.isEmpty(category) && StringUtils.isEmpty(categoryScheme)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "category");
|
||||
if (!StringUtils.isEmpty(category)) {
|
||||
serializer.attribute(null /* ns */, "term", category);
|
||||
}
|
||||
if (!StringUtils.isEmpty(categoryScheme)) {
|
||||
serializer.attribute(null /* ns */, "scheme", categoryScheme);
|
||||
}
|
||||
serializer.endTag(null /* ns */, "category");
|
||||
}
|
||||
|
||||
private static void serializePublicationDate(XmlSerializer serializer,
|
||||
String publicationDate) throws IOException {
|
||||
if (StringUtils.isEmpty(publicationDate)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "published");
|
||||
serializer.text(publicationDate);
|
||||
serializer.endTag(null /* ns */, "published");
|
||||
}
|
||||
|
||||
private static void serializeUpdateDate(XmlSerializer serializer,
|
||||
String updateDate) throws IOException {
|
||||
if (StringUtils.isEmpty(updateDate)) {
|
||||
return;
|
||||
}
|
||||
serializer.startTag(null /* ns */, "updated");
|
||||
serializer.text(updateDate);
|
||||
serializer.endTag(null /* ns */, "updated");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void serializeExtraEntryContents(XmlSerializer serializer,
|
||||
int format) throws IOException {
|
||||
Map<String, String> attrs = entry.getAllAttributes();
|
||||
for (Map.Entry<String, String> attr : attrs.entrySet()) {
|
||||
serializer.startTag("http://schemas.google.com/g/2005", "customProperty");
|
||||
serializer.attribute(null, "name", attr.getKey());
|
||||
serializer.text(attr.getValue());
|
||||
serializer.endTag("http://schemas.google.com/g/2005", "customProperty");
|
||||
}
|
||||
String privacy = entry.getPrivacy();
|
||||
if (!StringUtils.isEmpty(privacy)) {
|
||||
serializer.setPrefix("app", APP_NAMESPACE);
|
||||
if ("public".equals(privacy)) {
|
||||
serializer.startTag(APP_NAMESPACE, "control");
|
||||
serializer.startTag(APP_NAMESPACE, "draft");
|
||||
serializer.text("no");
|
||||
serializer.endTag(APP_NAMESPACE, "draft");
|
||||
serializer.endTag(APP_NAMESPACE, "control");
|
||||
}
|
||||
if ("unlisted".equals(privacy)) {
|
||||
serializer.startTag(APP_NAMESPACE, "control");
|
||||
serializer.startTag(APP_NAMESPACE, "draft");
|
||||
serializer.text("yes");
|
||||
serializer.endTag(APP_NAMESPACE, "draft");
|
||||
serializer.endTag(APP_NAMESPACE, "control");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class PeriodicTaskExecuter {
|
||||
}
|
||||
|
||||
Date start = new Date(next);
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
task.getClass().getSimpleName() + " scheduled to start at " + start
|
||||
+ " every " + interval + " milliseconds.");
|
||||
timer.scheduleAtFixedRate(new PeriodicTimerTask(), start, interval);
|
||||
@@ -87,7 +87,7 @@ public class PeriodicTaskExecuter {
|
||||
* Cleans up this object.
|
||||
*/
|
||||
public void shutdown() {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
task.getClass().getSimpleName() + " shutting down.");
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
|
||||
this.sharedPreferences = service.getSharedPreferences(
|
||||
MyTracksSettings.SETTINGS_NAME, 0);
|
||||
if (sharedPreferences == null) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(Constants.TAG,
|
||||
"TrackRecordingService: Couldn't get shared preferences.");
|
||||
throw new IllegalStateException("Couldn't get shared preferences");
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
|
||||
String key) {
|
||||
if (service == null) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(Constants.TAG,
|
||||
"onSharedPreferenceChanged: a preference change (key = " + key
|
||||
+ ") after a call to shutdown()");
|
||||
return;
|
||||
@@ -98,7 +98,7 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener {
|
||||
sharedPreferences.getInt(
|
||||
minRecordingDistanceKey,
|
||||
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE));
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"TrackRecordingService: minRecordingDistance = "
|
||||
+ service.getMinRecordingDistance());
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.util.UnitConversions;
|
||||
|
||||
@@ -81,7 +81,7 @@ public class SplitManager {
|
||||
|
||||
if (splitFrequency >= 0) {
|
||||
nextSplitDistance = Double.MAX_VALUE;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"SplitManager: Distance splits disabled.");
|
||||
return;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ public class SplitManager {
|
||||
int index = (int) (dist / splitFrequency);
|
||||
index -= 1;
|
||||
nextSplitDistance = splitFrequency * index;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"SplitManager: Next split distance: " + nextSplitDistance);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class SplitManager {
|
||||
* @param splitFrequency The frequency in time or distance
|
||||
*/
|
||||
public void setSplitFrequency(int splitFrequency) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"setSplitFrequency: splitFrequency = " + splitFrequency);
|
||||
this.splitFrequency = splitFrequency;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2009 Google Inc.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
@@ -99,7 +101,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
* Called when the TTS engine is initialized.
|
||||
*/
|
||||
protected void onTtsInit(int status) {
|
||||
Log.i(MyTracksConstants.TAG, "TrackRecordingService.TTS init: " + status);
|
||||
Log.i(TAG, "TrackRecordingService.TTS init: " + status);
|
||||
this.ready = status == TextToSpeech.SUCCESS;
|
||||
|
||||
if (ready) {
|
||||
@@ -111,7 +113,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
languageAvailability == TextToSpeech.LANG_NOT_SUPPORTED) {
|
||||
// English is probably supported.
|
||||
// TODO: Somehow use announcement strings from English too.
|
||||
Log.w(MyTracksConstants.TAG, "Default language not available, using English.");
|
||||
Log.w(TAG, "Default language not available, using English.");
|
||||
speechLanguage = Locale.ENGLISH;
|
||||
}
|
||||
tts.setLanguage(speechLanguage);
|
||||
@@ -129,7 +131,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
@Override
|
||||
public void run(TrackRecordingService service) {
|
||||
if (service == null) {
|
||||
Log.e(MyTracksConstants.TAG, "StatusAnnouncer TrackRecordingService not initialized");
|
||||
Log.e(TAG, "StatusAnnouncer TrackRecordingService not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -143,23 +145,22 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
*/
|
||||
protected void runWithStatistics(TripStatistics statistics) {
|
||||
if (statistics == null) {
|
||||
Log.e(MyTracksConstants.TAG, "StatusAnnouncer stats not initialized.");
|
||||
Log.e(TAG, "StatusAnnouncer stats not initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ready || tts == null) {
|
||||
Log.e(MyTracksConstants.TAG, "StatusAnnouncer Tts not ready.");
|
||||
Log.e(TAG, "StatusAnnouncer Tts not ready.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!speechAllowed) {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"Not making announcement - not allowed at this time");
|
||||
return;
|
||||
}
|
||||
|
||||
String announcement = getAnnouncement(statistics);
|
||||
Log.d(MyTracksConstants.TAG, "Announcement: " + announcement);
|
||||
Log.d(Constants.TAG, "Announcement: " + announcement);
|
||||
speakAnnouncment(announcement);
|
||||
}
|
||||
|
||||
@@ -179,7 +180,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
boolean metricUnits = true;
|
||||
boolean reportSpeed = true;
|
||||
if (preferences != null) {
|
||||
metricUnits =
|
||||
metricUnits =
|
||||
preferences.getBoolean(context.getString(R.string.metric_units_key),
|
||||
true);
|
||||
reportSpeed =
|
||||
@@ -218,7 +219,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
speed = String.format("%.1f", s);
|
||||
} else {
|
||||
double pace = 3600000.0 / s;
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(Constants.TAG,
|
||||
"Converted speed: " + s + " to pace: " + pace);
|
||||
speed = stringUtils.formatTimeLong((long) pace);
|
||||
}
|
||||
@@ -237,7 +238,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
Log.i(MyTracksConstants.TAG, "Starting TTS");
|
||||
Log.i(Constants.TAG, "Starting TTS");
|
||||
if (tts == null) {
|
||||
// We can't have this class also be the listener, otherwise it's unsafe to
|
||||
// reference it in Cupcake (even if we don't instantiate it).
|
||||
@@ -264,7 +265,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
|
||||
tts = null;
|
||||
}
|
||||
|
||||
Log.i(MyTracksConstants.TAG, "TTS shut down");
|
||||
Log.i(Constants.TAG, "TTS shut down");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@@ -49,14 +49,14 @@ public class TaskExecuterManager {
|
||||
*/
|
||||
public void setFrequency(int frequency, TrackRecordingService service) {
|
||||
this.frequency = frequency;
|
||||
Log.i(MyTracksConstants.TAG, "Frequency set to " + frequency
|
||||
Log.i(Constants.TAG, "Frequency set to " + frequency
|
||||
+ " for task " + task.getClass().getSimpleName());
|
||||
|
||||
if (frequency == -1) {
|
||||
if (executer != null) {
|
||||
executer.shutdown();
|
||||
executer = null;
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(Constants.TAG,
|
||||
"Shut down service: " + task.getClass().getSimpleName());
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -15,20 +15,21 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.RESUME_TRACK_EXTRA_NAME;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.content.WaypointsColumns;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.services.sensors.SensorManager;
|
||||
import com.google.android.apps.mytracks.services.sensors.SensorManagerFactory;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
@@ -86,8 +87,8 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
private int minRequiredAccuracy =
|
||||
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY;
|
||||
private int autoResumeTrackTimeout =
|
||||
MyTracksSettings.DEFAULT_AUTO_RESUME_TRACK_TIMEOUT;
|
||||
|
||||
MyTracksSettings.DEFAULT_AUTO_RESUME_TRACK_TIMEOUT;
|
||||
|
||||
private long recordingTrackId = -1;
|
||||
|
||||
private long currentWaypointId = -1;
|
||||
@@ -117,9 +118,9 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
private SplitManager splitManager;
|
||||
|
||||
private SensorManager sensorManager;
|
||||
|
||||
|
||||
private PreferenceManager prefManager;
|
||||
|
||||
|
||||
/**
|
||||
* The interval in milliseconds that we have requested to be notified of gps
|
||||
* readings.
|
||||
@@ -144,7 +145,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
if (isRecording()) {
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(Constants.TAG,
|
||||
"Re-registering location listener with TrackRecordingService.");
|
||||
unregisterLocationListener();
|
||||
registerLocationListener();
|
||||
@@ -168,7 +169,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
* The most recent recording track.
|
||||
*/
|
||||
private Track recordingTrack;
|
||||
|
||||
|
||||
/**
|
||||
* Is the service currently recording a track?
|
||||
*/
|
||||
@@ -269,7 +270,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
// Insert failed, most likely because of SqlLite error code 5
|
||||
// (SQLite_BUSY). This is expected to happen extremely rarely (if our
|
||||
// listener gets invoked twice at about the same time).
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(TAG,
|
||||
"Caught SQLiteException: " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
@@ -314,15 +315,15 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
try {
|
||||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
if (pm == null) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"TrackRecordingService: Power manager not found!");
|
||||
return;
|
||||
}
|
||||
if (wakeLock == null) {
|
||||
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
MyTracksConstants.TAG);
|
||||
TAG);
|
||||
if (wakeLock == null) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"TrackRecordingService: Could not create wake lock (null).");
|
||||
return;
|
||||
}
|
||||
@@ -330,12 +331,12 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
if (!wakeLock.isHeld()) {
|
||||
wakeLock.acquire();
|
||||
if (!wakeLock.isHeld()) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"TrackRecordingService: Could not acquire wake lock.");
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"TrackRecordingService: Caught unexpected exception: "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
@@ -376,40 +377,40 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
public void registerLocationListener() {
|
||||
if (locationManager == null) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"TrackRecordingService: Do not have any location manager.");
|
||||
return;
|
||||
}
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Preparing to register location listener w/ TrackRecordingService...");
|
||||
try {
|
||||
long desiredInterval = locationListenerPolicy.getDesiredPollingInterval();
|
||||
locationManager.requestLocationUpdates(
|
||||
MyTracksConstants.GPS_PROVIDER, desiredInterval,
|
||||
Constants.GPS_PROVIDER, desiredInterval,
|
||||
locationListenerPolicy.getMinDistance(),
|
||||
// , 0 /* minDistance, get all updates to properly time pauses */
|
||||
TrackRecordingService.this);
|
||||
currentRecordingInterval = desiredInterval;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"...location listener now registered w/ TrackRecordingService @ "
|
||||
+ currentRecordingInterval);
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"Could not register location listener: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterLocationListener() {
|
||||
if (locationManager == null) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"TrackRecordingService: Do not have any location manager.");
|
||||
return;
|
||||
}
|
||||
locationManager.removeUpdates(this);
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Location listener now unregistered w/ TrackRecordingService.");
|
||||
}
|
||||
|
||||
|
||||
private Track getRecordingTrack() {
|
||||
if (recordingTrackId < 0) {
|
||||
return null;
|
||||
@@ -419,9 +420,9 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
}
|
||||
|
||||
private void restoreStats(Track track) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Restoring stats of track with ID: " + track.getId());
|
||||
|
||||
|
||||
TripStatistics stats = track.getStatistics();
|
||||
statsBuilder = new TripStatisticsBuilder(stats.getStartTime());
|
||||
statsBuilder.setMinRecordingDistance(minRecordingDistance);
|
||||
@@ -446,7 +447,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = providerUtils.getLocationsCursor(
|
||||
recordingTrackId, -1, MyTracksConstants.MAX_LOADED_TRACK_POINTS,
|
||||
recordingTrackId, -1, Constants.MAX_LOADED_TRACK_POINTS,
|
||||
true);
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToLast()) {
|
||||
@@ -465,10 +466,10 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
statsBuilder.pauseAt(stats.getStopTime());
|
||||
statsBuilder.resumeAt(System.currentTimeMillis());
|
||||
} else {
|
||||
Log.e(MyTracksConstants.TAG, "Could not get track points cursor.");
|
||||
Log.e(TAG, "Could not get track points cursor.");
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Error while restoring track.", e);
|
||||
Log.e(TAG, "Error while restoring track.", e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
@@ -493,12 +494,12 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
}
|
||||
|
||||
private void onLocationChangedAsync(Location location) {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.onLocationChanged");
|
||||
Log.d(TAG, "TrackRecordingService.onLocationChanged");
|
||||
|
||||
try {
|
||||
// Don't record if the service has been asked to pause recording:
|
||||
if (!isRecording) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(TAG,
|
||||
"Not recording because recording has been paused.");
|
||||
return;
|
||||
}
|
||||
@@ -506,14 +507,14 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
// This should never happen, but just in case (we really don't want the
|
||||
// service to crash):
|
||||
if (location == null) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(TAG,
|
||||
"Location changed, but location is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't record if the accuracy is too bad:
|
||||
if (location.getAccuracy() > minRequiredAccuracy) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Not recording. Bad accuracy.");
|
||||
return;
|
||||
}
|
||||
@@ -521,7 +522,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
// At least one track must be available for appending points:
|
||||
recordingTrack = getRecordingTrack();
|
||||
if (recordingTrack == null) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Not recording. No track to append to available.");
|
||||
return;
|
||||
}
|
||||
@@ -555,7 +556,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
// maxRecordingDistance = 0
|
||||
if (distanceToLast == 0 && !hasSensorData) {
|
||||
if (isMoving) {
|
||||
Log.d(MyTracksConstants.TAG, "Found two identical locations.");
|
||||
Log.d(TAG, "Found two identical locations.");
|
||||
isMoving = false;
|
||||
if (lastLocation != null && lastRecordedLocation != null
|
||||
&& !lastRecordedLocation.equals(lastLocation)) {
|
||||
@@ -570,7 +571,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
lastRecordedLocationId++;
|
||||
}
|
||||
} else {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Not recording. More than two identical locations.");
|
||||
}
|
||||
} else if (distanceToLastRecorded > minRecordingDistance
|
||||
@@ -595,8 +596,8 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
&& recordingTrack.getStartId() >= 0;
|
||||
if (startNewSegment) {
|
||||
// Insert a separator point to indicate start of new track:
|
||||
Log.d(MyTracksConstants.TAG, "Inserting a separator.");
|
||||
Location separator = new Location(MyTracksConstants.GPS_PROVIDER);
|
||||
Log.d(TAG, "Inserting a separator.");
|
||||
Location separator = new Location(Constants.GPS_PROVIDER);
|
||||
separator.setLongitude(0);
|
||||
separator.setLatitude(100);
|
||||
separator.setTime(lastRecordedLocation.getTime());
|
||||
@@ -608,7 +609,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Log.d(MyTracksConstants.TAG, String.format(
|
||||
Log.d(TAG, String.format(
|
||||
"Not recording. Distance to last recorded point (%f m) is less than"
|
||||
+ " %d m.", distanceToLastRecorded, minRecordingDistance));
|
||||
// Return here so that the location is NOT recorded as the last location.
|
||||
@@ -616,11 +617,11 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
}
|
||||
} catch (Error e) {
|
||||
// Probably important enough to rethrow.
|
||||
Log.e(MyTracksConstants.TAG, "Error in onLocationChanged", e);
|
||||
Log.e(TAG, "Error in onLocationChanged", e);
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
// Safe usually to trap exceptions.
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"Trapping exception in onLocationChanged", e);
|
||||
throw e;
|
||||
}
|
||||
@@ -657,7 +658,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.onCreate");
|
||||
Log.d(TAG, "TrackRecordingService.onCreate");
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
notificationManager =
|
||||
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
@@ -682,7 +683,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
} else {
|
||||
if (recordingTrackId != -1) {
|
||||
// Make sure we have consistent state in shared preferences.
|
||||
Log.w(MyTracksConstants.TAG, "TrackRecordingService.onCreate: "
|
||||
Log.w(TAG, "TrackRecordingService.onCreate: "
|
||||
+ "Resetting an orphaned recording track = " + recordingTrackId);
|
||||
}
|
||||
prefManager.setRecordingTrack(recordingTrackId = -1);
|
||||
@@ -697,7 +698,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
* the announcements, otherwise this method is no-op.
|
||||
*/
|
||||
private void setUpAnnouncer() {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.setUpAnnouncer: "
|
||||
Log.d(TAG, "TrackRecordingService.setUpAnnouncer: "
|
||||
+ announcementExecuter);
|
||||
if (announcementFrequency != -1 && recordingTrackId != -1) {
|
||||
handler.post(new Runnable() {
|
||||
@@ -721,9 +722,9 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void shutdownAnnouncer() {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.shutdownAnnouncer: "
|
||||
Log.d(TAG, "TrackRecordingService.shutdownAnnouncer: "
|
||||
+ announcementExecuter);
|
||||
if (announcementExecuter != null) {
|
||||
try {
|
||||
@@ -736,7 +737,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.onDestroy");
|
||||
Log.d(TAG, "TrackRecordingService.onDestroy");
|
||||
|
||||
isRecording = false;
|
||||
showNotification();
|
||||
@@ -764,29 +765,29 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
// This should be the last operation.
|
||||
releaseWakeLock();
|
||||
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.onBind");
|
||||
Log.d(TAG, "TrackRecordingService.onBind");
|
||||
return binder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUnbind(Intent intent) {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.onUnbind");
|
||||
Log.d(TAG, "TrackRecordingService.onUnbind");
|
||||
return super.onUnbind(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopService(Intent name) {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.stopService");
|
||||
Log.d(TAG, "TrackRecordingService.stopService");
|
||||
unregisterLocationListener();
|
||||
return super.stopService(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStart(Intent intent, int startId) {
|
||||
handleStartCommand(intent, startId);
|
||||
@@ -799,50 +800,50 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
}
|
||||
|
||||
private void handleStartCommand(Intent intent, int startId) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"TrackRecordingService.handleStartCommand: " + startId);
|
||||
|
||||
// Check if called on phone reboot with resume intent.
|
||||
if (intent != null &&
|
||||
intent.getBooleanExtra(RESUME_TRACK_EXTRA_NAME, false)) {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService: requested resume");
|
||||
|
||||
Log.d(TAG, "TrackRecordingService: requested resume");
|
||||
|
||||
// Make sure that the current track exists and is fresh enough.
|
||||
if (recordingTrack == null || !shouldResumeTrack(recordingTrack)) {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(TAG,
|
||||
"TrackRecordingService: Not resuming, because the previous track ("
|
||||
+ recordingTrack + ") doesn't exist or is too old");
|
||||
isRecording = false;
|
||||
prefManager.setRecordingTrack(recordingTrackId = -1);
|
||||
prefManager.setRecordingTrack(recordingTrackId = -1);
|
||||
stopSelfResult(startId);
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(MyTracksConstants.TAG, "TrackRecordingService: resuming");
|
||||
|
||||
Log.i(TAG, "TrackRecordingService: resuming");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setAutoResumeTrackRetries(
|
||||
SharedPreferences sharedPreferences, int retryAttempts) {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"Updating auto-resume retry attempts to: " + retryAttempts);
|
||||
prefManager.setAutoResumeTrackCurrentRetry(retryAttempts);
|
||||
}
|
||||
|
||||
|
||||
private boolean shouldResumeTrack(Track track) {
|
||||
Log.d(MyTracksConstants.TAG, "shouldResumeTrack: autoResumeTrackTimeout = "
|
||||
Log.d(TAG, "shouldResumeTrack: autoResumeTrackTimeout = "
|
||||
+ autoResumeTrackTimeout);
|
||||
|
||||
// Check if we haven't exceeded the maximum number of retry attempts.
|
||||
SharedPreferences sharedPreferences =
|
||||
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
|
||||
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
|
||||
int retries = sharedPreferences.getInt(
|
||||
getString(R.string.auto_resume_track_current_retry_key), 0);
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"shouldResumeTrack: Attempting to auto-resume the track ("
|
||||
+ (retries + 1) + "/" + MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS + ")");
|
||||
if (retries >= MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS) {
|
||||
Log.i(MyTracksConstants.TAG,
|
||||
Log.i(TAG,
|
||||
"shouldResumeTrack: Not resuming because exceeded the maximum "
|
||||
+ "number of auto-resume retries");
|
||||
return false;
|
||||
@@ -853,13 +854,13 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
// Check for special cases.
|
||||
if (autoResumeTrackTimeout == 0) {
|
||||
// Never resume.
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
// Never resume.
|
||||
Log.d(TAG,
|
||||
"shouldResumeTrack: Auto-resume disabled (never resume)");
|
||||
return false;
|
||||
} else if (autoResumeTrackTimeout == -1) {
|
||||
// Always resume.
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"shouldResumeTrack: Auto-resume forced (always resume)");
|
||||
return true;
|
||||
}
|
||||
@@ -867,11 +868,11 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
// Check if the last modified time is within the acceptable range.
|
||||
long lastModified =
|
||||
track.getStatistics() != null ? track.getStatistics().getStopTime() : 0;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"shouldResumeTrack: lastModified = " + lastModified
|
||||
+ ", autoResumeTrackTimeout: " + autoResumeTrackTimeout);
|
||||
return lastModified > 0 && System.currentTimeMillis() - lastModified <=
|
||||
autoResumeTrackTimeout * 60 * 1000;
|
||||
autoResumeTrackTimeout * 60 * 1000;
|
||||
}
|
||||
|
||||
public boolean isRecording() {
|
||||
@@ -897,7 +898,8 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
}
|
||||
wpt.setTrackId(recordingTrackId);
|
||||
wpt.setLength(length);
|
||||
if (lastValidLocation == null) {
|
||||
if (lastLocation == null
|
||||
|| statsBuilder == null || statsBuilder.getStatistics() == null) {
|
||||
// A null location is ok, and expected on track start.
|
||||
// Make it an impossible location.
|
||||
Location l = new Location("");
|
||||
@@ -905,11 +907,9 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
l.setLongitude(180);
|
||||
wpt.setLocation(l);
|
||||
} else {
|
||||
// A null location is ok, and expected on track start.
|
||||
wpt.setLocation(lastLocation);
|
||||
if (lastLocation != null) {
|
||||
wpt.setDuration(lastLocation.getTime() - statsBuilder.getStatistics().getStartTime());
|
||||
}
|
||||
wpt.setDuration(lastLocation.getTime()
|
||||
- statsBuilder.getStatistics().getStartTime());
|
||||
}
|
||||
Uri uri = providerUtils.insertWaypoint(wpt);
|
||||
return Long.parseLong(uri.getLastPathSegment());
|
||||
@@ -962,27 +962,27 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
// Create a new stats keeper for the next marker.
|
||||
waypointStatsBuilder = new TripStatisticsBuilder(time);
|
||||
}
|
||||
|
||||
|
||||
private ServiceBinder binder = new ServiceBinder(this);
|
||||
|
||||
|
||||
/**
|
||||
* TODO: There is a bug in Android that leaks Binder instances. This bug is
|
||||
* especially visible if we have a non-static class, as there is no way to
|
||||
* nullify reference to the outer class (the service).
|
||||
* A workaround is to use a static class and explicitly clear service
|
||||
* and detach it from the underlying Binder. With this approach, we minimize
|
||||
* the leak to 24 bytes per each service instance.
|
||||
* the leak to 24 bytes per each service instance.
|
||||
*
|
||||
* For more details, see the following bug:
|
||||
* http://code.google.com/p/android/issues/detail?id=6426.
|
||||
*/
|
||||
private static class ServiceBinder extends ITrackRecordingService.Stub {
|
||||
private TrackRecordingService service;
|
||||
|
||||
|
||||
public ServiceBinder(TrackRecordingService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the reference to the outer class to minimize the leak.
|
||||
*/
|
||||
@@ -990,7 +990,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
this.service = null;
|
||||
attachInterface(null, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isRecording() {
|
||||
checkService();
|
||||
@@ -1005,13 +1005,13 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
@Override
|
||||
public long getRecordingTrackId() {
|
||||
checkService();
|
||||
checkService();
|
||||
return service.recordingTrackId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRecorded() {
|
||||
checkService();
|
||||
checkService();
|
||||
return service.providerUtils.getLastTrackId() >= 0;
|
||||
}
|
||||
|
||||
@@ -1049,19 +1049,19 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
@Override
|
||||
public void recordLocation(Location loc) {
|
||||
checkService();
|
||||
checkService();
|
||||
service.onLocationChanged(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getSensorData() {
|
||||
checkService();
|
||||
checkService();
|
||||
if (service.sensorManager == null) {
|
||||
Log.d(MyTracksConstants.TAG, "No sensor manager for data.");
|
||||
Log.d(TAG, "No sensor manager for data.");
|
||||
return null;
|
||||
}
|
||||
if (service.sensorManager.getSensorDataSet() == null) {
|
||||
Log.d(MyTracksConstants.TAG, "Sensor data set is null.");
|
||||
Log.d(TAG, "Sensor data set is null.");
|
||||
return null;
|
||||
}
|
||||
return service.sensorManager.getSensorDataSet().toByteArray();
|
||||
@@ -1069,9 +1069,9 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
|
||||
@Override
|
||||
public int getSensorState() {
|
||||
checkService();
|
||||
checkService();
|
||||
if (service.sensorManager == null) {
|
||||
Log.d(MyTracksConstants.TAG, "No sensor manager for data.");
|
||||
Log.d(TAG, "No sensor manager for data.");
|
||||
return Sensor.SensorState.NONE.getNumber();
|
||||
}
|
||||
return service.sensorManager.getSensorState().getNumber();
|
||||
@@ -1079,7 +1079,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
}
|
||||
|
||||
public long startNewTrack() {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.startNewTrack");
|
||||
Log.d(TAG, "TrackRecordingService.startNewTrack");
|
||||
if (recordingTrackId != -1 || isRecording) {
|
||||
throw new IllegalStateException("A track is already in progress!");
|
||||
}
|
||||
@@ -1129,7 +1129,7 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
}
|
||||
|
||||
private void endCurrentTrack() {
|
||||
Log.d(MyTracksConstants.TAG, "TrackRecordingService.endCurrentTrack");
|
||||
Log.d(TAG, "TrackRecordingService.endCurrentTrack");
|
||||
if (recordingTrackId == -1 || !isRecording) {
|
||||
throw new IllegalStateException("No recording track in progress!");
|
||||
}
|
||||
@@ -1156,12 +1156,12 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
showNotification();
|
||||
long recordedTrackId = recordingTrackId;
|
||||
prefManager.setRecordingTrack(recordingTrackId = -1);
|
||||
|
||||
|
||||
if (sensorManager != null) {
|
||||
sensorManager.shutdown();
|
||||
sensorManager = null;
|
||||
}
|
||||
|
||||
|
||||
releaseWakeLock();
|
||||
|
||||
// Notify the world that we're no longer recording.
|
||||
@@ -1243,11 +1243,11 @@ public class TrackRecordingService extends Service implements LocationListener {
|
||||
LocationListenerPolicy locationListenerPolicy) {
|
||||
this.locationListenerPolicy = locationListenerPolicy;
|
||||
}
|
||||
|
||||
|
||||
public int getAutoResumeTrackTimeout() {
|
||||
return autoResumeTrackTimeout;
|
||||
}
|
||||
|
||||
|
||||
public void setAutoResumeTrackTimeout(int autoResumeTrackTimeout) {
|
||||
this.autoResumeTrackTimeout = autoResumeTrackTimeout;
|
||||
}
|
||||
|
||||
+5
-5
@@ -15,17 +15,17 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
|
||||
import com.dsi.ant.AntDefine;
|
||||
import com.dsi.ant.AntMesg;
|
||||
import com.dsi.ant.exception.AntInterfaceException;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.services.sensors.ant.AntChannelIdMessage;
|
||||
import com.google.android.apps.mytracks.services.sensors.ant.AntChannelResponseMessage;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import com.dsi.ant.AntDefine;
|
||||
import com.dsi.ant.AntMesg;
|
||||
import com.dsi.ant.exception.AntInterfaceException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
+24
-18
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import com.dsi.ant.AntDefine;
|
||||
import com.dsi.ant.AntMesg;
|
||||
import com.dsi.ant.exception.AntInterfaceException;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
@@ -82,10 +82,10 @@ public class AntSRMSensorManager extends AntSensorManager {
|
||||
@Override
|
||||
public void handleMessage(byte[] antMessage) {
|
||||
// Parse channel number
|
||||
byte receivedChannel = (byte) (antMessage[AntMesg.MESG_DATA_OFFSET]
|
||||
byte recievedChannel = (byte) (antMessage[AntMesg.MESG_DATA_OFFSET]
|
||||
& AntDefine.CHANNEL_NUMBER_MASK);
|
||||
if (receivedChannel != channel) {
|
||||
Log.d(TAG, "Unexpected channel: " + receivedChannel);
|
||||
if (recievedChannel != channel) {
|
||||
Log.d(Constants.TAG, "Unexpected channel: " + recievedChannel);
|
||||
return;
|
||||
}
|
||||
switch (antMessage[AntMesg.MESG_ID_OFFSET]) {
|
||||
@@ -99,17 +99,18 @@ public class AntSRMSensorManager extends AntSensorManager {
|
||||
handleChannelId(antMessage);
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Unexpected message id: " + antMessage[3]);
|
||||
Log.e(Constants.TAG,
|
||||
"Unexpected message id: " + antMessage[3]);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleBroadcastData(byte[] antMessage) {
|
||||
if (deviceId == WILDCARD) {
|
||||
try {
|
||||
Log.d(TAG, "Requesting channel id id.");
|
||||
Log.d(Constants.TAG, "Requesting channel id id.");
|
||||
getAntReceiver().ANTRequestMessage(channel, AntMesg.MESG_CHANNEL_ID_ID);
|
||||
} catch (AntInterfaceException e) {
|
||||
Log.e(TAG, "Failed to request channel id id", e);
|
||||
Log.e(Constants.TAG, "Failed to request channel id id", e);
|
||||
}
|
||||
}
|
||||
setSensorState(Sensor.SensorState.CONNECTED);
|
||||
@@ -121,14 +122,15 @@ public class AntSRMSensorManager extends AntSensorManager {
|
||||
parseSensorData(antMessage);
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Unexpected message type: " + antMessage[MESSAGE_TYPE_INDEX]);
|
||||
Log.e(Constants.TAG,
|
||||
"Unexpected message type: " + antMessage[MESSAGE_TYPE_INDEX]);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleChannelId(byte[] antMessage) {
|
||||
// Store the device id.
|
||||
deviceId = antMessage[3];
|
||||
Log.i(TAG, "Found device id: " + deviceId);
|
||||
Log.i(Constants.TAG, "Found device id: " + deviceId);
|
||||
|
||||
SharedPreferences prefs = context.getSharedPreferences(
|
||||
MyTracksSettings.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
@@ -141,34 +143,38 @@ public class AntSRMSensorManager extends AntSensorManager {
|
||||
if (antMessage[3] == AntMesg.MESG_EVENT_ID
|
||||
&& antMessage[4] == AntDefine.EVENT_RX_SEARCH_TIMEOUT) {
|
||||
// Search timeout
|
||||
Log.w(TAG, "Search timed out. Unassigning channel.");
|
||||
Log.w(Constants.TAG, "Search timed out. Unassigning channel.");
|
||||
try {
|
||||
getAntReceiver().ANTUnassignChannel(channel);
|
||||
} catch (AntInterfaceException e) {
|
||||
Log.e(TAG, "Failed to unassign ANT channel", e);
|
||||
Log.e(Constants.TAG, "Failed to unassign ANT channel", e);
|
||||
}
|
||||
setSensorState(Sensor.SensorState.DISCONNECTED);
|
||||
} else if (antMessage[3] == AntMesg.MESG_UNASSIGN_CHANNEL_ID) {
|
||||
setSensorState(Sensor.SensorState.DISCONNECTED);
|
||||
Log.i(TAG, "Disconnected from the sensor: " + getSensorState());
|
||||
Log.i(Constants.TAG,
|
||||
"Disconnected from the sensor: " + getSensorState());
|
||||
}
|
||||
}
|
||||
|
||||
private void parseSensorData(byte[] antMessage) {
|
||||
if (antMessage.length != 11) {
|
||||
Log.e(TAG, "Unexpected ant message length: " + antMessage.length);
|
||||
Log.e(Constants.TAG,
|
||||
"Unexpected ant message length: " + antMessage.length);
|
||||
return;
|
||||
}
|
||||
|
||||
int newMessageId = antMessage[MESSAGE_ID_INDEX] & 0xFF;
|
||||
if (lastMessageId == newMessageId) {
|
||||
// Repeated message.
|
||||
Log.i(TAG, String.format("SRM ignoring repeat: 0x%X", newMessageId));
|
||||
Log.i(Constants.TAG,
|
||||
String.format("SRM ignoring repeat: 0x%X", newMessageId));
|
||||
return;
|
||||
}
|
||||
if (newMessageId < lastMessageId) {
|
||||
if (!(newMessageId < 20 && lastMessageId > 200)) {
|
||||
Log.i(TAG, String.format("SRM ignoring repeat: 0x%X", newMessageId));
|
||||
Log.i(Constants.TAG,
|
||||
String.format("SRM ignoring repeat: 0x%X", newMessageId));
|
||||
return;
|
||||
} // else assume the byte overflowed to 0.
|
||||
}
|
||||
|
||||
+22
-21
@@ -15,16 +15,16 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.services.sensors.ant.AntStartupMessage;
|
||||
|
||||
import com.dsi.ant.AntDefine;
|
||||
import com.dsi.ant.AntInterface;
|
||||
import com.dsi.ant.AntInterfaceIntent;
|
||||
import com.dsi.ant.AntMesg;
|
||||
import com.dsi.ant.exception.AntInterfaceException;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.services.sensors.ant.AntStartupMessage;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -84,7 +84,7 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String antAction = intent.getAction();
|
||||
Log.i(TAG, "enter status onReceive" + antAction);
|
||||
Log.i(Constants.TAG, "enter status onReceive" + antAction);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -93,12 +93,12 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String antAction = intent.getAction();
|
||||
Log.i(TAG, "enter data onReceive" + antAction);
|
||||
Log.i(Constants.TAG, "enter data onReceive" + antAction);
|
||||
|
||||
if (antAction.equals(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION)) {
|
||||
byte[] antMessage = intent.getByteArrayExtra(AntInterfaceIntent.ANT_MESSAGE);
|
||||
if (DEBUGGING) {
|
||||
Log.d(TAG, "Received RX message " + messageToString(antMessage));
|
||||
Log.d(Constants.TAG, "Received RX message " + messageToString(antMessage));
|
||||
}
|
||||
|
||||
handleMessage(antMessage);
|
||||
@@ -119,7 +119,7 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected() {
|
||||
Log.d(TAG, "ANT interface reports disconnection");
|
||||
Log.d(Constants.TAG, "ANT interface reports disconnection");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -129,14 +129,14 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.i(TAG, "destroying AntSensorManager");
|
||||
Log.i(Constants.TAG, "destroying AntSensorManager");
|
||||
context.unregisterReceiver(statusReceiver);
|
||||
context.unregisterReceiver(dataReceiver);
|
||||
|
||||
try {
|
||||
antReceiver.releaseInterface();
|
||||
} catch (AntInterfaceException e) {
|
||||
Log.e(TAG, "failed to release ANT interface", e);
|
||||
Log.e(Constants.TAG, "failed to release ANT interface", e);
|
||||
}
|
||||
|
||||
antReceiver.destroy();
|
||||
@@ -177,7 +177,7 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
antReceiver = AntInterface.getInstance(context, antServiceListener);
|
||||
|
||||
if (antReceiver == null) {
|
||||
Log.e(TAG, "Failed to get ANT Receiver");
|
||||
Log.e(Constants.TAG, "Failed to get ANT Receiver");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -190,11 +190,11 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
* to initiate any ANT commands.
|
||||
*/
|
||||
private synchronized void serviceConnected() {
|
||||
Log.d(TAG, "ANT service connected");
|
||||
Log.d(Constants.TAG, "ANT service connected");
|
||||
|
||||
try {
|
||||
if (!antReceiver.claimInterface()) {
|
||||
Log.e(TAG, "failed to claim ANT interface");
|
||||
Log.e(Constants.TAG, "failed to claim ANT interface");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,14 +202,14 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
// Make sure not to call AntInterface.enable() again, if it has been
|
||||
// already called before
|
||||
if (antInterrupted == false) {
|
||||
Log.i(TAG, "Powering on Radio");
|
||||
Log.i(Constants.TAG, "Powering on Radio");
|
||||
antReceiver.enable();
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "Radio already enabled");
|
||||
Log.i(Constants.TAG, "Radio already enabled");
|
||||
}
|
||||
} catch (AntInterfaceException e) {
|
||||
Log.e(TAG, "failed to enable ANT", e);
|
||||
Log.e(Constants.TAG, "failed to enable ANT", e);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -220,7 +220,7 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
// that message.
|
||||
antReceiver.ANTResetSystem();
|
||||
} catch (AntInterfaceException e) {
|
||||
Log.e(TAG, "failed to reset ANT (expected exception)", e);
|
||||
Log.e(Constants.TAG, "failed to reset ANT (expected exception)", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
protected void handleMessage(byte[] antMessage) {
|
||||
int len = antMessage[0];
|
||||
if (len != antMessage.length - 2 || antMessage.length <= 2) {
|
||||
Log.e(TAG, "Invalid message: " + messageToString(antMessage));
|
||||
Log.e(Constants.TAG, "Invalid message: " + messageToString(antMessage));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -253,7 +253,8 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
*/
|
||||
protected boolean handleMessage(byte messageId, byte[] messageData) {
|
||||
if (messageId == AntMesg.MESG_STARTUP_MESG_ID) {
|
||||
Log.d(TAG, String.format("Received startup message (reason %02x); initializing channel",
|
||||
Log.d(Constants.TAG, String.format(
|
||||
"Received startup message (reason %02x); initializing channel",
|
||||
new AntStartupMessage(messageData).getMessage()));
|
||||
setupAntSensorChannels();
|
||||
return true;
|
||||
@@ -304,13 +305,13 @@ public abstract class AntSensorManager extends SensorManager {
|
||||
return true;
|
||||
|
||||
} catch (AntInterfaceException e) {
|
||||
Log.e(TAG, "failed to setup ANT channel", e);
|
||||
Log.e(Constants.TAG, "failed to setup ANT channel", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void registerForAntIntents() {
|
||||
Log.i(TAG, "Registering for ant intents.");
|
||||
Log.i(Constants.TAG, "Registering for ant intents.");
|
||||
// Register for ANT intent broadcasts.
|
||||
IntentFilter statusIntentFilter = new IntentFilter();
|
||||
statusIntentFilter.addAction(AntInterfaceIntent.ANT_ENABLED_ACTION);
|
||||
|
||||
+27
-26
@@ -16,8 +16,7 @@
|
||||
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
@@ -86,7 +85,7 @@ public class BluetoothConnectionManager {
|
||||
*/
|
||||
private synchronized void setState(Sensor.SensorState state) {
|
||||
// TODO pretty print this.
|
||||
Log.d(TAG, "setState(" + state + ")");
|
||||
Log.d(Constants.TAG, "setState(" + state + ")");
|
||||
this.state = state;
|
||||
|
||||
// Give the new state to the Handler so the UI Activity can update
|
||||
@@ -105,7 +104,7 @@ public class BluetoothConnectionManager {
|
||||
* in listening (server) mode. Called by the Activity onResume()
|
||||
*/
|
||||
public synchronized void start() {
|
||||
Log.d(TAG, "BluetoothConnectionManager.start()");
|
||||
Log.d(Constants.TAG, "BluetoothConnectionManager.start()");
|
||||
|
||||
// Cancel any thread attempting to make a connection
|
||||
if (connectThread != null) {
|
||||
@@ -128,7 +127,7 @@ public class BluetoothConnectionManager {
|
||||
* @param device The BluetoothDevice to connect
|
||||
*/
|
||||
public synchronized void connect(BluetoothDevice device) {
|
||||
Log.d(TAG, "connect to: " + device);
|
||||
Log.d(Constants.TAG, "connect to: " + device);
|
||||
|
||||
// Cancel any thread attempting to make a connection
|
||||
if (state == Sensor.SensorState.CONNECTING) {
|
||||
@@ -158,7 +157,7 @@ public class BluetoothConnectionManager {
|
||||
*/
|
||||
public synchronized void connected(BluetoothSocket socket,
|
||||
BluetoothDevice device) {
|
||||
Log.d(TAG, "connected");
|
||||
Log.d(Constants.TAG, "connected");
|
||||
|
||||
// Cancel the thread that completed the connection
|
||||
if (connectThread != null) {
|
||||
@@ -190,7 +189,7 @@ public class BluetoothConnectionManager {
|
||||
* Stop all threads
|
||||
*/
|
||||
public synchronized void stop() {
|
||||
Log.d(TAG, "stop()");
|
||||
Log.d(Constants.TAG, "stop()");
|
||||
if (connectThread != null) {
|
||||
connectThread.cancel();
|
||||
connectThread = null;
|
||||
@@ -227,7 +226,7 @@ public class BluetoothConnectionManager {
|
||||
*/
|
||||
private void connectionFailed() {
|
||||
setState(Sensor.SensorState.DISCONNECTED);
|
||||
Log.i(TAG, "Bluetooth connection failed.");
|
||||
Log.i(Constants.TAG, "Bluetooth connection failed.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,7 +234,7 @@ public class BluetoothConnectionManager {
|
||||
*/
|
||||
private void connectionLost() {
|
||||
setState(Sensor.SensorState.DISCONNECTED);
|
||||
Log.i(TAG, "Bluetooth connection lost.");
|
||||
Log.i(Constants.TAG, "Bluetooth connection lost.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,7 +255,7 @@ public class BluetoothConnectionManager {
|
||||
try {
|
||||
tmp = getSocket();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "create() failed", e);
|
||||
Log.e(Constants.TAG, "create() failed", e);
|
||||
}
|
||||
socket = tmp;
|
||||
}
|
||||
@@ -269,22 +268,22 @@ public class BluetoothConnectionManager {
|
||||
insecure.setAccessible(true);
|
||||
return (BluetoothSocket) insecure.invoke(device, 1);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "Unable to get insecure connect.", e);
|
||||
Log.e(Constants.TAG, "Unable to get insecure connect.", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Log.e(TAG, "Unable to get insecure connect.", e);
|
||||
Log.e(Constants.TAG, "Unable to get insecure connect.", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Unable to get insecure connect.", e);
|
||||
Log.e(Constants.TAG, "Unable to get insecure connect.", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(TAG, "Unable to get insecure connect.", e);
|
||||
Log.e(Constants.TAG, "Unable to get insecure connect.", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e(TAG, "Unable to get insecure connect.", e);
|
||||
Log.e(Constants.TAG, "Unable to get insecure connect.", e);
|
||||
}
|
||||
return device.createRfcommSocketToServiceRecord(SPP_UUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG, "BEGIN mConnectThread");
|
||||
Log.d(Constants.TAG, "BEGIN mConnectThread");
|
||||
|
||||
// Always cancel discovery because it will slow down a connection
|
||||
adapter.cancelDiscovery();
|
||||
@@ -300,7 +299,8 @@ public class BluetoothConnectionManager {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) {
|
||||
Log.e(TAG, "unable to close() socket during connection failure", e2);
|
||||
Log.e(Constants.TAG,
|
||||
"unable to close() socket during connection failure", e2);
|
||||
}
|
||||
// Start the service over to restart listening mode
|
||||
BluetoothConnectionManager.this.start();
|
||||
@@ -320,7 +320,7 @@ public class BluetoothConnectionManager {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "close() of connect socket failed", e);
|
||||
Log.e(Constants.TAG, "close() of connect socket failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,7 +335,7 @@ public class BluetoothConnectionManager {
|
||||
private final OutputStream mmOutStream;
|
||||
|
||||
public ConnectedThread(BluetoothSocket socket) {
|
||||
Log.d(TAG, "create ConnectedThread");
|
||||
Log.d(Constants.TAG, "create ConnectedThread");
|
||||
btSocket = socket;
|
||||
InputStream tmpIn = null;
|
||||
OutputStream tmpOut = null;
|
||||
@@ -345,7 +345,7 @@ public class BluetoothConnectionManager {
|
||||
tmpIn = socket.getInputStream();
|
||||
tmpOut = socket.getOutputStream();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "temp sockets not created", e);
|
||||
Log.e(Constants.TAG, "temp sockets not created", e);
|
||||
}
|
||||
|
||||
mmInStream = tmpIn;
|
||||
@@ -354,7 +354,7 @@ public class BluetoothConnectionManager {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "BEGIN mConnectedThread");
|
||||
Log.i(Constants.TAG, "BEGIN mConnectedThread");
|
||||
byte[] buffer = new byte[parser.getFrameSize()];
|
||||
int bytes;
|
||||
int offset = 0;
|
||||
@@ -383,10 +383,11 @@ public class BluetoothConnectionManager {
|
||||
// re-align
|
||||
offset = parser.getFrameSize() - index;
|
||||
System.arraycopy(buffer, index, buffer, 0, offset);
|
||||
Log.w(TAG, "Misaligned data, found new message at " + index + " recovering...");
|
||||
Log.w(Constants.TAG, "Misaligned data, found new message at " +
|
||||
index + " recovering...");
|
||||
continue;
|
||||
}
|
||||
Log.w(TAG, "Could not find valid data, dropping data");
|
||||
Log.w(Constants.TAG, "Could not find valid data, dropping data");
|
||||
offset = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -397,7 +398,7 @@ public class BluetoothConnectionManager {
|
||||
handler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
|
||||
.sendToTarget();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "disconnected", e);
|
||||
Log.e(Constants.TAG, "disconnected", e);
|
||||
connectionLost();
|
||||
break;
|
||||
}
|
||||
@@ -416,7 +417,7 @@ public class BluetoothConnectionManager {
|
||||
// Share the sent message back to the UI Activity
|
||||
handler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Exception during write", e);
|
||||
Log.e(Constants.TAG, "Exception during write", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +425,7 @@ public class BluetoothConnectionManager {
|
||||
try {
|
||||
btSocket.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "close() of connect socket failed", e);
|
||||
Log.e(Constants.TAG, "close() of connect socket failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -51,7 +50,7 @@ public class BluetoothSensorManager extends SensorManager {
|
||||
private Sensor.SensorDataSet sensorDataSet = null;
|
||||
|
||||
private MessageParser parser;
|
||||
|
||||
|
||||
public BluetoothSensorManager(
|
||||
Context context, MessageParser parser) {
|
||||
this.context = context;
|
||||
@@ -67,7 +66,7 @@ public class BluetoothSensorManager extends SensorManager {
|
||||
}
|
||||
|
||||
private void setupSensor() {
|
||||
Log.d(TAG, "setupSensor()");
|
||||
Log.d(Constants.TAG, "setupSensor()");
|
||||
|
||||
// Initialize the BluetoothSensorAdapter to perform bluetooth connections.
|
||||
connectionManager = new BluetoothConnectionManager(messageHandler, parser);
|
||||
@@ -79,7 +78,7 @@ public class BluetoothSensorManager extends SensorManager {
|
||||
|
||||
public void setupChannel() {
|
||||
if (!isEnabled() || connectionManager == null) {
|
||||
Log.w(TAG, "Disabled manager onStartTrack");
|
||||
Log.w(Constants.TAG, "Disabled manager onStartTrack");
|
||||
return;
|
||||
}
|
||||
SharedPreferences prefs =
|
||||
@@ -89,7 +88,7 @@ public class BluetoothSensorManager extends SensorManager {
|
||||
if (address == null) {
|
||||
return;
|
||||
}
|
||||
Log.w(TAG, "Connecting to bluetooth sensor: " + address);
|
||||
Log.w(Constants.TAG, "Connecting to bluetooth sensor: " + address);
|
||||
// Get the BluetoothDevice object
|
||||
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
|
||||
// Attempt to connect to the device
|
||||
@@ -103,7 +102,7 @@ public class BluetoothSensorManager extends SensorManager {
|
||||
// already
|
||||
if (connectionManager.getState() == Sensor.SensorState.NONE) {
|
||||
// Start the Bluetooth sensor services
|
||||
Log.w(TAG, "Disabled manager onStartTrack");
|
||||
Log.w(Constants.TAG, "Disabled manager onStartTrack");
|
||||
connectionManager.start();
|
||||
}
|
||||
}
|
||||
@@ -133,7 +132,7 @@ public class BluetoothSensorManager extends SensorManager {
|
||||
switch (msg.what) {
|
||||
case BluetoothConnectionManager.MESSAGE_STATE_CHANGE:
|
||||
// TODO should we update the SensorManager state var?
|
||||
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
|
||||
Log.i(Constants.TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
|
||||
break;
|
||||
case BluetoothConnectionManager.MESSAGE_WRITE:
|
||||
break;
|
||||
@@ -142,14 +141,15 @@ public class BluetoothSensorManager extends SensorManager {
|
||||
try {
|
||||
readBuf = (byte[]) msg.obj;
|
||||
sensorDataSet = parser.parseBuffer(readBuf);
|
||||
Log.d(TAG, "MESSAGE_READ: " + sensorDataSet.toString());
|
||||
Log.d(Constants.TAG, "MESSAGE_READ: " + sensorDataSet.toString());
|
||||
} catch (IllegalArgumentException iae) {
|
||||
sensorDataSet = null;
|
||||
Log.i(TAG, "Got bad sensor data: " + new String(readBuf, 0, readBuf.length),
|
||||
Log.i(Constants.TAG,
|
||||
"Got bad sensor data: " + new String(readBuf, 0, readBuf.length),
|
||||
iae);
|
||||
} catch (RuntimeException re) {
|
||||
sensorDataSet = null;
|
||||
Log.i(TAG, "Unexpected exception on read.", re);
|
||||
Log.i(Constants.TAG, "Unexpected exception on read.", re);
|
||||
}
|
||||
break;
|
||||
case BluetoothConnectionManager.MESSAGE_DEVICE_NAME:
|
||||
|
||||
@@ -15,14 +15,13 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
/**
|
||||
* Manage the connection to a sensor.
|
||||
@@ -51,17 +50,19 @@ public abstract class SensorManager {
|
||||
private TimerTask checkSensorManager = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "SensorManager state: " + getSensorState());
|
||||
Log.i(Constants.TAG,
|
||||
"SensorManager state: " + getSensorState());
|
||||
switch (getSensorState()) {
|
||||
case CONNECTING:
|
||||
long age = System.currentTimeMillis() - getSensorStateTimestamp();
|
||||
if (age > 2 * RETRY_PERIOD) {
|
||||
Log.i(TAG, "Retrying connecting SensorManager.");
|
||||
Log.i(Constants.TAG, "Retrying connecting SensorManager.");
|
||||
setupChannel();
|
||||
}
|
||||
break;
|
||||
case DISCONNECTED:
|
||||
Log.i(TAG, "Re-registering disconnected SensorManager.");
|
||||
Log.i(Constants.TAG,
|
||||
"Re-registering disconnected SensoManager.");
|
||||
setupChannel();
|
||||
break;
|
||||
}
|
||||
|
||||
+10
-9
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2009 Google Inc.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
@@ -30,7 +29,9 @@ import android.util.Log;
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class SensorManagerFactory {
|
||||
private SensorManagerFactory() {}
|
||||
|
||||
private SensorManagerFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new sensor manager.
|
||||
@@ -43,9 +44,9 @@ public class SensorManagerFactory {
|
||||
if (prefs == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
String sensor = prefs.getString(context.getString(R.string.sensor_type_key), null);
|
||||
Log.i(TAG, "Creating sensor of type: " + sensor);
|
||||
Log.i(Constants.TAG, "Creating sensor of type: " + sensor);
|
||||
|
||||
if (sensor == null) {
|
||||
return null;
|
||||
@@ -56,7 +57,7 @@ public class SensorManagerFactory {
|
||||
} else if (sensor.equals(context.getString(R.string.zephyr_sensor_type))) {
|
||||
return new ZephyrSensorManager(context);
|
||||
} else {
|
||||
Log.w(TAG, "Unable to find sensor type: " + sensor);
|
||||
Log.w(Constants.TAG, "Unable to find sensor type: " + sensor);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -15,12 +15,11 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
/**
|
||||
* An implementation of a SensorData parser for Zephyr HRM.
|
||||
*
|
||||
@@ -34,7 +33,7 @@ public class ZephyrMessageParser implements MessageParser {
|
||||
for (int i = 0; i < buffer.length; i++) {
|
||||
sb.append(String.format("%02X", buffer[i]));
|
||||
}
|
||||
Log.w(TAG, "Got zephyr data: " + sb);
|
||||
Log.w(Constants.TAG, "Got zephyr data: " + sb);
|
||||
// The provided units are 1/16 strides per minute.
|
||||
// TODO: Fix the cadence calculation.
|
||||
// int cadence = SensorUtils.unsignedShortToInt(buffer, 56);
|
||||
@@ -50,7 +49,7 @@ public class ZephyrMessageParser implements MessageParser {
|
||||
.setCreationTime(System.currentTimeMillis())
|
||||
.setHeartRate(b)
|
||||
.build();
|
||||
|
||||
|
||||
return sds;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package com.google.android.apps.mytracks.stats;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
|
||||
import android.location.Location;
|
||||
@@ -65,25 +67,25 @@ public class TripStatisticsBuilder {
|
||||
* A buffer of the last speed readings in meters/second.
|
||||
*/
|
||||
private final DoubleBuffer speedBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.SPEED_SMOOTHING_FACTOR);
|
||||
new DoubleBuffer(Constants.SPEED_SMOOTHING_FACTOR);
|
||||
|
||||
/**
|
||||
* A buffer of the recent elevation readings in meters.
|
||||
*/
|
||||
private final DoubleBuffer elevationBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
/**
|
||||
* A buffer of the distance between recent gps readings in meters.
|
||||
*/
|
||||
private final DoubleBuffer distanceBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.DISTANCE_SMOOTHING_FACTOR);
|
||||
new DoubleBuffer(Constants.DISTANCE_SMOOTHING_FACTOR);
|
||||
|
||||
/**
|
||||
* A buffer of the recent grade calculations.
|
||||
*/
|
||||
private final DoubleBuffer gradeBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.GRADE_SMOOTHING_FACTOR);
|
||||
new DoubleBuffer(Constants.GRADE_SMOOTHING_FACTOR);
|
||||
|
||||
/**
|
||||
* The total number of locations in this trip.
|
||||
@@ -126,7 +128,7 @@ public class TripStatisticsBuilder {
|
||||
*/
|
||||
public boolean addLocation(Location currentLocation, long systemTime) {
|
||||
if (paused) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
Log.w(TAG,
|
||||
"Tried to account for location while track is paused");
|
||||
return false;
|
||||
}
|
||||
@@ -151,7 +153,7 @@ public class TripStatisticsBuilder {
|
||||
// Don't do anything if we didn't move since last fix:
|
||||
double distance = lastLocation.distanceTo(currentLocation);
|
||||
if (distance < minRecordingDistance &&
|
||||
currentSpeed < MyTracksConstants.MAX_NO_MOVEMENT_SPEED) {
|
||||
currentSpeed < Constants.MAX_NO_MOVEMENT_SPEED) {
|
||||
lastLocation = currentLocation;
|
||||
return false;
|
||||
}
|
||||
@@ -208,7 +210,7 @@ public class TripStatisticsBuilder {
|
||||
// We are now sure the user is moving.
|
||||
long timeDifference = updateTime - lastLocationTime;
|
||||
if (timeDifference < 0) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(TAG,
|
||||
"Found negative time change: " + timeDifference);
|
||||
}
|
||||
data.addMovingTime(timeDifference);
|
||||
@@ -224,7 +226,7 @@ public class TripStatisticsBuilder {
|
||||
data.setMaxSpeed(movingSpeed);
|
||||
}
|
||||
} else {
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
Log.d(TAG,
|
||||
"TripStatistics ignoring big change: Raw Speed: " + speed
|
||||
+ " old: " + lastLocationSpeed + " [" + toString() + "]");
|
||||
}
|
||||
@@ -263,7 +265,7 @@ public class TripStatisticsBuilder {
|
||||
// likely. Ignore any speeds that imply accelaration greater than 2g's
|
||||
// Really who can accelerate faster?
|
||||
double speedDifference = Math.abs(lastLocationSpeed - speed);
|
||||
if (speedDifference > MyTracksConstants.MAX_ACCELERATION * timeDifference) {
|
||||
if (speedDifference > Constants.MAX_ACCELERATION * timeDifference) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -275,7 +277,7 @@ public class TripStatisticsBuilder {
|
||||
double smoothedDiff = Math.abs(smoothedSpeed - speed);
|
||||
return !speedBuffer.isFull() ||
|
||||
(speed < smoothedSpeed * 10
|
||||
&& smoothedDiff < MyTracksConstants.MAX_ACCELERATION * timeDifference);
|
||||
&& smoothedDiff < Constants.MAX_ACCELERATION * timeDifference);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
@@ -72,7 +72,7 @@ public class ApiFeatures {
|
||||
apiPlatformAdapter = new CupcakePlatformAdapter();
|
||||
}
|
||||
|
||||
Log.i(MyTracksConstants.TAG, "Using platform adapter " + apiPlatformAdapter.getClass());
|
||||
Log.i(Constants.TAG, "Using platform adapter " + apiPlatformAdapter.getClass());
|
||||
}
|
||||
|
||||
public ApiPlatformAdapter getApiPlatformAdapter() {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
@@ -158,14 +158,14 @@ public abstract class BluetoothDeviceUtils {
|
||||
public static BluetoothDeviceUtils getInstance() {
|
||||
if (instance == null) {
|
||||
if (!isBluetoothMethodSupported()) {
|
||||
Log.d(MyTracksConstants.TAG, "Using dummy bluetooth utils");
|
||||
Log.d(Constants.TAG, "Using dummy bluetooth utils");
|
||||
instance = new DummyImpl();
|
||||
} else {
|
||||
Log.d(MyTracksConstants.TAG, "Using real bluetooth utils");
|
||||
Log.d(Constants.TAG, "Using real bluetooth utils");
|
||||
try {
|
||||
instance = new RealImpl();
|
||||
} catch (IllegalStateException ise) {
|
||||
Log.w(MyTracksConstants.TAG, "Oops, I mean, using dummy bluetooth utils", ise);
|
||||
Log.w(Constants.TAG, "Oops, I mean, using dummy bluetooth utils", ise);
|
||||
instance = new DummyImpl();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Service;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class FileUtils {
|
||||
StringBuilder dirNameBuilder = new StringBuilder();
|
||||
dirNameBuilder.append(Environment.getExternalStorageDirectory());
|
||||
dirNameBuilder.append(File.separatorChar);
|
||||
dirNameBuilder.append(MyTracksConstants.SDCARD_TOP_DIR);
|
||||
dirNameBuilder.append(Constants.SDCARD_TOP_DIR);
|
||||
for (String component : components) {
|
||||
dirNameBuilder.append(File.separatorChar);
|
||||
dirNameBuilder.append(component);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.os.StrictMode;
|
||||
@@ -21,7 +21,7 @@ public class GingerbreadPlatformAdapter extends EclairPlatformAdapter {
|
||||
|
||||
@Override
|
||||
public void enableStrictMode() {
|
||||
Log.d(MyTracksConstants.TAG, "Enabling strict mode");
|
||||
Log.d(Constants.TAG, "Enabling strict mode");
|
||||
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
|
||||
.detectDiskWrites()
|
||||
.detectNetwork()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
|
||||
@@ -146,7 +146,7 @@ public class MyTracksUtils {
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
Log.d(MyTracksConstants.TAG, "Decimating " + n + " points to " + i
|
||||
Log.d(Constants.TAG, "Decimating " + n + " points to " + i
|
||||
+ " w/ tolerance = " + tolerance);
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ public class MyTracksUtils {
|
||||
}
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Unable to get signatures", e);
|
||||
Log.e(Constants.TAG, "Unable to get signatures", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -285,7 +285,7 @@ public class MyTracksUtils {
|
||||
PackageManager.GET_META_DATA);
|
||||
return pi.versionName;
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.w(MyTracksConstants.TAG, "Failed to get version info.", e);
|
||||
Log.w(Constants.TAG, "Failed to get version info.", e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -295,19 +295,19 @@ public class MyTracksUtils {
|
||||
* and gives up trying in case the wake lock cannot be acquired.
|
||||
*/
|
||||
public static WakeLock acquireWakeLock(Activity activity, WakeLock wakeLock) {
|
||||
Log.i(MyTracksConstants.TAG, "MyTracksUtils: Acquiring wake lock.");
|
||||
Log.i(Constants.TAG, "MyTracksUtils: Acquiring wake lock.");
|
||||
try {
|
||||
PowerManager pm = (PowerManager) activity
|
||||
.getSystemService(Context.POWER_SERVICE);
|
||||
if (pm == null) {
|
||||
Log.e(MyTracksConstants.TAG, "MyTracksUtils: Power manager not found!");
|
||||
Log.e(Constants.TAG, "MyTracksUtils: Power manager not found!");
|
||||
return wakeLock;
|
||||
}
|
||||
if (wakeLock == null) {
|
||||
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
MyTracksConstants.TAG);
|
||||
Constants.TAG);
|
||||
if (wakeLock == null) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(Constants.TAG,
|
||||
"MyTracksUtils: Could not create wake lock (null).");
|
||||
}
|
||||
return wakeLock;
|
||||
@@ -315,12 +315,12 @@ public class MyTracksUtils {
|
||||
if (!wakeLock.isHeld()) {
|
||||
wakeLock.acquire();
|
||||
if (!wakeLock.isHeld()) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(Constants.TAG,
|
||||
"MyTracksUtils: Could not acquire wake lock.");
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(MyTracksConstants.TAG,
|
||||
Log.e(Constants.TAG,
|
||||
"MyTracksUtils: Caught unexpected exception: " + e.getMessage(), e);
|
||||
}
|
||||
return wakeLock;
|
||||
|
||||
@@ -165,7 +165,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
|
||||
|
||||
// Watch for MyTracksDetails activity.
|
||||
ActivityMonitor monitor = getInstrumentation().addMonitor(
|
||||
MyTracksDetails.class.getName(), null, false);
|
||||
TrackDetails.class.getName(), null, false);
|
||||
|
||||
// Now, stop the track and make sure that it is still selected, but
|
||||
// no longer recording.
|
||||
@@ -173,7 +173,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
|
||||
|
||||
// Check if we got back MyTracksDetails activity.
|
||||
Activity activity = getInstrumentation().waitForMonitor(monitor);
|
||||
assertTrue(activity instanceof MyTracksDetails);
|
||||
assertTrue(activity instanceof TrackDetails);
|
||||
|
||||
// TODO: Update track name and other properties and test if they were
|
||||
// properly saved.
|
||||
|
||||
@@ -4,21 +4,32 @@ package com.google.android.apps.mytracks.io;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for the GPX track exporter.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class TcxTrackWriterTest extends TrackFormatWriterTest {
|
||||
private DateFormat timestampFormatter;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
timestampFormatter = new SimpleDateFormat(TcxTrackWriter.TIMESTAMP_FORMAT);
|
||||
timestampFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
public void testXmlOutput() throws Exception {
|
||||
TrackFormatWriter writer = new TcxTrackWriter();
|
||||
TrackFormatWriter writer = new TcxTrackWriter(getContext());
|
||||
String result = writeTrack(writer);
|
||||
Document doc = parseXmlDocument(result);
|
||||
|
||||
@@ -58,8 +69,8 @@ public class TcxTrackWriterTest extends TrackFormatWriterTest {
|
||||
getChildTextValue(posTag, "LatitudeDegrees"));
|
||||
assertEquals(Double.toString(loc.getLongitude()),
|
||||
getChildTextValue(posTag, "LongitudeDegrees"));
|
||||
assertEquals(
|
||||
TcxTrackWriter.TIMESTAMP_FORMAT.format(new Date(loc.getTime())),
|
||||
|
||||
assertEquals(timestampFormatter.format(loc.getTime()),
|
||||
getChildTextValue(tag, "Time"));
|
||||
assertEquals(Double.toString(loc.getAltitude()),
|
||||
getChildTextValue(tag, "AltitudeMeters"));
|
||||
|
||||
-2
@@ -82,7 +82,6 @@ public class PreferenceBackupHelperTest extends TestCase {
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putStringSet(String key, Set<String> value) {
|
||||
return put(key, value);
|
||||
}
|
||||
@@ -143,7 +142,6 @@ public class PreferenceBackupHelperTest extends TestCase {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getStringSet(String key, Set<String> defValue) {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import static com.google.android.apps.mytracks.MyTracksConstants.RESUME_TRACK_EXTRA_NAME;
|
||||
import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProvider;
|
||||
|
||||
+16
-16
@@ -2,7 +2,7 @@
|
||||
|
||||
package com.google.android.apps.mytracks.stats;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
@@ -56,18 +56,18 @@ public class TripStatisticsBuilderTest extends TestCase {
|
||||
assertEquals(10000 * i, stats.getTotalTime());
|
||||
assertEquals(10000 * i, stats.getMovingTime());
|
||||
assertEquals(i, builder.getSmoothedElevation(),
|
||||
MyTracksConstants.ELEVATION_SMOOTHING_FACTOR / 2);
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR / 2);
|
||||
assertEquals(0.0, stats.getMinElevation());
|
||||
assertEquals(i, stats.getMaxElevation(),
|
||||
MyTracksConstants.ELEVATION_SMOOTHING_FACTOR / 2);
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR / 2);
|
||||
assertEquals(i, stats.getTotalElevationGain(),
|
||||
MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
if (i > MyTracksConstants.SPEED_SMOOTHING_FACTOR) {
|
||||
if (i > Constants.SPEED_SMOOTHING_FACTOR) {
|
||||
assertEquals(11.1f, stats.getMaxSpeed(), 0.1);
|
||||
}
|
||||
if ((i > MyTracksConstants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > MyTracksConstants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
if ((i > Constants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > Constants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
assertEquals(0.009, stats.getMinGrade(), 0.0001);
|
||||
assertEquals(0.009, stats.getMaxGrade(), 0.0001);
|
||||
}
|
||||
@@ -97,9 +97,9 @@ public class TripStatisticsBuilderTest extends TestCase {
|
||||
public void testElevationGain() throws Exception {
|
||||
for (double i = 0; i < 1000; i++) {
|
||||
double expectedGain;
|
||||
if (i < (MyTracksConstants.ELEVATION_SMOOTHING_FACTOR - 1)) {
|
||||
if (i < (Constants.ELEVATION_SMOOTHING_FACTOR - 1)) {
|
||||
expectedGain = 0;
|
||||
} else if (i < MyTracksConstants.ELEVATION_SMOOTHING_FACTOR) {
|
||||
} else if (i < Constants.ELEVATION_SMOOTHING_FACTOR) {
|
||||
expectedGain = 0.5;
|
||||
} else {
|
||||
expectedGain = 1.0;
|
||||
@@ -110,9 +110,9 @@ public class TripStatisticsBuilderTest extends TestCase {
|
||||
TripStatistics data = builder.getStatistics();
|
||||
assertEquals(0.0, data.getMinElevation(), 0.0);
|
||||
assertEquals(i, data.getMaxElevation(),
|
||||
MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
assertEquals(i, data.getTotalElevationGain(),
|
||||
MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,8 +122,8 @@ public class TripStatisticsBuilderTest extends TestCase {
|
||||
// buffer.
|
||||
builder.updateElevation(i);
|
||||
builder.updateGrade(100, 100);
|
||||
if ((i > MyTracksConstants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > MyTracksConstants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
if ((i > Constants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > Constants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
assertEquals(1.0, builder.getStatistics().getMaxGrade());
|
||||
assertEquals(1.0, builder.getStatistics().getMinGrade());
|
||||
}
|
||||
@@ -133,8 +133,8 @@ public class TripStatisticsBuilderTest extends TestCase {
|
||||
// buffer.
|
||||
builder.updateElevation(i);
|
||||
builder.updateGrade(100, -100);
|
||||
if ((i > MyTracksConstants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > MyTracksConstants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
if ((i > Constants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > Constants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
assertEquals(1.0, builder.getStatistics().getMaxGrade());
|
||||
assertEquals(-1.0, builder.getStatistics().getMinGrade());
|
||||
}
|
||||
@@ -176,7 +176,7 @@ public class TripStatisticsBuilderTest extends TestCase {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
builder.updateSpeed(i + 1000, 4.0, i, 4.0);
|
||||
assertEquals((i + 1) * 1000, builder.getStatistics().getMovingTime());
|
||||
if (i > MyTracksConstants.SPEED_SMOOTHING_FACTOR) {
|
||||
if (i > Constants.SPEED_SMOOTHING_FACTOR) {
|
||||
assertEquals(4.0, builder.getStatistics().getMaxSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracksConstants;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
@@ -53,7 +53,7 @@ public class FileUtilsTest extends TestCase {
|
||||
public void testBuildExternalDirectoryPath() {
|
||||
String expectedName = Environment.getExternalStorageDirectory()
|
||||
+ File.separator
|
||||
+ MyTracksConstants.SDCARD_TOP_DIR
|
||||
+ Constants.SDCARD_TOP_DIR
|
||||
+ File.separator
|
||||
+ "a"
|
||||
+ File.separator
|
||||
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2010 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# This script retrieves the value of a given named string from all indicated
|
||||
# strings.xml files. If invoked in a project directory (a directory with a
|
||||
# 'res' subdirectory), and if no strings.xml files are provided, the script
|
||||
# will automatically analyze res/values*/strings.xml
|
||||
|
||||
PROGNAME=$(basename "$0")
|
||||
|
||||
function usage() {
|
||||
echo "Usage: ${PROGNAME} string_name [file file..]" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
function die() {
|
||||
echo "${PROGNAME}: $@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ "$#" -lt 1 ]] ; then
|
||||
usage
|
||||
fi
|
||||
|
||||
name=$1
|
||||
shift
|
||||
|
||||
files=
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
if [[ -d res ]] ; then
|
||||
files=res/values*/strings.xml
|
||||
else
|
||||
die "invoked outside of project root with no file arguments"
|
||||
fi
|
||||
else
|
||||
files="$@"
|
||||
fi
|
||||
|
||||
for file in $files ; do
|
||||
echo === $file
|
||||
xmllint --xpath /resources/string[@name=\"$name\"] $file
|
||||
echo
|
||||
done
|
||||
Reference in New Issue
Block a user