Modified "show on map" functionality to only share locations and no other track data.

This commit is contained in:
Dennis Guse
2019-08-25 00:11:55 +02:00
parent 2753cf7d0b
commit 3a7562d96c
10 changed files with 248 additions and 176 deletions
@@ -42,17 +42,23 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
public static final String TAG = ShareContentProvider.class.getCanonicalName();
private static final int URI_KML = 1;
private static final int URI_KMZ = 2;
private static final int URI_GPX = 3;
private static final int URI_GPX = 0;
private static final int URI_KML_ONLY = 1;
private static final int URI_KML_WITH_SENSORDATA = 2;
private static final int URI_KMZ_ONLY_TRACK = 3;
private static final int URI_KMZ_WITH_SENSORDATA = 4;
private static final int URI_KMZ_WITH_SENSORDATA_AND_PICTURES = 5;
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final String TRACKID_DELIMITER = "_";
static {
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/kml/*", URI_KML);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/kmz/*", URI_KMZ);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/gpx/*", URI_GPX);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_ONLY_TRACK.getName() + "/*", URI_KML_ONLY);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_WITH_SENSORDATA.getName() + "/*", URI_KML_WITH_SENSORDATA);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_ONLY_TRACK.getName() + "/*", URI_KMZ_ONLY_TRACK);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_SENSORDATA.getName() + "/*", URI_KMZ_WITH_SENSORDATA);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_SENSORDATA_AND_PICTURES.getName() + "/*", URI_KMZ_WITH_SENSORDATA_AND_PICTURES);
uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.GPX.getName() + "/*", URI_GPX);
}
public static Pair<Uri, String> createURI(long[] trackIds, @NonNull TrackFileFormat trackFileFormat) {
@@ -66,7 +72,7 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
}
builder.deleteCharAt(builder.lastIndexOf(TRACKID_DELIMITER));
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/" + TracksColumns.TABLE_NAME + "/" + trackFileFormat.getExtension() + "/" + builder + "." + trackFileFormat.getExtension());
Uri uri = Uri.parse(ContentProviderUtils.CONTENT_BASE_URI + "/" + TracksColumns.TABLE_NAME + "/" + trackFileFormat.getName() + "/" + builder + "." + trackFileFormat.getExtension());
String mime = getTypeMime(uri);
return new Pair<>(uri, mime);
}
@@ -105,9 +111,33 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
}
}
private static TrackFileFormat getTrackFileFormat(@NonNull Uri uri) {
switch (uriMatcher.match(uri)) {
case URI_GPX:
return TrackFileFormat.GPX;
case URI_KML_ONLY:
return TrackFileFormat.KML_ONLY_TRACK;
case URI_KML_WITH_SENSORDATA:
return TrackFileFormat.KML_WITH_SENSORDATA;
case URI_KMZ_ONLY_TRACK:
return TrackFileFormat.KMZ_ONLY_TRACK;
case URI_KMZ_WITH_SENSORDATA:
return TrackFileFormat.KMZ_WITH_SENSORDATA;
case URI_KMZ_WITH_SENSORDATA_AND_PICTURES:
return TrackFileFormat.KMZ_WITH_SENSORDATA_AND_PICTURES;
default: //URI_KML_ONLY
return TrackFileFormat.KMZ_ONLY_TRACK;
}
}
@Nullable
public static String getTypeMime(@NonNull Uri uri) {
return getTrackFileFormat(uri).getMimeType();
}
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
if (uriMatcher.match(uri) != URI_KML) {
if (uriMatcher.match(uri) != URI_KML_ONLY) {
return super.query(uri, projection, selection, selectionArgs, sortOrder);
}
@@ -137,22 +167,6 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
return cursor;
}
@Nullable
public static String getTypeMime(@NonNull Uri uri) {
return getTrackFileFormat(uri).getMimeType();
}
private static TrackFileFormat getTrackFileFormat(@NonNull Uri uri) {
switch (uriMatcher.match(uri)) {
case URI_KMZ:
return TrackFileFormat.KMZ;
case URI_GPX:
return TrackFileFormat.GPX;
default: //URI_KML
return TrackFileFormat.KML;
}
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
@@ -63,12 +63,11 @@ public class FileTypeDialogFragment extends AbstractDialogFragment {
protected Dialog createDialog() {
int optionId = getArguments().getInt(KEY_OPTION_ID);
final int titleId = getArguments().getInt(KEY_TITLE_ID);
TrackFileFormat[] trackFileFormats = TrackFileFormat.values();
final TrackFileFormat[] trackFileFormats = {TrackFileFormat.KML_WITH_SENSORDATA, TrackFileFormat.KMZ_WITH_SENSORDATA_AND_PICTURES, TrackFileFormat.GPX};
String[] choices = new String[trackFileFormats.length];
for (int i = 0; i < choices.length; i++) {
TrackFileFormat trackFileFormat = trackFileFormats[i];
choices[i] = getString(optionId, trackFileFormat.name(),
FileUtils.getPathDisplayName(trackFileFormat.getExtension()));
choices[i] = getString(optionId, trackFileFormat.getExtension().toUpperCase(), FileUtils.getPathDisplayName(trackFileFormat.getExtension()));
}
return new AlertDialog.Builder(getActivity())
.setNegativeButton(R.string.generic_cancel, new OnClickListener() {
@@ -81,7 +80,7 @@ public class FileTypeDialogFragment extends AbstractDialogFragment {
@Override
public void onClick(DialogInterface dialog, int which) {
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
caller.onFileTypeDone(TrackFileFormat.values()[position]);
caller.onFileTypeDone(trackFileFormats[position]);
}
})
.setSingleChoiceItems(choices, 0, null)
@@ -21,35 +21,88 @@ import de.dennisguse.opentracks.io.file.exporter.TrackWriter;
* Definition of all possible track formats.
*/
public enum TrackFileFormat implements Parcelable {
KML {
KML_ONLY_TRACK {
@Override
public TrackWriter newTrackWriter(Context context, boolean multiple) {
return new KmlTrackWriter(context, multiple, false);
return new KmlTrackWriter(context, multiple, false, false, false);
}
@Override
public String getMimeType() {
return "application/vnd.google-earth.kml+xml";
return MIME_KML;
}
public String getExtension() {
return "kml";
}
},
KMZ {
KML_WITH_SENSORDATA {
@Override
public TrackWriter newTrackWriter(Context context, boolean multiple) {
return new KmlTrackWriter(context, multiple, true);
return new KmlTrackWriter(context, multiple, true, true, false);
}
@Override
public String getMimeType() {
return "application/vnd.google-earth.kmz";
return MIME_KML;
}
public String getExtension() {
return "kml";
}
},
KMZ_ONLY_TRACK {
@Override
public TrackWriter newTrackWriter(Context context, boolean multiple) {
return new KmlTrackWriter(context, multiple, false, false, false);
}
@Override
public String getMimeType() {
return MIME_KMZ;
}
public String getExtension() {
return "kmz";
}
},
KMZ_WITH_SENSORDATA {
@Override
public TrackWriter newTrackWriter(Context context, boolean multiple) {
return new KmlTrackWriter(context, multiple, true, true, false);
}
@Override
public String getMimeType() {
return MIME_KMZ;
}
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
ContentProviderUtils contentProviderUtils = ContentProviderUtils.Factory.get(context);
TrackWriter trackWriter = this.newTrackWriter(context, tracks.length > 1);
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, trackExporterListener);
}
FileTrackExporter fileTrackExporter = new FileTrackExporter(contentProviderUtils, trackWriter, tracks, trackExporterListener);
public String getExtension() {
return "kmz";
}
},
KMZ_WITH_SENSORDATA_AND_PICTURES {
@Override
public TrackWriter newTrackWriter(Context context, boolean multiple) {
return new KmlTrackWriter(context, multiple, true, true, true);
}
return new KmzTrackExporter(contentProviderUtils, fileTrackExporter, tracks);
@Override
public String getMimeType() {
return MIME_KMZ;
}
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
return newKmzTrackExporter(context, this.newTrackWriter(context, tracks.length > 1), tracks, trackExporterListener);
}
public String getExtension() {
return "kmz";
}
},
GPX {
@@ -62,8 +115,13 @@ public enum TrackFileFormat implements Parcelable {
public String getMimeType() {
return "application/gpx+xml";
}
public String getExtension() {
return "gpx";
}
};
@Deprecated
public static final Creator<TrackFileFormat> CREATOR = new Creator<TrackFileFormat>() {
@Override
public TrackFileFormat createFromParcel(final Parcel source) {
@@ -86,13 +144,7 @@ public enum TrackFileFormat implements Parcelable {
dest.writeInt(ordinal());
}
/**
* Creates a new track writer for the format.
*
* @param context the context
* @param multiple true for writing multiple tracks
*/
public abstract TrackWriter newTrackWriter(Context context, boolean multiple);
private static final String MIME_KML = "application/vnd.google-earth.kml+xml";
public TrackExporter newTrackExporter(Context context, Track[] tracks, TrackExporterListener trackExporterListener) {
ContentProviderUtils contentProviderUtils = ContentProviderUtils.Factory.get(context);
@@ -105,10 +157,33 @@ public enum TrackFileFormat implements Parcelable {
*/
public abstract String getMimeType();
private static final String MIME_KMZ = "application/vnd.google-earth.kml+xml";
private static TrackExporter newKmzTrackExporter(Context context, TrackWriter trackWriter, Track[] tracks, TrackExporterListener trackExporterListener) {
ContentProviderUtils contentProviderUtils = ContentProviderUtils.Factory.get(context);
FileTrackExporter fileTrackExporter = new FileTrackExporter(contentProviderUtils, trackWriter, tracks, trackExporterListener);
return new KmzTrackExporter(contentProviderUtils, fileTrackExporter, tracks);
}
/**
* Creates a new track writer for the format.
*
* @param context the context
* @param multiple true for writing multiple tracks
*/
public abstract TrackWriter newTrackWriter(Context context, boolean multiple);
/**
* Returns the file extension for each format.
*/
public String getExtension() {
public abstract String getExtension();
/**
* Returns the name of for each format.
*/
public String getName() {
return this.name().toLowerCase(Locale.US);
}
}
@@ -18,16 +18,15 @@ package de.dennisguse.opentracks.io.file.exporter;
import android.location.Location;
import de.dennisguse.opentracks.content.Track;
import de.dennisguse.opentracks.content.Waypoint;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.util.StringUtils;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.Locale;
import de.dennisguse.opentracks.content.Track;
import de.dennisguse.opentracks.content.Waypoint;
import de.dennisguse.opentracks.util.StringUtils;
/**
* Write track as GPX to a file.
*
@@ -59,11 +58,6 @@ public class GpxTrackWriter implements TrackWriter {
this.creator = creator;
}
@Override
public String getExtension() {
return TrackFileFormat.GPX.getExtension();
}
@Override
public void prepare(OutputStream outputStream) {
this.printWriter = new PrintWriter(outputStream);
@@ -83,11 +77,9 @@ public class GpxTrackWriter implements TrackWriter {
printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
printWriter.println("<gpx");
printWriter.println("version=\"1.1\"");
printWriter.println(
"creator=\"" + creator + "\"");
printWriter.println("creator=\"" + creator + "\"");
printWriter.println("xmlns=\"http://www.topografix.com/GPX/1/1\"");
printWriter.println(
"xmlns:topografix=\"http://www.topografix.com/GPX/Private/TopoGrafix/0/1\"");
printWriter.println("xmlns:topografix=\"http://www.topografix.com/GPX/Private/TopoGrafix/0/1\"");
printWriter.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
printWriter.println("xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1"
+ " http://www.topografix.com/GPX/1/1/gpx.xsd"
@@ -20,9 +20,6 @@ import android.database.Cursor;
import android.location.Location;
import android.net.Uri;
import androidx.annotation.VisibleForTesting;
import java.io.File;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -36,7 +33,6 @@ import de.dennisguse.opentracks.content.Track;
import de.dennisguse.opentracks.content.Waypoint;
import de.dennisguse.opentracks.content.Waypoint.WaypointType;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.util.StringUtils;
/**
@@ -63,8 +59,10 @@ public class KmlTrackWriter implements TrackWriter {
private static final String TRACK_ICON = "http://earth.google.com/images/kml-icons/track-directional/track-0.png";
private final Context context;
private final boolean multiple;
private final boolean isKMZ;
private final boolean hasMultipleTracks;
private final boolean exportPictures;
private final boolean exportTrackDetails;
private final boolean exportSensorData;
private final DescriptionGenerator descriptionGenerator;
private final ContentProviderUtils contentProviderUtils;
@@ -76,24 +74,25 @@ public class KmlTrackWriter implements TrackWriter {
private boolean hasCadence;
private boolean hasHeartRate;
public KmlTrackWriter(Context context, boolean multiple, boolean isKMZ) {
this(context, multiple, isKMZ, new DescriptionGeneratorImpl(context));
}
private Location startLocation;
@VisibleForTesting
KmlTrackWriter(Context context, boolean multiple, boolean isKMZ, DescriptionGenerator descriptionGenerator) {
/**
* @param context the context
* @param hasMultipleTracks should encode multiple tracks into one file?
* @param exportPictures should pictures be exported (if true: exports to KMZ)?
* @param exportTrackDetails should detailed information about the track be exported (e.g., title, description, waypoints, timing)?
* @param exportSensorData should {@link SensorDataSet} be exported?
*/
public KmlTrackWriter(Context context, boolean hasMultipleTracks, boolean exportTrackDetails, boolean exportSensorData, boolean exportPictures) {
this.context = context;
this.multiple = multiple;
this.isKMZ = isKMZ;
this.descriptionGenerator = descriptionGenerator;
this.hasMultipleTracks = hasMultipleTracks;
this.exportTrackDetails = exportTrackDetails;
this.exportSensorData = exportSensorData;
this.exportPictures = exportPictures;
this.descriptionGenerator = new DescriptionGeneratorImpl(context);
this.contentProviderUtils = ContentProviderUtils.Factory.get(context);
}
@Override
public String getExtension() {
return TrackFileFormat.KML.getExtension();
}
@Override
public void prepare(OutputStream outputStream) {
this.printWriter = new PrintWriter(outputStream);
@@ -117,8 +116,12 @@ public class KmlTrackWriter implements TrackWriter {
printWriter.println("<Document>");
printWriter.println("<open>1</open>");
printWriter.println("<visibility>1</visibility>");
Track track = tracks[0];
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
if (exportTrackDetails) {
Track track = tracks[0];
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
}
printWriter.println("<atom:author><atom:name>" + StringUtils.formatCData(context.getString(R.string.app_name)) + "</atom:name></atom:author>");
writeTrackStyle();
writePlacemarkerStyle(START_STYLE, START_ICON, 32, 1);
@@ -126,9 +129,12 @@ public class KmlTrackWriter implements TrackWriter {
writePlacemarkerStyle(STATISTICS_STYLE, STATISTICS_ICON, 20, 2);
writePlacemarkerStyle(WAYPOINT_STYLE, WAYPOINT_ICON, 20, 2);
printWriter.println("<Schema id=\"" + SCHEMA_ID + "\">");
writeSensorStyle(POWER, context.getString(R.string.description_sensor_power));
writeSensorStyle(CADENCE, context.getString(R.string.description_sensor_cadence));
writeSensorStyle(HEART_RATE, context.getString(R.string.description_sensor_heart_rate));
if (exportSensorData) {
writeSensorStyle(POWER, context.getString(R.string.description_sensor_power));
writeSensorStyle(CADENCE, context.getString(R.string.description_sensor_cadence));
writeSensorStyle(HEART_RATE, context.getString(R.string.description_sensor_heart_rate));
}
printWriter.println("</Schema>");
}
}
@@ -144,7 +150,10 @@ public class KmlTrackWriter implements TrackWriter {
@Override
public void writeBeginWaypoints(Track track) {
if (printWriter != null) {
printWriter.println("<Folder><name>" + StringUtils.formatCData(context.getString(R.string.track_markers, track.getName())) + "</name>");
printWriter.println("<Folder>");
if (exportTrackDetails) {
printWriter.println("<name>" + StringUtils.formatCData(context.getString(R.string.track_markers, track.getName())) + "</name>");
}
printWriter.println("<open>1</open>");
}
}
@@ -158,7 +167,7 @@ public class KmlTrackWriter implements TrackWriter {
@Override
public void writeWaypoint(Waypoint waypoint) {
if (printWriter != null) {
if (printWriter != null && exportTrackDetails) {
String styleName = waypoint.getType() == WaypointType.STATISTICS ? STATISTICS_STYLE : WAYPOINT_STYLE;
if (waypoint.hasPhoto()) {
float heading = getHeading(waypoint.getTrackId(), waypoint.getLocation());
@@ -171,7 +180,7 @@ public class KmlTrackWriter implements TrackWriter {
@Override
public void writeBeginTracks() {
if (printWriter != null && multiple) {
if (printWriter != null && hasMultipleTracks) {
printWriter.println("<Folder id=tour>");
printWriter.println("<name>" + context.getString(R.string.generic_tracks) + "</name>");
printWriter.println("<open>1</open>");
@@ -180,20 +189,20 @@ public class KmlTrackWriter implements TrackWriter {
@Override
public void writeEndTracks() {
if (printWriter != null && multiple) {
if (printWriter != null && hasMultipleTracks) {
printWriter.println("</Folder>");
}
}
@Override
public void writeBeginTrack(Track track, Location startLocation) {
this.startLocation = startLocation;
if (printWriter != null) {
String name = context.getString(R.string.marker_label_start, track.getName());
writePlacemark(name, "", "", START_STYLE, startLocation);
printWriter.println("<Placemark>");
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
printWriter.println(
"<description>" + StringUtils.formatCData(track.getDescription()) + "</description>");
printWriter.println("<description>" + StringUtils.formatCData(track.getDescription()) + "</description>");
printWriter.println("<styleUrl>#" + TRACK_STYLE + "</styleUrl>");
writeCategory(track.getCategory());
printWriter.println("<gx:MultiTrack>");
@@ -231,14 +240,16 @@ public class KmlTrackWriter implements TrackWriter {
if (printWriter != null) {
printWriter.println("<ExtendedData>");
printWriter.println("<SchemaData schemaUrl=\"#" + SCHEMA_ID + "\">");
if (hasPower) {
writeSensorData(powerList, POWER);
}
if (hasCadence) {
writeSensorData(cadenceList, CADENCE);
}
if (hasHeartRate) {
writeSensorData(heartRateList, HEART_RATE);
if (exportSensorData) {
if (hasPower) {
writeSensorData(powerList, POWER);
}
if (hasCadence) {
writeSensorData(cadenceList, CADENCE);
}
if (hasHeartRate) {
writeSensorData(heartRateList, HEART_RATE);
}
}
printWriter.println("</SchemaData>");
printWriter.println("</ExtendedData>");
@@ -249,9 +260,13 @@ public class KmlTrackWriter implements TrackWriter {
@Override
public void writeLocation(Location location) {
if (printWriter != null) {
printWriter.println("<when>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</when>");
if (exportTrackDetails) {
printWriter.println("<when>" + getTime(location) + "</when>");
}
printWriter.println("<gx:coord>" + getCoordinates(location, " ") + "</gx:coord>");
if (location instanceof SensorDataSetLocation) {
if (exportSensorData && location instanceof SensorDataSetLocation) {
SensorDataSet sensorDataSet = ((SensorDataSetLocation) location).getSensorDataSet();
if (sensorDataSet != null) {
if (sensorDataSet.hasHeartRate()) {
@@ -291,13 +306,12 @@ public class KmlTrackWriter implements TrackWriter {
* @param styleName the style name
* @param location the location
*/
private void writePlacemark(
String name, String category, String description, String styleName, Location location) {
if (location != null) {
private void writePlacemark(String name, String category, String description, String styleName, Location location) {
if (location != null && exportTrackDetails) {
printWriter.println("<Placemark>");
printWriter.println("<name>" + StringUtils.formatCData(name) + "</name>");
printWriter.println( "<description>" + StringUtils.formatCData(description) + "</description>");
printWriter.println("<TimeStamp><when>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</when></TimeStamp>");
printWriter.println("<description>" + StringUtils.formatCData(description) + "</description>");
printWriter.println("<TimeStamp><when>" + getTime(location) + "</when></TimeStamp>");
printWriter.println("<styleUrl>#" + styleName + "</styleUrl>");
writeCategory(category);
printWriter.println("<Point>");
@@ -319,10 +333,10 @@ public class KmlTrackWriter implements TrackWriter {
* @param heading the heading
*/
private void writePhotoOverlay(String name, String category, String description, String styleName, Location location, String photoUrl, float heading) {
if (location != null) {
if (location != null && exportTrackDetails) {
printWriter.println("<PhotoOverlay>");
printWriter.println("<name>" + StringUtils.formatCData(name) + "</name>");
printWriter.println( "<description>" + StringUtils.formatCData(description) + "</description>");
printWriter.println("<description>" + StringUtils.formatCData(description) + "</description>");
printWriter.print("<Camera>");
printWriter.print("<longitude>" + location.getLongitude() + "</longitude>");
printWriter.print("<latitude>" + location.getLatitude() + "</latitude>");
@@ -330,15 +344,12 @@ public class KmlTrackWriter implements TrackWriter {
printWriter.print("<heading>" + heading + "</heading>");
printWriter.print("<tilt>90</tilt>");
printWriter.println("</Camera>");
printWriter.println("<TimeStamp><when>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</when></TimeStamp>");
printWriter.println("<TimeStamp><when>" + getTime(location) + "</when></TimeStamp>");
printWriter.println("<styleUrl>#" + styleName + "</styleUrl>");
writeCategory(category);
if (isKMZ) {
if (exportPictures) {
printWriter.println("<Icon><href>" + Uri.decode(photoUrl) + "</href></Icon>");
} else {
Uri uri = Uri.parse(photoUrl);
printWriter.println("<Icon><href>" + KmzTrackExporter.KMZ_IMAGES_DIR + File.separatorChar + uri.getLastPathSegment() + "</href></Icon>");
}
printWriter.print("<ViewVolume>");
@@ -355,6 +366,19 @@ public class KmlTrackWriter implements TrackWriter {
}
}
/**
* Returns the formatted time of the location; either absolute or relative depending exportTrackDetails.
*
* @param location the location
*/
private String getTime(Location location) {
if (exportTrackDetails) {
return StringUtils.formatDateTimeIso8601(location.getTime());
} else {
return StringUtils.formatDateTimeIso8601(location.getTime() - startLocation.getTime());
}
}
/**
* Gets the heading to a location.
*
@@ -396,7 +420,7 @@ public class KmlTrackWriter implements TrackWriter {
return;
}
printWriter.println("<ExtendedData>");
printWriter.println( "<Data name=\"type\"><value>" + StringUtils.formatCData(category) + "</value></Data>");
printWriter.println("<Data name=\"type\"><value>" + StringUtils.formatCData(category) + "</value></Data>");
printWriter.println("</ExtendedData>");
}
@@ -37,8 +37,6 @@ import de.dennisguse.opentracks.content.Waypoint;
* @author Jimmy Shih
*/
public class KmzTrackExporter implements TrackExporter {
public static final String KMZ_EXTENSION = "kmz";
public static final String KMZ_IMAGES_DIR = "images";
public static final String KMZ_KML_FILE = "doc.kml";
@@ -17,11 +17,11 @@ package de.dennisguse.opentracks.io.file.exporter;
import android.location.Location;
import java.io.OutputStream;
import de.dennisguse.opentracks.content.Track;
import de.dennisguse.opentracks.content.Waypoint;
import java.io.OutputStream;
/**
* Interface for writing tracks to a file. The expected sequence of calls is:
*
@@ -51,11 +51,6 @@ import java.io.OutputStream;
*/
public interface TrackWriter {
/**
* Gets the file extension (e.g, gpx, kml, ...).
*/
String getExtension();
/**
* Prepares the output stream.
*
@@ -20,7 +20,6 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
@@ -70,11 +69,6 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
@Override
public void onFileTypeDone(TrackFileFormat trackFileFormat) {
Intent intent = getIntent();
if (trackFileFormat == null) {
trackFileFormat = TrackFileFormat.GPX;
}
if (!FileUtils.isExternalStorageAvailable()) {
Toast.makeText(this, R.string.external_storage_not_available, Toast.LENGTH_LONG).show();
finish();
@@ -84,8 +78,7 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
directoryDisplayName = FileUtils.getPathDisplayName(trackFileFormat.getExtension());
String directoryPath = FileUtils.getPath(trackFileFormat.getExtension());
if (!FileUtils.isDirectory(new File(directoryPath))) {
Toast.makeText(
this, getString(R.string.import_no_directory, directoryDisplayName), Toast.LENGTH_LONG)
Toast.makeText(this, getString(R.string.import_no_directory, directoryDisplayName), Toast.LENGTH_LONG)
.show();
finish();
return;
@@ -24,7 +24,6 @@ import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -33,7 +32,6 @@ import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.ContentProviderUtils;
import de.dennisguse.opentracks.content.Track;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.io.file.exporter.KmzTrackExporter;
import de.dennisguse.opentracks.util.FileUtils;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.SystemUtils;
@@ -107,11 +105,8 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
try {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
// Get the wake lock if not recording or paused
boolean isRecording =
PreferencesUtils.getLong(importActivity, R.string.recording_track_id_key)
!= PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
boolean isPaused = PreferencesUtils.getBoolean(importActivity,
R.string.recording_track_paused_key, PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT);
boolean isRecording = PreferencesUtils.getLong(importActivity, R.string.recording_track_id_key) != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
boolean isPaused = PreferencesUtils.getBoolean(importActivity, R.string.recording_track_paused_key, PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT);
if (!isRecording || isPaused) {
wakeLock = SystemUtils.acquireWakeLock(importActivity, wakeLock);
}
@@ -169,37 +164,28 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
* @param file the file
*/
private boolean importFile(final File file) {
FileInputStream fileInputStream = null;
try {
TrackImporter trackImporter;
if (trackFileFormat == TrackFileFormat.KML) {
String extension = FileUtils.getExtension(file.getName());
if (TrackFileFormat.KML.getExtension().equals(extension)) {
trackImporter = new KmlFileTrackImporter(context, -1L);
} else {
ContentProviderUtils contentProviderUtils = ContentProviderUtils.Factory.get(context);
Uri uri = contentProviderUtils.insertTrack(new Track());
long newId = Long.parseLong(uri.getLastPathSegment());
trackImporter = new KmzTrackImporter(context, newId);
}
TrackImporter trackImporter;
if (trackFileFormat == TrackFileFormat.GPX) {
trackImporter = new GpxFileTrackImporter(context);
} else { //KML or KMZ
String extension = FileUtils.getExtension(file.getName());
if (TrackFileFormat.KML_ONLY_TRACK.getExtension().equals(extension)) {
trackImporter = new KmlFileTrackImporter(context, -1L);
} else {
trackImporter = new GpxFileTrackImporter(context);
ContentProviderUtils contentProviderUtils = ContentProviderUtils.Factory.get(context);
Uri uri = contentProviderUtils.insertTrack(new Track());
long newId = Long.parseLong(uri.getLastPathSegment());
trackImporter = new KmzTrackImporter(context, newId);
}
fileInputStream = new FileInputStream(file);
}
try (FileInputStream fileInputStream = new FileInputStream(file)) {
trackId = trackImporter.importFile(fileInputStream);
return trackId != -1L;
} catch (FileNotFoundException e) {
} catch (IOException e) {
Log.e(TAG, "Unable to import file", e);
return false;
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
Log.e(TAG, "Unable to close file input stream", e);
}
}
}
}
@@ -213,22 +199,18 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
File file = new File(path);
File[] candidates = file.listFiles();
if (candidates != null) {
for (File candidate : candidates) {
if (!FileUtils.isDirectory(candidate)) {
String extension = FileUtils.getExtension(candidate.getName());
if (trackFileFormat == TrackFileFormat.KML
&& (TrackFileFormat.KML.getExtension().equals(extension)
|| KmzTrackExporter.KMZ_EXTENSION.equals(extension))) {
files.add(candidate);
} else if (trackFileFormat == TrackFileFormat.GPX && TrackFileFormat.GPX.getExtension().equals(extension)) {
files.add(candidate);
}
if (candidates == null) {
return files;
}
for (File candidate : candidates) {
if (!FileUtils.isDirectory(candidate)) {
String extension = FileUtils.getExtension(candidate.getName());
if (trackFileFormat.getExtension().equals(extension)) {
files.add(candidate);
}
}
}
return files;
}
}
@@ -80,7 +80,7 @@ public class IntentUtils {
Track track = ContentProviderUtils.Factory.get(context).getTrack(trackIds[0]);
trackDescription = track == null ? "" : new DescriptionGeneratorImpl(context).generateTrackDescription(track, false);
}
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, TrackFileFormat.KML);
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, TrackFileFormat.KMZ_WITH_SENSORDATA_AND_PICTURES);
return new Intent(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_STREAM, uriAndMime.first)
@@ -112,7 +112,7 @@ public class IntentUtils {
return;
}
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, TrackFileFormat.KML);
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, TrackFileFormat.KMZ_ONLY_TRACK);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(uriAndMime.first, uriAndMime.second);