diff --git a/MyTracks/res/drawable-hdpi/track_run.png b/MyTracks/res/drawable-hdpi/track_run.png
index bd3c873e0..8ca86ad23 100755
Binary files a/MyTracks/res/drawable-hdpi/track_run.png and b/MyTracks/res/drawable-hdpi/track_run.png differ
diff --git a/MyTracks/res/drawable-mdpi/track_run.png b/MyTracks/res/drawable-mdpi/track_run.png
index 61439d736..c84476f43 100755
Binary files a/MyTracks/res/drawable-mdpi/track_run.png and b/MyTracks/res/drawable-mdpi/track_run.png differ
diff --git a/MyTracks/res/drawable-xhdpi/track_run.png b/MyTracks/res/drawable-xhdpi/track_run.png
index 0a888debb..403d4d11d 100755
Binary files a/MyTracks/res/drawable-xhdpi/track_run.png and b/MyTracks/res/drawable-xhdpi/track_run.png differ
diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml
index d760c71c6..ebf2d632d 100644
--- a/MyTracks/res/values/keys.xml
+++ b/MyTracks/res/values/keys.xml
@@ -47,9 +47,7 @@ limitations under the License.
sendToFusionTables
sendToMaps
sensorType
- showCheckUnitsDialog
showConfrimSharingDialog
- showWelcomeDialog
splitFrequency
statsShowCoordinate
statsShowElevation
diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java
index e3527df64..8261ad858 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java
@@ -278,23 +278,21 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
* Shows start up dialogs.
*/
public void showStartupDialogs() {
- if (!EulaUtils.getEulaValue(this)) {
+ if (!EulaUtils.getAcceptEula(this)) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(EulaDialogFragment.EULA_DIALOG_TAG);
if (fragment == null) {
EulaDialogFragment.newInstance(false)
.show(getSupportFragmentManager(), EulaDialogFragment.EULA_DIALOG_TAG);
}
- } else if (PreferencesUtils.getBoolean(
- this, R.string.show_welcome_dialog_key, PreferencesUtils.SHOW_WELCOME_DIALOG_DEFAULT)) {
+ } else if (EulaUtils.getShowWelcome(this)) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(WelcomeDialogFragment.WELCOME_DIALOG_TAG);
if (fragment == null) {
new WelcomeDialogFragment().show(
getSupportFragmentManager(), WelcomeDialogFragment.WELCOME_DIALOG_TAG);
}
- } else if (PreferencesUtils.getBoolean(this, R.string.show_check_units_dialog_key,
- PreferencesUtils.SHOW_CHECK_UNITS_DIALOG_DEFAULT)) {
+ } else if (EulaUtils.getShowCheckUnits(this)) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(CheckUnitsDialogFragment.CHECK_UNITS_DIALOG_TAG);
if (fragment == null) {
diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/CheckUnitsDialogFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/CheckUnitsDialogFragment.java
index 41953a8c8..68fa93ba4 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/fragments/CheckUnitsDialogFragment.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/CheckUnitsDialogFragment.java
@@ -17,6 +17,7 @@
package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.TrackListActivity;
+import com.google.android.apps.mytracks.util.EulaUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
@@ -69,7 +70,7 @@ public class CheckUnitsDialogFragment extends DialogFragment {
* Tasks to perform when done.
*/
private void onDone() {
- PreferencesUtils.setBoolean(getActivity(), R.string.show_check_units_dialog_key, false);
+ EulaUtils.setShowCheckUnits(getActivity());
TrackListActivity trackListActivity = (TrackListActivity) getActivity();
trackListActivity.showStartupDialogs();
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/EulaDialogFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/EulaDialogFragment.java
index 6c1affb84..65c255193 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/fragments/EulaDialogFragment.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/EulaDialogFragment.java
@@ -77,7 +77,7 @@ public class EulaDialogFragment extends DialogFragment {
.setPositiveButton(R.string.eula_accept, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- EulaUtils.setEulaValue(getActivity());
+ EulaUtils.setAcceptEula(getActivity());
TrackListActivity trackListActivity = (TrackListActivity) getActivity();
trackListActivity.showStartupDialogs();
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/WelcomeDialogFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/WelcomeDialogFragment.java
index c1d72d99e..92bcec677 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/fragments/WelcomeDialogFragment.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/WelcomeDialogFragment.java
@@ -17,7 +17,7 @@
package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.TrackListActivity;
-import com.google.android.apps.mytracks.util.PreferencesUtils;
+import com.google.android.apps.mytracks.util.EulaUtils;
import com.google.android.maps.mytracks.R;
import android.app.AlertDialog;
@@ -55,7 +55,7 @@ public class WelcomeDialogFragment extends DialogFragment {
}
private void onDone() {
- PreferencesUtils.setBoolean(getActivity(), R.string.show_welcome_dialog_key, false);
+ EulaUtils.setShowWelcome(getActivity());
TrackListActivity trackListActivity = (TrackListActivity) getActivity();
trackListActivity.showStartupDialogs();
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/GpxImporter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/GpxImporter.java
index 7fe573a8d..06f155df2 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/file/GpxImporter.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/GpxImporter.java
@@ -31,6 +31,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
@@ -42,19 +43,15 @@ import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
- * Imports GPX XML files to the my tracks provider.
- *
- * TODO: Show progress indication to the user.
- *
+ * Imports GPX file to My Tracks.
+ *
* @author Leif Hendrik Wilden
* @author Steffen Horlacher
* @author Rodrigo Damazio
*/
public class GpxImporter extends DefaultHandler {
- /*
- * GPX-XML tag names and attributes.
- */
+ // GPX tag names and attributes.
private static final String TAG_TRACK = "trk";
private static final String TAG_TRACK_POINT = "trkpt";
private static final Object TAG_TRACK_SEGMENT = "trkseg";
@@ -66,20 +63,21 @@ public class GpxImporter extends DefaultHandler {
private static final String ATT_LON = "lon";
/**
- * The maximum number of locations to buffer for bulk-insertion into the database.
+ * The maximum number of locations to buffer for bulk-insertion into the
+ * database.
*/
private static final int MAX_BUFFERED_LOCATIONS = 512;
/**
- * Utilities for accessing the contnet provider.
+ * Utilities for accessing the content provider.
*/
- private final MyTracksProviderUtils providerUtils;
+ private final MyTracksProviderUtils myTracksProviderUtils;
/**
* List of track ids written in the database. Only contains successfully
* written tracks.
*/
- private final List tracksWritten;
+ private final List tracksIds;
/**
* Contains the current elements content.
@@ -87,15 +85,20 @@ public class GpxImporter extends DefaultHandler {
private String content;
/**
- * Currently reading location.
+ * Currently location.
*/
private Location location;
/**
- * Previous location, required for calculations.
+ * Last location.
*/
private Location lastLocation;
-
+
+ /**
+ * Last segment location.
+ */
+ private Location lastSegmentLocation;
+
/**
* Currently reading track.
*/
@@ -104,7 +107,7 @@ public class GpxImporter extends DefaultHandler {
/**
* Statistics builder for the current track.
*/
- private TripStatisticsBuilder statsBuilder;
+ private TripStatisticsBuilder tripStatisticsBuilder;
/**
* Buffer of locations to be bulk-inserted into the database.
@@ -115,82 +118,79 @@ public class GpxImporter extends DefaultHandler {
* Number of locations buffered to be inserted into the database.
*/
private int numBufferedPointInserts = 0;
-
+
/**
* Number of locations already processed.
*/
- private int numberOfLocations;
+ private int numberOfLocations = 0;
/**
* Number of segments already processed.
*/
- private int numberOfSegments;
+ private int numberOfSegments = 0;
/**
* Used to identify if a track was written to the database but not yet
* finished successfully.
*/
- private boolean isCurrentTrackRollbackable;
+ private boolean isCurrentTrackRollbackable = false;
/**
- * Flag to indicate if we're inside a track's xml element.
- * Some sub elements like name may be used in other parts of the gpx file,
- * and we use this to ignore them.
+ * Flag to indicate if we're inside a track's xml element. Some sub elements
+ * like name may be used in other parts of the GPX file, and we use this to
+ * ignore them.
*/
- private boolean isInTrackElement;
+ private boolean isInTrackElement = false;
/**
- * Counter to find out which child level of track we are processing.
+ * Counter to find out which child level of the track we are processing.
*/
- private int trackChildDepth;
+ private int trackChildDepth = 0;
/**
- * SAX-Locator to get current line information.
+ * SAX locator to get the current line information.
*/
private Locator locator;
- private Location lastSegmentLocation;
/**
* Reads GPS tracks from a GPX file and writes tracks and their coordinates to
* the database.
*
- * @param is a input steam with gpx-xml data
- * @return long[] array of track ids written in the database
- * @throws SAXException a parsing error
- * @throws ParserConfigurationException internal error
- * @throws IOException a file reading problem
+ * @param inputStream an input stream for the GPX file
+ * @param myTracksProviderUtils my tracks provider utils
+ * @return long[] array of track ids written to the database.
*/
- public static long[] importGPXFile(final InputStream is,
- final MyTracksProviderUtils providerUtils)
+ public static long[] importGPXFile(
+ final InputStream inputStream, final MyTracksProviderUtils myTracksProviderUtils)
throws ParserConfigurationException, SAXException, IOException {
- SAXParserFactory factory = SAXParserFactory.newInstance();
- GpxImporter handler = new GpxImporter(providerUtils);
- SAXParser parser = factory.newSAXParser();
- long[] trackIds = null;
+ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+ SAXParser saxParser = saxParserFactory.newSAXParser();
+ GpxImporter gpxImporter = new GpxImporter(myTracksProviderUtils);
+ long[] trackIds = new long[0];
try {
long start = System.currentTimeMillis();
- parser.parse(is, handler);
+ saxParser.parse(inputStream, gpxImporter);
long end = System.currentTimeMillis();
Log.d(Constants.TAG, "Total import time: " + (end - start) + "ms");
- trackIds = handler.getImportedTrackIds();
+ trackIds = gpxImporter.getImportedTrackIds();
+ if (trackIds.length == 0) {
+ throw new IOException("No track imported.");
+ }
} finally {
- // delete track if not finished
- handler.rollbackUnfinishedTracks();
+ // Delete track if not finished
+ gpxImporter.rollbackUnfinishedTracks();
}
return trackIds;
}
- /**
- * Constructor, requires providerUtils for writing tracks the database.
- */
- public GpxImporter(MyTracksProviderUtils providerUtils) {
- this.providerUtils = providerUtils;
- tracksWritten = new ArrayList();
+ public GpxImporter(MyTracksProviderUtils myTracksProviderUtils) {
+ this.myTracksProviderUtils = myTracksProviderUtils;
+ tracksIds = new ArrayList();
}
@Override
@@ -199,16 +199,18 @@ public class GpxImporter extends DefaultHandler {
if (content == null) {
content = newContent;
} else {
- // In 99% of the cases, a single call to this method will be made for each
- // sequence of characters we're interested in, so we'll rarely be
- // concatenating strings, thus not justifying the use of a StringBuilder.
+ /*
+ * In 99% of the cases, a single call to this method will be made for each
+ * sequence of characters we're interested in, so we'll rarely be
+ * concatenating strings, thus not justifying the use of a StringBuilder.
+ */
content += newContent;
}
}
@Override
- public void startElement(String uri, String localName, String name,
- Attributes attributes) throws SAXException {
+ public void startElement(String uri, String localName, String name, Attributes attributes)
+ throws SAXException {
if (isInTrackElement) {
trackChildDepth++;
if (localName.equals(TAG_TRACK_POINT)) {
@@ -216,8 +218,7 @@ public class GpxImporter extends DefaultHandler {
} else if (localName.equals(TAG_TRACK_SEGMENT)) {
onTrackSegmentElementStart();
} else if (localName.equals(TAG_TRACK)) {
- String msg = createErrorMessage("Invalid GPX-XML detected");
- throw new SAXException(msg);
+ throw new SAXException(createErrorMessage("Invalid GPX detected."));
}
} else if (localName.equals(TAG_TRACK)) {
isInTrackElement = true;
@@ -227,8 +228,7 @@ public class GpxImporter extends DefaultHandler {
}
@Override
- public void endElement(String uri, String localName, String name)
- throws SAXException {
+ public void endElement(String uri, String localName, String name) throws SAXException {
if (!isInTrackElement) {
content = null;
return;
@@ -270,33 +270,58 @@ public class GpxImporter extends DefaultHandler {
}
/**
- * Create a new Track object and insert empty track in database. Track will be
- * updated with missing values later.
+ * Rolls back last track if possible.
+ */
+ public void rollbackUnfinishedTracks() {
+ if (isCurrentTrackRollbackable) {
+ myTracksProviderUtils.deleteTrack(track.getId());
+ isCurrentTrackRollbackable = false;
+ }
+ }
+
+ /**
+ * On track element start.
*/
private void onTrackElementStart() {
track = new Track();
numberOfLocations = 0;
- Uri trackUri = providerUtils.insertTrack(track);
- long trackId = Long.parseLong(trackUri.getLastPathSegment());
+ Uri uri = myTracksProviderUtils.insertTrack(track);
+ long trackId = Long.parseLong(uri.getLastPathSegment());
track.setId(trackId);
isCurrentTrackRollbackable = true;
}
- private void onDescriptionElementEnd() {
- track.setDescription(content.toString().trim());
- }
+ /**
+ * On track element end.
+ */
+ private void onTrackElementEnd() {
+ if (lastLocation != null) {
+ flushPoints();
- private void onNameElementEnd() {
- track.setName(content.toString().trim());
+ // Calculate statistics for the imported track
+ tripStatisticsBuilder.pauseAt(lastLocation.getTime());
+ track.setStopId(getLastPointId());
+ } else {
+ tripStatisticsBuilder = new TripStatisticsBuilder(0);
+ tripStatisticsBuilder.pauseAt(0);
+ }
+ track.setTripStatistics(tripStatisticsBuilder.getStatistics());
+ track.setNumberOfPoints(numberOfLocations);
+ myTracksProviderUtils.updateTrack(track);
+ tracksIds.add(track.getId());
+ isCurrentTrackRollbackable = false;
+ lastSegmentLocation = null;
+ lastLocation = null;
+ tripStatisticsBuilder = null;
}
/**
- * Track segment started.
+ * On track segment start.
*/
private void onTrackSegmentElementStart() {
if (numberOfSegments > 0) {
- // Add a segment separator:
+ // Add a segment separator
location = new Location(LocationManager.GPS_PROVIDER);
location.setLatitude(100.0);
location.setLongitude(100.0);
@@ -304,73 +329,61 @@ public class GpxImporter extends DefaultHandler {
if (lastLocation != null) {
location.setTime(lastLocation.getTime());
}
- insertTrackPoint(location);
+ insertPoint(location);
lastLocation = location;
lastSegmentLocation = null;
location = null;
}
-
numberOfSegments++;
}
/**
- * Reads trackpoint attributes and assigns them to the current location.
- *
- * @param attributes xml attributes
+ * On track segment element end.
+ */
+ private void onTrackSegmentElementEnd() {
+ // Nothing to be done
+ }
+
+ /**
+ * On track point element start.
+ *
+ * @param attributes the attributes
*/
private void onTrackPointElementStart(Attributes attributes) throws SAXException {
if (location != null) {
- String errorMsg = createErrorMessage("Found a track point inside another one.");
- throw new SAXException(errorMsg);
+ throw new SAXException(createErrorMessage("Found a track point inside another one."));
}
-
- location = createLocationFromAttributes(attributes);
- }
-
- /**
- * Creates and returns a location with the position parsed from the given
- * attributes.
- *
- * @param attributes the attributes to parse
- * @return the created location
- * @throws SAXException if the attributes cannot be parsed
- */
- private Location createLocationFromAttributes(Attributes attributes) throws SAXException {
String latitude = attributes.getValue(ATT_LAT);
String longitude = attributes.getValue(ATT_LON);
-
+
if (latitude == null || longitude == null) {
- throw new SAXException(createErrorMessage("Point with no longitude or latitude"));
+ throw new SAXException(createErrorMessage("Point with no longitude or latitude."));
}
-
- // create new location and set attributes
- Location loc = new Location(LocationManager.GPS_PROVIDER);
+
+ Location newLocation = new Location(LocationManager.GPS_PROVIDER);
try {
- loc.setLatitude(Double.parseDouble(latitude));
- loc.setLongitude(Double.parseDouble(longitude));
+ newLocation.setLatitude(Double.parseDouble(latitude));
+ newLocation.setLongitude(Double.parseDouble(longitude));
} catch (NumberFormatException e) {
- String msg = createErrorMessage(
- "Unable to parse lat/long: " + latitude + "/" + longitude);
- throw new SAXException(msg, e);
+ throw new SAXException(createErrorMessage(
+ "Unable to parse latitude/longitude: " + latitude + "/" + longitude), e);
}
- return loc;
+ location = newLocation;
}
/**
- * Track point finished, write in database.
- *
- * @throws SAXException - thrown if track point is invalid
+ * On track point element end.
*/
private void onTrackPointElementEnd() throws SAXException {
if (LocationUtils.isValidLocation(location)) {
- if (statsBuilder == null) {
+ if (tripStatisticsBuilder == null) {
// first point did not have a time, start stats builder without it
- statsBuilder = new TripStatisticsBuilder(0);
+ tripStatisticsBuilder = new TripStatisticsBuilder(0);
}
- statsBuilder.addLocation(location, location.getTime());
+ tripStatisticsBuilder.addLocation(location, location.getTime());
// insert in db
- insertTrackPoint(location);
+ insertPoint(location);
// first track point?
if (lastLocation == null && numberOfSegments == 1) {
@@ -382,78 +395,31 @@ public class GpxImporter extends DefaultHandler {
location = null;
} else {
// invalid location - abort import
- String msg = createErrorMessage("Invalid location detected: " + location);
- throw new SAXException(msg);
- }
- }
-
- private void insertTrackPoint(Location loc) {
- bufferedPointInserts[numBufferedPointInserts] = loc;
- numBufferedPointInserts++;
- numberOfLocations++;
-
- if (numBufferedPointInserts >= MAX_BUFFERED_LOCATIONS) {
- flushPointInserts();
- }
- }
-
- private void flushPointInserts() {
- if (numBufferedPointInserts <= 0) { return; }
-
- providerUtils.bulkInsertTrackPoints(bufferedPointInserts, numBufferedPointInserts, track.getId());
- numBufferedPointInserts = 0;
- }
-
- /**
- * Track segment finished.
- */
- private void onTrackSegmentElementEnd() {
- // Nothing to be done
- }
-
- /**
- * Track finished - update in database.
- */
- private void onTrackElementEnd() {
- if (lastLocation != null) {
- flushPointInserts();
-
- // Calculate statistics for the imported track and update
- statsBuilder.pauseAt(lastLocation.getTime());
- track.setStopId(getLastPointId());
- track.setNumberOfPoints(numberOfLocations);
- track.setTripStatistics(statsBuilder.getStatistics());
- providerUtils.updateTrack(track);
- tracksWritten.add(track.getId());
- isCurrentTrackRollbackable = false;
- lastSegmentLocation = null;
- lastLocation = null;
- statsBuilder = null;
- } else {
- // track contains no track points makes no real
- // sense to import it as we have no location
- // information -> roll back
- rollbackUnfinishedTracks();
+ throw new SAXException(createErrorMessage("Invalid location detected: " + location));
}
}
/**
- * Setting time and doing additional calculations as this is the last value
- * required. Also sets the start time for track and statistics as there is no
- * start time in the track root element.
- *
- * @throws SAXException on parsing errors
+ * On time element end. Sets location time and doing additional calculations
+ * as this is the last value required for the location. Also sets the start time
+ * for the trip statistics builder as there is no start time in the track root
+ * element.
*/
private void onTimeElementEnd() throws SAXException {
- if (location == null) { return; }
+ if (location == null) {
+ return;
+ }
+ if (content == null) {
+ return;
+ }
+
// Parse the time
long time;
try {
time = StringUtils.getTime(content.trim());
} catch (IllegalArgumentException e) {
- String msg = createErrorMessage("Unable to parse time: " + content);
- throw new SAXException(msg, e);
+ throw new SAXException(createErrorMessage("Unable to parse time: " + content), e);
}
// Calculate derived attributes from previous point
@@ -465,11 +431,12 @@ public class GpxImporter extends DefaultHandler {
Log.w(Constants.TAG, "Found negative time change.");
} else {
- // We don't have a speed and bearing in GPX, make something up from
- // the last two points.
- // TODO GPS points tend to have some inherent imprecision,
- // speed and bearing will likely be off, so the statistics for things like
- // max speed will also be off.
+ /*
+ * We don't have a speed and bearing in GPX, make something up from the
+ * last two points. GPS points tend to have some inherent imprecision,
+ * speed and bearing will likely be off, so the statistics for things
+ * like max speed will also be off.
+ */
float speed = location.distanceTo(lastLocation) * 1000.0f / timeDifference;
location.setSpeed(speed);
location.setBearing(lastSegmentLocation.bearingTo(location));
@@ -480,69 +447,96 @@ public class GpxImporter extends DefaultHandler {
location.setTime(time);
// initialize start time with time of first track point
- if (statsBuilder == null) {
- statsBuilder = new TripStatisticsBuilder(time);
+ if (tripStatisticsBuilder == null) {
+ tripStatisticsBuilder = new TripStatisticsBuilder(time);
}
}
+ /**
+ * On altitude element end.
+ */
private void onAltitudeElementEnd() throws SAXException {
- if (location != null) {
+ if (location != null && content != null) {
try {
location.setAltitude(Double.parseDouble(content));
} catch (NumberFormatException e) {
- String msg = createErrorMessage("Unable to parse altitude: " + content);
- throw new SAXException(msg, e);
+ throw new SAXException(createErrorMessage("Unable to parse altitude: " + content), e);
}
}
}
/**
- * Deletes the last track if it was not completely imported.
+ * On name element end.
*/
- public void rollbackUnfinishedTracks() {
- if (isCurrentTrackRollbackable) {
- providerUtils.deleteTrack(track.getId());
- isCurrentTrackRollbackable = false;
+ private void onNameElementEnd() {
+ if (content != null) {
+ track.setName(content.toString().trim());
}
}
/**
- * Get all track ids of the tracks created by this importer run.
+ * On description element end.
+ */
+ private void onDescriptionElementEnd() {
+ if (content != null) {
+ track.setDescription(content.toString().trim());
+ }
+ }
+
+ /**
+ * Inserts a point.
*
- * @return array of track ids
+ * @param newLocation the location
+ */
+ private void insertPoint(Location newLocation) {
+ bufferedPointInserts[numBufferedPointInserts] = newLocation;
+ numBufferedPointInserts++;
+ numberOfLocations++;
+
+ if (numBufferedPointInserts >= MAX_BUFFERED_LOCATIONS) {
+ flushPoints();
+ }
+ }
+
+ /**
+ * Flushes the points to the database.
+ */
+ private void flushPoints() {
+ if (numBufferedPointInserts <= 0) {
+ return;
+ }
+ myTracksProviderUtils.bulkInsertTrackPoints(
+ bufferedPointInserts, numBufferedPointInserts, track.getId());
+ numBufferedPointInserts = 0;
+ }
+
+ /**
+ * Gets the imported track ids.
+ *
*/
private long[] getImportedTrackIds() {
- // Convert from java.lang.Long for convenience
- long[] result = new long[tracksWritten.size()];
+ long[] result = new long[tracksIds.size()];
for (int i = 0; i < result.length; i++) {
- result[i] = tracksWritten.get(i);
+ result[i] = tracksIds.get(i);
}
return result;
}
/**
- * Returns the ID of the last point inserted into the database.
+ * Gets the last point id inserted into the database.
*/
private long getLastPointId() {
- flushPointInserts();
-
- return providerUtils.getLastLocationId(track.getId());
+ flushPoints();
+ return myTracksProviderUtils.getLastLocationId(track.getId());
}
/**
- * Builds a parsing error message with current line information.
+ * Creates an error message.
*
- * @param details details about the error, will be appended
- * @return error message string with current line information
+ * @param message the message
*/
- private String createErrorMessage(String details) {
- StringBuffer msg = new StringBuffer();
- msg.append("Parsing error at line: ");
- msg.append(locator.getLineNumber());
- msg.append(" column: ");
- msg.append(locator.getColumnNumber());
- msg.append(". ");
- msg.append(details);
- return msg.toString();
+ private String createErrorMessage(String message) {
+ return String.format(Locale.US, "Parsing error at line: %d column: %d. %s",
+ locator.getLineNumber(), locator.getColumnNumber(), message);
}
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackWriterImpl.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackWriterImpl.java
index 8fbf20975..e7fe59768 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackWriterImpl.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/TrackWriterImpl.java
@@ -318,7 +318,9 @@ class TrackWriterImpl implements TrackWriter {
locationFactory);
try {
if (!it.hasNext()) {
- Log.w(Constants.TAG, "Unable to get any points to write");
+ // Writes an empty track
+ writer.writeBeginTrack(null);
+ writer.writeEndTrack(null);
return;
}
int pointNumber = 0;
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/EulaUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/EulaUtils.java
index 8c683a3ff..29269a459 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/EulaUtils.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/EulaUtils.java
@@ -29,21 +29,47 @@ public class EulaUtils {
private static final String EULA_PREFERENCE_FILE = "eula";
// Accepting Google mobile terms of service
- private static final String EULA_PREFERENCE_KEY = "eula.google_mobile_tos_accepted";
-
+ private static final String ACCEPT_EULA_PREFERENCE_KEY = "eula.google_mobile_tos_accepted";
+ private static final String SHOW_WELCOME_PREFERENCE_KEY = "showWelcome";
+ private static final String SHOW_CHECK_UNITS_PREFERENCE_KEY = "showCheckUnits";
+
private EulaUtils() {}
- public static boolean getEulaValue(Context context) {
- SharedPreferences sharedPreferences = context.getSharedPreferences(
- EULA_PREFERENCE_FILE, Context.MODE_PRIVATE);
- return sharedPreferences.getBoolean(EULA_PREFERENCE_KEY, false);
+ public static boolean getAcceptEula(Context context) {
+ return getValue(context, ACCEPT_EULA_PREFERENCE_KEY, false);
}
- public static void setEulaValue(Context context) {
+ public static void setAcceptEula(Context context) {
+ setValue(context, ACCEPT_EULA_PREFERENCE_KEY, true);
+ }
+
+ public static boolean getShowWelcome(Context context) {
+ return getValue(context, SHOW_WELCOME_PREFERENCE_KEY, true);
+ }
+
+ public static void setShowWelcome(Context context) {
+ setValue(context, SHOW_WELCOME_PREFERENCE_KEY, false);
+ }
+
+ public static boolean getShowCheckUnits(Context context) {
+ return getValue(context, SHOW_CHECK_UNITS_PREFERENCE_KEY, true);
+ }
+
+ public static void setShowCheckUnits(Context context) {
+ setValue(context, SHOW_CHECK_UNITS_PREFERENCE_KEY, false);
+ }
+
+ private static boolean getValue(Context context, String key, boolean defaultValue) {
+ SharedPreferences sharedPreferences = context.getSharedPreferences(
+ EULA_PREFERENCE_FILE, Context.MODE_PRIVATE);
+ return sharedPreferences.getBoolean(key, defaultValue);
+ }
+
+ private static void setValue(Context context, String key, boolean value) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
EULA_PREFERENCE_FILE, Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();
- editor.putBoolean(EULA_PREFERENCE_KEY, true);
+ editor.putBoolean(key, value);
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
}
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java
index dc018bd5f..f13535c4f 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java
@@ -73,9 +73,7 @@ public class PreferencesUtils {
public static final boolean SEND_TO_DOCS_DEFAULT = true;
public static final boolean SEND_TO_FUSION_TABLES_DEFAULT = true;
public static final boolean SEND_TO_MAPS_DEFAULT = true;
- public static final boolean SHOW_CHECK_UNITS_DIALOG_DEFAULT = true;
public static final boolean SHOW_CONFIRM_SHARING_DIALOG_DEFAULT = true;
- public static final boolean SHOW_WELCOME_DIALOG_DEFAULT = true;
public static final int SPLIT_FREQUENCY_DEFAULT = 0;
public static final boolean STATS_SHOW_COORDINATE_DEFAULT = false;
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java
index 90684bc04..467221475 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/TrackWriterTest.java
@@ -225,6 +225,8 @@ public class TrackWriterTest extends AndroidTestCase {
// Set expected mock behavior
formatWriter.writeHeader();
+ formatWriter.writeBeginTrack(null);
+ formatWriter.writeEndTrack(null);
formatWriter.writeFooter();
formatWriter.close();
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java
index d20d5e96b..8c8f02205 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtilsTest.java
@@ -67,6 +67,7 @@ public class SendFusionTablesUtilsTest extends TestCase {
*/
public void testGetMapUrl_valid_track() {
Track track = new Track();
+ track.setNumberOfPoints(2);
TripStatistics stats = new TripStatistics();
stats.setBounds((int) 100.E6, (int) 10.E6, (int) 50.E6, (int) 5.E6);
track.setTripStatistics(stats);