From b182c1cb80c4e97015f4cd72d9ef4f790684a71b Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Wed, 2 Oct 2013 15:22:00 -0700 Subject: [PATCH] When play track, add a containing folder to contain all the merged tracks --- MyTracks/res/values/strings.xml | 134 ++++++----- .../mytracks/content/MyTracksProvider.java | 3 +- .../mytracks/fragments/ChartFragment.java | 15 +- .../mytracks/io/file/TrackFileFormat.java | 12 +- .../io/file/exporter/CsvTrackWriter.java | 63 +++-- .../io/file/exporter/FileTrackExporter.java | 24 +- .../io/file/exporter/GpxTrackWriter.java | 97 ++++---- .../io/file/exporter/KmlTrackWriter.java | 56 +++-- .../io/file/exporter/SaveAsyncTask.java | 4 +- .../io/file/exporter/TcxTrackWriter.java | 46 ++-- .../io/file/exporter/TrackWriter.java | 111 +++++---- .../apps/mytracks/io/sync/SyncUtils.java | 4 +- .../content/MyTracksProviderTest.java | 219 ++++++++++++------ .../mytracks/fragments/ChartFragmentTest.java | 29 +-- .../file/exporter/FileTrackExporterTest.java | 46 ++-- .../io/file/exporter/KmlTrackWriterTest.java | 1 - .../io/file/exporter/TrackWriterTest.java | 8 +- 17 files changed, 503 insertions(+), 369 deletions(-) diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 1f073a043..d4533c632 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -564,7 +564,7 @@ limitations under the License. + %1$s host name, 'm.google.com'"> By using Google\'s mobile products and services (“Services”), you agree to be bound by a) the YouTube Terms of Use (%1$s/tos_youtube) for YouTube-related Services, b) the Google Maps Terms and Conditions (%1$s/tos_maps) for mapping, local and location-based Services, c) the @@ -589,7 +589,7 @@ limitations under the License. translation_description="The footer in the 'Terms of Service'. See http://m.google.com/toscountry. - %1$s: host name, 'm.google.com'"> + %1$s host name, 'm.google.com'"> Any required attribution or notice for the third party content may be found at %1$s/legalnotices. @@ -603,8 +603,8 @@ limitations under the License. translation_description="When exporting all tracks to the external storage, the option to export as a certain file format. - %1$s: the file format. E.g., 'KML'. - %2$s: the directory. E.g., '/MyTracks/kml'."> + %1$s the file format. E.g., 'KML'. + %2$s the directory. E.g., '/MyTracks/kml'."> All as %1$s to %2$s + %1$s the file format. E.g., 'KML'. + %2$s the directory. E.g., '/MyTracks/kml'."> as %1$s to %2$s + %1$s the directory. E.g., '/MyTracks/kml'."> Exporting to %1$s… + %1$s service name. E.g, Google Maps. + %2$s service url. E.g, maps.google.com."> An error has occurred. Unable to export to %1$s (%2$s). Please try again. + %1$s service name. E.g, Google Maps. + %2$s service url. E.g, maps.google.com."> Track exported to %1$s (%2$s). It may take a few minutes for it to appear. Success + + Tracks + Yes @@ -933,14 +937,14 @@ limitations under the License. translation_description="When importing from the external storage, the error message when the directory doesn't exist. - %1$s: the directory. E.g., '/MyTracks/kml'."> + %1$s the directory. E.g., '/MyTracks/kml'."> %1$s does not exist. + %1$s the directory. E.g., '/MyTracks/kml'."> There were no files to import. Connect your device to your computer and place the files to import in %1$s. @@ -952,15 +956,15 @@ limitations under the License. + %1$s the directory. E.g., '/MyTracks/kml'."> Importing from %1$s… + %1$s the file format. E.g., 'KML'. + %2$s the directory. E.g., '/MyTracks/kml'."> All %1$s from %2$s + %1$d an integer value. E.g., '2'."> %1$d selected @@ -1012,26 +1016,26 @@ limitations under the License. translation_description="When inserting a marker to indicate the end of a track, the marker's name. E.g., 'track_name (End)'. - %1$s track name. E.g., 'track_name'."> + %1$s track name. E.g., 'Grand Canyon trail'."> %1$s (End) + %1$s track name. E.g., 'Grand Canyon trail'."> %1$s (Start) + %1$d number. E.g., '1'."> Marker %1$d + %1$d number. E.g., '1'."> Split %1$d @@ -1334,7 +1338,7 @@ limitations under the License. translation_description="For a marker returned in the search result, the text field indicating the track that the marker belongs to. - %1$s: track name. E.g., 'Grand Canyon trail'."> + %1$s track name. E.g., 'Grand Canyon trail'."> In track ‘%1$s’. Created by %1$sGoogle My Tracks%2$s on Android. @@ -1376,15 +1380,15 @@ limitations under the License. + %1$s service name. 'Google Maps', 'Google Fusion Tables', or 'Google Spreadsheets'."> Sending to %1$s… + %1$s track name. E.g., 'Grand Canyon trail'. + %2$d part number. E.g., '1'."> %1$s (Part %2$d) @@ -1405,7 +1409,7 @@ limitations under the License. translation_description="In the 'Sensor state' page, the value for the 'Cadence'. Cadence is the number of revolutions of the crank per minute. E.g., 'Cadence: 80 rpm'. - %1$d: a number. E.g., '80'."> + %1$d a number. E.g., '80'."> %1$d rpm + %1$d a number. E.g., '100'."> %1$d bpm + %1$d a number. E.g., '50'."> %1$d W + %1$d an integer value. E.g., '15'."> The medium speed range is %1$d %% from the average speed + %1$d device id number. E.g., '1'."> Paired with %1$d + %1$s sensor name. E.g., 'Polar Bluetooth'."> Connected to %1$s + %1$s track description."> I think you might be interested in this track.\n\nTo view this track, use Google Earth or other mapping software.\n\n%1$s @@ -2094,8 +2098,8 @@ limitations under the License. translation_description="When sharing a track URL with friends, the body of the message. Note that \n is the newline character. - %1$s: url. E.g., 'https://maps.google.com/maps'. - %2$s: track description."> + %1$s url. E.g., 'https://maps.google.com/maps'. + %2$s track description."> I think you might be interested in this track:\n\n%1$s\n\n%2$s + %1$d track number. E.g., '1'."> Track %1$d Recording your track… - + + %1$s Markers + + @@ -2431,140 +2441,140 @@ limitations under the License. + %1$.2f a float number. E.g., '2.22'."> %1$.2f ft + %1$.2f a float number. E.g., '2.22'."> %1$.2f km + %1$.2f a float number. E.g., '2.22'."> %1$.2f m + %1$.2f a float number. E.g., '2.22'."> %1$.2f mi + %1$.1f a float number. E.g., '2.2'."> %1$.1f mi (poor GPS) + %1$d an integer value. E.g., '2'."> %1$d ft + %1$d an integer value. E.g., '2'."> %1$d ft (excellent GPS) + %1$d an integer value. E.g., '2'."> %1$d ft (recommended) + %1$d an integer value. E.g., '2'."> %1$d km + %1$d an integer value. E.g., '2'."> %1$d kg + %1$d an integer value. E.g., '2'."> %1$d km/h + %1$d an integer value. E.g., '2'."> %1$d m + %1$d an integer value. E.g., '2'."> %1$d m (excellent GPS) + %1$d an integer value. E.g., '2'."> %1$d m (poor GPS) + %1$d an integer value. E.g., '2'."> %1$d m (recommended) + %1$d an integer value. E.g., '2'."> %1$d mi + %1$d an integer value. E.g., '2'."> %1$d mi/h + %1$d an integer value. E.g., '2'."> %1$d min + %1$d an integer value. E.g., '2'."> %1$d %% + %1$d an integer value. E.g., '2'."> %1$d lb + %1$d an integer value. E.g., '2'."> %1$d s My Tracks %1$s in %2$s at %3$s. diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java index 84361c946..c85ba0956 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProvider.java @@ -52,7 +52,8 @@ import java.util.ArrayList; public class MyTracksProvider extends ContentProvider { private static final String TAG = MyTracksProvider.class.getSimpleName(); - private static final int DATABASE_VERSION = 22; + @VisibleForTesting + static final int DATABASE_VERSION = 22; @VisibleForTesting static final String DATABASE_NAME = "mytracks.db"; diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java index 7ec6ab351..6d55b0d36 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java @@ -34,6 +34,7 @@ import com.google.android.apps.mytracks.util.UnitConversions; import com.google.android.maps.mytracks.R; import com.google.common.annotations.VisibleForTesting; +import android.content.Context; import android.location.Location; import android.os.Bundle; import android.support.v4.app.Fragment; @@ -188,7 +189,7 @@ public class ChartFragment extends Fragment implements TrackDataListener { public void onSampledInTrackPoint(Location location) { if (isResumed()) { double[] data = new double[ChartView.NUM_SERIES + 1]; - fillDataPoint(location, data); + fillDataPoint(getActivity(), location, data); pendingPoints.add(data); } } @@ -196,14 +197,14 @@ public class ChartFragment extends Fragment implements TrackDataListener { @Override public void onSampledOutTrackPoint(Location location) { if (isResumed()) { - fillDataPoint(location, null); + fillDataPoint(getActivity(), location, null); } } @Override public void onSegmentSplit(Location location) { if (isResumed()) { - fillDataPoint(location, null); + fillDataPoint(getActivity(), location, null); } } @@ -437,11 +438,12 @@ public class ChartFragment extends Fragment implements TrackDataListener { * data[5] = cadence
* data[6] = power
* + * @param context the context * @param location the location * @param data the data point to fill in, can be null */ @VisibleForTesting - void fillDataPoint(Location location, double data[]) { + void fillDataPoint(Context context, Location location, double data[]) { double timeOrDistance = Double.NaN; double elevation = Double.NaN; double speed = Double.NaN; @@ -451,8 +453,9 @@ public class ChartFragment extends Fragment implements TrackDataListener { double power = Double.NaN; if (tripStatisticsUpdater != null) { - tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, PreferencesUtils - .getInt(getActivity(), R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT)); + int weight = PreferencesUtils.getInt( + context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT); + tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, weight); TripStatistics tripStatistics = tripStatisticsUpdater.getTripStatistics(); if (chartByDistance) { double distance = tripStatistics.getTotalDistance() * UnitConversions.M_TO_KM; diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackFileFormat.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackFileFormat.java index 3392277af..355fbeebe 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackFileFormat.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackFileFormat.java @@ -18,25 +18,25 @@ import java.util.Locale; public enum TrackFileFormat implements Parcelable { KML { @Override - public TrackWriter newTrackWriter(Context context, boolean inZip) { - return new KmlTrackWriter(context, inZip); + public TrackWriter newTrackWriter(Context context, boolean playTrack) { + return new KmlTrackWriter(context, playTrack); } }, GPX { @Override - public TrackWriter newTrackWriter(Context context, boolean inZip) { + public TrackWriter newTrackWriter(Context context, boolean playTrack) { return new GpxTrackWriter(context); } }, CSV { @Override - public TrackWriter newTrackWriter(Context context, boolean inZip) { + public TrackWriter newTrackWriter(Context context, boolean playTrack) { return new CsvTrackWriter(context); } }, TCX { @Override - public TrackWriter newTrackWriter(Context context, boolean inZip) { + public TrackWriter newTrackWriter(Context context, boolean playTrack) { return new TcxTrackWriter(context); } }; @@ -66,7 +66,7 @@ public enum TrackFileFormat implements Parcelable { /** * Creates a new track writer for the format. */ - public abstract TrackWriter newTrackWriter(Context context, boolean inZip); + public abstract TrackWriter newTrackWriter(Context context, boolean playTrack); /** * Returns the mime type for each format. diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/CsvTrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/CsvTrackWriter.java index 43c06c454..13c06f9f0 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/CsvTrackWriter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/CsvTrackWriter.java @@ -46,7 +46,7 @@ import java.text.NumberFormat; * "Segment","Point","Latitude (deg)","Longitude (deg)","Altitude (m)","Bearing * (deg)","Accuracy (m)","Speed (m/s)","Time","Power (W)","Cadence (rpm)","Heart * rate (bpm)","Battery level (%)"
- * + * * @author Rodrigo Damazio */ public class CsvTrackWriter implements TrackWriter { @@ -85,12 +85,13 @@ public class CsvTrackWriter implements TrackWriter { printWriter = null; } } - + @Override - public void writeHeader(Track track) { + public void writeHeader(Track[] tracks) { writeCommaSeparatedLine(context.getString(R.string.generic_name), context.getString(R.string.track_edit_activity_type_hint), context.getString(R.string.generic_description)); + Track track = tracks[0]; writeCommaSeparatedLine(track.getName(), track.getCategory(), track.getDescription()); writeCommaSeparatedLine(); } @@ -101,7 +102,7 @@ public class CsvTrackWriter implements TrackWriter { } @Override - public void writeBeginWaypoints() { + public void writeBeginWaypoints(Track track) { writeCommaSeparatedLine(context.getString(R.string.generic_name), context.getString(R.string.marker_edit_marker_type_hint), context.getString(R.string.generic_description), @@ -122,20 +123,24 @@ public class CsvTrackWriter implements TrackWriter { @Override public void writeWaypoint(Waypoint waypoint) { Location location = waypoint.getLocation(); - writeCommaSeparatedLine(waypoint.getName(), - waypoint.getCategory(), - waypoint.getDescription(), - Double.toString(location.getLatitude()), - Double.toString(location.getLongitude()), - getAltitude(location), - getBearing(location), - getAccuracy(location), - getSpeed(location), + writeCommaSeparatedLine(waypoint.getName(), waypoint.getCategory(), waypoint.getDescription(), + Double.toString(location.getLatitude()), Double.toString(location.getLongitude()), + getAltitude(location), getBearing(location), getAccuracy(location), getSpeed(location), StringUtils.formatDateTimeIso8601(location.getTime())); } @Override - public void writeBeginTrack(Track track, Location firstPoint) { + public void writeBeginTracks() { + // Do nothing + } + + @Override + public void writeEndTracks() { + // Do nothing + } + + @Override + public void writeBeginTrack(Track track, Location startLocation) { writeCommaSeparatedLine(context.getString(R.string.description_track_segment), context.getString(R.string.description_track_point), context.getString(R.string.description_location_latitude), @@ -151,7 +156,7 @@ public class CsvTrackWriter implements TrackWriter { } @Override - public void writeEndTrack(Track track, Location lastPoint) { + public void writeEndTrack(Track track, Location endLocation) { // Do nothing } @@ -196,39 +201,31 @@ public class CsvTrackWriter implements TrackWriter { } } pointIndex++; - writeCommaSeparatedLine(Integer.toString(segmentIndex), - Integer.toString(pointIndex), - Double.toString(location.getLatitude()), - Double.toString(location.getLongitude()), - getAltitude(location), - getBearing(location), - getAccuracy(location), - getSpeed(location), - StringUtils.formatDateTimeIso8601(location.getTime()), - power, - cadence, - heartRate); + writeCommaSeparatedLine(Integer.toString(segmentIndex), Integer.toString(pointIndex), + Double.toString(location.getLatitude()), Double.toString(location.getLongitude()), + getAltitude(location), getBearing(location), getAccuracy(location), getSpeed(location), + StringUtils.formatDateTimeIso8601(location.getTime()), power, cadence, heartRate); } - + private String getAltitude(Location location) { return location.hasAltitude() ? Double.toString(location.getAltitude()) : null; } - + private String getBearing(Location location) { return location.hasBearing() ? Double.toString(location.getBearing()) : null; } - + private String getAccuracy(Location location) { return location.hasAccuracy() ? SHORT_FORMAT.format(location.getAccuracy()) : null; } - + private String getSpeed(Location location) { return location.hasSpeed() ? SHORT_FORMAT.format(location.getSpeed()) : null; } - + /** * Writes a single line of a CSV file. - * + * * @param values the values to be written as CSV */ private void writeCommaSeparatedLine(String... values) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporter.java index 978dae454..954624713 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporter.java @@ -22,11 +22,8 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Waypoint; -import com.google.android.apps.mytracks.io.file.TrackFileFormat; import com.google.android.apps.mytracks.util.LocationUtils; -import com.google.common.annotations.VisibleForTesting; -import android.content.Context; import android.database.Cursor; import android.location.Location; import android.util.Log; @@ -51,20 +48,11 @@ public class FileTrackExporter implements TrackExporter { /** * Constructor. * - * @param context the context * @param myTracksProviderUtils the my tracks provider utils * @param tracks the tracks - * @param trackFileFormat the track file format + * @param trackWriter the track writer * @param trackExporterListener the track export listener */ - public FileTrackExporter(MyTracksProviderUtils myTracksProviderUtils, - Track[] tracks, TrackFileFormat trackFileFormat, Context context, boolean inZip, - TrackExporterListener trackExporterListener) { - this(myTracksProviderUtils, tracks, trackFileFormat.newTrackWriter(context, inZip), - trackExporterListener); - } - - @VisibleForTesting public FileTrackExporter(MyTracksProviderUtils myTracksProviderUtils, Track[] tracks, TrackWriter trackWriter, TrackExporterListener trackExporterListener) { this.myTracksProviderUtils = myTracksProviderUtils; @@ -77,13 +65,17 @@ public class FileTrackExporter implements TrackExporter { public boolean writeTrack(OutputStream outputStream) { try { trackWriter.prepare(outputStream); - trackWriter.writeHeader(tracks[0]); - long startTime = tracks[0].getTripStatistics().getStartTime(); + trackWriter.writeHeader(tracks); for (int i = 0; i < tracks.length; i++) { writeWaypoints(tracks[i]); + } + trackWriter.writeBeginTracks(); + long startTime = tracks[0].getTripStatistics().getStartTime(); + for (int i = 0; i < tracks.length; i++) { long offset = tracks[i].getTripStatistics().getStartTime() - startTime; writeLocations(tracks[i], offset); } + trackWriter.writeEndTracks(); trackWriter.writeFooter(); trackWriter.close(); return true; @@ -117,7 +109,7 @@ public class FileTrackExporter implements TrackExporter { throw new InterruptedException(); } if (!hasWaypoints) { - trackWriter.writeBeginWaypoints(); + trackWriter.writeBeginWaypoints(track); hasWaypoints = true; } Waypoint waypoint = myTracksProviderUtils.createWaypoint(cursor); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/GpxTrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/GpxTrackWriter.java index 6b4a9b41b..487165899 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/GpxTrackWriter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/GpxTrackWriter.java @@ -78,7 +78,7 @@ public class GpxTrackWriter implements TrackWriter { } @Override - public void writeHeader(Track track) { + public void writeHeader(Track[] tracks) { if (printWriter != null) { printWriter.println(""); printWriter.println(""); printWriter.println(""); + Track track = tracks[0]; printWriter.println("" + StringUtils.formatCData(track.getName()) + ""); printWriter.println("" + StringUtils.formatCData(track.getDescription()) + ""); printWriter.println(""); @@ -108,48 +109,7 @@ public class GpxTrackWriter implements TrackWriter { } @Override - public void writeBeginTrack(Track track, Location firstLocation) { - if (printWriter != null) { - printWriter.println(""); - printWriter.println("" + StringUtils.formatCData(track.getName()) + ""); - printWriter.println("" + StringUtils.formatCData(track.getDescription()) + ""); - printWriter.println("" + StringUtils.formatCData(track.getCategory()) + ""); - printWriter.println("c0c0c0"); - } - } - - @Override - public void writeEndTrack(Track track, Location lastLocation) { - if (printWriter != null) { - printWriter.println(""); - } - } - - @Override - public void writeOpenSegment() { - printWriter.println(""); - } - - @Override - public void writeCloseSegment() { - printWriter.println(""); - } - - @Override - public void writeLocation(Location location) { - if (printWriter != null) { - printWriter.println(""); - if (location.hasAltitude()) { - printWriter.println("" + ELEVATION_FORMAT.format(location.getAltitude()) + ""); - } - printWriter.println( - ""); - printWriter.println(""); - } - } - - @Override - public void writeBeginWaypoints() { + public void writeBeginWaypoints(Track track) { // Do nothing } @@ -179,6 +139,57 @@ public class GpxTrackWriter implements TrackWriter { } } + @Override + public void writeBeginTracks() { + // Do nothing + } + + @Override + public void writeEndTracks() { + // Do nothing + } + + @Override + public void writeBeginTrack(Track track, Location startLocation) { + if (printWriter != null) { + printWriter.println(""); + printWriter.println("" + StringUtils.formatCData(track.getName()) + ""); + printWriter.println("" + StringUtils.formatCData(track.getDescription()) + ""); + printWriter.println("" + StringUtils.formatCData(track.getCategory()) + ""); + printWriter.println("c0c0c0"); + } + } + + @Override + public void writeEndTrack(Track track, Location endLocation) { + if (printWriter != null) { + printWriter.println(""); + } + } + + @Override + public void writeOpenSegment() { + printWriter.println(""); + } + + @Override + public void writeCloseSegment() { + printWriter.println(""); + } + + @Override + public void writeLocation(Location location) { + if (printWriter != null) { + printWriter.println(""); + if (location.hasAltitude()) { + printWriter.println("" + ELEVATION_FORMAT.format(location.getAltitude()) + ""); + } + printWriter.println( + ""); + printWriter.println(""); + } + } + /** * Formats a location with latitude and longitude coordinates. * diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriter.java index 8d9ba8252..28ef5f2ec 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriter.java @@ -70,7 +70,7 @@ public class KmlTrackWriter implements TrackWriter { TRACK_ICON = "http://earth.google.com/images/kml-icons/track-directional/track-0.png"; private final Context context; - private final boolean inKmz; + private final boolean playTrack; private final DescriptionGenerator descriptionGenerator; private final MyTracksProviderUtils myTracksProviderUtils; @@ -82,14 +82,14 @@ public class KmlTrackWriter implements TrackWriter { private boolean hasCadence; private boolean hasHeartRate; - public KmlTrackWriter(Context context, boolean inKmz) { - this(context, inKmz, new DescriptionGeneratorImpl(context)); + public KmlTrackWriter(Context context, boolean playTrack) { + this(context, playTrack, new DescriptionGeneratorImpl(context)); } @VisibleForTesting - KmlTrackWriter(Context context, boolean inKmz, DescriptionGenerator descriptionGenerator) { + KmlTrackWriter(Context context, boolean playTrack, DescriptionGenerator descriptionGenerator) { this.context = context; - this.inKmz = inKmz; + this.playTrack = playTrack; this.descriptionGenerator = descriptionGenerator; this.myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context); } @@ -113,7 +113,7 @@ public class KmlTrackWriter implements TrackWriter { } @Override - public void writeHeader(Track track) { + public void writeHeader(Track[] tracks) { if (printWriter != null) { printWriter.println(""); printWriter.println(""); printWriter.println("1"); printWriter.println("1"); + Track track = tracks[0]; printWriter.println("" + StringUtils.formatCData(track.getName()) + ""); printWriter.println("" + StringUtils.formatCData(context.getString(R.string.send_google_by_my_tracks, "", "")) @@ -148,10 +149,11 @@ public class KmlTrackWriter implements TrackWriter { } @Override - public void writeBeginWaypoints() { + public void writeBeginWaypoints(Track track) { if (printWriter != null) { printWriter.println("" - + StringUtils.formatCData(context.getString(R.string.menu_markers)) + ""); + + StringUtils.formatCData(context.getString(R.string.track_markers, track.getName())) + + ""); printWriter.println("1"); } } @@ -181,11 +183,31 @@ public class KmlTrackWriter implements TrackWriter { } @Override - public void writeBeginTrack(Track track, Location firstLocation) { + public void writeBeginTracks() { + if (printWriter != null && playTrack) { + printWriter.println(""); + printWriter.println("" + context.getString(R.string.generic_tracks) + ""); + printWriter.println("1"); + } + } + + @Override + public void writeEndTracks() { + if (printWriter != null && playTrack) { + printWriter.println(""); + } + } + + @Override + public void writeBeginTrack(Track track, Location startLocation) { if (printWriter != null) { String name = context.getString(R.string.marker_label_start, track.getName()); - writePlacemark(name, "", "", START_STYLE, firstLocation); - printWriter.println(""); + writePlacemark(name, "", "", START_STYLE, startLocation); + if (playTrack) { + printWriter.println(""); + } else { + printWriter.println(""); + } printWriter.println("" + StringUtils.formatCData(track.getName()) + ""); printWriter.println( "" + StringUtils.formatCData(track.getDescription()) + ""); @@ -198,13 +220,13 @@ public class KmlTrackWriter implements TrackWriter { } @Override - public void writeEndTrack(Track track, Location lastLocation) { + public void writeEndTrack(Track track, Location endLocation) { if (printWriter != null) { printWriter.println(""); printWriter.println(""); String name = context.getString(R.string.marker_label_end, track.getName()); String description = descriptionGenerator.generateTrackDescription(track, null, null, false); - writePlacemark(name, "", description, END_STYLE, lastLocation); + writePlacemark(name, "", description, END_STYLE, endLocation); } } @@ -353,12 +375,12 @@ public class KmlTrackWriter implements TrackWriter { + StringUtils.formatDateTimeIso8601(location.getTime()) + ""); printWriter.println("#" + styleName + ""); writeCategory(category); - if (inKmz) { + if (playTrack) { + printWriter.println("" + Uri.decode(photoUrl) + ""); + } else { Uri uri = Uri.parse(photoUrl); printWriter.println("" + KmzTrackExporter.KMZ_IMAGES_DIR + File.separatorChar - + uri.getLastPathSegment() + ""); - } else { - printWriter.println("" + Uri.decode(photoUrl) + ""); + + uri.getLastPathSegment() + ""); } printWriter.print(""); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/SaveAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/SaveAsyncTask.java index c314cd293..2368f45ec 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/SaveAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/SaveAsyncTask.java @@ -184,7 +184,7 @@ public class SaveAsyncTask extends AsyncTask { return false; } Track track = tracks[0]; - boolean useKmz = !playTrack && trackFileFormat == TrackFileFormat.KML; + boolean useKmz = trackFileFormat == TrackFileFormat.KML && !playTrack; String extension = useKmz ? KmzTrackExporter.KMZ_EXTENSION : trackFileFormat.getExtension(); // Make sure the file doesn't exist yet (possibly by changing the filename) @@ -195,7 +195,7 @@ public class SaveAsyncTask extends AsyncTask { } FileTrackExporter fileTrackExporter = new FileTrackExporter(myTracksProviderUtils, tracks, - trackFileFormat, context, useKmz, new TrackExporterListener() { + trackFileFormat.newTrackWriter(context, playTrack), new TrackExporterListener() { @Override public void onProgressUpdate(int number, int max) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TcxTrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TcxTrackWriter.java index 9f7f7978b..add3b50fb 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TcxTrackWriter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TcxTrackWriter.java @@ -111,7 +111,7 @@ public class TcxTrackWriter implements TrackWriter { } @Override - public void writeHeader(Track track) { + public void writeHeader(Track[] tracks) { if (printWriter != null) { printWriter.println(""); printWriter.println(""); printWriter.println("" + StringUtils.formatCData(track.getDescription()) + ""); @@ -261,21 +286,6 @@ public class TcxTrackWriter implements TrackWriter { } } - @Override - public void writeBeginWaypoints() { - // Do nothing. - } - - @Override - public void writeEndWaypoints() { - // Do nothing. - } - - @Override - public void writeWaypoint(Waypoint waypoint) { - // Do nothing. - } - /** * Writes the TCX Version. */ diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriter.java index 58d66597c..2e3429ecf 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriter.java @@ -23,58 +23,57 @@ import android.location.Location; import java.io.OutputStream; /** - * Interface for writing tracks to a file. - * - * The expected sequence of calls is: - *
    - *
  • {@link #prepare}
  • - *
  • {@link #writeHeader}
  • - *
  • For each track:
  • - *
      - *
    • {@link #writeBeginWaypoints} - *
    • For each waypoint: {@link #writeWaypoint} - *
    • {@link #writeEndWaypoints} - *
    • {@link #writeBeginTrack} - *
    • For each segment: - *
        - *
      • {@link #writeOpenSegment}
      • - *
      • For each location in the segment: {@link #writeLocation}
      • - *
      • {@link #writeCloseSegment}
      • - *
      - *
    • - *
    • {@link #writeEndTrack}
    • - *
    - *
  • {@link #writeFooter}
  • - *
  • {@link #close}
  • - *
- * + * Interface for writing tracks to a file. The expected sequence of calls is: + * + *
+ * {@link #prepare(OutputStream)}
+ * {@link #writeHeader(Track[])}
+ * For each track:
+ *     {@link #writeBeginWaypoints(Track)}
+ *     For each waypoint:
+ *         {@link #writeWaypoint(Waypoint)}
+ *     {@link #writeEndWaypoints()}
+ * {@link #writeBeginTracks()}
+ * For each track:
+ *     {@link #writeBeginTrack(Track, Location)}
+ *     For each segment:
+ *         {@link #writeOpenSegment()}
+ *         For each location in the segment:
+ *             {@link #writeLocation(Location)}
+ *         {@link #writeCloseSegment()}
+ *     {@link #writeEndTrack(Track, Location)}
+ * {@link #writeEndTracks()}
+ * {@link #writeFooter()}
+ * {@link #close()}
+ * 
+ * * @author Rodrigo Damazio */ public interface TrackWriter { /** - * Gets the file extension (i.e. gpx, kml, ...) + * Gets the file extension (e.g, gpx, kml, ...). */ public String getExtension(); /** - * Sets up the file handler. - * - * @param outputStream the output stream for the file handler + * Prepares the output stream. + * + * @param outputStream the output stream */ public void prepare(OutputStream outputStream); /** - * Closes the underlying file handler. + * Closes the output stream. */ public void close(); /** - * Writes the header for a file + * Writes the header * - * @param track the track + * @param tracks the tracks */ - public void writeHeader(Track track); + public void writeHeader(Track[] tracks); /** * Writes the footer. @@ -83,50 +82,62 @@ public interface TrackWriter { /** * Writes the beginning of the waypoints. + * + * @param track the track */ - public void writeBeginWaypoints(); - + public void writeBeginWaypoints(Track track); + /** * Writes the end of the waypoints. */ public void writeEndWaypoints(); - + /** * Writes a waypoint. - * + * * @param waypoint the waypoint */ public void writeWaypoint(Waypoint waypoint); /** - * Writes the beginning of the track. - * - * @param track the track - * @param firstLocation the first location + * Writes the beginning of the tracks. */ - public void writeBeginTrack(Track track, Location firstLocation); + public void writeBeginTracks(); /** - * Writes the end of the track. - * - * @param track the track - * @param lastLocation the last location + * Writes the end of the tracks, */ - public void writeEndTrack(Track track, Location lastLocation); + public void writeEndTracks(); /** - * Writes the statements necessary to open a new segment. + * Writes the beginning of a track. + * + * @param track the track + * @param startLocation the start location + */ + public void writeBeginTrack(Track track, Location startLocation); + + /** + * Writes the end of a track. + * + * @param track the track + * @param endLocation the end location + */ + public void writeEndTrack(Track track, Location endLocation); + + /** + * Writes open segment. */ public void writeOpenSegment(); /** - * Writes the statements necessary to close a segment. + * Writes close segment. */ public void writeCloseSegment(); /** * Writes a location. - * + * * @param location the location */ public void writeLocation(Location location); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java index 157947447..0b222d750 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java @@ -441,8 +441,8 @@ public class SyncUtils { java.io.File file = new java.io.File(directory, FileUtils.buildUniqueFileName(directory, track.getName(), trackFileFormat.getExtension())); - FileTrackExporter fileTrackExporter = new FileTrackExporter( - myTracksProviderUtils, new Track[] { track }, trackFileFormat, context, false, null); + FileTrackExporter fileTrackExporter = new FileTrackExporter(myTracksProviderUtils, + new Track[] { track }, trackFileFormat.newTrackWriter(context, false), null); FileOutputStream fileOutputStream = null; try { diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/content/MyTracksProviderTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/content/MyTracksProviderTest.java index 3622175e4..75fb116ab 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/content/MyTracksProviderTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/content/MyTracksProviderTest.java @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ + package com.google.android.apps.mytracks.content; import com.google.android.apps.mytracks.content.MyTracksProvider.DatabaseHelper; @@ -22,150 +23,202 @@ import android.net.Uri; import android.test.AndroidTestCase; /** - * A unit test for {@link MyTracksProvider}. + * Tests {@link MyTracksProvider}. * * @author Youtao Liu */ public class MyTracksProviderTest extends AndroidTestCase { + private static final String DATABASE_NAME = "mytrackstest.db"; + private SQLiteDatabase db; private MyTracksProvider myTracksProvider; - private String DATABASE_NAME = "mytrackstest.db"; @Override protected void setUp() throws Exception { + super.setUp(); getContext().deleteDatabase(DATABASE_NAME); db = (new DatabaseHelper(getContext(), DATABASE_NAME)).getWritableDatabase(); - myTracksProvider = new MyTracksProvider(); - super.setUp(); } /** - * Tests the method {@link MyTracksProvider.DatabaseHelper#onCreate()}. + * Tests {@link MyTracksProvider.DatabaseHelper#onCreate(SQLiteDatabase)}. */ public void testDatabaseHelper_OnCreate() { - assertTrue(checkTable(TrackPointsColumns.TABLE_NAME)); - assertTrue(checkTable(TracksColumns.TABLE_NAME)); - assertTrue(checkTable(WaypointsColumns.TABLE_NAME)); + assertTrue(hasTable(TracksColumns.TABLE_NAME)); + assertTrue(hasTable(TrackPointsColumns.TABLE_NAME)); + assertTrue(hasTable(WaypointsColumns.TABLE_NAME)); } /** - * Tests the method - * {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, int)} - * when version is less than 17. + * Tests {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, + * int)} when version is less than 17. */ public void testDatabaseHelper_onUpgrade_Version16() { - DatabaseHelper databaseHelper = new DatabaseHelper(getContext()); - dropTable(TrackPointsColumns.TABLE_NAME); dropTable(TracksColumns.TABLE_NAME); + dropTable(TrackPointsColumns.TABLE_NAME); dropTable(WaypointsColumns.TABLE_NAME); - databaseHelper.onUpgrade(db, 16, 20); - assertTrue(checkTable(TrackPointsColumns.TABLE_NAME)); - assertTrue(checkTable(TracksColumns.TABLE_NAME)); - assertTrue(checkTable(WaypointsColumns.TABLE_NAME)); + + int oldVersion = 16; + DatabaseHelper databaseHelper = new DatabaseHelper(getContext()); + databaseHelper.onUpgrade(db, oldVersion, MyTracksProvider.DATABASE_VERSION); + + assertTrue(hasTable(TracksColumns.TABLE_NAME)); + assertTrue(hasTable(TrackPointsColumns.TABLE_NAME)); + assertTrue(hasTable(WaypointsColumns.TABLE_NAME)); } /** - * Tests the method - * {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, int)} - * when version is 17. + * Tests {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, + * int)} when version is 17. */ public void testDatabaseHelper_onUpgrade_Version17() { - DatabaseHelper databaseHelper = new DatabaseHelper(getContext()); + setupUpgrade(17); - // Make two table is only contains one normal integer column. - dropTable(TrackPointsColumns.TABLE_NAME); - dropTable(TracksColumns.TABLE_NAME); - createEmptyTable(TrackPointsColumns.TABLE_NAME); - createEmptyTable(TracksColumns.TABLE_NAME); - databaseHelper.onUpgrade(db, 17, 20); - assertTrue(isColumnExisted(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); - assertTrue(isColumnExisted(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); - assertTrue(isColumnExisted(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertTrue(hasColumn(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.DRIVEID)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.MODIFIEDTIME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDWITHME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDOWNER)); + assertTrue(hasColumn(WaypointsColumns.TABLE_NAME, WaypointsColumns.PHOTOURL)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.CALORIE)); } /** - * Tests the method - * {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, int)} - * when version is 18. + * Tests {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, + * int)} when version is 18. */ public void testDatabaseHelper_onUpgrade_Version18() { - DatabaseHelper databaseHelper = new DatabaseHelper(getContext()); + setupUpgrade(18); - // Make two table is only contains one normal integer column. - dropTable(TrackPointsColumns.TABLE_NAME); - dropTable(TracksColumns.TABLE_NAME); - createEmptyTable(TrackPointsColumns.TABLE_NAME); - createEmptyTable(TracksColumns.TABLE_NAME); - databaseHelper.onUpgrade(db, 18, 20); - assertFalse(isColumnExisted(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); - assertTrue(isColumnExisted(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); - assertTrue(isColumnExisted(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertFalse(hasColumn(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.DRIVEID)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.MODIFIEDTIME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDWITHME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDOWNER)); + assertTrue(hasColumn(WaypointsColumns.TABLE_NAME, WaypointsColumns.PHOTOURL)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.CALORIE)); } /** - * Tests the method - * {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, int)} - * when version is 19. + * Tests {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, + * int)} when version is 19. */ public void testDatabaseHelper_onUpgrade_Version19() { - DatabaseHelper databaseHelper = new DatabaseHelper(getContext()); + setupUpgrade(19); - // Make two table is only contains one normal integer column. - dropTable(TrackPointsColumns.TABLE_NAME); - dropTable(TracksColumns.TABLE_NAME); - createEmptyTable(TrackPointsColumns.TABLE_NAME); - createEmptyTable(TracksColumns.TABLE_NAME); - databaseHelper.onUpgrade(db, 19, 20); - assertFalse(isColumnExisted(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); - assertFalse(isColumnExisted(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); - assertTrue(isColumnExisted(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertFalse(hasColumn(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.DRIVEID)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.MODIFIEDTIME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDWITHME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDOWNER)); + assertTrue(hasColumn(WaypointsColumns.TABLE_NAME, WaypointsColumns.PHOTOURL)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.CALORIE)); } /** - * Tests the method {@link MyTracksProvider#onCreate()}. + * Tests {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, + * int)} when version is 20. + */ + public void testDatabaseHelper_onUpgrade_Version20() { + setupUpgrade(20); + + assertFalse(hasColumn(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.DRIVEID)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.MODIFIEDTIME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDWITHME)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDOWNER)); + assertTrue(hasColumn(WaypointsColumns.TABLE_NAME, WaypointsColumns.PHOTOURL)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.CALORIE)); + } + + /** + * Tests {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, + * int)} when version is 21. + */ + public void testDatabaseHelper_onUpgrade_Version21() { + setupUpgrade(21); + + assertFalse(hasColumn(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.DRIVEID)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.MODIFIEDTIME)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDWITHME)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDOWNER)); + assertTrue(hasColumn(WaypointsColumns.TABLE_NAME, WaypointsColumns.PHOTOURL)); + assertTrue(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.CALORIE)); + } + + /** + * Tests {@link MyTracksProvider.DatabaseHelper#onUpgrade(SQLiteDatabase, int, + * int)} when version is 22. + */ + public void testDatabaseHelper_onUpgrade_Version22() { + setupUpgrade(22); + + assertFalse(hasColumn(TrackPointsColumns.TABLE_NAME, TrackPointsColumns.SENSOR)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.TABLEID)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.ICON)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.DRIVEID)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.MODIFIEDTIME)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDWITHME)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.SHAREDOWNER)); + assertFalse(hasColumn(WaypointsColumns.TABLE_NAME, WaypointsColumns.PHOTOURL)); + assertFalse(hasColumn(TracksColumns.TABLE_NAME, TracksColumns.CALORIE)); + } + + /** + * Tests {@link MyTracksProvider#onCreate(android.content.Context)}. */ public void testOnCreate() { assertTrue(myTracksProvider.onCreate(getContext())); } /** - * Tests the method {@link MyTracksProvider#getType(Uri)}. + * Tests {@link MyTracksProvider#getType(Uri)}. */ public void testGetType() { - assertEquals(TrackPointsColumns.CONTENT_TYPE, - myTracksProvider.getType(TrackPointsColumns.CONTENT_URI)); assertEquals(TracksColumns.CONTENT_TYPE, myTracksProvider.getType(TracksColumns.CONTENT_URI)); - assertEquals(WaypointsColumns.CONTENT_TYPE, - myTracksProvider.getType(WaypointsColumns.CONTENT_URI)); + assertEquals( + TrackPointsColumns.CONTENT_TYPE, myTracksProvider.getType(TrackPointsColumns.CONTENT_URI)); + assertEquals( + WaypointsColumns.CONTENT_TYPE, myTracksProvider.getType(WaypointsColumns.CONTENT_URI)); } /** - * Creates an table only contains one column. + * Creates a table, containing one column. * - * @param table the name of table + * @param table the table name */ - private void createEmptyTable(String table) { + private void createTable(String table) { db.execSQL("CREATE TABLE " + table + " (test INTEGER)"); } /** * Drops a table in database. * - * @param table + * @param table the table name */ private void dropTable(String table) { db.execSQL("Drop TABLE " + table); } /** - * Checks whether a table is existed. + * Returns true if the table exists. * - * @param table the name of table - * @return true means the table has existed + * @param table the table name */ - private boolean checkTable(String table) { + private boolean hasTable(String table) { try { db.rawQuery("select count(*) from " + table, null); return true; @@ -175,14 +228,12 @@ public class MyTracksProviderTest extends AndroidTestCase { } /** - * Checks whether a column in a table is existed by whether can order by the - * column. + * Returns true if the column in the table exists. * - * @param table the name of table - * @param column the name of column - * @return true means the column has existed + * @param table the table name + * @param column the column name */ - private boolean isColumnExisted(String table, String column) { + private boolean hasColumn(String table, String column) { try { db.execSQL("SElECT count(*) from " + table + " order by " + column); } catch (Exception e) { @@ -193,4 +244,20 @@ public class MyTracksProviderTest extends AndroidTestCase { return true; } + /** + * Sets up upgrade. + * + * @param oldVersion thd old database version + */ + private void setupUpgrade(int oldVersion) { + dropTable(TracksColumns.TABLE_NAME); + dropTable(TrackPointsColumns.TABLE_NAME); + dropTable(WaypointsColumns.TABLE_NAME); + createTable(TracksColumns.TABLE_NAME); + createTable(TrackPointsColumns.TABLE_NAME); + createTable(WaypointsColumns.TABLE_NAME); + + DatabaseHelper databaseHelper = new DatabaseHelper(getContext()); + databaseHelper.onUpgrade(db, oldVersion, MyTracksProvider.DATABASE_VERSION); + } } \ No newline at end of file diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java index 1eb7b2cd7..e4a8a88a4 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java @@ -33,9 +33,9 @@ import android.test.AndroidTestCase; */ public class ChartFragmentTest extends AndroidTestCase { - private ChartFragment chartFragment; + private static final double HOURS_PER_UNIT = 60.0; - private final double HOURS_PER_UNIT = 60.0; + private ChartFragment chartFragment; @Override protected void setUp() throws Exception { @@ -46,7 +46,7 @@ public class ChartFragmentTest extends AndroidTestCase { /** * Tests the logic to get the incorrect values of sensor in - * {@link ChartFragment#fillDataPoint(Location, double[])} + * {@link ChartFragment#fillDataPoint(android.content.Context, Location, double[])} */ public void testFillDataPoint_sensorIncorrect() { MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation(); @@ -83,7 +83,7 @@ public class ChartFragmentTest extends AndroidTestCase { /** * Tests the logic to get the correct values of sensor in - * {@link ChartFragment#fillDataPoint(Location, double[])}. + * {@link ChartFragment#fillDataPoint(android.content.Context, Location, double[])}. */ public void testFillDataPoint_sensorCorrect() { MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation(); @@ -118,7 +118,7 @@ public class ChartFragmentTest extends AndroidTestCase { /** * Tests the logic to get the value of metric Distance in - * {@link ChartFragment#fillDataPoint(Location, double[])}. + * {@link ChartFragment#fillDataPoint(android.content.Context, Location, double[])}. */ public void testFillDataPoint_distanceMetric() { // By distance. @@ -159,7 +159,7 @@ public class ChartFragmentTest extends AndroidTestCase { /** * Tests the logic to get the value of imperial Distance in - * {@link ChartFragment#fillDataPoint(Location, double[])}. + * {@link ChartFragment#fillDataPoint(android.content.Context, Location, double[])}. */ public void testFillDataPoint_distanceImperial() { // By distance. @@ -204,7 +204,7 @@ public class ChartFragmentTest extends AndroidTestCase { /** * Tests the logic to get the values of time in - * {@link ChartFragment#fillDataPoint(Location, double[])}. + * {@link ChartFragment#fillDataPoint(android.content.Context, Location, double[])}. */ public void testFillDataPoint_time() { // By time @@ -220,9 +220,9 @@ public class ChartFragmentTest extends AndroidTestCase { } /** - * Tests the logic to get the value of elevation in - * {@link ChartFragment#fillDataPoint(Location, double[])} by one and two - * points. + * Tests the logic to get the value of elevation in + * {@link ChartFragment#fillDataPoint(android.content.Context, + * Location, double[])} by one and two points. */ public void testFillDataPoint_elevation() { MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation(); @@ -247,9 +247,10 @@ public class ChartFragmentTest extends AndroidTestCase { /** * Tests the logic to get the value of speed in - * {@link ChartFragment#fillDataPoint(Location, double[])}. In this test, - * firstly remove all points in memory, and then fill in two points one by - * one. The speed values of these points are 129, 130. + * {@link ChartFragment#fillDataPoint(android.content.Context, Location, double[])}. In this test, + * firstly remove all points in memory, + * and then fill in two points one by one. The speed values of these points + * are 129, 130. */ public void testFillDataPoint_speed() { /* @@ -358,7 +359,7 @@ public class ChartFragmentTest extends AndroidTestCase { */ private double[] fillDataPointTestHelper(Location location) { double[] point = new double[ChartView.NUM_SERIES + 1]; - chartFragment.fillDataPoint(location, point); + chartFragment.fillDataPoint(getContext(), location, point); return point; } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporterTest.java index 22ccc135d..5c524bc2c 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporterTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/FileTrackExporterTest.java @@ -7,9 +7,6 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Waypoint; -import com.google.android.apps.mytracks.io.file.exporter.FileTrackExporter; -import com.google.android.apps.mytracks.io.file.exporter.TrackExporterListener; -import com.google.android.apps.mytracks.io.file.exporter.TrackWriter; import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext; import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory; @@ -42,7 +39,7 @@ public class FileTrackExporterTest extends AndroidTestCase { private IMocksControl mocksControl; private TrackWriter trackWriter; - private Track track; + private Track[] tracks; private OutputStream outputStream; private FileTrackExporter fileTrackExporter; @@ -65,10 +62,12 @@ public class FileTrackExporterTest extends AndroidTestCase { mocksControl = EasyMock.createStrictControl(); trackWriter = mocksControl.createMock(TrackWriter.class); - track = new Track(); + Track track = new Track(); track.setName(TRACK_NAME); track.setId(TRACK_ID); + tracks = new Track[] {track}; + outputStream = new ByteArrayOutputStream(); TrackExporterListener trackExporterListener = new TrackExporterListener() { @@ -79,7 +78,7 @@ public class FileTrackExporterTest extends AndroidTestCase { } }; fileTrackExporter = new FileTrackExporter( - myTracksProviderUtils, new Track[] { track }, trackWriter, trackExporterListener); + myTracksProviderUtils, tracks, trackWriter, trackExporterListener); } @Override @@ -95,10 +94,13 @@ public class FileTrackExporterTest extends AndroidTestCase { // Set expected mock behavior trackWriter.prepare(outputStream); - trackWriter.writeHeader(track); - trackWriter.writeBeginTrack(track, null); - trackWriter.writeEndTrack(track, null); + trackWriter.writeHeader(tracks); + trackWriter.writeBeginTracks(); + trackWriter.writeBeginTrack(tracks[0], null); + trackWriter.writeEndTrack(tracks[0], null); + trackWriter.writeEndTracks(); trackWriter.writeFooter(); + trackWriter.close(); mocksControl.replay(); assertTrue(fileTrackExporter.writeTrack(outputStream)); @@ -124,11 +126,14 @@ public class FileTrackExporterTest extends AndroidTestCase { // Set expected mock behavior trackWriter.prepare(outputStream); - trackWriter.writeHeader(track); - trackWriter.writeBeginTrack(track, null); - trackWriter.writeEndTrack(track, null); + trackWriter.writeHeader(tracks); + trackWriter.writeBeginTracks(); + trackWriter.writeBeginTrack(tracks[0], null); + trackWriter.writeEndTrack(tracks[0], null); + trackWriter.writeEndTracks(); trackWriter.writeFooter(); - + trackWriter.close(); + mocksControl.replay(); assertTrue(fileTrackExporter.writeTrack(outputStream)); @@ -161,16 +166,17 @@ public class FileTrackExporterTest extends AndroidTestCase { } trackWriter.prepare(outputStream); - trackWriter.writeHeader(track); + trackWriter.writeHeader(tracks); // Expect reading/writing of the waypoints (except the first) - trackWriter.writeBeginWaypoints(); + trackWriter.writeBeginWaypoints(tracks[0]); trackWriter.writeWaypoint(waypointEq(waypoints[1])); trackWriter.writeWaypoint(waypointEq(waypoints[2])); trackWriter.writeEndWaypoints(); // Begin the track - trackWriter.writeBeginTrack(trackEq(track), locationEq(locations[0])); + trackWriter.writeBeginTracks(); + trackWriter.writeBeginTrack(trackEq(tracks[0]), locationEq(locations[0])); // Write locations 1-2 trackWriter.writeOpenSegment(); @@ -188,10 +194,12 @@ public class FileTrackExporterTest extends AndroidTestCase { trackWriter.writeCloseSegment(); // End the track - trackWriter.writeEndTrack(trackEq(track), locationEq(locations[5])); - + trackWriter.writeEndTrack(trackEq(tracks[0]), locationEq(locations[5])); + trackWriter.writeEndTracks(); + trackWriter.writeFooter(); - + trackWriter.close(); + mocksControl.replay(); assertTrue(fileTrackExporter.writeTrack(outputStream)); diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriterTest.java index e4adae4bc..e73c3d479 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriterTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/KmlTrackWriterTest.java @@ -17,7 +17,6 @@ package com.google.android.apps.mytracks.io.file.exporter; import com.google.android.apps.mytracks.content.DescriptionGenerator; import com.google.android.apps.mytracks.content.Track; -import com.google.android.apps.mytracks.io.file.exporter.KmlTrackWriter; import com.google.android.apps.mytracks.stats.TripStatistics; import android.location.Location; diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriterTest.java index 99f718bfd..cd8e3f622 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriterTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/exporter/TrackWriterTest.java @@ -5,7 +5,6 @@ import com.google.android.apps.mytracks.content.MyTracksLocation; import com.google.android.apps.mytracks.content.Sensor; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Waypoint; -import com.google.android.apps.mytracks.io.file.exporter.TrackWriter; import android.test.AndroidTestCase; @@ -117,11 +116,12 @@ public abstract class TrackWriterTest extends AndroidTestCase { protected String writeTrack(TrackWriter trackWriter) throws Exception { OutputStream output = new ByteArrayOutputStream(BUFFER_SIZE); trackWriter.prepare(output); - trackWriter.writeHeader(track); - trackWriter.writeBeginWaypoints(); + trackWriter.writeHeader(new Track[] {track}); + trackWriter.writeBeginWaypoints(track); trackWriter.writeWaypoint(wp1); trackWriter.writeWaypoint(wp2); trackWriter.writeEndWaypoints(); + trackWriter.writeBeginTracks(); trackWriter.writeBeginTrack(track, location1); trackWriter.writeOpenSegment(); trackWriter.writeLocation(location1); @@ -132,7 +132,9 @@ public abstract class TrackWriterTest extends AndroidTestCase { trackWriter.writeLocation(location4); trackWriter.writeCloseSegment(); trackWriter.writeEndTrack(track, location4); + trackWriter.writeEndTracks(); trackWriter.writeFooter(); + trackWriter.close(); return output.toString(); }