diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java b/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java index 85bd7b2af..08f63bd20 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java @@ -492,52 +492,60 @@ public class TrackDataHub implements DataSourceListener { long lastTrackPointId = myTracksProviderUtils.getLastTrackPointId(selectedTrackId); int samplingFrequency = -1; - LocationIterator iterator = myTracksProviderUtils.getTrackPointLocationIterator(selectedTrackId, - localLastSeenLocationId + 1, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY); boolean includeNextPoint = false; - while (iterator.hasNext()) { - Location location = iterator.next(); - long locationId = iterator.getLocationId(); + LocationIterator locationIterator = null; - // Stop if past the last wanted point - if (maxPointId != -1L && locationId > maxPointId) { - break; - } + try { + locationIterator = myTracksProviderUtils.getTrackPointLocationIterator(selectedTrackId, + localLastSeenLocationId + 1, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY); - if (localFirstSeenLocationId == -1) { - localFirstSeenLocationId = locationId; - } + while (locationIterator.hasNext()) { + Location location = locationIterator.next(); + long locationId = locationIterator.getLocationId(); - if (samplingFrequency == -1) { - long numTotalPoints = Math.max(0L, lastTrackPointId - localFirstSeenLocationId); - samplingFrequency = 1 + (int) (numTotalPoints / targetNumPoints); - } - - if (!LocationUtils.isValidLocation(location)) { - // TODO: also include the last valid point before a split - for (TrackDataListener trackDataListener : sampledInListeners) { - trackDataListener.onSegmentSplit(location); - includeNextPoint = true; + // Stop if past the last wanted point + if (maxPointId != -1L && locationId > maxPointId) { + break; } - } else { - // Also include the last point if the selected track is not recording. - if (includeNextPoint || (localNumLoadedPoints % samplingFrequency == 0) - || (locationId == lastTrackPointId && !isSelectedTrackRecording())) { - includeNextPoint = false; + + if (localFirstSeenLocationId == -1) { + localFirstSeenLocationId = locationId; + } + + if (samplingFrequency == -1) { + long numTotalPoints = Math.max(0L, lastTrackPointId - localFirstSeenLocationId); + samplingFrequency = 1 + (int) (numTotalPoints / targetNumPoints); + } + + if (!LocationUtils.isValidLocation(location)) { + // TODO: also include the last valid point before a split for (TrackDataListener trackDataListener : sampledInListeners) { - trackDataListener.onSampledInTrackPoint(location); + trackDataListener.onSegmentSplit(location); + includeNextPoint = true; } } else { - for (TrackDataListener trackDataListener : sampledOutListeners) { - trackDataListener.onSampledOutTrackPoint(location); + // Also include the last point if the selected track is not recording. + if (includeNextPoint || (localNumLoadedPoints % samplingFrequency == 0) + || (locationId == lastTrackPointId && !isSelectedTrackRecording())) { + includeNextPoint = false; + for (TrackDataListener trackDataListener : sampledInListeners) { + trackDataListener.onSampledInTrackPoint(location); + } + } else { + for (TrackDataListener trackDataListener : sampledOutListeners) { + trackDataListener.onSampledOutTrackPoint(location); + } } } - } - localNumLoadedPoints++; - localLastSeenLocationId = locationId; + localNumLoadedPoints++; + localLastSeenLocationId = locationId; + } + } finally { + if (locationIterator != null) { + locationIterator.close(); + } } - iterator.close(); if (updateSamplingState) { numLoadedPoints = localNumLoadedPoints; 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 df95b0baa..ed2e6a170 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 @@ -134,11 +134,13 @@ public class FileTrackExporter implements TrackExporter { boolean wroteSegment = false; boolean isLastLocationValid = false; TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory(); - LocationIterator locationIterator = myTracksProviderUtils.getTrackPointLocationIterator( - track.getId(), -1L, false, locationFactory); + int locationNumber = 0; + LocationIterator locationIterator = null; try { - int locationNumber = 0; + locationIterator = myTracksProviderUtils.getTrackPointLocationIterator( + track.getId(), -1L, false, locationFactory); + while (locationIterator.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); @@ -195,7 +197,9 @@ public class FileTrackExporter implements TrackExporter { trackWriter.writeEndTrack(track, null); } } finally { - locationIterator.close(); + if (locationIterator != null) { + locationIterator.close(); + } } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/importer/AbstractFileTrackImporter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/importer/AbstractFileTrackImporter.java index 4b277c317..20f0bb209 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/importer/AbstractFileTrackImporter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/importer/AbstractFileTrackImporter.java @@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.io.file.importer; import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl; 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.content.Waypoint.WaypointType; @@ -34,7 +35,6 @@ import com.google.android.apps.mytracks.util.UnitConversions; import com.google.android.maps.mytracks.R; import android.content.Context; -import android.database.Cursor; import android.location.Location; import android.location.LocationManager; import android.net.Uri; @@ -211,20 +211,19 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track if (track == null) { return; } - Cursor trackPointCursor = null; + + int waypointPosition = -1; + Waypoint waypoint = null; + Location location = null; + TripStatisticsUpdater trackTripStatisticstrackUpdater = new TripStatisticsUpdater( + track.getTripStatistics().getStartTime()); + TripStatisticsUpdater markerTripStatisticsUpdater = new TripStatisticsUpdater( + track.getTripStatistics().getStartTime()); + LocationIterator locationIterator = null; + try { - trackPointCursor = myTracksProviderUtils.getTrackPointCursor(track.getId(), -1L, -1, false); - if (trackPointCursor == null) { - return; - } - int waypointPosition = -1; - Waypoint waypoint = null; - int trackPointPosition = -1; - Location trackPoint = null; - TripStatisticsUpdater trackTripStatisticstrackUpdater = new TripStatisticsUpdater( - track.getTripStatistics().getStartTime()); - TripStatisticsUpdater markerTripStatisticsUpdater = new TripStatisticsUpdater( - track.getTripStatistics().getStartTime()); + locationIterator = myTracksProviderUtils.getTrackPointLocationIterator( + track.getId(), -1L, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY); while (true) { if (waypoint == null) { @@ -235,28 +234,25 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track return; } } - if (trackPoint == null) { - trackPointPosition++; - trackPoint = trackPointCursor.moveToPosition(trackPointPosition) ? myTracksProviderUtils - .createTrackPoint(trackPointCursor) - : null; - if (trackPoint == null) { + if (location == null) { + if (!locationIterator.hasNext()) { // No more track points. Ignore the rest of the waypoints. return; } - trackTripStatisticstrackUpdater.addLocation(trackPoint, recordingDistanceInterval, false, + location = locationIterator.next(); + trackTripStatisticstrackUpdater.addLocation(location, recordingDistanceInterval, false, ActivityType.INVALID, PreferencesUtils.WEIGHT_DEFAULT); - markerTripStatisticsUpdater.addLocation(trackPoint, recordingDistanceInterval, false, + markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, false, ActivityType.INVALID, PreferencesUtils.WEIGHT_DEFAULT); } - if (waypoint.getLocation().getTime() > trackPoint.getTime()) { - trackPoint = null; - } else if (waypoint.getLocation().getTime() < trackPoint.getTime()) { + if (waypoint.getLocation().getTime() > location.getTime()) { + location = null; + } else if (waypoint.getLocation().getTime() < location.getTime()) { waypoint = null; } else { // The waypoint location time matches the track point time - if (trackPoint.getLatitude() == waypoint.getLocation().getLatitude() - && trackPoint.getLongitude() == waypoint.getLocation().getLongitude()) { + if (location.getLatitude() == waypoint.getLocation().getLatitude() + && location.getLongitude() == waypoint.getLocation().getLongitude()) { // Get tripStatistics, description, and icon TripStatistics tripStatistics; @@ -264,7 +260,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track String icon; if (waypoint.getType() == WaypointType.STATISTICS) { tripStatistics = markerTripStatisticsUpdater.getTripStatistics(); - markerTripStatisticsUpdater = new TripStatisticsUpdater(trackPoint.getTime()); + markerTripStatisticsUpdater = new TripStatisticsUpdater(location.getTime()); waypointDescription = new DescriptionGeneratorImpl(context) .generateWaypointDescription(tripStatistics); icon = context.getString(R.string.marker_statistics_icon_url); @@ -281,15 +277,15 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track // Insert waypoint Waypoint newWaypoint = new Waypoint(waypoint.getName(), waypointDescription, waypoint.getCategory(), icon, track.getId(), waypoint.getType(), length, duration, - -1L, -1L, trackPoint, tripStatistics, waypoint.getPhotoUrl()); + -1L, -1L, location, tripStatistics, waypoint.getPhotoUrl()); myTracksProviderUtils.insertWaypoint(newWaypoint); } waypoint = null; } } } finally { - if (trackPointCursor != null) { - trackPointCursor.close(); + if (locationIterator != null) { + locationIterator.close(); } } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java index e49ace669..0d873829a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesAsyncTask.java @@ -6,6 +6,7 @@ import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.content.DescriptionGenerator; import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl; 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.content.Waypoint.WaypointType; @@ -227,23 +228,19 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { */ private boolean uploadAllTrackPoints(Fusiontables fusiontables, String tableId, Track track) throws IOException { - Cursor cursor = null; + int numberOfPoints = track.getNumberOfPoints(); + List locations = new ArrayList(MAX_POINTS_PER_UPLOAD); + Location lastValidLocation = null; + boolean sentStartMarker = false; + int readCount = 0; + + LocationIterator locationIterator = null; try { - cursor = myTracksProviderUtils.getTrackPointCursor(trackId, -1L, -1, false); - if (cursor == null) { - Log.d(TAG, "Location cursor is null"); - return false; - } + locationIterator = myTracksProviderUtils.getTrackPointLocationIterator( + trackId, -1L, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY); - int count = cursor.getCount(); - List locations = new ArrayList(MAX_POINTS_PER_UPLOAD); - Location lastValidLocation = null; - boolean sentStartMarker = false; - - for (int i = 0; i < count; i++) { - cursor.moveToPosition(i); - - Location location = myTracksProviderUtils.createTrackPoint(cursor); + while (locationIterator.hasNext()) { + Location location = locationIterator.next(); locations.add(location); if (LocationUtils.isValidLocation(location)) { @@ -258,13 +255,13 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { } // Upload periodically - int readCount = i + 1; + readCount++; if (readCount % MAX_POINTS_PER_UPLOAD == 0) { if (!prepareAndUploadPoints(fusiontables, tableId, track, locations, false)) { Log.d(TAG, "Unable to upload points"); return false; } - updateProgress(readCount, count); + updateProgress(readCount, numberOfPoints); locations.clear(); } } @@ -285,8 +282,8 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask { } return true; } finally { - if (cursor != null) { - cursor.close(); + if (locationIterator != null) { + locationIterator.close(); } } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java index 7eda2c29c..663fea54a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java @@ -19,6 +19,7 @@ import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.content.DescriptionGenerator; import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl; 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.gdata.GDataClientFactory; @@ -235,33 +236,29 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { */ @VisibleForTesting boolean uploadAllTrackPoints(Track track) { - Cursor cursor = null; + int numberOfPoints = track.getNumberOfPoints(); + List locations = new ArrayList(MAX_POINTS_PER_UPLOAD); + Location lastValidLocation = null; + boolean sentStartMarker = false; + + // For chart server, limit the number of elevation readings to 250. + int elevationSamplingFrequency = Math.max(1, (int) (numberOfPoints / 250.0)); + Vector distances = new Vector(); + Vector elevations = new Vector(); + TripStatisticsUpdater tripStatisticsUpdater = new TripStatisticsUpdater( + track.getTripStatistics().getStartTime()); + int recordingDistanceInterval = PreferencesUtils.getInt(context, + R.string.recording_distance_interval_key, + PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT); + int readCount = 0; + LocationIterator locationIterator = null; + try { - cursor = myTracksProviderUtils.getTrackPointCursor(trackId, -1L, -1, false); - if (cursor == null) { - Log.d(TAG, "Location cursor is null"); - return false; - } + locationIterator = myTracksProviderUtils.getTrackPointLocationIterator( + trackId, -1L, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY); - int count = cursor.getCount(); - List locations = new ArrayList(MAX_POINTS_PER_UPLOAD); - Location lastValidLocation = null; - boolean sentStartMarker = false; - - // For chart server, limit the number of elevation readings to 250. - int elevationSamplingFrequency = Math.max(1, (int) (count / 250.0)); - Vector distances = new Vector(); - Vector elevations = new Vector(); - TripStatisticsUpdater tripStatisticsUpdater = new TripStatisticsUpdater( - track.getTripStatistics().getStartTime()); - int recordingDistanceInterval = PreferencesUtils.getInt(context, - R.string.recording_distance_interval_key, - PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT); - - for (int i = 0; i < count; i++) { - cursor.moveToPosition(i); - - Location location = myTracksProviderUtils.createTrackPoint(cursor); + while (locationIterator.hasNext()) { + Location location = locationIterator.next(); locations.add(location); if (LocationUtils.isValidLocation(location)) { @@ -280,19 +277,19 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, false, ActivityType.INVALID, PreferencesUtils.WEIGHT_DEFAULT); - if (i % elevationSamplingFrequency == 0) { + if (readCount % elevationSamplingFrequency == 0) { distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance()); elevations.add(tripStatisticsUpdater.getSmoothedElevation()); } // Upload periodically - int readCount = i + 1; + readCount++; if (readCount % MAX_POINTS_PER_UPLOAD == 0) { if (!prepareAndUploadPoints(track, locations, false)) { Log.d(TAG, "Unable to upload points"); return false; } - updateProgress(readCount, count); + updateProgress(readCount, numberOfPoints); locations.clear(); } } @@ -318,8 +315,8 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { } return true; } finally { - if (cursor != null) { - cursor.close(); + if (locationIterator != null) { + locationIterator.close(); } } } 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 f5e3da218..ba4359cdd 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -667,6 +667,7 @@ public class TrackRecordingService extends Service { try { locationIterator = myTracksProviderUtils.getTrackPointLocationIterator( track.getId(), -1L, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY); + while (locationIterator.hasNext()) { Location location = locationIterator.next(); trackTripStatisticsUpdater.addLocation( diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java index 633c0ae83..f27115744 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java @@ -108,6 +108,7 @@ public class CalorieUtils { try { locationIterator = myTracksProviderUtils.getTrackPointLocationIterator( track.getId(), startTrackPointId, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY); + while (locationIterator.hasNext()) { tripStatisticsUpdater.addLocation( locationIterator.next(), recordingDistanceInterval, true, activityType, weight);