forked from upstream-mirrors/OpenTracks
Export track in kmz or kml
This commit is contained in:
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 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 android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class for {@link TrackExporter}.
|
||||||
|
*
|
||||||
|
* @author Jimmy Shih
|
||||||
|
*/
|
||||||
|
abstract class AbstractTrackExporter implements TrackExporter {
|
||||||
|
|
||||||
|
private static final String TAG = AbstractTrackExporter.class.getSimpleName();
|
||||||
|
|
||||||
|
private Thread writeThread;
|
||||||
|
private boolean success = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTrack(final OutputStream outputStream) {
|
||||||
|
writeThread = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
performWrite(outputStream);
|
||||||
|
success = true;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.e(TAG, "Unable to perform write", e);
|
||||||
|
success = false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Unable to perform write", e);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
writeThread.start();
|
||||||
|
try {
|
||||||
|
writeThread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.e(TAG, "Interrupted while waiting for write thread to finish", e);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopWriteTrack() {
|
||||||
|
if (writeThread != null && writeThread.isAlive()) {
|
||||||
|
Log.i(TAG, "Attempting to stop write thread");
|
||||||
|
writeThread.interrupt();
|
||||||
|
try {
|
||||||
|
writeThread.join();
|
||||||
|
Log.i(TAG, "Write thread stopped");
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.e(TAG, "Interrupted while waiting for write thread to stop", e);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void performWrite(OutputStream outputStream) throws InterruptedException, IOException;
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ import com.google.common.annotations.VisibleForTesting;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
@@ -38,18 +37,13 @@ import java.io.OutputStream;
|
|||||||
* @author Sandor Dornbush
|
* @author Sandor Dornbush
|
||||||
* @author Rodrigo Damazio
|
* @author Rodrigo Damazio
|
||||||
*/
|
*/
|
||||||
public class FileTrackExporter implements TrackExporter {
|
public class FileTrackExporter extends AbstractTrackExporter {
|
||||||
|
|
||||||
private final static String TAG = FileTrackExporter.class.getSimpleName();
|
|
||||||
|
|
||||||
private final MyTracksProviderUtils myTracksProviderUtils;
|
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||||
private final Track[] tracks;
|
private final Track[] tracks;
|
||||||
private final TrackWriter trackWriter;
|
private final TrackWriter trackWriter;
|
||||||
private final TrackExporterListener trackExporterListener;
|
private final TrackExporterListener trackExporterListener;
|
||||||
|
|
||||||
private Thread writeThread;
|
|
||||||
private boolean success = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -59,10 +53,10 @@ public class FileTrackExporter implements TrackExporter {
|
|||||||
* @param trackFileFormat the track file format
|
* @param trackFileFormat the track file format
|
||||||
* @param trackExporterListener the track export listener
|
* @param trackExporterListener the track export listener
|
||||||
*/
|
*/
|
||||||
public FileTrackExporter(Context context, MyTracksProviderUtils myTracksProviderUtils,
|
public FileTrackExporter(MyTracksProviderUtils myTracksProviderUtils,
|
||||||
Track[] tracks, TrackFileFormat trackFileFormat,
|
Track[] tracks, TrackFileFormat trackFileFormat, Context context, boolean inZip,
|
||||||
TrackExporterListener trackExporterListener) {
|
TrackExporterListener trackExporterListener) {
|
||||||
this(myTracksProviderUtils, tracks, trackFileFormat.newTrackWriter(context),
|
this(myTracksProviderUtils, tracks, trackFileFormat.newTrackWriter(context, inZip),
|
||||||
trackExporterListener);
|
trackExporterListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,55 +70,17 @@ public class FileTrackExporter implements TrackExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSuccess() {
|
void performWrite(OutputStream outputStream) throws InterruptedException {
|
||||||
return success;
|
trackWriter.prepare(outputStream);
|
||||||
}
|
trackWriter.writeHeader(tracks[0]);
|
||||||
|
long startTime = tracks[0].getTripStatistics().getStartTime();
|
||||||
@Override
|
for (int i = 0; i < tracks.length; i++) {
|
||||||
public void writeTrack(final OutputStream outputStream) {
|
writeWaypoints(tracks[i]);
|
||||||
writeThread = new Thread() {
|
long offset = tracks[i].getTripStatistics().getStartTime() - startTime;
|
||||||
@Override
|
writeLocations(tracks[i], offset);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
trackWriter.writeFooter();
|
||||||
|
trackWriter.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import android.database.Cursor;
|
|||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -68,8 +69,10 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
TRACK_ICON = "http://earth.google.com/images/kml-icons/track-directional/track-0.png";
|
TRACK_ICON = "http://earth.google.com/images/kml-icons/track-directional/track-0.png";
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
private final boolean inKmz;
|
||||||
private final DescriptionGenerator descriptionGenerator;
|
private final DescriptionGenerator descriptionGenerator;
|
||||||
private final MyTracksProviderUtils myTracksProviderUtils;
|
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||||
|
|
||||||
private PrintWriter printWriter;
|
private PrintWriter printWriter;
|
||||||
private ArrayList<Integer> powerList = new ArrayList<Integer>();
|
private ArrayList<Integer> powerList = new ArrayList<Integer>();
|
||||||
private ArrayList<Integer> cadenceList = new ArrayList<Integer>();
|
private ArrayList<Integer> cadenceList = new ArrayList<Integer>();
|
||||||
@@ -78,13 +81,14 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
private boolean hasCadence;
|
private boolean hasCadence;
|
||||||
private boolean hasHeartRate;
|
private boolean hasHeartRate;
|
||||||
|
|
||||||
public KmlTrackWriter(Context context) {
|
public KmlTrackWriter(Context context, boolean inKmz) {
|
||||||
this(context, new DescriptionGeneratorImpl(context));
|
this(context, inKmz, new DescriptionGeneratorImpl(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
KmlTrackWriter(Context context, DescriptionGenerator descriptionGenerator) {
|
KmlTrackWriter(Context context, boolean inKmz, DescriptionGenerator descriptionGenerator) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.inKmz = inKmz;
|
||||||
this.descriptionGenerator = descriptionGenerator;
|
this.descriptionGenerator = descriptionGenerator;
|
||||||
this.myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
|
this.myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
|
||||||
}
|
}
|
||||||
@@ -335,9 +339,8 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
if (location != null) {
|
if (location != null) {
|
||||||
printWriter.println("<PhotoOverlay>");
|
printWriter.println("<PhotoOverlay>");
|
||||||
printWriter.println("<name>" + StringUtils.formatCData(name) + "</name>");
|
printWriter.println("<name>" + StringUtils.formatCData(name) + "</name>");
|
||||||
printWriter.println("<description>"
|
printWriter.println(
|
||||||
+ StringUtils.formatCData(StringUtils.getCategoryDescription(category, description))
|
"<description>" + StringUtils.formatCData(description) + "</description>");
|
||||||
+ "</description>");
|
|
||||||
printWriter.print("<Camera>");
|
printWriter.print("<Camera>");
|
||||||
printWriter.print("<longitude>" + location.getLongitude() + "</longitude>");
|
printWriter.print("<longitude>" + location.getLongitude() + "</longitude>");
|
||||||
printWriter.print("<latitude>" + location.getLatitude() + "</latitude>");
|
printWriter.print("<latitude>" + location.getLatitude() + "</latitude>");
|
||||||
@@ -345,8 +348,18 @@ public class KmlTrackWriter implements TrackWriter {
|
|||||||
printWriter.print("<heading>" + heading + "</heading>");
|
printWriter.print("<heading>" + heading + "</heading>");
|
||||||
printWriter.print("<tilt>90</tilt>");
|
printWriter.print("<tilt>90</tilt>");
|
||||||
printWriter.println("</Camera>");
|
printWriter.println("</Camera>");
|
||||||
|
printWriter.println("<TimeStamp><when>"
|
||||||
|
+ StringUtils.formatDateTimeIso8601(location.getTime()) + "</when></TimeStamp>");
|
||||||
printWriter.println("<styleUrl>#" + styleName + "</styleUrl>");
|
printWriter.println("<styleUrl>#" + styleName + "</styleUrl>");
|
||||||
printWriter.println("<Icon><href>" + Uri.decode(photoUrl) + "</href></Icon>");
|
writeCategory(category);
|
||||||
|
if (inKmz) {
|
||||||
|
Uri uri = Uri.parse(photoUrl);
|
||||||
|
printWriter.println("<Icon><href>" + KmzTrackExporter.KMZ_IMAGES_DIR + File.separatorChar
|
||||||
|
+ uri.getLastPathSegment() + "</href></Icon>");
|
||||||
|
} else {
|
||||||
|
printWriter.println("<Icon><href>" + Uri.decode(photoUrl) + "</href></Icon>");
|
||||||
|
}
|
||||||
|
|
||||||
printWriter.print("<ViewVolume>");
|
printWriter.print("<ViewVolume>");
|
||||||
printWriter.print("<near>10</near>");
|
printWriter.print("<near>10</near>");
|
||||||
printWriter.print("<leftFov>-60</leftFov>");
|
printWriter.print("<leftFov>-60</leftFov>");
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 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.content.MyTracksProviderUtils;
|
||||||
|
import com.google.android.apps.mytracks.content.Track;
|
||||||
|
import com.google.android.apps.mytracks.content.Waypoint;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KMZ track exporter.
|
||||||
|
*
|
||||||
|
* @author Jimmy Shih
|
||||||
|
*/
|
||||||
|
public class KmzTrackExporter extends AbstractTrackExporter {
|
||||||
|
|
||||||
|
public static final String KMZ_IMAGES_DIR = "images";
|
||||||
|
public static final String KMZ_EXTENSION = "kmz";
|
||||||
|
public static final int BUFFER_SIZE = 4096;
|
||||||
|
public static final String KML_FILE_NAME = "doc.kml";
|
||||||
|
|
||||||
|
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||||
|
private final TrackExporter trackExporter;
|
||||||
|
private final Track[] tracks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param myTracksProviderUtils the my tracks provider utils
|
||||||
|
* @param trackExporter the track exporter
|
||||||
|
* @param tracks the tracks to export
|
||||||
|
*/
|
||||||
|
public KmzTrackExporter(
|
||||||
|
MyTracksProviderUtils myTracksProviderUtils, TrackExporter trackExporter, Track[] tracks) {
|
||||||
|
this.myTracksProviderUtils = myTracksProviderUtils;
|
||||||
|
this.trackExporter = trackExporter;
|
||||||
|
this.tracks = tracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return trackExporter.isSuccess() && super.isSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopWriteTrack() {
|
||||||
|
trackExporter.stopWriteTrack();
|
||||||
|
super.stopWriteTrack();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void performWrite(OutputStream outputStream) throws InterruptedException, IOException {
|
||||||
|
ZipOutputStream zipOutputStream = null;
|
||||||
|
try {
|
||||||
|
zipOutputStream = new ZipOutputStream(outputStream);
|
||||||
|
|
||||||
|
// Add kml file
|
||||||
|
ZipEntry zipEntry = new ZipEntry(KML_FILE_NAME);
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
trackExporter.writeTrack(byteArrayOutputStream);
|
||||||
|
zipOutputStream.write(byteArrayOutputStream.toByteArray());
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
|
||||||
|
// Add photos
|
||||||
|
addImages(zipOutputStream);
|
||||||
|
} finally {
|
||||||
|
if (zipOutputStream != null) {
|
||||||
|
zipOutputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addImages(ZipOutputStream zipOutputStream) throws IOException {
|
||||||
|
for (Track track : tracks) {
|
||||||
|
Cursor cursor = null;
|
||||||
|
try {
|
||||||
|
cursor = myTracksProviderUtils.getWaypointCursor(track.getId(), -1L, -1);
|
||||||
|
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()) {
|
||||||
|
Waypoint waypoint = myTracksProviderUtils.createWaypoint(cursor);
|
||||||
|
String photoUrl = waypoint.getPhotoUrl();
|
||||||
|
if (photoUrl != null && !photoUrl.equals("")) {
|
||||||
|
addImage(zipOutputStream, photoUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addImage(ZipOutputStream zipOutputStream, String photoUrl) throws IOException {
|
||||||
|
Uri uri = Uri.parse(photoUrl);
|
||||||
|
ZipEntry zipEntry = new ZipEntry(
|
||||||
|
KMZ_IMAGES_DIR + File.separatorChar + uri.getLastPathSegment());
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
|
||||||
|
FileInputStream fileInputStream = null;
|
||||||
|
try {
|
||||||
|
fileInputStream = new FileInputStream(new File(uri.getPath()));
|
||||||
|
byte[] buffer = new byte[BUFFER_SIZE];
|
||||||
|
int byteCount = 0;
|
||||||
|
while ((byteCount = fileInputStream.read(buffer)) != -1) {
|
||||||
|
zipOutputStream.write(buffer, 0, byteCount);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (fileInputStream != null) {
|
||||||
|
fileInputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -99,7 +99,7 @@ public class SaveActivity extends Activity {
|
|||||||
saveAsyncTask = (SaveAsyncTask) retained;
|
saveAsyncTask = (SaveAsyncTask) retained;
|
||||||
saveAsyncTask.setActivity(this);
|
saveAsyncTask.setActivity(this);
|
||||||
} else {
|
} else {
|
||||||
saveAsyncTask = new SaveAsyncTask(this, trackFileFormat, trackIds, directory);
|
saveAsyncTask = new SaveAsyncTask(this, trackFileFormat, trackIds, directory, playTrack);
|
||||||
saveAsyncTask.execute();
|
saveAsyncTask.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import android.util.Log;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Async Task to save tracks to the external storage.
|
* Async Task to save tracks to the external storage.
|
||||||
@@ -49,11 +48,12 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
|||||||
private final TrackFileFormat trackFileFormat;
|
private final TrackFileFormat trackFileFormat;
|
||||||
private final long[] trackIds;
|
private final long[] trackIds;
|
||||||
private final File directory;
|
private final File directory;
|
||||||
|
private final boolean playTrack;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final MyTracksProviderUtils myTracksProviderUtils;
|
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||||
|
|
||||||
private WakeLock wakeLock;
|
private WakeLock wakeLock;
|
||||||
private FileTrackExporter fileTrackExporter;
|
private TrackExporter trackExporter;
|
||||||
|
|
||||||
// true if the AsyncTask has completed
|
// true if the AsyncTask has completed
|
||||||
private boolean completed;
|
private boolean completed;
|
||||||
@@ -75,13 +75,15 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
|||||||
* @param trackIds the track ids to save. To save all, set to size 1 with
|
* @param trackIds the track ids to save. To save all, set to size 1 with
|
||||||
* trackIds[0] == -1L
|
* trackIds[0] == -1L
|
||||||
* @param directory the directory to save to
|
* @param directory the directory to save to
|
||||||
|
* @param playTrack true to play track
|
||||||
*/
|
*/
|
||||||
public SaveAsyncTask(
|
public SaveAsyncTask(SaveActivity saveActivity, TrackFileFormat trackFileFormat, long[] trackIds,
|
||||||
SaveActivity saveActivity, TrackFileFormat trackFileFormat, long[] trackIds, File directory) {
|
File directory, boolean playTrack) {
|
||||||
this.saveActivity = saveActivity;
|
this.saveActivity = saveActivity;
|
||||||
this.trackFileFormat = trackFileFormat;
|
this.trackFileFormat = trackFileFormat;
|
||||||
this.trackIds = trackIds;
|
this.trackIds = trackIds;
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
|
this.playTrack = playTrack;
|
||||||
context = saveActivity.getApplicationContext();
|
context = saveActivity.getApplicationContext();
|
||||||
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
|
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
|
||||||
|
|
||||||
@@ -164,8 +166,8 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCancelled() {
|
protected void onCancelled() {
|
||||||
if (fileTrackExporter != null) {
|
if (trackExporter != null) {
|
||||||
fileTrackExporter.stopWriteTrack();
|
trackExporter.stopWriteTrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,16 +181,18 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Track track = tracks[0];
|
Track track = tracks[0];
|
||||||
|
boolean useKmz = !playTrack && trackFileFormat == TrackFileFormat.KML;
|
||||||
|
String extension = useKmz ? KmzTrackExporter.KMZ_EXTENSION : trackFileFormat.getExtension();
|
||||||
|
|
||||||
// Make sure the file doesn't exist yet (possibly by changing the filename)
|
// Make sure the file doesn't exist yet (possibly by changing the filename)
|
||||||
String fileName = FileUtils.buildUniqueFileName(
|
String fileName = FileUtils.buildUniqueFileName(directory, track.getName(), extension);
|
||||||
directory, track.getName(), trackFileFormat.getExtension());
|
|
||||||
if (fileName == null) {
|
if (fileName == null) {
|
||||||
Log.d(TAG, "Unable to get a unique filename for " + track.getName());
|
Log.d(TAG, "Unable to get a unique filename for " + track.getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileTrackExporter = new FileTrackExporter(
|
FileTrackExporter fileTrackExporter = new FileTrackExporter(myTracksProviderUtils, tracks,
|
||||||
context, myTracksProviderUtils, tracks, trackFileFormat, new TrackExporterListener() {
|
trackFileFormat, context, useKmz, new TrackExporterListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProgressUpdate(int number, int max) {
|
public void onProgressUpdate(int number, int max) {
|
||||||
@@ -202,24 +206,27 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
File file = null;
|
trackExporter = useKmz ? new KmzTrackExporter(myTracksProviderUtils, fileTrackExporter, tracks)
|
||||||
|
: fileTrackExporter;
|
||||||
|
|
||||||
|
File file = new File(directory, fileName);
|
||||||
|
FileOutputStream fileOutputStream;
|
||||||
try {
|
try {
|
||||||
file = new File(directory, fileName);
|
fileOutputStream = new FileOutputStream(file);
|
||||||
OutputStream outputStream = new FileOutputStream(file);
|
|
||||||
fileTrackExporter.writeTrack(outputStream);
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Log.d(TAG, "File not found " + fileName, e);
|
Log.e(TAG, "Unable to open file " + file.getName(), e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
trackExporter.writeTrack(fileOutputStream);
|
||||||
|
|
||||||
if (fileTrackExporter.isSuccess()) {
|
if (trackExporter.isSuccess()) {
|
||||||
savedPath = file.getAbsolutePath();
|
savedPath = file.getAbsolutePath();
|
||||||
} else {
|
} else {
|
||||||
if (!file.delete()) {
|
if (!file.delete()) {
|
||||||
Log.w(TAG, "Failed to delete file " + file.getAbsolutePath());
|
Log.w(TAG, "Failed to delete file " + file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fileTrackExporter.isSuccess();
|
return trackExporter.isSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,25 +12,25 @@ import java.util.Locale;
|
|||||||
public enum TrackFileFormat implements Parcelable {
|
public enum TrackFileFormat implements Parcelable {
|
||||||
KML {
|
KML {
|
||||||
@Override
|
@Override
|
||||||
TrackWriter newTrackWriter(Context context) {
|
TrackWriter newTrackWriter(Context context, boolean inZip) {
|
||||||
return new KmlTrackWriter(context);
|
return new KmlTrackWriter(context, inZip);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GPX {
|
GPX {
|
||||||
@Override
|
@Override
|
||||||
TrackWriter newTrackWriter(Context context) {
|
TrackWriter newTrackWriter(Context context, boolean inZip) {
|
||||||
return new GpxTrackWriter(context);
|
return new GpxTrackWriter(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CSV {
|
CSV {
|
||||||
@Override
|
@Override
|
||||||
public TrackWriter newTrackWriter(Context context) {
|
public TrackWriter newTrackWriter(Context context, boolean inZip) {
|
||||||
return new CsvTrackWriter(context);
|
return new CsvTrackWriter(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TCX {
|
TCX {
|
||||||
@Override
|
@Override
|
||||||
public TrackWriter newTrackWriter(Context context) {
|
public TrackWriter newTrackWriter(Context context, boolean inZip) {
|
||||||
return new TcxTrackWriter(context);
|
return new TcxTrackWriter(context);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -60,7 +60,7 @@ public enum TrackFileFormat implements Parcelable {
|
|||||||
/**
|
/**
|
||||||
* Creates a new track writer for the format.
|
* Creates a new track writer for the format.
|
||||||
*/
|
*/
|
||||||
abstract TrackWriter newTrackWriter(Context context);
|
abstract TrackWriter newTrackWriter(Context context, boolean inZip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the mime type for each format.
|
* Returns the mime type for each format.
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ public class SyncUtils {
|
|||||||
java.io.File file = new java.io.File(directory,
|
java.io.File file = new java.io.File(directory,
|
||||||
FileUtils.buildUniqueFileName(directory, track.getName(), trackFileFormat.getExtension()));
|
FileUtils.buildUniqueFileName(directory, track.getName(), trackFileFormat.getExtension()));
|
||||||
FileTrackExporter fileTrackExporter = new FileTrackExporter(
|
FileTrackExporter fileTrackExporter = new FileTrackExporter(
|
||||||
context, myTracksProviderUtils, new Track[] {track}, trackFileFormat, null);
|
myTracksProviderUtils, new Track[] { track }, trackFileFormat, context, false, null);
|
||||||
|
|
||||||
fileTrackExporter.writeTrack(new FileOutputStream(file));
|
fileTrackExporter.writeTrack(new FileOutputStream(file));
|
||||||
if (fileTrackExporter.isSuccess()) {
|
if (fileTrackExporter.isSuccess()) {
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ public class KmlTrackWriterTest extends TrackWriterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testXmlOutput() throws Exception {
|
public void testXmlOutput() throws Exception {
|
||||||
KmlTrackWriter kmlTrackWriter = new KmlTrackWriter(getContext(), new FakeDescriptionGenerator());
|
KmlTrackWriter kmlTrackWriter = new KmlTrackWriter(
|
||||||
|
getContext(), false, new FakeDescriptionGenerator());
|
||||||
String result = writeTrack(kmlTrackWriter);
|
String result = writeTrack(kmlTrackWriter);
|
||||||
Document doc = parseXmlDocument(result);
|
Document doc = parseXmlDocument(result);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user