forked from upstream-mirrors/OpenTracks
Code cleanup: Add TrackExporter interface
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
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;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Track Writer for writing tracks to an {@link OutputStream}.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class FileTrackExporter implements TrackExporter {
|
||||
|
||||
private final static String TAG = FileTrackExporter.class.getSimpleName();
|
||||
|
||||
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||
private final Track[] tracks;
|
||||
private final TrackWriter trackWriter;
|
||||
private final TrackExporterListener trackExporterListener;
|
||||
|
||||
private Thread writeThread;
|
||||
private boolean success = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param context the context
|
||||
* @param myTracksProviderUtils the my tracks provider utils
|
||||
* @param tracks the tracks
|
||||
* @param trackFileFormat the track file format
|
||||
* @param trackExporterListener the track export listener
|
||||
*/
|
||||
public FileTrackExporter(Context context, MyTracksProviderUtils myTracksProviderUtils,
|
||||
Track[] tracks, TrackFileFormat trackFileFormat,
|
||||
TrackExporterListener trackExporterListener) {
|
||||
this(myTracksProviderUtils, tracks, trackFileFormat.newTrackWriter(context),
|
||||
trackExporterListener);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public FileTrackExporter(MyTracksProviderUtils myTracksProviderUtils, Track[] tracks,
|
||||
TrackWriter trackWriter, TrackExporterListener trackExporterListener) {
|
||||
this.myTracksProviderUtils = myTracksProviderUtils;
|
||||
this.tracks = tracks;
|
||||
this.trackWriter = trackWriter;
|
||||
this.trackExporterListener = trackExporterListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTrack(final OutputStream outputStream) {
|
||||
writeThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
trackWriter.prepare(outputStream);
|
||||
trackWriter.writeHeader(tracks[0]);
|
||||
long startTime = tracks[0].getTripStatistics().getStartTime();
|
||||
for (int i = 0; i < tracks.length; i++) {
|
||||
writeWaypoints(tracks[i]);
|
||||
long offset = tracks[i].getTripStatistics().getStartTime() - startTime;
|
||||
writeLocations(tracks[i], offset);
|
||||
}
|
||||
trackWriter.writeFooter();
|
||||
trackWriter.close();
|
||||
success = true;
|
||||
} catch (InterruptedException e) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
writeThread.start();
|
||||
try {
|
||||
writeThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Interrupted while waiting for write to complete", e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopWriteTrack() {
|
||||
if (writeThread != null && writeThread.isAlive()) {
|
||||
Log.i(TAG, "Attempting to stop track write");
|
||||
writeThread.interrupt();
|
||||
|
||||
try {
|
||||
writeThread.join();
|
||||
Log.i(TAG, "Track write stopped");
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Interrupted while waiting for writer to stop", e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the waypoints.
|
||||
*/
|
||||
private void writeWaypoints(Track track) {
|
||||
/*
|
||||
* TODO: Stream through the waypoints in chunks. I am leaving the number of
|
||||
* waypoints very high which should not be a problem because we don't try to
|
||||
* load them into objects all at the same time.
|
||||
*/
|
||||
boolean hasWaypoints = false;
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = myTracksProviderUtils.getWaypointCursor(
|
||||
track.getId(), -1L, Constants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
/*
|
||||
* Yes, this will skip the first waypoint and that is intentional as the
|
||||
* first waypoint holds the stats for the track.
|
||||
*/
|
||||
while (cursor.moveToNext()) {
|
||||
if (!hasWaypoints) {
|
||||
trackWriter.writeBeginWaypoints();
|
||||
hasWaypoints = true;
|
||||
}
|
||||
Waypoint waypoint = myTracksProviderUtils.createWaypoint(cursor);
|
||||
trackWriter.writeWaypoint(waypoint);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
if (hasWaypoints) {
|
||||
trackWriter.writeEndWaypoints();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the locations.
|
||||
*/
|
||||
private void writeLocations(Track track, long offset) throws InterruptedException {
|
||||
boolean wroteTrack = false;
|
||||
boolean wroteSegment = false;
|
||||
boolean isLastLocationValid = false;
|
||||
TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory();
|
||||
LocationIterator iterator = myTracksProviderUtils.getTrackPointLocationIterator(
|
||||
track.getId(), -1L, false, locationFactory);
|
||||
|
||||
try {
|
||||
int locationNumber = 0;
|
||||
while (iterator.hasNext()) {
|
||||
Location location = iterator.next();
|
||||
setLocationTime(location, offset);
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
locationNumber++;
|
||||
|
||||
boolean isLocationValid = LocationUtils.isValidLocation(location);
|
||||
boolean isSegmentValid = isLocationValid && isLastLocationValid;
|
||||
if (!wroteTrack && isSegmentValid) {
|
||||
// Found the first two consecutive locations that are valid
|
||||
trackWriter.writeBeginTrack(track, locationFactory.lastLocation);
|
||||
wroteTrack = true;
|
||||
}
|
||||
|
||||
if (isSegmentValid) {
|
||||
if (!wroteSegment) {
|
||||
// Start a segment
|
||||
trackWriter.writeOpenSegment();
|
||||
wroteSegment = true;
|
||||
|
||||
// Write the previous location, which we had previously skipped
|
||||
trackWriter.writeLocation(locationFactory.lastLocation);
|
||||
}
|
||||
|
||||
// Write the current location
|
||||
trackWriter.writeLocation(location);
|
||||
if (trackExporterListener != null) {
|
||||
trackExporterListener.onProgressUpdate(locationNumber, track.getNumberOfPoints());
|
||||
}
|
||||
} else {
|
||||
if (wroteSegment) {
|
||||
trackWriter.writeCloseSegment();
|
||||
wroteSegment = false;
|
||||
}
|
||||
}
|
||||
locationFactory.swapLocations();
|
||||
isLastLocationValid = isLocationValid;
|
||||
}
|
||||
|
||||
if (wroteSegment) {
|
||||
trackWriter.writeCloseSegment();
|
||||
wroteSegment = false;
|
||||
}
|
||||
if (wroteTrack) {
|
||||
Location lastValidTrackPoint = myTracksProviderUtils.getLastValidTrackPoint(track.getId());
|
||||
setLocationTime(lastValidTrackPoint, offset);
|
||||
trackWriter.writeEndTrack(track, lastValidTrackPoint);
|
||||
} else {
|
||||
// Write an empty track
|
||||
trackWriter.writeBeginTrack(track, null);
|
||||
trackWriter.writeEndTrack(track, null);
|
||||
}
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a location time.
|
||||
*
|
||||
* @param location the location
|
||||
* @param offset the time offset
|
||||
*/
|
||||
private void setLocationTime(Location location, long offset) {
|
||||
if (location != null) {
|
||||
location.setTime(location.getTime() - offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Track writer location factory. Keeping the last two locations.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
private class TrackWriterLocationFactory implements MyTracksProviderUtils.LocationFactory {
|
||||
Location currentLocation;
|
||||
Location lastLocation;
|
||||
|
||||
@Override
|
||||
public Location createLocation() {
|
||||
if (currentLocation == null) {
|
||||
currentLocation = new MyTracksLocation("");
|
||||
}
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public void swapLocations() {
|
||||
Location tempLocation = lastLocation;
|
||||
lastLocation = currentLocation;
|
||||
currentLocation = tempLocation;
|
||||
if (currentLocation != null) {
|
||||
currentLocation.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.io.file;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.io.file.TrackExporter.TrackExporterListener;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.apps.mytracks.util.SystemUtils;
|
||||
@@ -52,7 +53,7 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||
|
||||
private WakeLock wakeLock;
|
||||
private TrackExporter trackExporter;
|
||||
private FileTrackExporter fileTrackExporter;
|
||||
|
||||
// true if the AsyncTask has completed
|
||||
private boolean completed;
|
||||
@@ -163,8 +164,8 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
@Override
|
||||
protected void onCancelled() {
|
||||
if (trackExporter != null) {
|
||||
trackExporter.stopWriteTrack();
|
||||
if (fileTrackExporter != null) {
|
||||
fileTrackExporter.stopWriteTrack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,10 +187,11 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
trackExporter = new TrackExporter(
|
||||
context, myTracksProviderUtils, tracks, trackFileFormat, new TrackExporter.OnWriteListener() {
|
||||
fileTrackExporter = new FileTrackExporter(
|
||||
context, myTracksProviderUtils, tracks, trackFileFormat, new TrackExporterListener() {
|
||||
|
||||
@Override
|
||||
public void onWrite(int number, int max) {
|
||||
public void onProgressUpdate(int number, int max) {
|
||||
/*
|
||||
* If only saving one track, update the progress dialog once every
|
||||
* 500 points
|
||||
@@ -204,20 +206,20 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
try {
|
||||
file = new File(directory, fileName);
|
||||
OutputStream outputStream = new FileOutputStream(file);
|
||||
trackExporter.writeTrack(outputStream);
|
||||
fileTrackExporter.writeTrack(outputStream);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.d(TAG, "File not found " + fileName, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (trackExporter.wasSuccess()) {
|
||||
if (fileTrackExporter.isSuccess()) {
|
||||
savedPath = file.getAbsolutePath();
|
||||
} else {
|
||||
if (!file.delete()) {
|
||||
Log.w(TAG, "Failed to delete file " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
return trackExporter.wasSuccess();
|
||||
return fileTrackExporter.isSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,284 +16,47 @@
|
||||
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
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;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Track Writer for writing tracks to an {@link OutputStream}.
|
||||
* Track exporting for exporting track to an {@link OutputStream}.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
* @author Rodrigo Damazio
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class TrackExporter {
|
||||
public interface TrackExporter {
|
||||
|
||||
/**
|
||||
* Listener for when a track location is written.
|
||||
*/
|
||||
public interface OnWriteListener {
|
||||
|
||||
/**
|
||||
* When a track location is written.
|
||||
*
|
||||
* @param number the location number
|
||||
* @param max the maximum number of locations in a track, for calculation of completion
|
||||
* percentage
|
||||
*/
|
||||
public void onWrite(int number, int max);
|
||||
}
|
||||
|
||||
private final static String TAG = TrackExporter.class.getSimpleName();
|
||||
|
||||
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||
private final Track[] tracks;
|
||||
private final TrackWriter trackWriter;
|
||||
private final OnWriteListener onWriteListener;
|
||||
|
||||
private Thread writeThread;
|
||||
private boolean success = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param context the context
|
||||
* @param myTracksProviderUtils the my tracks provider utils
|
||||
* @param tracks the tracks
|
||||
* @param trackFileFormat the track file format
|
||||
* @param onWriteListener the on write listener
|
||||
*/
|
||||
public TrackExporter(Context context, MyTracksProviderUtils myTracksProviderUtils, Track[] tracks,
|
||||
TrackFileFormat trackFileFormat, OnWriteListener onWriteListener) {
|
||||
this(myTracksProviderUtils, tracks, trackFileFormat.newTrackWriter(context), onWriteListener);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public TrackExporter(MyTracksProviderUtils myTracksProviderUtils, Track[] tracks,
|
||||
TrackWriter trackWriter, OnWriteListener onWriteListener) {
|
||||
this.myTracksProviderUtils = myTracksProviderUtils;
|
||||
this.tracks = tracks;
|
||||
this.trackWriter = trackWriter;
|
||||
this.onWriteListener = onWriteListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the write completed successfully.
|
||||
*/
|
||||
public boolean wasSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given track to the output stream.
|
||||
*
|
||||
* @param outputStream the output stream.
|
||||
*/
|
||||
public void writeTrack(final OutputStream outputStream) {
|
||||
writeThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
trackWriter.prepare(outputStream);
|
||||
trackWriter.writeHeader(tracks[0]);
|
||||
long startTime = tracks[0].getTripStatistics().getStartTime();
|
||||
for (int i = 0; i < tracks.length; i++) {
|
||||
writeWaypoints(tracks[i]);
|
||||
long offset = tracks[i].getTripStatistics().getStartTime() - startTime;
|
||||
writeLocations(tracks[i], offset);
|
||||
}
|
||||
trackWriter.writeFooter();
|
||||
trackWriter.close();
|
||||
success = true;
|
||||
} catch (InterruptedException e) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
writeThread.start();
|
||||
try {
|
||||
writeThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Interrupted while waiting for write to complete", e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops any in-progress writes.
|
||||
*/
|
||||
public void stopWriteTrack() {
|
||||
if (writeThread != null && writeThread.isAlive()) {
|
||||
Log.i(TAG, "Attempting to stop track write");
|
||||
writeThread.interrupt();
|
||||
|
||||
try {
|
||||
writeThread.join();
|
||||
Log.i(TAG, "Track write stopped");
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Interrupted while waiting for writer to stop", e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the waypoints.
|
||||
*/
|
||||
private void writeWaypoints(Track track) {
|
||||
/*
|
||||
* TODO: Stream through the waypoints in chunks. I am leaving the number of
|
||||
* waypoints very high which should not be a problem because we don't try to
|
||||
* load them into objects all at the same time.
|
||||
*/
|
||||
boolean hasWaypoints = false;
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = myTracksProviderUtils.getWaypointCursor(
|
||||
track.getId(), -1L, Constants.MAX_LOADED_WAYPOINTS_POINTS);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
/*
|
||||
* Yes, this will skip the first waypoint and that is intentional as the
|
||||
* first waypoint holds the stats for the track.
|
||||
*/
|
||||
while (cursor.moveToNext()) {
|
||||
if (!hasWaypoints) {
|
||||
trackWriter.writeBeginWaypoints();
|
||||
hasWaypoints = true;
|
||||
}
|
||||
Waypoint waypoint = myTracksProviderUtils.createWaypoint(cursor);
|
||||
trackWriter.writeWaypoint(waypoint);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
if (hasWaypoints) {
|
||||
trackWriter.writeEndWaypoints();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the locations.
|
||||
*/
|
||||
private void writeLocations(Track track, long offset) throws InterruptedException {
|
||||
boolean wroteTrack = false;
|
||||
boolean wroteSegment = false;
|
||||
boolean isLastLocationValid = false;
|
||||
TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory();
|
||||
LocationIterator iterator = myTracksProviderUtils.getTrackPointLocationIterator(
|
||||
track.getId(), -1L, false, locationFactory);
|
||||
|
||||
try {
|
||||
int locationNumber = 0;
|
||||
while (iterator.hasNext()) {
|
||||
Location location = iterator.next();
|
||||
setLocationTime(location, offset);
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
locationNumber++;
|
||||
|
||||
boolean isLocationValid = LocationUtils.isValidLocation(location);
|
||||
boolean isSegmentValid = isLocationValid && isLastLocationValid;
|
||||
if (!wroteTrack && isSegmentValid) {
|
||||
// Found the first two consecutive locations that are valid
|
||||
trackWriter.writeBeginTrack(track, locationFactory.lastLocation);
|
||||
wroteTrack = true;
|
||||
}
|
||||
|
||||
if (isSegmentValid) {
|
||||
if (!wroteSegment) {
|
||||
// Start a segment
|
||||
trackWriter.writeOpenSegment();
|
||||
wroteSegment = true;
|
||||
|
||||
// Write the previous location, which we had previously skipped
|
||||
trackWriter.writeLocation(locationFactory.lastLocation);
|
||||
}
|
||||
|
||||
// Write the current location
|
||||
trackWriter.writeLocation(location);
|
||||
if (onWriteListener != null) {
|
||||
onWriteListener.onWrite(locationNumber, track.getNumberOfPoints());
|
||||
}
|
||||
} else {
|
||||
if (wroteSegment) {
|
||||
trackWriter.writeCloseSegment();
|
||||
wroteSegment = false;
|
||||
}
|
||||
}
|
||||
locationFactory.swapLocations();
|
||||
isLastLocationValid = isLocationValid;
|
||||
}
|
||||
|
||||
if (wroteSegment) {
|
||||
trackWriter.writeCloseSegment();
|
||||
wroteSegment = false;
|
||||
}
|
||||
if (wroteTrack) {
|
||||
Location lastValidTrackPoint = myTracksProviderUtils.getLastValidTrackPoint(track.getId());
|
||||
setLocationTime(lastValidTrackPoint, offset);
|
||||
trackWriter.writeEndTrack(track, lastValidTrackPoint);
|
||||
} else {
|
||||
// Write an empty track
|
||||
trackWriter.writeBeginTrack(track, null);
|
||||
trackWriter.writeEndTrack(track, null);
|
||||
}
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a location time.
|
||||
*
|
||||
* @param location the location
|
||||
* @param offset the time offset
|
||||
*/
|
||||
private void setLocationTime(Location location, long offset) {
|
||||
if (location != null) {
|
||||
location.setTime(location.getTime() - offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Track writer location factory. Keeping the last two locations.
|
||||
* Listener for {@link TrackExporter} progress.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
private class TrackWriterLocationFactory implements MyTracksProviderUtils.LocationFactory {
|
||||
Location currentLocation;
|
||||
Location lastLocation;
|
||||
interface TrackExporterListener {
|
||||
|
||||
@Override
|
||||
public Location createLocation() {
|
||||
if (currentLocation == null) {
|
||||
currentLocation = new MyTracksLocation("");
|
||||
}
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public void swapLocations() {
|
||||
Location tempLocation = lastLocation;
|
||||
lastLocation = currentLocation;
|
||||
currentLocation = tempLocation;
|
||||
if (currentLocation != null) {
|
||||
currentLocation.reset();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Called to update progress.
|
||||
*
|
||||
* @param number the number of locations written
|
||||
* @param max the maximum number of locations in a track, for calculation of
|
||||
* completion percentage
|
||||
*/
|
||||
void onProgressUpdate(int number, int max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write track to an output stream
|
||||
*
|
||||
* @param outputStream the output stream
|
||||
*/
|
||||
void writeTrack(OutputStream outputStream);
|
||||
|
||||
/**
|
||||
* Stops {@link #writeTrack(OutputStream)}.
|
||||
*/
|
||||
void stopWriteTrack();
|
||||
|
||||
/**
|
||||
* Returns true if {@link #writeTrack(OutputStream)} completed successfully.
|
||||
*/
|
||||
boolean isSuccess();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
/**
|
||||
* Listener for {@link TrackExporter} progress.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public interface TrackExporterListener {
|
||||
|
||||
/**
|
||||
* Called to update progress.
|
||||
*
|
||||
* @param number the number of locations written
|
||||
* @param max the maximum number of locations in a track, for calculation of
|
||||
* completion percentage
|
||||
*/
|
||||
public void onProgressUpdate(int number, int max);
|
||||
}
|
||||
@@ -20,8 +20,8 @@ import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.io.file.FileTrackExporter;
|
||||
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
|
||||
import com.google.android.apps.mytracks.io.file.TrackExporter;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -441,11 +441,11 @@ public class SyncUtils {
|
||||
|
||||
java.io.File file = new java.io.File(directory,
|
||||
FileUtils.buildUniqueFileName(directory, track.getName(), trackFileFormat.getExtension()));
|
||||
TrackExporter trackExporter = new TrackExporter(
|
||||
FileTrackExporter fileTrackExporter = new FileTrackExporter(
|
||||
context, myTracksProviderUtils, new Track[] {track}, trackFileFormat, null);
|
||||
|
||||
trackExporter.writeTrack(new FileOutputStream(file));
|
||||
if (trackExporter.wasSuccess()) {
|
||||
fileTrackExporter.writeTrack(new FileOutputStream(file));
|
||||
if (fileTrackExporter.isSuccess()) {
|
||||
return file;
|
||||
}
|
||||
Log.d(TAG, "Unable to get file for track " + track.getName());
|
||||
|
||||
+15
-14
@@ -7,7 +7,7 @@ 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.TrackExporter.OnWriteListener;
|
||||
import com.google.android.apps.mytracks.io.file.TrackExporter.TrackExporterListener;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
|
||||
|
||||
@@ -25,11 +25,11 @@ import org.easymock.IArgumentMatcher;
|
||||
import org.easymock.IMocksControl;
|
||||
|
||||
/**
|
||||
* Tests for {@link TrackExporter}.
|
||||
* Tests for {@link FileTrackExporter}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TrackExporterTest extends AndroidTestCase {
|
||||
public class FileTrackExporterTest extends AndroidTestCase {
|
||||
|
||||
private static final long TRACK_ID = 1234567L;
|
||||
private static final String TRACK_NAME = "Swimming across the pacific";
|
||||
@@ -42,7 +42,7 @@ public class TrackExporterTest extends AndroidTestCase {
|
||||
private TrackWriter trackWriter;
|
||||
private Track track;
|
||||
private OutputStream outputStream;
|
||||
private TrackExporter trackExporter;
|
||||
private FileTrackExporter fileTrackExporter;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
@@ -68,15 +68,16 @@ public class TrackExporterTest extends AndroidTestCase {
|
||||
track.setId(TRACK_ID);
|
||||
|
||||
outputStream = new ByteArrayOutputStream();
|
||||
OnWriteListener onWriteListener = new OnWriteListener() {
|
||||
|
||||
TrackExporterListener trackExporterListener = new TrackExporterListener() {
|
||||
|
||||
@Override
|
||||
public void onWrite(int number, int max) {
|
||||
public void onProgressUpdate(int number, int max) {
|
||||
// Safe to ignore
|
||||
|
||||
}
|
||||
};
|
||||
trackExporter = new TrackExporter(myTracksProviderUtils, new Track[] {track}, trackWriter, onWriteListener);
|
||||
fileTrackExporter = new FileTrackExporter(
|
||||
myTracksProviderUtils, new Track[] { track }, trackWriter, trackExporterListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,9 +100,9 @@ public class TrackExporterTest extends AndroidTestCase {
|
||||
trackWriter.close();
|
||||
|
||||
mocksControl.replay();
|
||||
trackExporter.writeTrack(outputStream);
|
||||
fileTrackExporter.writeTrack(outputStream);
|
||||
|
||||
assertTrue(trackExporter.wasSuccess());
|
||||
assertTrue(fileTrackExporter.isSuccess());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
@@ -131,9 +132,9 @@ public class TrackExporterTest extends AndroidTestCase {
|
||||
trackWriter.close();
|
||||
|
||||
mocksControl.replay();
|
||||
trackExporter.writeTrack(outputStream);
|
||||
fileTrackExporter.writeTrack(outputStream);
|
||||
|
||||
assertTrue(trackExporter.wasSuccess());
|
||||
assertTrue(fileTrackExporter.isSuccess());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
@@ -196,9 +197,9 @@ public class TrackExporterTest extends AndroidTestCase {
|
||||
trackWriter.close();
|
||||
|
||||
mocksControl.replay();
|
||||
trackExporter.writeTrack(outputStream);
|
||||
fileTrackExporter.writeTrack(outputStream);
|
||||
|
||||
assertTrue(trackExporter.wasSuccess());
|
||||
assertTrue(fileTrackExporter.isSuccess());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user