diff --git a/MyTracks/res/layout/about.xml b/MyTracks/res/layout/about.xml
index e3fe3cfb8..51f432b90 100644
--- a/MyTracks/res/layout/about.xml
+++ b/MyTracks/res/layout/about.xml
@@ -95,8 +95,9 @@ limitations under the License.
android:textSize="20sp" />
diff --git a/MyTracks/res/menu/main.xml b/MyTracks/res/menu/main.xml
new file mode 100644
index 000000000..23053e2d5
--- /dev/null
+++ b/MyTracks/res/menu/main.xml
@@ -0,0 +1,29 @@
+
+
diff --git a/MyTracks/res/values/arrays.xml b/MyTracks/res/values/arrays.xml
index d1be00be5..78075af5f 100644
--- a/MyTracks/res/values/arrays.xml
+++ b/MyTracks/res/values/arrays.xml
@@ -370,5 +370,6 @@ limitations under the License.
- GPX
- KML
- CSV
+ - TCX
diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml
new file mode 100644
index 000000000..d982f7dd0
--- /dev/null
+++ b/MyTracks/res/values/keys.xml
@@ -0,0 +1,42 @@
+
+
+
+
+ announcementFrequency
+ bluetoothDevice
+ bluetoothPairing
+ bluetoothSensor
+ defaultMapPublic
+ maxRecordingDistance
+ metricUnits
+ minRecordingDistance
+ minRecordingInterval
+ minRequiredAccuracy
+ modularStatsDisplay
+ pickExistingMap
+ recordingTrack
+ reportSpeed
+ selectedTrack
+ sendStatsAndPoints
+ sendToDocs
+ sendToMyMaps
+ sensorId
+ sensorType
+ shareUrlOnly
+ signalSamplingFrequency
+ splitFrequency
+
\ No newline at end of file
diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml
index 80a182bf6..c8c68c17c 100644
--- a/MyTracks/res/values/strings.xml
+++ b/MyTracks/res/values/strings.xml
@@ -122,6 +122,7 @@ limitations under the License.
Save a GPX file
Save a KML file
Save a CSV file
+ Save a TCX file
Send to Google My Maps
Delete all tracks
@@ -135,6 +136,7 @@ limitations under the License.
A GPX file
A KML file
A CSV file
+ A TCX file
Clear map
@@ -204,6 +206,21 @@ limitations under the License.
Maximum time or distance after which a new split marker will be inserted
Pace
+ Only supported in Android 2.0 or above
+ Sensor Type
+ The type of sensor to connect to.
+
+ Sensor Id
+ The Id sent to sensors.
+ The Id must be an integer value.
+
+ Bluetooth sensor
+ The bluetooth sensor to connect to.
+
+ Modular Stats Display
+ The stats screen is split in various modes.
+ Display all stats on one screen
+
GPS Satellites
@@ -291,6 +308,7 @@ limitations under the License.
minutes
second
seconds
+ ms
m
@@ -310,6 +328,12 @@ limitations under the License.
min/mi
per mile
+
+ W
+
+ rpm
+ bpm
+
Moving Time
Total Time
@@ -320,6 +344,10 @@ limitations under the License.
Statistics
Total Distance
Distance
+ Power
+ Cadence
+ Heart Rate
+ Max Heart Rate
-
Waiting...
@@ -337,7 +365,6 @@ limitations under the License.
Support:
- 1.0.14
mytracks@googlegroups.com
mytracks.appspot.com
Copyright 2009 Google Inc.
@@ -403,4 +430,29 @@ limitations under the License.
GSM Strength: %1$d
CDMA Strength: %1$d dBm
EVDO Strength: %1$d dBm
+
+
+ Bluetooth
+ Bluetooth options
+ Device pairing
+ Open Android\'s bluetooth settings to pair a device
+ bluetoothSensorsEnabled
+ Sensor Options
+
+
+ NONE
+ ANT
+ SRM
+ ATHLOSOFT
+
+
+ Connected to %s
+ Bluetooth sensor connecting ...
+ Bluetooth sensor not connected
+
+
+ Sensor Data Time
+ Power meter enabled
+ Heart rate monitor enabled
+
diff --git a/MyTracks/res/xml/preferences.xml b/MyTracks/res/xml/preferences.xml
index 77f1abcf7..c39a33b02 100644
--- a/MyTracks/res/xml/preferences.xml
+++ b/MyTracks/res/xml/preferences.xml
@@ -18,26 +18,26 @@ limitations under the License.
xmlns:android="http://schemas.android.com/apk/res/android">
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/MyTracks/src/com/google/android/apps/mymaps/VersionChecker.java b/MyTracks/src/com/google/android/apps/mymaps/VersionChecker.java
index 6a47a7879..cfc1f8a3d 100644
--- a/MyTracks/src/com/google/android/apps/mymaps/VersionChecker.java
+++ b/MyTracks/src/com/google/android/apps/mymaps/VersionChecker.java
@@ -29,6 +29,9 @@ import android.app.Dialog;
import android.app.TabActivity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
@@ -80,7 +83,17 @@ public class VersionChecker {
final boolean newVersion; // Returned new version available
final boolean newVersionRecommended; // Returned new version recommended
final boolean newVersionRequired; // Returned new version required
- String currentVersion = parentActivity.getString(R.string.version);
+ String currentVersion = "";
+ try {
+ PackageInfo pi =
+ parentActivity.getPackageManager().getPackageInfo(
+ "com.google.android.maps.mytracks",
+ PackageManager.GET_META_DATA);
+ currentVersion = pi.versionName;
+ } catch (NameNotFoundException e) {
+ Log.w(MyTracksConstants.TAG, "Failed to get version info.", e);
+ return;
+ }
GDataParser parser = client.getParserForFeed(
Entry.class,
diff --git a/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java b/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java
index f31539bee..14e3edc6b 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java
@@ -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
@@ -49,7 +49,7 @@ import java.util.ArrayList;
/**
* An activity that displays a chart from the track point provider.
- *
+ *
* @author Sandor Dornbush
*/
public class ChartActivity extends Activity implements
@@ -204,23 +204,27 @@ public class ChartActivity extends Activity implements
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key != null) {
- if (key.equals(MyTracksSettings.SELECTED_TRACK)) {
+ if (key.equals(getString(R.string.selected_track_key))) {
selectedTrackId =
- sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
+ sharedPreferences.getLong(getString(R.string.selected_track_key),
+ -1);
readProfileAsync();
- } else if (key.equals(MyTracksSettings.METRIC_UNITS)) {
+ } else if (key.equals(getString(R.string.metric_units_key))) {
metricUnits =
- sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ sharedPreferences.getBoolean(getString(R.string.metric_units_key),
+ true);
cv.setMetricUnits(metricUnits);
readProfileAsync();
- } else if (key.equals(MyTracksSettings.REPORT_SPEED)) {
+ } else if (key.equals(getString(R.string.report_speed_key))) {
reportSpeed =
- sharedPreferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
+ sharedPreferences.getBoolean(getString(R.string.report_speed_key),
+ true);
cv.setReportSpeed(reportSpeed, this);
readProfileAsync();
- } else if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
+ } else if (key.equals(getString(R.string.recording_track_key))) {
recordingTrackId =
- sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ sharedPreferences.getLong(getString(R.string.recording_track_key),
+ -1);
runOnUiThread(updateChart);
}
}
@@ -246,12 +250,14 @@ public class ChartActivity extends Activity implements
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
selectedTrackId =
- preferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
+ preferences.getLong(getString(R.string.selected_track_key), -1);
recordingTrackId =
- preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
- metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ preferences.getLong(getString(R.string.recording_track_key), -1);
+ metricUnits = preferences.getBoolean(getString(R.string.metric_units_key),
+ true);
cv.setMetricUnits(metricUnits);
- reportSpeed = preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
+ reportSpeed = preferences.getBoolean(getString(R.string.report_speed_key),
+ true);
cv.setReportSpeed(reportSpeed, this);
preferences.registerOnSharedPreferenceChangeListener(this);
}
@@ -450,7 +456,7 @@ public class ChartActivity extends Activity implements
* data[0] = the time or distance
* data[1] = the elevation
* data[2] = the speed
- *
+ *
* @param location a location
* @return the data point
*/
diff --git a/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java b/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java
index 07311fca2..cb582f089 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java
@@ -109,7 +109,8 @@ public class ExportAllTracks {
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
long recordingTrackId = -1;
if (prefs != null) {
- recordingTrackId = prefs.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ recordingTrackId =
+ prefs.getLong(context.getString(R.string.recording_track_key), -1);
}
if (recordingTrackId != -1) {
acquireWakeLock();
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MenuManager.java b/MyTracks/src/com/google/android/apps/mytracks/MenuManager.java
new file mode 100644
index 000000000..e09011b86
--- /dev/null
+++ b/MyTracks/src/com/google/android/apps/mytracks/MenuManager.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+package com.google.android.apps.mytracks;
+
+import com.google.android.maps.mytracks.R;
+
+import android.content.Intent;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * Manage the application menus.
+ *
+ * @author Sandor Dornbush
+ */
+class MenuManager {
+
+ private MyTracks activity;
+
+ public MenuManager(MyTracks activity) {
+ this.activity = activity;
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu) {
+ activity.getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ public void onPrepareOptionsMenu(Menu menu, boolean hasRecorded,
+ boolean isRecording, boolean hasSelectedTrack) {
+ menu.findItem(R.id.menu_list_tracks).setEnabled(hasRecorded);
+ menu.findItem(R.id.menu_list_markers)
+ .setEnabled(hasRecorded && hasSelectedTrack);
+ MenuItem startRecording = menu.findItem(R.id.menu_start_recording);
+ startRecording.setEnabled(!isRecording);
+ startRecording.setVisible(!isRecording);
+ MenuItem stopRecording = menu.findItem(R.id.menu_stop_recording);
+ stopRecording.setEnabled(isRecording);
+ stopRecording.setVisible(isRecording);
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_start_recording: {
+ activity.startRecording();
+ return true;
+ }
+ case R.id.menu_stop_recording: {
+ activity.stopRecording();
+ return true;
+ }
+ case R.id.menu_list_tracks: {
+ Intent startIntent = new Intent(activity, MyTracksList.class);
+ activity.startActivityForResult(startIntent, MyTracksConstants.SHOW_TRACK);
+ return true;
+ }
+ case R.id.menu_list_markers: {
+ Intent startIntent = new Intent(activity, MyTracksWaypointsList.class);
+ startIntent.putExtra("trackid", activity.getSelectedTrack());
+ activity.startActivityForResult(startIntent, MyTracksConstants.SHOW_WAYPOINT);
+ return true;
+ }
+ case R.id.menu_settings: {
+ Intent startIntent = new Intent(activity, MyTracksSettings.class);
+ activity.startActivity(startIntent);
+ return true;
+ }
+ case R.id.menu_help: {
+ Intent startIntent = new Intent(activity, WelcomeActivity.class);
+ activity.startActivity(startIntent);
+ return true;
+ }
+ case MyTracksConstants.MENU_CLEAR_MAP: {
+ activity.setSelectedTrack(-1);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
index 7aae5c7f3..27fda84eb 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
@@ -134,15 +134,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
private ChartSettingsDialog chartSettingsDialog;
/*
- * Menu items:
+ * Menu manager.
*/
-
- private MenuItem startRecording;
- private MenuItem stopRecording;
- private MenuItem listTracks;
- private MenuItem listMarkers;
- private MenuItem settings;
- private MenuItem help;
+ private MenuManager menuManager;
/*
* Information on upload success to MyMaps/Docs.
@@ -283,6 +277,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
super.onCreate(savedInstanceState);
instance = this;
providerUtils = MyTracksProviderUtils.Factory.get(this);
+ menuManager = new MenuManager(this);
// The volume we want to control is the Text-To-Speech volume
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
@@ -321,8 +316,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
SharedPreferences prefs =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (prefs != null) {
- selectedTrackId = prefs.getLong(MyTracksSettings.SELECTED_TRACK, -1);
- recordingTrackId = prefs.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ selectedTrackId =
+ prefs.getLong(getString(R.string.selected_track_key), -1);
+ recordingTrackId =
+ prefs.getLong(getString(R.string.recording_track_key), -1);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@@ -416,81 +413,21 @@ public class MyTracks extends TabActivity implements OnTouchListener,
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
- startRecording = menu.add(0, MyTracksConstants.MENU_START_RECORDING, 0,
- R.string.start_recording);
- startRecording.setIcon(R.drawable.menu_record);
- stopRecording = menu.add(0, MyTracksConstants.MENU_STOP_RECORDING, 0,
- R.string.stop_recording);
- stopRecording.setIcon(R.drawable.menu_stop);
- listTracks = menu.add(0, MyTracksConstants.MENU_LIST_TRACKS, 0,
- R.string.list_tracks);
- listTracks.setIcon(R.drawable.menu_list_tracks);
- listMarkers = menu.add(0, MyTracksConstants.MENU_LIST_MARKERS, 0,
- R.string.list_markers);
- listMarkers.setIcon(R.drawable.menu_marker);
- settings = menu.add(0, MyTracksConstants.MENU_SETTINGS, 10001,
- R.string.settings);
- settings.setIcon(android.R.drawable.ic_menu_preferences);
- help = menu.add(0, MyTracksConstants.MENU_HELP, 10002, R.string.help);
- help.setIcon(android.R.drawable.ic_menu_info_details);
- return true;
+ return menuManager.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
- boolean hasRecorded = providerUtils.getLastTrack() != null;
- boolean isRecording = isRecording();
- listTracks = menu.findItem(MyTracksConstants.MENU_LIST_TRACKS);
- listTracks.setEnabled(hasRecorded);
- listMarkers = menu.findItem(MyTracksConstants.MENU_LIST_MARKERS);
- listMarkers.setEnabled(hasRecorded && selectedTrackId >= 0);
- startRecording = menu.findItem(MyTracksConstants.MENU_START_RECORDING);
- startRecording.setEnabled(!isRecording);
- startRecording.setVisible(!isRecording);
- stopRecording = menu.findItem(MyTracksConstants.MENU_STOP_RECORDING);
- stopRecording.setEnabled(isRecording);
- stopRecording.setVisible(isRecording);
+ menuManager.onPrepareOptionsMenu(menu, providerUtils.getLastTrack() != null,
+ isRecording(), selectedTrackId >= 0);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case MyTracksConstants.MENU_START_RECORDING: {
- startRecording();
- return true;
- }
- case MyTracksConstants.MENU_STOP_RECORDING: {
- stopRecording();
- return true;
- }
- case MyTracksConstants.MENU_LIST_TRACKS: {
- Intent startIntent = new Intent(this, MyTracksList.class);
- startActivityForResult(startIntent, MyTracksConstants.SHOW_TRACK);
- return true;
- }
- case MyTracksConstants.MENU_LIST_MARKERS: {
- Intent startIntent = new Intent(this, MyTracksWaypointsList.class);
- startIntent.putExtra("trackid", selectedTrackId);
- startActivityForResult(startIntent, MyTracksConstants.SHOW_WAYPOINT);
- return true;
- }
- case MyTracksConstants.MENU_SETTINGS: {
- Intent startIntent = new Intent(this, MyTracksSettings.class);
- startActivity(startIntent);
- return true;
- }
- case MyTracksConstants.MENU_HELP: {
- Intent startIntent = new Intent(this, WelcomeActivity.class);
- startActivity(startIntent);
- return true;
- }
- case MyTracksConstants.MENU_CLEAR_MAP: {
- setSelectedTrack(-1);
- return true;
- }
- }
- return super.onOptionsItemSelected(item);
+ return (menuManager.onOptionsItemSelected(item)
+ ? true
+ : super.onOptionsItemSelected(item));
}
/*
@@ -787,8 +724,11 @@ public class MyTracks extends TabActivity implements OnTouchListener,
case MyTracksConstants.SAVE_KML_FILE:
if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
//$FALL-THROUGH$
- case MyTracksConstants.SAVE_CSV_FILE: {
+ case MyTracksConstants.SAVE_CSV_FILE:
if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
+ //$FALL-THROUGH$
+ case MyTracksConstants.SAVE_TCX_FILE:
+ if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
if (results != null && resultCode == Activity.RESULT_OK) {
final long trackId = results.getLongExtra("trackid", selectedTrackId);
@@ -797,7 +737,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
}
break;
- }
case MyTracksConstants.SHARE_LINK: {
Track selectedTrack = providerUtils.getTrack(selectedTrackId);
if (selectedTrack != null) {
@@ -811,15 +750,21 @@ public class MyTracks extends TabActivity implements OnTouchListener,
break;
}
case MyTracksConstants.SHARE_GPX_FILE:
- case MyTracksConstants.SHARE_KML_FILE: {
- if (results != null && resultCode == RESULT_OK) {
- long trackId = results.getLongExtra("trackid", selectedTrackId);
+ if (exportFormat == null) { exportFormat = TrackFileFormat.GPX; }
+ //$FALL-THROUGH$
+ case MyTracksConstants.SHARE_KML_FILE:
+ if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
+ //$FALL-THROUGH$
+ case MyTracksConstants.SHARE_CSV_FILE:
+ if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
+ //$FALL-THROUGH$
+ case MyTracksConstants.SHARE_TCX_FILE: {
+ if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
+
+ if (results != null && resultCode == Activity.RESULT_OK) {
+ final long trackId = results.getLongExtra("trackid", selectedTrackId);
if (trackId >= 0) {
- TrackFileFormat format =
- (requestCode == MyTracksConstants.SHARE_GPX_FILE)
- ? TrackFileFormat.GPX
- : TrackFileFormat.KML;
- sendTrack(trackId, format);
+ sendTrack(trackId, exportFormat);
}
}
break;
@@ -862,9 +807,9 @@ public class MyTracks extends TabActivity implements OnTouchListener,
+ "to shared preferences: ", e);
}
}
- if (key != null && key.equals(MyTracksSettings.SELECTED_TRACK)) {
+ if (key != null && key.equals(getString(R.string.selected_track_key))) {
selectedTrackId =
- sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
+ sharedPreferences.getLong(getString(R.string.selected_track_key), -1);
}
}
@@ -1069,7 +1014,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
boolean shareUrlOnly = true;
if (prefs != null) {
- shareUrlOnly = prefs.getBoolean(MyTracksSettings.SHARE_URL_ONLY, false);
+ shareUrlOnly =
+ prefs.getBoolean(getString(R.string.share_url_only_key), false);
}
String url = MyMapsConstants.MAPSHOP_BASE_URL + "?msa=0&msid=" + mapId;
@@ -1292,7 +1238,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
* Starts the track recording service (if not already running) and binds to
* it. Starts recording a new track.
*/
- private void startRecording() {
+ public void startRecording() {
if (trackRecordingService == null) {
startNewTrackRequested = true;
Intent startIntent = new Intent(this, TrackRecordingService.class);
@@ -1318,7 +1264,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
* Stops the track recording service and unbinds from it. Will display a toast
* "Stopped recording" and pop up the Track Details activity.
*/
- private void stopRecording() {
+ public void stopRecording() {
if (trackRecordingService != null) {
try {
trackRecordingService.endCurrentTrack();
@@ -1377,18 +1323,22 @@ public class MyTracks extends TabActivity implements OnTouchListener,
*
* @param trackId the id of the track
*/
- private void setSelectedTrack(final long trackId) {
+ public void setSelectedTrack(final long trackId) {
runOnUiThread(new Runnable() {
public void run() {
SharedPreferences prefs =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();
- editor.putLong(MyTracksSettings.SELECTED_TRACK, trackId);
+ editor.putLong(getString(R.string.selected_track_key), trackId);
editor.commit();
}
});
}
+ protected long getSelectedTrack() {
+ return selectedTrackId;
+ }
+
/**
* Writes the recording track id to the shared preferences.
* Executed on the UI thread.
@@ -1401,7 +1351,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
SharedPreferences prefs =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();
- editor.putLong(MyTracksSettings.RECORDING_TRACK, trackId);
+ editor.putLong(getString(R.string.recording_track_key), trackId);
editor.commit();
}
});
@@ -1419,8 +1369,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (prefs != null) {
SharedPreferences.Editor editor = prefs.edit();
- editor.putLong(MyTracksSettings.SELECTED_TRACK, theSelectedTrackId);
- editor.putLong(MyTracksSettings.RECORDING_TRACK, theRecordingTrackId);
+ editor.putLong(getString(R.string.selected_track_key), theSelectedTrackId);
+ editor.putLong(getString(R.string.recording_track_key), theRecordingTrackId);
editor.commit();
}
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java
index 226bd2ddb..be01ace79 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksConstants.java
@@ -54,29 +54,25 @@ public abstract class MyTracksConstants {
public static final int SHARE_GPX_FILE = 15;
public static final int SHARE_KML_FILE = 16;
public static final int SHARE_CSV_FILE = 17;
- public static final int EDIT_DETAILS = 18;
- public static final int SAVE_GPX_FILE = 19;
- public static final int SAVE_KML_FILE = 20;
- public static final int SAVE_CSV_FILE = 21;
- public static final int CLEAR_MAP = 22;
- public static final int SHOW_WAYPOINT = 23;
- public static final int EDIT_WAYPOINT = 24;
- public static final int WELCOME = 25;
+ public static final int SHARE_TCX_FILE = 18;
+ public static final int EDIT_DETAILS = 19;
+ public static final int SAVE_GPX_FILE = 20;
+ public static final int SAVE_KML_FILE = 21;
+ public static final int SAVE_CSV_FILE = 22;
+ public static final int SAVE_TCX_FILE = 23;
+ public static final int CLEAR_MAP = 24;
+ public static final int SHOW_WAYPOINT = 25;
+ public static final int EDIT_WAYPOINT = 26;
+ public static final int WELCOME = 27;
/*
* Menu ids:
*/
- public static final int MENU_START_RECORDING = 1;
- public static final int MENU_STOP_RECORDING = 2;
- public static final int MENU_LIST_TRACKS = 3;
- public static final int MENU_LIST_MARKERS = 4;
- public static final int MENU_SETTINGS = 5;
- public static final int MENU_MY_LOCATION = 6;
- public static final int MENU_TOGGLE_LAYERS = 7;
- public static final int MENU_CHART_SETTINGS = 8;
- public static final int MENU_HELP = 9;
- public static final int MENU_CURRENT_SEGMENT = 10;
+ public static final int MENU_MY_LOCATION = 1;
+ public static final int MENU_TOGGLE_LAYERS = 2;
+ public static final int MENU_CHART_SETTINGS = 3;
+ public static final int MENU_CURRENT_SEGMENT = 4;
/*
* Context menu ids:
@@ -91,11 +87,13 @@ public abstract class MyTracksConstants {
public static final int MENU_SHARE_GPX_FILE = 201;
public static final int MENU_SHARE_KML_FILE = 202;
public static final int MENU_SHARE_CSV_FILE = 203;
- public static final int MENU_WRITE_TO_SD_CARD = 204;
- public static final int MENU_SAVE_GPX_FILE = 205;
- public static final int MENU_SAVE_KML_FILE = 206;
- public static final int MENU_SAVE_CSV_FILE = 207;
- public static final int MENU_CLEAR_MAP = 208;
+ public static final int MENU_SHARE_TCX_FILE = 204;
+ public static final int MENU_WRITE_TO_SD_CARD = 205;
+ public static final int MENU_SAVE_GPX_FILE = 206;
+ public static final int MENU_SAVE_KML_FILE = 207;
+ public static final int MENU_SAVE_CSV_FILE = 208;
+ public static final int MENU_SAVE_TCX_FILE = 209;
+ public static final int MENU_CLEAR_MAP = 210;
/**
* The number of distance readings to smooth to get a stable signal.
@@ -123,6 +121,12 @@ public abstract class MyTracksConstants {
*/
public static final int MAX_DISPLAYED_TRACK_POINTS = 10000;
+ /**
+ * Target number of track points displayed by the map overlay.
+ * We may display more than this number of points.
+ */
+ public static final int TARGET_DISPLAYED_TRACK_POINTS = 5000;
+
/**
* Maximum number of track points ever loaded at once from the provider into
* memory.
@@ -179,12 +183,16 @@ public abstract class MyTracksConstants {
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;
default:
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java
index 4762c840e..8a5f255f1 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksDeleteAllTracks.java
@@ -62,7 +62,7 @@ public class MyTracksDeleteAllTracks extends Handler {
SharedPreferences prefs =
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();
- editor.putLong(MyTracksSettings.SELECTED_TRACK, -1);
+ editor.putLong(context.getString(R.string.selected_track_key), -1);
editor.commit();
if (done != null) {
Handler h = new Handler();
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java
index c2be23dce..f88421868 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksList.java
@@ -90,6 +90,8 @@ public class MyTracksList extends ListActivity
R.string.tracklist_share_kml_file);
share.add(0, MyTracksConstants.MENU_SHARE_CSV_FILE, 0,
R.string.tracklist_share_csv_file);
+ share.add(0, MyTracksConstants.MENU_SHARE_TCX_FILE, 0,
+ R.string.tracklist_share_tcx_file);
SubMenu save = menu.addSubMenu(0,
MyTracksConstants.MENU_WRITE_TO_SD_CARD, 0,
R.string.tracklist_write_to_sd);
@@ -99,6 +101,8 @@ public class MyTracksList extends ListActivity
R.string.tracklist_save_as_kml);
save.add(0, MyTracksConstants.MENU_SAVE_CSV_FILE, 0,
R.string.tracklist_save_as_csv);
+ save.add(0, MyTracksConstants.MENU_SAVE_TCX_FILE, 0,
+ R.string.tracklist_save_as_tcx);
menu.add(0, MyTracksConstants.MENU_DELETE, 0,
R.string.tracklist_delete_track);
}
@@ -111,14 +115,16 @@ public class MyTracksList extends ListActivity
if (key == null) {
return;
}
- if (key.equals(MyTracksSettings.METRIC_UNITS)) {
- metricUnits = sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ if (key.equals(getString(R.string.metric_units_key))) {
+ metricUnits = sharedPreferences.getBoolean(
+ getString(R.string.metric_units_key), true);
if (tracksCursor != null && !tracksCursor.isClosed()) {
tracksCursor.requery();
}
}
- if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
- recordingTrackId = sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ if (key.equals(getString(R.string.recording_track_key))) {
+ recordingTrackId = sharedPreferences.getLong(
+ getString(R.string.recording_track_key), -1);
}
}
@@ -193,9 +199,10 @@ public class MyTracksList extends ListActivity
SharedPreferences preferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
preferences.registerOnSharedPreferenceChangeListener(this);
- metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ metricUnits =
+ preferences.getBoolean(getString(R.string.metric_units_key), true);
recordingTrackId =
- preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ preferences.getLong(getString(R.string.recording_track_key), -1);
tracksCursor = getContentResolver().query(
TracksColumns.CONTENT_URI, null, null, null, "_id DESC");
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java
index c7b73f7d7..c60e9888e 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java
@@ -136,6 +136,11 @@ public class MyTracksMap extends MapActivity
private Handler updateTrackHandler;
private MyTracksProviderUtils providerUtils;
+
+ /**
+ * This value is used to decide how many points to display.
+ */
+ private int samplingFrequency = 1;
/**
* A runnable that updates the track from the provider (looking for points
@@ -147,35 +152,7 @@ public class MyTracksMap extends MapActivity
if (selectedTrack == null) {
return;
}
- Cursor cursor = null;
- try {
- cursor = providerUtils.getLocationsCursor(
- recordingTrackId,
- lastSeenLocationId + 1,
- MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS
- - selectedTrack.getLocations().size(),
- true);
- if (cursor != null) {
- if (cursor.moveToLast()) {
- final int idColumnIdx =
- cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
- do {
- lastSeenLocationId = cursor.getLong(idColumnIdx);
- Location location = providerUtils.createLocation(cursor);
- if (location != null) {
- selectedTrack.addLocation(location);
- }
- } while (cursor.moveToPrevious());
- }
- }
- } catch (RuntimeException e) {
- Log.w(MyTracksConstants.TAG, "Caught an unexpected exception: ", e);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- mapView.postInvalidate();
- }
+ readAllNewTrackPoints();
}
};
@@ -188,9 +165,9 @@ public class MyTracksMap extends MapActivity
if (selectedTrack == null) {
return;
}
- lastSeenLocationId = providerUtils.getTrackPoints(selectedTrack,
- MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS);
- mapView.postInvalidate();
+ mapOverlay.clearPoints();
+ lastSeenLocationId = selectedTrack.getStartId();
+ readAllNewTrackPoints();
}
};
@@ -380,12 +357,12 @@ public class MyTracksMap extends MapActivity
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
minRequiredAccuracy = preferences.getInt(
- MyTracksSettings.MIN_REQUIRED_ACCURACY,
+ getString(R.string.min_required_accuracy_key),
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY);
recordingTrackId =
- preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ preferences.getLong(getString(R.string.recording_track_key), -1);
long selectedTrackId =
- preferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
+ preferences.getLong(getString(R.string.selected_track_key), -1);
if (selectedTrackId >= 0) {
setSelectedTrack(selectedTrackId);
}
@@ -783,6 +760,8 @@ public class MyTracksMap extends MapActivity
R.string.tracklist_share_kml_file);
share.add(0, MyTracksConstants.MENU_SHARE_CSV_FILE, 0,
R.string.tracklist_share_csv_file);
+ share.add(0, MyTracksConstants.MENU_SHARE_TCX_FILE, 0,
+ R.string.tracklist_share_tcx_file);
SubMenu save = menu.addSubMenu(0,
MyTracksConstants.MENU_WRITE_TO_SD_CARD, 0,
R.string.tracklist_write_to_sd);
@@ -792,6 +771,8 @@ public class MyTracksMap extends MapActivity
R.string.tracklist_save_as_kml);
save.add(0, MyTracksConstants.MENU_SAVE_CSV_FILE, 0,
R.string.tracklist_save_as_csv);
+ save.add(0, MyTracksConstants.MENU_SAVE_TCX_FILE, 0,
+ R.string.tracklist_save_as_tcx);
menu.add(0, MyTracksConstants.MENU_CLEAR_MAP, 0,
R.string.tracklist_clear_map);
menu.add(0, MyTracksConstants.MENU_DELETE, 0,
@@ -888,17 +869,19 @@ public class MyTracksMap extends MapActivity
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key != null) {
- if (key.equals(MyTracksSettings.MIN_REQUIRED_ACCURACY)) {
+ if (key.equals(getString(R.string.min_required_accuracy_key))) {
minRequiredAccuracy = sharedPreferences.getInt(
- MyTracksSettings.MIN_REQUIRED_ACCURACY,
+ getString(R.string.min_required_accuracy_key),
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY);
- } else if (key.equals(MyTracksSettings.SELECTED_TRACK)) {
+ } else if (key.equals(getString(R.string.selected_track_key))) {
long selectedTrackId =
- sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
+ sharedPreferences.getLong(getString(R.string.selected_track_key),
+ -1);
setSelectedTrack(selectedTrackId);
- } else if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
+ } else if (key.equals(getString(R.string.recording_track_key))) {
recordingTrackId =
- sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ sharedPreferences.getLong(getString(R.string.recording_track_key),
+ -1);
if (selectedTrack != null) {
mapOverlay.setShowEndMarker(
selectedTrack.getId() != recordingTrackId);
@@ -977,4 +960,63 @@ public class MyTracksMap extends MapActivity
public void onAccuracyChanged(Sensor s, int accuracy) {
// do nothing
}
+
+ /**
+ * Set the sampling frequency from the total number of points in the track.
+ *
+ * @param track The track to read the total number of points from.
+ */
+ private void setSamplingFrequency(Track track) {
+ long totalLocations = track.getStopId() - track.getStartId();
+
+ // Limit the number of map points readings.
+ samplingFrequency =
+ (int) (1 +
+ totalLocations / MyTracksConstants.TARGET_DISPLAYED_TRACK_POINTS);
+ Log.i(MyTracksConstants.TAG, "Sampling locations: " + samplingFrequency);
+ }
+
+ private void readAllNewTrackPoints() {
+ Cursor cursor = null;
+ // Refetch the track to get the latest StopId
+ selectedTrack = providerUtils.getTrack(selectedTrack.getId());
+ long totalLocations = selectedTrack.getStopId() -
+ selectedTrack.getStartId();
+
+ setSamplingFrequency(selectedTrack);
+ int bufferSize = 1024;
+ int points = 0;
+ while (lastSeenLocationId < selectedTrack.getStopId()) {
+ cursor = providerUtils.getLocationsCursor(
+ selectedTrack.getId(), lastSeenLocationId, bufferSize, false);
+ if (cursor != null && cursor.moveToFirst()) {
+ final int idColumnIdx = cursor.getColumnIndexOrThrow(
+ TrackPointsColumns._ID);
+ while (cursor.moveToNext()) {
+ points++;
+ Location location = providerUtils.createLocation(cursor);
+ lastSeenLocationId = cursor.getLong(idColumnIdx);
+ // Include a point if it fits one of the following criteria:
+ // - Has the mod for the sampling frequency.
+ // - Is the first point.
+ // - Is the last point and we are not recording this track.
+ if (!MyTracksUtils.isValidLocation(location) ||
+ points % samplingFrequency == 0 ||
+ points == 0 ||
+ (recordingTrackId != selectedTrack.getId() &&
+ points == (totalLocations - 1))) {
+ mapOverlay.addLocation(location);
+ }
+ }
+ } else {
+ lastSeenLocationId += bufferSize;
+ }
+ cursor.close();
+ cursor = null;
+ }
+ if (cursor != null) {
+ cursor.close();
+ }
+ mapView.postInvalidate();
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java
index d24d45f7f..8441dabc7 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksOverlay.java
@@ -1,12 +1,12 @@
/*
* Copyright 2008 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
@@ -55,6 +55,7 @@ public class MyTracksOverlay extends Overlay {
private final Paint errorCirclePaint;
private final Context context;
private final ArrayList waypoints = new ArrayList();
+ private final ArrayList points = new ArrayList(1024);
private Track selectedTrack;
private int lastHeading = 0;
@@ -128,6 +129,17 @@ public class MyTracksOverlay extends Overlay {
return selectedTrack;
}
+ /**
+ * Add a location to the map overlay.
+ *
+ * NOTE: this method takes ownership of this location and may change it.
+ *
+ * @param l the location to add
+ */
+ public void addLocation(Location l) {
+ points.add(l);
+ }
+
public void addWaypoint(Waypoint wpt) {
waypoints.add(wpt);
}
@@ -136,6 +148,10 @@ public class MyTracksOverlay extends Overlay {
waypoints.clear();
}
+ public void clearPoints() {
+ points.clear();
+ }
+
public void setShowEndMarker(boolean showEndMarker) {
this.showEndMarker = showEndMarker;
}
@@ -200,7 +216,6 @@ public class MyTracksOverlay extends Overlay {
if (track == null) {
return;
}
- ArrayList points = track.getLocations();
if (points.size() < 2) {
return;
}
@@ -210,7 +225,7 @@ public class MyTracksOverlay extends Overlay {
int h = mapView.getLatitudeSpan();
int cx = mapView.getMapCenter().getLongitudeE6();
int cy = mapView.getMapCenter().getLatitudeE6();
- Rect rect = new Rect(cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2);
+ Rect rect = new Rect(cx - w, cy - h, cx + w, cy + h);
Point pt = new Point();
GeoPoint geoPoint;
@@ -226,14 +241,6 @@ public class MyTracksOverlay extends Overlay {
int lastLocLon = (int) (points.get(0).getLongitude() * 1E6);
int lastLocLat = (int) (points.get(0).getLatitude() * 1E6);
- // Line decimation for dummies:
- // Skip di additional points, where di depends on zoom level:
- int di = 0;
- int dl = 17 - mapView.getZoomLevel();
- if (dl > 0) {
- di += (dl * dl);
- }
-
// Loop over track points:
path = new Path();
for (int i = 1; i < points.size(); i++) {
@@ -245,23 +252,6 @@ public class MyTracksOverlay extends Overlay {
locLon = (int) (loc.getLongitude() * 1E6);
locLat = (int) (loc.getLatitude() * 1E6);
- // Skip to every n-th point (depends on zoom level, see above):
- for (int j = 0; j < di && i < points.size() - 1; j++) {
- // TODO Check the thread synchronization.
- // There is no reason that points.get(i + 1) should be null but users
- // have reported it causing null pointer exceptions.
- if ((locLat > 90E6) ||
- (lastLocLat > 90E6) ||
- (points.get(i + 1) == null) ||
- (points.get(i + 1).getLatitude() > 90)) {
- break;
- }
- i++;
- loc = points.get(i);
- locLon = (int) (loc.getLongitude() * 1E6);
- locLat = (int) (loc.getLatitude() * 1E6);
- }
-
// Draw a line segment if it's inside the viewing window:
if (locLat < 90E6 && lastLocLat < 90E6) {
lastValidLocation = loc;
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java
index 776b5612f..8615ca83e 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksSettings.java
@@ -1,12 +1,12 @@
/*
* Copyright 2008 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
@@ -37,26 +37,6 @@ public class MyTracksSettings extends PreferenceActivity {
public static final String SETTINGS_NAME = "MyTracksSettings";
- public static final String ANNOUNCEMENT_FREQUENCY = "announcementFrequency";
- public static final String DEFAULT_MAP_PUBLIC = "defaultMapPublic";
- public static final String MAX_RECORDING_DISTANCE = "maxRecordingDistance";
- public static final String METRIC_UNITS = "metricUnits";
- public static final String MIN_RECORDING_DISTANCE = "minRecordingDistance";
- public static final String MIN_RECORDING_INTERVAL = "minRecordingInterval";
- public static final String MIN_REQUIRED_ACCURACY = "minRequiredAccuracy";
- public static final String PICK_EXISTING_MAP = "pickExistingMap";
- public static final String RECORDING_TRACK = "recordingTrack";
- public static final String REPORT_SPEED = "reportSpeed";
- public static final String SELECTED_TRACK = "selectedTrack";
- public static final String SEND_STATS_AND_POINTS = "sendStatsAndPoints";
- public static final String SEND_TO_DOCS = "sendToDocs";
- public static final String SEND_TO_MYMAPS = "sendToMyMaps";
- public static final String SHARE_URL_ONLY = "shareUrlOnly";
- public static final String SIGNAL_SAMPLING_FREQUENCY =
- "signalSamplingFrequency";
- public static final String SPLIT_FREQUENCY = "splitFrequency";
- public static final String WRITE_TO_SD_CARD = "writeToSdCard";
-
/*
* Default values - keep in sync with those in preferences.xml.
*/
@@ -96,7 +76,7 @@ public class MyTracksSettings extends PreferenceActivity {
// Hook up switching of displayed list entries between metric and imperial
// units
CheckBoxPreference metricUnitsPreference =
- (CheckBoxPreference) findPreference(METRIC_UNITS);
+ (CheckBoxPreference) findPreference(getString(R.string.metric_units_key));
metricUnitsPreference.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
@Override
@@ -112,7 +92,8 @@ public class MyTracksSettings extends PreferenceActivity {
// Disable TTS announcement preference if not available
if (!mTTSAvailable) {
IntegerListPreference announcementFrequency =
- (IntegerListPreference) findPreference(ANNOUNCEMENT_FREQUENCY);
+ (IntegerListPreference) findPreference(
+ getString(R.string.announcement_frequency_key));
announcementFrequency.setEnabled(false);
announcementFrequency.setValue("-1");
announcementFrequency.setSummary(
@@ -128,13 +109,17 @@ public class MyTracksSettings extends PreferenceActivity {
*/
private void updatePreferenceUnits(boolean isMetric) {
final ListPreference minRecordingDistance =
- (ListPreference) findPreference(MIN_RECORDING_DISTANCE);
+ (ListPreference) findPreference(
+ getString(R.string.min_recording_distance_key));
final ListPreference maxRecordingDistance =
- (ListPreference) findPreference(MAX_RECORDING_DISTANCE);
+ (ListPreference) findPreference(
+ getString(R.string.max_recording_distance_key));
final ListPreference minRequiredAccuracy =
- (ListPreference) findPreference(MIN_REQUIRED_ACCURACY);
+ (ListPreference) findPreference(
+ getString(R.string.min_required_accuracy_key));
final ListPreference splitFrequency =
- (ListPreference) findPreference(SPLIT_FREQUENCY);
+ (ListPreference) findPreference(
+ getString(R.string.split_frequency_key));
minRecordingDistance.setEntries(isMetric
? R.array.min_recording_distance_options
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java
index 33b911762..82604320b 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointDetails.java
@@ -66,11 +66,11 @@ public class MyTracksWaypointDetails extends Activity
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
boolean useMetric =
- preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ preferences.getBoolean(getString(R.string.metric_units_key), true);
utils.setMetricUnits(useMetric);
boolean displaySpeed =
- preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
+ preferences.getBoolean(getString(R.string.report_speed_key), true);
utils.setReportSpeed(displaySpeed);
utils.updateWaypointUnits();
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java
index 0e9d6040d..594c9fb98 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksWaypointsList.java
@@ -139,9 +139,9 @@ public class MyTracksWaypointsList extends ListActivity
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
recordingTrackId =
- preferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ preferences.getLong(getString(R.string.recording_track_key), -1);
selectedTrackId =
- preferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
+ preferences.getLong(getString(R.string.selected_track_key), -1);
}
boolean selectedRecording = selectedTrackId > 0
&& selectedTrackId == recordingTrackId;
diff --git a/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java b/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java
index 8e7847cb0..3f6ef6da9 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/SendToGoogleDialog.java
@@ -105,17 +105,25 @@ public class SendToGoogleDialog extends Dialog {
getContext().getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (prefs != null) {
sendToMyMapsCheckBox.setChecked(
- prefs.getBoolean(MyTracksSettings.SEND_TO_MYMAPS, true));
+ prefs.getBoolean(
+ getContext().getString(R.string.send_to_my_maps_key), true));
sendToDocsCheckBox.setChecked(
- prefs.getBoolean(MyTracksSettings.SEND_TO_DOCS, true));
+ prefs.getBoolean(
+ getContext().getString(R.string.send_to_docs_key), true));
pickMapRadioButton.setChecked(
- prefs.getBoolean(MyTracksSettings.PICK_EXISTING_MAP, false));
+ prefs.getBoolean(
+ getContext().getString(R.string.pick_existing_map_key), false));
createNewMapRadioButton.setChecked(
- !prefs.getBoolean(MyTracksSettings.PICK_EXISTING_MAP, false));
+ !prefs.getBoolean(
+ getContext().getString(R.string.pick_existing_map_key), false));
sendStatsAndPointsRadioButton.setChecked(
- prefs.getBoolean(MyTracksSettings.SEND_STATS_AND_POINTS, false));
+ prefs.getBoolean(
+ getContext().getString(R.string.send_stats_and_points_key),
+ false));
sendStatsRadioButton.setChecked(
- !prefs.getBoolean(MyTracksSettings.SEND_STATS_AND_POINTS, false));
+ !prefs.getBoolean(
+ getContext().getString(R.string.send_stats_and_points_key),
+ false));
}
}
@@ -127,13 +135,16 @@ public class SendToGoogleDialog extends Dialog {
Editor editor = prefs.edit();
if (editor != null) {
editor.putBoolean(
- MyTracksSettings.SEND_TO_MYMAPS, sendToMyMapsCheckBox.isChecked());
+ getContext().getString(R.string.send_to_my_maps_key),
+ sendToMyMapsCheckBox.isChecked());
editor.putBoolean(
- MyTracksSettings.SEND_TO_DOCS, sendToDocsCheckBox.isChecked());
+ getContext().getString(R.string.send_to_docs_key),
+ sendToDocsCheckBox.isChecked());
editor.putBoolean(
- MyTracksSettings.PICK_EXISTING_MAP, pickMapRadioButton.isChecked());
+ getContext().getString(R.string.pick_existing_map_key),
+ pickMapRadioButton.isChecked());
editor.putBoolean(
- MyTracksSettings.SEND_STATS_AND_POINTS,
+ getContext().getString(R.string.send_stats_and_points_key),
sendStatsAndPointsRadioButton.isChecked());
editor.commit();
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
index c16bb69fa..a0deb9c4a 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
@@ -1,12 +1,12 @@
/*
* Copyright 2008 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,6 +15,9 @@
*/
package com.google.android.apps.mytracks;
+import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
+import com.google.android.apps.mytracks.content.MyTracksProviderUtilsImpl;
+import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.maps.mytracks.R;
@@ -24,7 +27,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.ContentObserver;
-import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -48,23 +50,6 @@ import android.widget.Toast;
public class StatsActivity extends Activity
implements OnSharedPreferenceChangeListener, LocationListener {
- /**
- * Columns we need from the provider
- */
- private static final String[] PROJECTION_COLUMNS = {
- TracksColumns._ID,
- TracksColumns.STARTTIME,
- TracksColumns.TOTALTIME,
- TracksColumns.MOVINGTIME,
- TracksColumns.TOTALDISTANCE,
- TracksColumns.AVGSPEED,
- TracksColumns.AVGMOVINGSPEED,
- TracksColumns.MAXSPEED,
- TracksColumns.MINELEVATION,
- TracksColumns.MAXELEVATION,
- TracksColumns.ELEVATIONGAIN,
- TracksColumns.MINGRADE,
- TracksColumns.MAXGRADE };
private final StatsUtilities utils;
private UIUpdateThread thread;
@@ -109,6 +94,9 @@ public class StatsActivity extends Activity
*/
private boolean showCurrentSegment = false;
+ private final MyTracksProviderUtils providerUtils;
+ private Track track = null;
+
/**
* A runnable for posting to the UI thread. Will update the total time field.
*/
@@ -147,7 +135,8 @@ public class StatsActivity extends Activity
}
public StatsActivity() {
- this.utils = new StatsUtilities(this);
+ utils = new StatsUtilities(this);
+ providerUtils = new MyTracksProviderUtilsImpl(this);
}
/** Called when the activity is first created. */
@@ -176,20 +165,20 @@ public class StatsActivity extends Activity
SharedPreferences preferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
- selectedTrackId = preferences.getLong(MyTracksSettings.SELECTED_TRACK,
- -1);
- recordingTrackId = preferences.getLong(MyTracksSettings.RECORDING_TRACK,
- -1);
- metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS,
- true);
+ selectedTrackId = preferences.getLong(
+ getString(R.string.selected_track_key), -1);
+ recordingTrackId = preferences.getLong(
+ getString(R.string.recording_track_key), -1);
+ metricUnits = preferences.getBoolean(
+ getString(R.string.metric_units_key), true);
displaySpeed =
- preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
+ preferences.getBoolean(getString(R.string.report_speed_key), true);
checkLiveTrack();
restoreStats();
updateLocation(null);
preferences.registerOnSharedPreferenceChangeListener(this);
}
- locationManager =
+ locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
utils.setMetricUnits(metricUnits);
utils.setReportSpeed(displaySpeed);
@@ -231,27 +220,31 @@ public class StatsActivity extends Activity
Log.d(MyTracksConstants.TAG,
"StatsActivity: onSharedPreferences changed " + key);
if (key != null) {
- if (key.equals(MyTracksSettings.SELECTED_TRACK)) {
+ if (key.equals(getString(R.string.selected_track_key))) {
selectedTrackId =
- sharedPreferences.getLong(MyTracksSettings.SELECTED_TRACK, -1);
+ sharedPreferences.getLong(getString(R.string.selected_track_key),
+ -1);
checkLiveTrack();
restoreStats();
updateLocation(null);
- } else if (key.equals(MyTracksSettings.RECORDING_TRACK)) {
+ } else if (key.equals(getString(R.string.recording_track_key))) {
recordingTrackId =
- sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
+ sharedPreferences.getLong(getString(R.string.recording_track_key),
+ -1);
checkLiveTrack();
restoreStats();
updateLocation(null);
- } else if (key.equals(MyTracksSettings.METRIC_UNITS)) {
+ } else if (key.equals(getString(R.string.metric_units_key))) {
metricUnits =
- sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ sharedPreferences.getBoolean(
+ getString(R.string.metric_units_key), true);
utils.setMetricUnits(metricUnits);
utils.updateUnits();
restoreStats();
- } else if (key.equals(MyTracksSettings.REPORT_SPEED)) {
+ } else if (key.equals(getString(R.string.report_speed_key))) {
displaySpeed =
- sharedPreferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
+ sharedPreferences.getBoolean(getString(R.string.report_speed_key),
+ true);
utils.setReportSpeed(displaySpeed);
utils.updateUnits();
utils.setSpeedLabel(
@@ -359,60 +352,13 @@ public class StatsActivity extends Activity
return;
}
- Cursor cursor = null;
- try {
- cursor = getContentResolver().query(
- showCurrentSegment
- ? WaypointsColumns.CONTENT_URI
- : TracksColumns.CONTENT_URI,
- PROJECTION_COLUMNS,
- showCurrentSegment
- ? WaypointsColumns.TRACKID + "=" + selectedTrackId
- : "_id=" + selectedTrackId,
- null,
- "_id LIMIT 1");
-
- if (cursor != null && cursor.moveToFirst()) {
- final int idxStartTime =
- cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
- final int idxTotalTime =
- cursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
- final int idxMovingTime =
- cursor.getColumnIndexOrThrow(TracksColumns.MOVINGTIME);
- final int idxTotalDistance =
- cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
- final int idxAverageSpeed =
- cursor.getColumnIndexOrThrow(TracksColumns.AVGSPEED);
- final int idxAverageMovingSpeed =
- cursor.getColumnIndexOrThrow(TracksColumns.AVGMOVINGSPEED);
- final int idxMaxSpeed =
- cursor.getColumnIndexOrThrow(TracksColumns.MAXSPEED);
- final int idxMinElevation =
- cursor.getColumnIndexOrThrow(TracksColumns.MINELEVATION);
- final int idxMaxElevation =
- cursor.getColumnIndexOrThrow(TracksColumns.MAXELEVATION);
- final int idxElevationGain =
- cursor.getColumnIndexOrThrow(TracksColumns.ELEVATIONGAIN);
- final int idxMinGrade =
- cursor.getColumnIndexOrThrow(TracksColumns.MINGRADE);
- final int idxMaxGrade =
- cursor.getColumnIndexOrThrow(TracksColumns.MAXGRADE);
- startTime = cursor.getLong(idxStartTime);
- if (!selectedTrackIsRecording()) {
- utils.setTime(R.id.total_time_register, cursor.getLong(idxTotalTime));
- }
- utils.setAllStats(cursor.getLong(idxMovingTime),
- cursor.getFloat(idxTotalDistance), cursor.getFloat(idxAverageSpeed),
- cursor.getFloat(idxAverageMovingSpeed),
- cursor.getFloat(idxMaxSpeed), cursor.getFloat(idxMinElevation),
- cursor.getFloat(idxMaxElevation), cursor.getFloat(idxElevationGain),
- cursor.getFloat(idxMinGrade), cursor.getFloat(idxMaxGrade));
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
+ track = providerUtils.getTrack(selectedTrackId);
+ startTime = track.getStatistics().getStartTime();
+ if(!selectedTrackIsRecording()) {
+ utils.setTime(R.id.total_time_register,
+ track.getStatistics().getTotalTime());
}
+ utils.setAllStats(track.getStatistics());
}
/**
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
index 163e29b03..448b820d1 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
@@ -112,7 +112,9 @@ public class SendToDocs {
SharedPreferences preferences = activity.getSharedPreferences(
MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
- metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ metricUnits =
+ preferences.getBoolean(activity.getString(R.string.metric_units_key),
+ true);
} else {
metricUnits = true;
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java
index cfebe4539..a5a89564f 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java
@@ -264,7 +264,9 @@ public class SendToMyMaps {
MyTracksSettings.SETTINGS_NAME, 0);
boolean metricUnits = true;
if (preferences != null) {
- metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ metricUnits =
+ preferences.getBoolean(context.getString(R.string.metric_units_key),
+ true);
}
// For the progress monitor:
@@ -390,7 +392,7 @@ public class SendToMyMaps {
boolean mapPublic = true;
if (preferences != null) {
mapPublic = preferences.getBoolean(
- MyTracksSettings.DEFAULT_MAP_PUBLIC, true);
+ context.getString(R.string.default_map_public_key), true);
}
metaData.setSearchable(mapPublic);
Entry entry = MyMapsGDataConverter.getMapEntryForMetadata(metaData);
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/TcxTrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/TcxTrackWriter.java
new file mode 100644
index 000000000..0a8b912d6
--- /dev/null
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/TcxTrackWriter.java
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+package com.google.android.apps.mytracks.io;
+
+import com.google.android.apps.mytracks.content.Track;
+import com.google.android.apps.mytracks.content.Waypoint;
+import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
+
+import android.location.Location;
+import android.os.Build;
+import android.os.Environment;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Write out a a track in the Garmin training center database, tcx format.
+ * As defined by:
+ * http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2
+ *
+ * @author Sandor Dornbush
+ */
+public class TcxTrackWriter implements TrackFormatWriter {
+
+ private PrintWriter pw = null;
+ private Track track;
+
+ static final SimpleDateFormat TIMESTAMP_FORMAT =
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ {
+ TIMESTAMP_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+ public TcxTrackWriter() {
+ }
+
+ @Override
+ public void prepare(Track track, OutputStream out) {
+ this.track = track;
+ this.pw = new PrintWriter(out);
+
+ }
+
+ @Override
+ public void close() {
+ if (pw != null) {
+ pw.close();
+ pw = null;
+ }
+ }
+
+ @Override
+ public String getDefaultDirectory() {
+ return Environment.getExternalStorageDirectory()
+ + System.getProperty("file.separator") + getExtension();
+ }
+
+ @Override
+ public String getExtension() {
+ return TrackFileFormat.TCX.getExtension();
+ }
+
+ @Override
+ public void writeHeader() {
+ if (pw == null) {
+ return;
+ }
+ pw.println("");
+ pw.print("");
+ pw.println();
+ }
+
+ @Override
+ public void writeBeginTrack(Location firstPoint) {
+ if (pw == null) {
+ return;
+ }
+ pw.println(" ");
+ pw.print(" ");
+ pw.print(" ");
+ pw.print(TIMESTAMP_FORMAT.format(track.getStatistics().getStartTime()));
+ pw.println("");
+ pw.println(" ");
+ pw.print(" ");
+ pw.print(track.getStatistics().getTotalTime() / 1000);
+ pw.println("");
+ pw.print(" ");
+ pw.print(track.getStatistics().getTotalDistance());
+ pw.println("");
+ // TODO max speed etc.
+ // Calories are a required element just put in 0.
+ pw.print("0");
+ pw.println("Active");
+ pw.println("Manual)");
+ }
+
+ @Override
+ public void writeOpenSegment() {
+ if (pw != null) {
+ pw.println(" ");
+ }
+ }
+
+ @Override
+ public void writeEndTrack(Location lastPoint) {
+ if (pw == null) {
+ return;
+ }
+ pw.println(" ");
+ pw.print(" ");
+ pw.print("");
+ pw.print(Build.MODEL);
+ pw.print("");
+ pw.println(")");
+ pw.println(" ");
+ pw.println(" ");
+ }
+
+ @Override
+ public void writeFooter() {
+ if (pw == null) {
+ return;
+ }
+ pw.print(" ");
+ pw.print("My Tracks by Google");
+ pw.println("");
+ pw.println("");
+ }
+
+ @Override
+ public void writeWaypoint(Waypoint waypoint) {
+ // TODO Write out the waypoints somewhere.
+ }
+}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java b/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java
index 98e7c177b..bc3c15ddd 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriterFactory.java
@@ -49,6 +49,12 @@ public class TrackWriterFactory {
public TrackFormatWriter newFormatWriter(Context context) {
return new CsvTrackWriter();
}
+ },
+ TCX {
+ @Override
+ public TrackFormatWriter newFormatWriter(Context context) {
+ return new TcxTrackWriter();
+ }
};
/**
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java
new file mode 100644
index 000000000..5128ceca0
--- /dev/null
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+package com.google.android.apps.mytracks.services;
+
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import com.google.android.apps.mytracks.MyTracksConstants;
+import com.google.android.apps.mytracks.MyTracksSettings;
+import com.google.android.maps.mytracks.R;
+
+/**
+ * A class that manages reading the shared preferences for the service.
+ *
+ * @author Sandor Dornbush
+ */
+public class PreferenceManager {
+ private TrackRecordingService service;
+ private String announcement_frequency_key;
+ private String max_recording_distance_key;
+ private String metric_units_key;
+ private String min_recording_distance_key;
+ private String min_recording_interval_key;
+ private String min_required_accuracy_key;
+ private String signal_sampling_frequency_key;
+ private String split_frequency_key;
+
+ public PreferenceManager(TrackRecordingService service) {
+ this.service = service;
+ announcement_frequency_key =
+ service.getString(R.string.announcement_frequency_key);
+ max_recording_distance_key =
+ service.getString(R.string.max_recording_distance_key);
+ metric_units_key =
+ service.getString(R.string.metric_units_key);
+ min_recording_distance_key =
+ service.getString(R.string.min_recording_distance_key);
+ min_recording_interval_key =
+ service.getString(R.string.min_recording_interval_key);
+ min_required_accuracy_key =
+ service.getString(R.string.min_required_accuracy_key);
+ split_frequency_key =
+ service.getString(R.string.split_frequency_key);
+ signal_sampling_frequency_key =
+ service.getString(R.string.signal_sampling_frequency_key);
+ }
+
+ /**
+ * Notifies that preferences have changed.
+ * Call this with key == null to update all preferences in one call.
+ *
+ * @param key the key that changed (may be null to update all preferences)
+ */
+ public void onSharedPreferenceChanged(String key) {
+ SharedPreferences sharedPreferences =
+ service.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
+ if (sharedPreferences == null) {
+ Log.w(MyTracksConstants.TAG,
+ "TrackRecordingService: Couldn't get shared preferences.");
+ return;
+ }
+
+ if (key == null || key.equals(min_recording_distance_key)) {
+ service.setMinRecordingDistance(
+ sharedPreferences.getInt(
+ min_recording_distance_key,
+ MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE));
+ Log.d(MyTracksConstants.TAG,
+ "TrackRecordingService: minRecordingDistance = "
+ + service.getMinRecordingDistance());
+ }
+ if (key == null || key.equals(max_recording_distance_key)) {
+ service.setMaxRecordingDistance(
+ sharedPreferences.getInt(
+ max_recording_distance_key,
+ MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE));
+ }
+ if (key == null || key.equals(min_recording_interval_key)) {
+ int minRecordingInterval = sharedPreferences.getInt(
+ min_recording_interval_key,
+ MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL);
+ switch (minRecordingInterval) {
+ case -2:
+ // Battery Miser
+ // min: 30 seconds
+ // max: 5 minutes
+ // minDist: 5 meters Choose battery life over moving time accuracy.
+ service.setLocationListenerPolicy(
+ new AdaptiveLocationListenerPolicy(30000, 300000, 5));
+ break;
+ case -1:
+ // High Accuracy
+ // min: 1 second
+ // max: 30 seconds
+ // minDist: 0 meters get all updates to properly measure moving time.
+ service.setLocationListenerPolicy(
+ new AdaptiveLocationListenerPolicy(1000, 30000, 0));
+ break;
+ default:
+ service.setLocationListenerPolicy(
+ new AbsoluteLocationListenerPolicy(minRecordingInterval * 1000));
+ }
+ }
+ if (key == null || key.equals(min_required_accuracy_key)) {
+ service.setMinRequiredAccuracy(
+ sharedPreferences.getInt(
+ min_required_accuracy_key,
+ MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY));
+ }
+ if (key == null || key.equals(announcement_frequency_key)) {
+ service.setAnnouncementFrequency(
+ sharedPreferences.getInt(announcement_frequency_key,
+ -1));
+ }
+ if (key == null || key.equals(split_frequency_key)) {
+ service.getSplitManager().setSplitFrequency(
+ sharedPreferences.getInt(split_frequency_key, 0));
+ }
+ if (key == null || key.equals(signal_sampling_frequency_key)) {
+ service.getSignalManager().setFrequency(
+ sharedPreferences.getInt(
+ signal_sampling_frequency_key, -1), service);
+ }
+ if (key == null || key.equals(metric_units_key)) {
+ service.getSplitManager().setMetricUnits(sharedPreferences.getBoolean(
+ metric_units_key, true));
+ }
+ }
+}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java
index d0ec9a41e..ba0f0cf52 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/StatusAnnouncerTask.java
@@ -116,10 +116,12 @@ public class StatusAnnouncerTask
boolean metricUnits = true;
boolean reportSpeed = true;
if (preferences != null) {
- metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS,
- true);
- reportSpeed = preferences.getBoolean(MyTracksSettings.REPORT_SPEED,
- true);
+ metricUnits =
+ preferences.getBoolean(context.getString(R.string.metric_units_key),
+ true);
+ reportSpeed =
+ preferences.getBoolean(context.getString(R.string.report_speed_key),
+ true);
}
double d = stats.getTotalDistance() / 1000;
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
index fc952387d..65eebf418 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
@@ -1,12 +1,12 @@
/*
* Copyright 2008 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
@@ -56,7 +56,7 @@ import java.util.TimerTask;
/**
* A background service that registers a location listener and records track
* points. Track points are saved to the MyTracksProvider.
- *
+ *
* @author Leif Hendrik Wilden
*/
public class TrackRecordingService extends Service implements LocationListener {
@@ -68,8 +68,6 @@ public class TrackRecordingService extends Service implements LocationListener {
private LocationManager locationManager;
private WakeLock wakeLock;
- private int minRecordingInterval =
- MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL;
private int minRecordingDistance =
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE;
private int maxRecordingDistance =
@@ -110,8 +108,10 @@ public class TrackRecordingService extends Service implements LocationListener {
private TaskExecuterManager signalManager;
private SplitManager splitManager;
+ private PreferenceManager prefManager;
+
/**
- * The interval in milliseconds that we have requested to be notfied of gps
+ * The interval in milliseconds that we have requested to be notified of gps
* readings.
*/
private long currentRecordingInterval = 0;
@@ -126,7 +126,7 @@ public class TrackRecordingService extends Service implements LocationListener {
* Task invoked by a timer periodically to make sure the location listener is
* still registered.
*/
- private TimerTask checkLocationListener = new TimerTask() {
+ private final TimerTask checkLocationListener = new TimerTask() {
@Override
public void run() {
if (!onCreateWasCalled) {
@@ -198,7 +198,7 @@ public class TrackRecordingService extends Service implements LocationListener {
/**
* Inserts a new location in the track points db and updates the corresponding
* track in the track db.
- *
+ *
* @param recordingTrack the track that is currently being recorded
* @param location the location to be inserted
* @param lastRecordedLocation the last recorded location before this one (or
@@ -475,8 +475,7 @@ public class TrackRecordingService extends Service implements LocationListener {
}
// This should never happen, but just in case (we really don't want the
- // service
- // to crash):
+ // service to crash):
if (location == null) {
Log.w(MyTracksConstants.TAG,
"Location changed, but location is null.");
@@ -559,8 +558,7 @@ public class TrackRecordingService extends Service implements LocationListener {
}
// If separation from last recorded point is too large insert a
- // separator
- // to indicate end of a segment:
+ // separator to indicate end of a segment:
boolean startNewSegment =
lastRecordedLocation != null
&& lastRecordedLocation.getLatitude() < 90
@@ -620,7 +618,7 @@ public class TrackRecordingService extends Service implements LocationListener {
*/
/**
- * Notifies that preferences have changed.
+ * Notifies that preferences have changed.
* Call this with key == null to update all preferences in one call.
*
* @param key the key that changed (may be null to update all preferences)
@@ -628,93 +626,7 @@ public class TrackRecordingService extends Service implements LocationListener {
public void onSharedPreferenceChanged(String key) {
Log.d(MyTracksConstants.TAG,
"TrackRecordingService.onSharedPreferenceChanged");
- SharedPreferences sharedPreferences =
- getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
- if (sharedPreferences == null) {
- Log.w(MyTracksConstants.TAG,
- "TrackRecordingService: Couldn't get shared preferences.");
- return;
- }
-
- if (key == null || key.equals(MyTracksSettings.MIN_RECORDING_DISTANCE)) {
- minRecordingDistance = sharedPreferences.getInt(
- MyTracksSettings.MIN_RECORDING_DISTANCE,
- MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE);
- Log.d(MyTracksConstants.TAG,
- "TrackRecordingService: minRecordingDistance = "
- + minRecordingDistance);
- }
- if (key == null || key.equals(MyTracksSettings.MAX_RECORDING_DISTANCE)) {
- maxRecordingDistance = sharedPreferences.getInt(
- MyTracksSettings.MAX_RECORDING_DISTANCE,
- MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE);
- }
- if (key == null || key.equals(MyTracksSettings.MIN_RECORDING_INTERVAL)) {
- minRecordingInterval = sharedPreferences.getInt(
- MyTracksSettings.MIN_RECORDING_INTERVAL,
- MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL);
- switch (minRecordingInterval) {
- case -2:
- // Battery Miser
- // min: 30 seconds
- // max: 5 minutes
- // minDist: 5 meters Choose battery life over moving time accuracy.
- locationListenerPolicy =
- new AdaptiveLocationListenerPolicy(30000, 300000, 5);
- break;
- case -1:
- // High Accuracy
- // min: 1 second
- // max: 30 seconds
- // minDist: 0 meters get all updates to properly measure moving time.
- locationListenerPolicy =
- new AdaptiveLocationListenerPolicy(1000, 30000, 0);
- break;
- default:
- locationListenerPolicy =
- new AbsoluteLocationListenerPolicy(minRecordingInterval * 1000);
- }
- }
- if (key == null || key.equals(MyTracksSettings.MIN_REQUIRED_ACCURACY)) {
- minRequiredAccuracy = sharedPreferences.getInt(
- MyTracksSettings.MIN_REQUIRED_ACCURACY,
- MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY);
- }
- if (key == null || key.equals(MyTracksSettings.RECORDING_TRACK)) {
- recordingTrackId =
- sharedPreferences.getLong(MyTracksSettings.RECORDING_TRACK, -1);
- }
- if (key == null || key.equals(MyTracksSettings.ANNOUNCEMENT_FREQUENCY)) {
- announcementFrequency =
- sharedPreferences.getInt(MyTracksSettings.ANNOUNCEMENT_FREQUENCY, -1);
- if (mTTSAvailable) {
- if (announcementFrequency == -1) {
- if (executer != null) {
- executer.shutdown();
- executer = null;
- }
- } else {
- if (executer == null) {
- SafeStatusAnnouncerTask announcer =
- new SafeStatusAnnouncerTask(this);
- executer = new PeriodicTaskExecuter(announcer, this);
- }
- executer.scheduleTask(announcementFrequency * 60000);
- }
- }
- }
- if (key == null || key.equals(MyTracksSettings.SPLIT_FREQUENCY)) {
- splitManager.setSplitFrequency(
- sharedPreferences.getInt(MyTracksSettings.SPLIT_FREQUENCY, 0));
- }
- if (key == null || key.equals(MyTracksSettings.SIGNAL_SAMPLING_FREQUENCY)) {
- signalManager.setFrequency(sharedPreferences.getInt(
- MyTracksSettings.SIGNAL_SAMPLING_FREQUENCY, -1), this);
- }
- if (key == null || key.equals(MyTracksSettings.METRIC_UNITS)) {
- splitManager.setMetricUnits(
- sharedPreferences.getBoolean(MyTracksSettings.METRIC_UNITS, true));
- }
+ prefManager.onSharedPreferenceChanged(key);
if (isRecording) {
registerLocationListener();
@@ -730,7 +642,6 @@ public class TrackRecordingService extends Service implements LocationListener {
Log.d(MyTracksConstants.TAG, "TrackRecordingService.onCreate");
super.onCreate();
onCreateWasCalled = true;
- setForeground(true);
providerUtils = MyTracksProviderUtils.Factory.get(this);
notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
@@ -748,6 +659,7 @@ public class TrackRecordingService extends Service implements LocationListener {
signalManager =
new TaskExecuterManager(-1, new SignalStrengthTask(this), this);
}
+ prefManager = new PreferenceManager(this);
onSharedPreferenceChanged(null);
restoreStats();
registerLocationListener();
@@ -815,7 +727,7 @@ public class TrackRecordingService extends Service implements LocationListener {
/**
* Inserts a statistics marker. A statistics marker holds the stats for the
* last segment up to this marker.
- *
+ *
* @param location the location where to insert
* @return the unique id of the inserted marker
*/
@@ -872,7 +784,7 @@ public class TrackRecordingService extends Service implements LocationListener {
public boolean hasRecorded() {
return providerUtils.getLastTrackId() >= 0;
}
-
+
@Override
public long startNewTrack() {
Log.d(MyTracksConstants.TAG, "TrackRecordingService.startNewTrack");
@@ -903,11 +815,11 @@ public class TrackRecordingService extends Service implements LocationListener {
signalManager.restore();
return trackId;
}
-
+
/**
* Insert the given waypoint marker. Users can insert waypoint markers
* to tag locations with a name, description, category etc.
- *
+ *
* @param waypoint a waypoint
* @return the unique id of the inserted marker
*/
@@ -915,11 +827,11 @@ public class TrackRecordingService extends Service implements LocationListener {
public long insertWaypointMarker(Waypoint waypoint) {
return TrackRecordingService.this.insertWaypointMarker(waypoint);
}
-
+
/**
* Insert a statistics marker. A statistics marker holds the stats for
* the last segment up to this marker.
- *
+ *
* @param location the location where to insert
* @return the unique id of the inserted marker
*/
@@ -927,7 +839,7 @@ public class TrackRecordingService extends Service implements LocationListener {
public long insertStatisticsMarker(Location location) {
return TrackRecordingService.this.insertStatisticsMarker(location);
}
-
+
@Override
public void endCurrentTrack() {
Log.d(MyTracksConstants.TAG, "TrackRecordingService.endCurrentTrack");
@@ -952,18 +864,18 @@ public class TrackRecordingService extends Service implements LocationListener {
showNotification();
recordingTrackId = -1;
}
-
+
@Override
public void deleteAllTracks() {
endCurrentTrack();
providerUtils.deleteAllTracks();
}
-
+
@Override
public void recordLocation(Location loc) {
onLocationChanged(loc);
}
-
+
@Override
public void sharedPreferenceChanged(String key) {
Log.d(MyTracksConstants.TAG,
@@ -983,4 +895,68 @@ public class TrackRecordingService extends Service implements LocationListener {
long getRecordingTrackId() {
return recordingTrackId;
}
+
+ public int getAnnouncementFrequency() {
+ return announcementFrequency;
+ }
+
+ public void setAnnouncementFrequency(int announcementFrequency) {
+ this.announcementFrequency = announcementFrequency;
+ if (mTTSAvailable) {
+ if (announcementFrequency == -1) {
+ if (executer != null) {
+ executer.shutdown();
+ executer = null;
+ }
+ } else {
+ if (executer == null) {
+ SafeStatusAnnouncerTask announcer =
+ new SafeStatusAnnouncerTask(this);
+ executer = new PeriodicTaskExecuter(announcer, this);
+ }
+ executer.scheduleTask(announcementFrequency * 60000);
+ }
+ }
+ }
+
+ public int getMaxRecordingDistance() {
+ return maxRecordingDistance;
+ }
+
+ public void setMaxRecordingDistance(int maxRecordingDistance) {
+ this.maxRecordingDistance = maxRecordingDistance;
+ }
+
+ public int getMinRecordingDistance() {
+ return minRecordingDistance;
+ }
+
+ public void setMinRecordingDistance(int minRecordingDistance) {
+ this.minRecordingDistance = minRecordingDistance;
+ }
+
+ public int getMinRequiredAccuracy() {
+ return minRequiredAccuracy;
+ }
+
+ public void setMinRequiredAccuracy(int minRequiredAccuracy) {
+ this.minRequiredAccuracy = minRequiredAccuracy;
+ }
+
+ public LocationListenerPolicy getLocationListenerPolicy() {
+ return locationListenerPolicy;
+ }
+
+ public void setLocationListenerPolicy(
+ LocationListenerPolicy locationListenerPolicy) {
+ this.locationListenerPolicy = locationListenerPolicy;
+ }
+
+ public SplitManager getSplitManager() {
+ return splitManager;
+ }
+
+ public TaskExecuterManager getSignalManager() {
+ return signalManager;
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
index 9724ba727..f0107e832 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
@@ -347,6 +347,8 @@ public class TripStatisticsBuilder {
* Returns the amount of time the user has been idle or 0 if they are moving.
*/
public long getIdleTime() {
+ if (lastLocation == null || lastMovingLocation == null)
+ return 0;
return lastLocation.getTime() - lastMovingLocation.getTime();
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java b/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
index f232dbf51..bd721512a 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
@@ -53,7 +53,8 @@ public class ChartURLGenerator {
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
boolean metricUnits = true;
if (preferences != null) {
- metricUnits = preferences.getBoolean(MyTracksSettings.METRIC_UNITS, true);
+ metricUnits = preferences.getBoolean(
+ context.getString(R.string.metric_units_key), true);
}
return getChartUrl(distances, elevations, track,
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java
index d5a8ed34b..c4c0b2317 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java
@@ -173,7 +173,7 @@ public class StringUtils implements DescriptionGenerator {
context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (preferences != null) {
displaySpeed =
- preferences.getBoolean(MyTracksSettings.REPORT_SPEED, true);
+ preferences.getBoolean(context.getString(R.string.report_speed_key), true);
}
TripStatistics trackStats = track.getStatistics();
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/TcxTrackWriterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/TcxTrackWriterTest.java
new file mode 100644
index 000000000..ec132e0db
--- /dev/null
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/TcxTrackWriterTest.java
@@ -0,0 +1,66 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+package com.google.android.apps.mytracks.io;
+
+import android.location.Location;
+
+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 {
+
+ public void testXmlOutput() throws Exception {
+ TrackFormatWriter writer = new TcxTrackWriter();
+ String result = writeTrack(writer);
+ Document doc = parseXmlDocument(result);
+
+ Element root = getChildElement(doc, "TrainingCenterDatabase");
+ Element activitiesTag = getChildElement(root, "Activities");
+ Element activityTag = getChildElement(activitiesTag, "Activity");
+ Element lapTag = getChildElement(activityTag, "Lap");
+
+ List segmentTags = getChildElements(lapTag, "Track", 2);
+ Element segment1Tag = segmentTags.get(0);
+ Element segment2Tag = segmentTags.get(1);
+ List seg1PointTags = getChildElements(segment1Tag, "Trackpoint", 2);
+ List seg2PointTags = getChildElements(segment2Tag, "Trackpoint", 2);
+ assertTagsMatchPoints(seg1PointTags, location1, location2);
+ assertTagsMatchPoints(seg2PointTags, location3, location4);
+ }
+
+ /**
+ * Asserts that the given tags describe the given points, in the same order.
+ */
+ private void assertTagsMatchPoints(List tags, Location... locs) {
+ assertEquals(locs.length, tags.size());
+ for (int i = 0; i < locs.length; i++) {
+ Element tag = tags.get(i);
+ Location loc = locs[i];
+
+ assertTagMatchesLocation(tag, loc);
+ }
+ }
+
+ /**
+ * Asserts that the given tag describes the given location.
+ */
+ private void assertTagMatchesLocation(Element tag, Location loc) {
+ Element posTag = getChildElement(tag, "Position");
+ assertEquals(Double.toString(loc.getLatitude()),
+ getChildTextValue(posTag, "LatitudeDegrees"));
+ assertEquals(Double.toString(loc.getLongitude()),
+ getChildTextValue(posTag, "LongitudeDegrees"));
+ assertEquals(
+ TcxTrackWriter.TIMESTAMP_FORMAT.format(new Date(loc.getTime())),
+ getChildTextValue(tag, "Time"));
+ assertEquals(Double.toString(loc.getAltitude()),
+ getChildTextValue(tag, "AltitudeMeters"));
+ }
+}
diff --git a/eclipse/mytracks-style.xml b/eclipse/mytracks-style.xml
new file mode 100644
index 000000000..45afba5bc
--- /dev/null
+++ b/eclipse/mytracks-style.xml
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eclipse/mytracks.importorder b/eclipse/mytracks.importorder
new file mode 100644
index 000000000..794a97650
--- /dev/null
+++ b/eclipse/mytracks.importorder
@@ -0,0 +1,7 @@
+#Organize Import Order
+#Fri May 28 03:20:44 BRT 2010
+4=org
+3=javax
+2=java
+1=android
+0=com