forked from upstream-mirrors/OpenTracks
Cleanup: mainly code formatting and made LocationIterator implement autoclosable.
This commit is contained in:
@@ -38,8 +38,8 @@ import de.dennisguse.opentracks.util.DialogUtils;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
/**
|
||||
* An activity for saving tracks to the external storage. If saving a specific
|
||||
* track, option to save it to a temp directory and play the track afterward.
|
||||
* An activity for saving tracks to the external storage.
|
||||
* If saving a specific track, option to save it to a temp directory and play the track afterward.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
@@ -53,13 +53,11 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
private String directoryDisplayName;
|
||||
|
||||
private ExportAsyncTask exportAsyncTask;
|
||||
|
||||
private ProgressDialog progressDialog;
|
||||
|
||||
// the number of tracks successfully saved
|
||||
private int successCount;
|
||||
|
||||
// the number of tracks to save
|
||||
private int totalCount;
|
||||
private int processedTrackCount;
|
||||
private int totalTrackCount;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@@ -144,8 +142,8 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
int titleId;
|
||||
String message;
|
||||
String totalTracks = getResources()
|
||||
.getQuantityString(R.plurals.tracks, totalCount, totalCount);
|
||||
if (successCount == totalCount) {
|
||||
.getQuantityString(R.plurals.tracks, totalTrackCount, totalTrackCount);
|
||||
if (processedTrackCount == totalTrackCount) {
|
||||
iconId = R.drawable.ic_dialog_success;
|
||||
titleId = R.string.generic_success_title;
|
||||
message = getString(
|
||||
@@ -153,7 +151,7 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
} else {
|
||||
iconId = android.R.drawable.ic_dialog_alert;
|
||||
titleId = R.string.generic_error_title;
|
||||
message = getString(R.string.export_external_storage_error, successCount, totalTracks,
|
||||
message = getString(R.string.export_external_storage_error, processedTrackCount, totalTracks,
|
||||
directoryDisplayName);
|
||||
}
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this).setCancelable(true)
|
||||
@@ -192,8 +190,8 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
* @param aTotalCount the number of tracks to save
|
||||
*/
|
||||
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount) {
|
||||
successCount = aSuccessCount;
|
||||
totalCount = aTotalCount;
|
||||
processedTrackCount = aSuccessCount;
|
||||
totalTrackCount = aTotalCount;
|
||||
removeDialog(DIALOG_PROGRESS_ID);
|
||||
showDialog(DIALOG_RESULT_ID);
|
||||
}
|
||||
|
||||
@@ -52,17 +52,10 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
private ExportActivity exportActivity;
|
||||
private WakeLock wakeLock;
|
||||
|
||||
// true if the AsyncTask has completed
|
||||
private boolean completed;
|
||||
|
||||
// the number of tracks successfully saved
|
||||
private int successCount;
|
||||
|
||||
// the number of tracks to save
|
||||
private int totalCount;
|
||||
|
||||
// the last successfully saved path
|
||||
private String savedPath;
|
||||
private int processedTrackCount;
|
||||
private int totalTrackCount;
|
||||
|
||||
/**
|
||||
* Creates an AsyncTask.
|
||||
@@ -79,9 +72,8 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
contentProviderUtils = ContentProviderUtils.Factory.get(context);
|
||||
|
||||
completed = false;
|
||||
successCount = 0;
|
||||
totalCount = 0;
|
||||
savedPath = null;
|
||||
processedTrackCount = 0;
|
||||
totalTrackCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +84,7 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
public void setActivity(ExportActivity exportActivity) {
|
||||
this.exportActivity = exportActivity;
|
||||
if (completed && exportActivity != null) {
|
||||
exportActivity.onAsyncTaskCompleted(successCount, totalCount);
|
||||
exportActivity.onAsyncTaskCompleted(processedTrackCount, totalTrackCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +124,7 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
protected void onPostExecute(Boolean result) {
|
||||
completed = true;
|
||||
if (exportActivity != null) {
|
||||
exportActivity.onAsyncTaskCompleted(successCount, totalCount);
|
||||
exportActivity.onAsyncTaskCompleted(processedTrackCount, totalTrackCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +132,7 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
protected void onCancelled() {
|
||||
completed = true;
|
||||
if (exportActivity != null) {
|
||||
exportActivity.onAsyncTaskCompleted(successCount, totalCount);
|
||||
exportActivity.onAsyncTaskCompleted(processedTrackCount, totalTrackCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +164,6 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
|
||||
if (trackExporter.writeTrack(fileOutputStream)) {
|
||||
savedPath = file.getAbsolutePath();
|
||||
return true;
|
||||
} else {
|
||||
if (!file.delete()) {
|
||||
@@ -198,17 +189,17 @@ public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
if (cursor == null) {
|
||||
return false;
|
||||
}
|
||||
totalCount = cursor.getCount();
|
||||
for (int i = 0; i < totalCount; i++) {
|
||||
totalTrackCount = cursor.getCount();
|
||||
for (int i = 0; i < totalTrackCount; i++) {
|
||||
if (isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
cursor.moveToPosition(i);
|
||||
Track track = contentProviderUtils.createTrack(cursor);
|
||||
if (track != null && saveTracks(new Track[]{track})) {
|
||||
successCount++;
|
||||
processedTrackCount++;
|
||||
}
|
||||
publishProgress(i + 1, totalCount);
|
||||
publishProgress(i + 1, totalTrackCount);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.util.Log;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import de.dennisguse.opentracks.Constants;
|
||||
import de.dennisguse.opentracks.content.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.ContentProviderUtils.LocationIterator;
|
||||
import de.dennisguse.opentracks.content.SensorDataSetLocation;
|
||||
@@ -89,17 +88,13 @@ public class FileTrackExporter implements TrackExporter {
|
||||
*/
|
||||
private void writeWaypoints(Track track) throws InterruptedException {
|
||||
/*
|
||||
* 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.
|
||||
* 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;
|
||||
try (Cursor cursor = contentProviderUtils.getWaypointCursor(track.getId(), -1L, Constants.MAX_LOADED_WAYPOINTS_POINTS)) {
|
||||
try (Cursor cursor = contentProviderUtils.getWaypointCursor(track.getId(), -1L, ContentProviderUtils.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.
|
||||
*/
|
||||
// Intentionally skip first waypoint (contains statistics).
|
||||
while (cursor.moveToNext()) {
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
@@ -127,10 +122,8 @@ public class FileTrackExporter implements TrackExporter {
|
||||
boolean isLastLocationValid = false;
|
||||
TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory();
|
||||
int locationNumber = 0;
|
||||
LocationIterator locationIterator = null;
|
||||
|
||||
try {
|
||||
locationIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, locationFactory);
|
||||
try (LocationIterator locationIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, locationFactory)) {
|
||||
|
||||
while (locationIterator.hasNext()) {
|
||||
if (Thread.interrupted()) {
|
||||
@@ -188,10 +181,6 @@ public class FileTrackExporter implements TrackExporter {
|
||||
trackWriter.writeBeginTrack(track, null);
|
||||
trackWriter.writeEndTrack(track, null);
|
||||
}
|
||||
} finally {
|
||||
if (locationIterator != null) {
|
||||
locationIterator.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +213,7 @@ public class FileTrackExporter implements TrackExporter {
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public void swapLocations() {
|
||||
void swapLocations() {
|
||||
Location tempLocation = lastLocation;
|
||||
lastLocation = currentLocation;
|
||||
currentLocation = tempLocation;
|
||||
|
||||
@@ -32,7 +32,7 @@ import de.dennisguse.opentracks.util.StringUtils;
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
//TODO Can we export Sensor.Data in GPX?
|
||||
//TODO Can we export SensorData in GPX?
|
||||
public class GpxTrackWriter implements TrackWriter {
|
||||
|
||||
private static final NumberFormat ELEVATION_FORMAT = NumberFormat.getInstance(Locale.US);
|
||||
@@ -188,7 +188,6 @@ public class GpxTrackWriter implements TrackWriter {
|
||||
* @param location the location
|
||||
*/
|
||||
private String formatLocation(Location location) {
|
||||
return "lat=\"" + COORDINATE_FORMAT.format(location.getLatitude()) + "\" lon=\""
|
||||
+ COORDINATE_FORMAT.format(location.getLongitude()) + "\"";
|
||||
return "lat=\"" + COORDINATE_FORMAT.format(location.getLatitude()) + "\" lon=\"" + COORDINATE_FORMAT.format(location.getLongitude()) + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
+34
-75
@@ -55,23 +55,26 @@ import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||
import de.dennisguse.opentracks.util.UnitConversions;
|
||||
|
||||
/**
|
||||
* Abstract class for various file track importers like {@link GpxFileTrackImporter} and
|
||||
* {@link KmlFileTrackImporter}.
|
||||
* Abstract class for file track importers.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
abstract class AbstractFileTrackImporter extends DefaultHandler implements TrackImporter {
|
||||
|
||||
private static final String TAG = AbstractFileTrackImporter.class.getSimpleName();
|
||||
|
||||
// The maximum number of buffered locations for bulk-insertion
|
||||
private static final int MAX_BUFFERED_LOCATIONS = 512;
|
||||
private final Context context;
|
||||
private final long importTrackId;
|
||||
private final ContentProviderUtils contentProviderUtils;
|
||||
private final int recordingDistanceInterval;
|
||||
|
||||
private final List<Long> trackIds;
|
||||
private final List<Waypoint> waypoints;
|
||||
|
||||
// The current element content
|
||||
//TODO Should be made private and getter be used by child classes.
|
||||
protected String content;
|
||||
protected String name;
|
||||
protected String description;
|
||||
@@ -82,25 +85,24 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
protected String time;
|
||||
protected String waypointType;
|
||||
protected String photoUrl;
|
||||
|
||||
// The current track data
|
||||
private TrackData trackData;
|
||||
|
||||
// The SAX locator to get the current line information
|
||||
private Locator locator;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param context the context
|
||||
* @param importTrackId the track id to import to. -1L to import to a new
|
||||
* track.
|
||||
* @param importTrackId the track id to import to. -1L to import to a new track.
|
||||
*/
|
||||
AbstractFileTrackImporter(
|
||||
Context context, long importTrackId, ContentProviderUtils contentProviderUtils) {
|
||||
AbstractFileTrackImporter(Context context, long importTrackId, ContentProviderUtils contentProviderUtils) {
|
||||
this.context = context;
|
||||
this.importTrackId = importTrackId;
|
||||
this.contentProviderUtils = contentProviderUtils;
|
||||
this.recordingDistanceInterval = PreferencesUtils.getInt(context,
|
||||
R.string.recording_distance_interval_key,
|
||||
PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT);
|
||||
this.recordingDistanceInterval = PreferencesUtils.getInt(context, R.string.recording_distance_interval_key, PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT);
|
||||
trackIds = new ArrayList<>();
|
||||
waypoints = new ArrayList<>();
|
||||
}
|
||||
@@ -116,11 +118,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
if (content == null) {
|
||||
content = newContent;
|
||||
} else {
|
||||
/*
|
||||
* In 99% of the cases, a single call to this method will be made for each
|
||||
* sequence of characters we're interested in, so we'll rarely be
|
||||
* concatenating strings, thus not justifying the use of a StringBuilder.
|
||||
*/
|
||||
// In 99% of the cases, a single call to this method will be made for each sequence of characters we're interested in, so we'll rarely be concatenating strings, thus not justifying the use of a StringBuilder.
|
||||
content += newContent;
|
||||
}
|
||||
}
|
||||
@@ -164,15 +162,10 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
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;
|
||||
TripStatisticsUpdater trackTripStatisticstrackUpdater = new TripStatisticsUpdater(track.getTripStatistics().getStartTime());
|
||||
TripStatisticsUpdater markerTripStatisticsUpdater = new TripStatisticsUpdater(track.getTripStatistics().getStartTime());
|
||||
|
||||
try {
|
||||
locationIterator = contentProviderUtils.getTrackPointLocationIterator(
|
||||
track.getId(), -1L, false, ContentProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
try (LocationIterator locationIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, ContentProviderUtils.DEFAULT_LOCATION_FACTORY)) {
|
||||
|
||||
while (true) {
|
||||
if (waypoint == null) {
|
||||
@@ -198,7 +191,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
waypoint = null;
|
||||
} else {
|
||||
// The waypoint location time matches the track point time
|
||||
|
||||
if (!LocationUtils.isValidLocation(location)) {
|
||||
// Invalid location, load the next location
|
||||
location = null;
|
||||
@@ -206,8 +198,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
}
|
||||
|
||||
// Valid location
|
||||
if (location.getLatitude() == waypoint.getLocation().getLatitude()
|
||||
&& location.getLongitude() == waypoint.getLocation().getLongitude()) {
|
||||
if (location.getLatitude() == waypoint.getLocation().getLatitude() && location.getLongitude() == waypoint.getLocation().getLongitude()) {
|
||||
|
||||
// Get tripStatistics, description, and icon
|
||||
TripStatistics tripStatistics;
|
||||
@@ -216,8 +207,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
if (waypoint.getType() == WaypointType.STATISTICS) {
|
||||
tripStatistics = markerTripStatisticsUpdater.getTripStatistics();
|
||||
markerTripStatisticsUpdater = new TripStatisticsUpdater(location.getTime());
|
||||
waypointDescription = new DescriptionGeneratorImpl(context)
|
||||
.generateWaypointDescription(tripStatistics);
|
||||
waypointDescription = new DescriptionGeneratorImpl(context).generateWaypointDescription(tripStatistics);
|
||||
icon = context.getString(R.string.marker_statistics_icon_url);
|
||||
} else {
|
||||
tripStatistics = null;
|
||||
@@ -230,9 +220,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
long duration = trackTripStatisticstrackUpdater.getTripStatistics().getTotalTime();
|
||||
|
||||
// Insert waypoint
|
||||
Waypoint newWaypoint = new Waypoint(waypoint.getName(), waypointDescription,
|
||||
waypoint.getCategory(), icon, track.getId(), waypoint.getType(), length, duration,
|
||||
-1L, -1L, location, tripStatistics, waypoint.getPhotoUrl());
|
||||
Waypoint newWaypoint = new Waypoint(waypoint.getName(), waypointDescription, waypoint.getCategory(), icon, track.getId(), waypoint.getType(), length, duration, -1L, -1L, location, tripStatistics, waypoint.getPhotoUrl());
|
||||
contentProviderUtils.insertWaypoint(newWaypoint);
|
||||
}
|
||||
|
||||
@@ -240,10 +228,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
waypoint = null;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (locationIterator != null) {
|
||||
locationIterator.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,8 +242,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
trackId = Long.parseLong(uri.getLastPathSegment());
|
||||
} else {
|
||||
if (trackIds.size() > 0) {
|
||||
throw new SAXException(createErrorMessage(
|
||||
"Cannot import more than one track to an existing track " + importTrackId));
|
||||
throw new SAXException(createErrorMessage("Cannot import more than one track to an existing track " + importTrackId));
|
||||
}
|
||||
trackId = importTrackId;
|
||||
contentProviderUtils.clearTrack(context, trackId);
|
||||
@@ -299,13 +282,9 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
protected void onTrackSegmentStart() {
|
||||
trackData.numberOfSegments++;
|
||||
|
||||
/*
|
||||
* If not the first segment, add a pause separator if there is at least one
|
||||
* location in the last segment.
|
||||
*/
|
||||
//If not the first segment, add a pause separator if there is at least one location in the last segment.
|
||||
if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment != null) {
|
||||
insertLocation(createLocation(TrackRecordingService.PAUSE_LATITUDE, 0.0, 0.0,
|
||||
trackData.lastLocationInCurrentSegment.getTime()));
|
||||
insertLocation(createLocation(TrackRecordingService.PAUSE_LATITUDE, 0.0, 0.0, trackData.lastLocationInCurrentSegment.getTime()));
|
||||
}
|
||||
trackData.lastLocationInCurrentSegment = null;
|
||||
}
|
||||
@@ -362,10 +341,8 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
} else {
|
||||
|
||||
/*
|
||||
* We don't have a speed and bearing in GPX, make something up from the
|
||||
* last two points. GPS points tend to have some inherent imprecision,
|
||||
* speed and bearing will likely be off, so the statistics for things
|
||||
* like max speed will also be off.
|
||||
* We don't have a speed and bearing in GPX, make something up from the last two points.
|
||||
* GPS points tend to have some inherent imprecision, speed and bearing will likely be off, so the statistics for things like max speed will also be off.
|
||||
*/
|
||||
double duration = timeDifference * UnitConversions.MS_TO_S;
|
||||
double speed = trackData.lastLocationInCurrentSegment.distanceTo(location) / duration;
|
||||
@@ -379,10 +356,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
}
|
||||
|
||||
if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment == null) {
|
||||
/*
|
||||
* If not the first segment, add a resume separator before adding the
|
||||
* first location.
|
||||
*/
|
||||
// If not the first segment, add a resume separator before adding the first location.
|
||||
insertLocation(
|
||||
createLocation(TrackRecordingService.RESUME_LATITUDE, 0.0, 0.0, location.getTime()));
|
||||
}
|
||||
@@ -441,17 +415,14 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
latitudeValue = Double.parseDouble(latitude);
|
||||
longitudeValue = Double.parseDouble(longitude);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new SAXException(createErrorMessage(String.format(
|
||||
Locale.US, "Unable to parse latitude longitude: %s %s", latitude, longitude)), e);
|
||||
throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse latitude longitude: %s %s", latitude, longitude)), e);
|
||||
}
|
||||
Double altitudeValue = null;
|
||||
if (altitude != null) {
|
||||
try {
|
||||
altitudeValue = Double.parseDouble(altitude);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new SAXException(
|
||||
createErrorMessage(String.format(Locale.US, "Unable to parse altitude: %s", altitude)),
|
||||
e);
|
||||
throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude: %s", altitude)), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,8 +433,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
try {
|
||||
timeValue = StringUtils.getTime(time);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new SAXException(
|
||||
createErrorMessage(String.format(Locale.US, "Unable to parse time: %s", time)), e);
|
||||
throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse time: %s", time)), e);
|
||||
}
|
||||
}
|
||||
return createLocation(latitudeValue, longitudeValue, altitudeValue, timeValue);
|
||||
@@ -477,8 +447,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
* @param altitudeValue the altitude value
|
||||
* @param timeValue the time value
|
||||
*/
|
||||
private Location createLocation(
|
||||
double latitudeValue, double longitudeValue, Double altitudeValue, long timeValue) {
|
||||
private Location createLocation(double latitudeValue, double longitudeValue, Double altitudeValue, long timeValue) {
|
||||
Location location = new Location(LocationManager.GPS_PROVIDER);
|
||||
location.setLatitude(latitudeValue);
|
||||
location.setLongitude(longitudeValue);
|
||||
@@ -501,8 +470,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
*/
|
||||
private void insertLocation(Location location) {
|
||||
if (trackData.tripStatisticsUpdater == null) {
|
||||
trackData.tripStatisticsUpdater = new TripStatisticsUpdater(
|
||||
location.getTime() != -1L ? location.getTime() : trackData.importTime);
|
||||
trackData.tripStatisticsUpdater = new TripStatisticsUpdater(location.getTime() != -1L ? location.getTime() : trackData.importTime);
|
||||
}
|
||||
trackData.tripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
|
||||
@@ -524,8 +492,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
if (data.numBufferedLocations <= 0) {
|
||||
return;
|
||||
}
|
||||
contentProviderUtils.bulkInsertTrackPoint(
|
||||
data.bufferedLocations, data.numBufferedLocations, data.track.getId());
|
||||
contentProviderUtils.bulkInsertTrackPoint(data.bufferedLocations, data.numBufferedLocations, data.track.getId());
|
||||
data.numBufferedLocations = 0;
|
||||
if (data.track.getStartId() == -1L) {
|
||||
data.track.setStartId(contentProviderUtils.getFirstTrackPointId(data.track.getId()));
|
||||
@@ -541,20 +508,16 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
private void insertFirstWaypoint(Track track) {
|
||||
String waypointName = context.getString(R.string.marker_split_name_format, 0);
|
||||
String waypointCategory = "";
|
||||
TripStatisticsUpdater updater = new TripStatisticsUpdater(
|
||||
track.getTripStatistics().getStartTime());
|
||||
TripStatisticsUpdater updater = new TripStatisticsUpdater(track.getTripStatistics().getStartTime());
|
||||
TripStatistics tripStatistics = updater.getTripStatistics();
|
||||
String waypointDescription = new DescriptionGeneratorImpl(context).generateWaypointDescription(
|
||||
tripStatistics);
|
||||
String waypointDescription = new DescriptionGeneratorImpl(context).generateWaypointDescription(tripStatistics);
|
||||
String icon = context.getString(R.string.marker_statistics_icon_url);
|
||||
double length = 0.0;
|
||||
long duration = 0L;
|
||||
Location waypointLocation = new Location("");
|
||||
waypointLocation.setLatitude(100);
|
||||
waypointLocation.setLongitude(180);
|
||||
Waypoint waypoint = new Waypoint(waypointName, waypointDescription, waypointCategory, icon,
|
||||
track.getId(), WaypointType.STATISTICS, length, duration, -1L, -1L, waypointLocation,
|
||||
tripStatistics, "");
|
||||
Waypoint waypoint = new Waypoint(waypointName, waypointDescription, waypointCategory, icon, track.getId(), WaypointType.STATISTICS, length, duration, -1L, -1L, waypointLocation, tripStatistics, "");
|
||||
contentProviderUtils.insertWaypoint(waypoint);
|
||||
}
|
||||
|
||||
@@ -573,17 +536,13 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
private class TrackData {
|
||||
|
||||
// The current track
|
||||
Track track = new Track();
|
||||
|
||||
// The number of segments processed for the current track
|
||||
int numberOfSegments = 0;
|
||||
|
||||
/*
|
||||
* The last location in the current segment. Null if the current segment
|
||||
* doesn't have a last location.
|
||||
*/
|
||||
// The last location in the current segment; Null if the current segment doesn't have a last location
|
||||
Location lastLocationInCurrentSegment;
|
||||
|
||||
// The number of locations processed for the current track
|
||||
|
||||
@@ -64,8 +64,7 @@ public class GpxFileTrackImporter extends AbstractFileTrackImporter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String tag, Attributes attributes)
|
||||
throws SAXException {
|
||||
public void startElement(String uri, String localName, String tag, Attributes attributes) throws SAXException {
|
||||
switch (tag) {
|
||||
case TAG_WAYPOINT:
|
||||
onWaypointStart(attributes);
|
||||
@@ -185,7 +184,6 @@ public class GpxFileTrackImporter extends AbstractFileTrackImporter {
|
||||
* On waypoint end.
|
||||
*/
|
||||
private void onWaypointEnd() throws SAXException {
|
||||
addWaypoint(WaypointType.STATISTICS.name().equals(waypointType) ? WaypointType.STATISTICS
|
||||
: WaypointType.WAYPOINT);
|
||||
addWaypoint(WaypointType.STATISTICS.name().equals(waypointType) ? WaypointType.STATISTICS : WaypointType.WAYPOINT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,11 +56,9 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
// the path on the external storage to import
|
||||
private String directoryDisplayName;
|
||||
|
||||
// the number of files successfully imported
|
||||
private int successCount;
|
||||
private int importedTrackCount;
|
||||
|
||||
// the number of files to import
|
||||
private int totalCount;
|
||||
private int totalTrackCount;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@@ -144,9 +142,9 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
int titleId;
|
||||
String message;
|
||||
String totalFiles = getResources()
|
||||
.getQuantityString(R.plurals.files, totalCount, totalCount);
|
||||
if (successCount == totalCount) {
|
||||
if (totalCount == 0) {
|
||||
.getQuantityString(R.plurals.files, totalTrackCount, totalTrackCount);
|
||||
if (importedTrackCount == totalTrackCount) {
|
||||
if (totalTrackCount == 0) {
|
||||
iconId = android.R.drawable.ic_dialog_info;
|
||||
titleId = R.string.import_no_file_title;
|
||||
message = getString(R.string.import_no_file, directoryDisplayName);
|
||||
@@ -159,7 +157,7 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
iconId = android.R.drawable.ic_dialog_alert;
|
||||
titleId = R.string.generic_error_title;
|
||||
message = getString(
|
||||
R.string.import_error, successCount, totalFiles, directoryDisplayName);
|
||||
R.string.import_error, importedTrackCount, totalFiles, directoryDisplayName);
|
||||
}
|
||||
final Dialog dialog = new AlertDialog.Builder(this).setCancelable(true).setIcon(iconId)
|
||||
.setMessage(message).setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@@ -195,8 +193,8 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr
|
||||
* @param aTotalCount the number of files to import
|
||||
*/
|
||||
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount) {
|
||||
successCount = aSuccessCount;
|
||||
totalCount = aTotalCount;
|
||||
importedTrackCount = aSuccessCount;
|
||||
totalTrackCount = aTotalCount;
|
||||
removeDialog(DIALOG_PROGRESS_ID);
|
||||
showDialog(DIALOG_RESULT_ID);
|
||||
}
|
||||
|
||||
@@ -53,11 +53,9 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
// true if the AsyncTask has completed
|
||||
private boolean completed;
|
||||
|
||||
// the number of files successfully imported
|
||||
private int successCount;
|
||||
private int importTrackCount;
|
||||
|
||||
// the number of files to import
|
||||
private int totalCount;
|
||||
private int totalTrackCount;
|
||||
|
||||
// the last successfully imported track id
|
||||
private long trackId;
|
||||
@@ -76,8 +74,8 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
context = importActivity.getApplicationContext();
|
||||
|
||||
completed = false;
|
||||
successCount = 0;
|
||||
totalCount = 0;
|
||||
importTrackCount = 0;
|
||||
totalTrackCount = 0;
|
||||
trackId = -1L;
|
||||
}
|
||||
|
||||
@@ -89,7 +87,7 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
public void setActivity(ImportActivity importActivity) {
|
||||
this.importActivity = importActivity;
|
||||
if (completed && importActivity != null) {
|
||||
importActivity.onAsyncTaskCompleted(successCount, totalCount);
|
||||
importActivity.onAsyncTaskCompleted(importTrackCount, totalTrackCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,20 +110,20 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
}
|
||||
|
||||
List<File> files = getFiles();
|
||||
totalCount = files.size();
|
||||
if (totalCount == 0) {
|
||||
totalTrackCount = files.size();
|
||||
if (totalTrackCount == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < totalCount; i++) {
|
||||
for (int i = 0; i < totalTrackCount; i++) {
|
||||
if (isCancelled()) {
|
||||
// If cancelled, return true to show the number of files imported
|
||||
return true;
|
||||
}
|
||||
if (importFile(files.get(i))) {
|
||||
successCount++;
|
||||
importTrackCount++;
|
||||
}
|
||||
publishProgress(i + 1, totalCount);
|
||||
publishProgress(i + 1, totalTrackCount);
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
@@ -146,7 +144,7 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
protected void onPostExecute(Boolean result) {
|
||||
completed = true;
|
||||
if (importActivity != null) {
|
||||
importActivity.onAsyncTaskCompleted(successCount, totalCount);
|
||||
importActivity.onAsyncTaskCompleted(importTrackCount, totalTrackCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +152,7 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
protected void onCancelled() {
|
||||
completed = true;
|
||||
if (importActivity != null) {
|
||||
importActivity.onAsyncTaskCompleted(successCount, totalCount);
|
||||
importActivity.onAsyncTaskCompleted(importTrackCount, totalTrackCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,9 +188,9 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of files. If importAll is true, returns a list of the files
|
||||
* under the path directory. If importAll is false, returns a list containing
|
||||
* just the path file.
|
||||
* Gets a list of files.
|
||||
* If importAll is true, returns a list of the files under the path directory.
|
||||
* If importAll is false, returns a list containing just the path file.
|
||||
*/
|
||||
private List<File> getFiles() {
|
||||
List<File> files = new ArrayList<>();
|
||||
|
||||
@@ -22,16 +22,16 @@ import android.net.Uri;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import de.dennisguse.opentracks.content.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.SensorDataSetLocation;
|
||||
import de.dennisguse.opentracks.content.Waypoint.WaypointType;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.dennisguse.opentracks.content.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.SensorDataSetLocation;
|
||||
import de.dennisguse.opentracks.content.Waypoint.WaypointType;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
|
||||
/**
|
||||
* Imports a KML file.
|
||||
*
|
||||
@@ -82,8 +82,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
KmlFileTrackImporter(
|
||||
Context context, long importTrackId, ContentProviderUtils contentProviderUtils) {
|
||||
KmlFileTrackImporter(Context context, long importTrackId, ContentProviderUtils contentProviderUtils) {
|
||||
super(context, importTrackId, contentProviderUtils);
|
||||
}
|
||||
|
||||
@@ -93,11 +92,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
||||
switch (tag) {
|
||||
case TAG_PLACEMARK:
|
||||
case TAG_PHOTO_OVERLAY:
|
||||
/*
|
||||
* Note that a track is contained in a Placemark, calling onWaypointStart
|
||||
* will clear various track variables like name, category, and
|
||||
* description.
|
||||
*/
|
||||
// Note that a track is contained in a Placemark, calling onWaypointStart will clear various track variables like name, category, and description.
|
||||
onWaypointStart();
|
||||
break;
|
||||
case TAG_GX_MULTI_TRACK:
|
||||
@@ -118,13 +113,11 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String tag) throws SAXException {
|
||||
//TODO Check if order is relevant (uses localname and tag); and convert to switch statement
|
||||
if (tag.equals(TAG_KML)) {
|
||||
onFileEnd();
|
||||
} else if (tag.equals(TAG_PLACEMARK) || tag.equals(TAG_PHOTO_OVERLAY)) {
|
||||
/*
|
||||
* Note that a track is contained in a Placemark, calling onWaypointend is
|
||||
* save since waypointType is not set for a track.
|
||||
*/
|
||||
// Note that a track is contained in a Placemark, calling onWaypointend is save since waypointType is not set for a track.
|
||||
onWaypointEnd();
|
||||
} else if (localName.equals(TAG_COORDINATES)) {
|
||||
onWaypointLocationEnd();
|
||||
@@ -187,19 +180,23 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
|
||||
*/
|
||||
private void onWaypointEnd() throws SAXException {
|
||||
// Add a waypoint if the waypointType matches
|
||||
WaypointType type = null;
|
||||
if (WAYPOINT_STYLE.equals(waypointType)) {
|
||||
type = WaypointType.WAYPOINT;
|
||||
} else if (STATISTICS_STYLE.equals(waypointType)) {
|
||||
type = WaypointType.STATISTICS;
|
||||
}
|
||||
if (type == null) {
|
||||
return;
|
||||
WaypointType type;
|
||||
switch (waypointType) {
|
||||
case WAYPOINT_STYLE:
|
||||
type = WaypointType.WAYPOINT;
|
||||
break;
|
||||
case STATISTICS_STYLE:
|
||||
type = WaypointType.STATISTICS;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (photoUrl != null) {
|
||||
Uri uri = Uri.parse(photoUrl);
|
||||
photoUrl = getPhotoUrl(uri.getLastPathSegment());
|
||||
}
|
||||
|
||||
addWaypoint(type);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,6 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import de.dennisguse.opentracks.content.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.io.file.exporter.KmzTrackExporter;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@@ -33,6 +29,11 @@ import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import de.dennisguse.opentracks.content.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.io.file.exporter.KmzTrackExporter;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
|
||||
/**
|
||||
* Imports a KMZ file.
|
||||
*
|
||||
@@ -41,6 +42,7 @@ import java.util.zip.ZipInputStream;
|
||||
public class KmzTrackImporter implements TrackImporter {
|
||||
|
||||
private static final String TAG = KmzTrackImporter.class.getSimpleName();
|
||||
|
||||
private static final int BUFFER_SIZE = 4096;
|
||||
|
||||
private final Context context;
|
||||
@@ -50,22 +52,19 @@ public class KmzTrackImporter implements TrackImporter {
|
||||
* Constructor.
|
||||
*
|
||||
* @param context the context
|
||||
* @param importTrackId track id to import to. This should not be -1L so that
|
||||
* images in the kmz file can be imported.
|
||||
* @param importTrackId track id to import to. This should not be -1L so that images in the kmz file can be imported.
|
||||
*/
|
||||
public KmzTrackImporter(Context context, long importTrackId) {
|
||||
KmzTrackImporter(Context context, long importTrackId) {
|
||||
this.context = context;
|
||||
this.importTrackId = importTrackId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long importFile(InputStream inputStream) {
|
||||
ZipInputStream zipInputStream = null;
|
||||
long trackId = importTrackId;
|
||||
try {
|
||||
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
|
||||
ZipEntry zipEntry;
|
||||
|
||||
zipInputStream = new ZipInputStream(inputStream);
|
||||
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
|
||||
if (Thread.interrupted()) {
|
||||
Log.d(TAG, "Thread interrupted");
|
||||
@@ -93,14 +92,6 @@ public class KmzTrackImporter implements TrackImporter {
|
||||
Log.e(TAG, "Unable to import file", e);
|
||||
cleanImport(trackId);
|
||||
return -1L;
|
||||
} finally {
|
||||
if (zipInputStream != null) {
|
||||
try {
|
||||
zipInputStream.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Unable to close zip input stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +101,7 @@ public class KmzTrackImporter implements TrackImporter {
|
||||
* @param trackId the trackId
|
||||
*/
|
||||
private void cleanImport(long trackId) {
|
||||
if (trackId != -1L) {
|
||||
if (trackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT) {
|
||||
ContentProviderUtils contentProviderUtils = ContentProviderUtils.Factory.get(context);
|
||||
contentProviderUtils.deleteTrack(context, trackId);
|
||||
}
|
||||
@@ -169,19 +160,17 @@ public class KmzTrackImporter implements TrackImporter {
|
||||
* @param fileName the file name
|
||||
*/
|
||||
private void readImageFile(ZipInputStream zipInputStream, String fileName) throws IOException {
|
||||
FileOutputStream fileOutputStream = null;
|
||||
try {
|
||||
if (importTrackId == -1L) {
|
||||
return;
|
||||
}
|
||||
if (fileName.equals("")) {
|
||||
return;
|
||||
}
|
||||
File dir = FileUtils.getPhotoDir(importTrackId);
|
||||
FileUtils.ensureDirectoryExists(dir);
|
||||
if (importTrackId == -1L) {
|
||||
return;
|
||||
}
|
||||
if (fileName.equals("")) {
|
||||
return;
|
||||
}
|
||||
File dir = FileUtils.getPhotoDir(importTrackId);
|
||||
FileUtils.ensureDirectoryExists(dir);
|
||||
File file = new File(dir, fileName);
|
||||
|
||||
File file = new File(dir, fileName);
|
||||
fileOutputStream = new FileOutputStream(file);
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int count;
|
||||
while ((count = zipInputStream.read(buffer)) != -1) {
|
||||
@@ -189,10 +178,6 @@ public class KmzTrackImporter implements TrackImporter {
|
||||
}
|
||||
|
||||
FileUtils.updateMediaScanner(context, Uri.fromFile(file));
|
||||
} finally {
|
||||
if (fileOutputStream != null) {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public interface TrackImporter {
|
||||
* Import a file.
|
||||
*
|
||||
* @param inputStream the file's input stream
|
||||
* @return the imported track id or -1L.
|
||||
* @return the imported track id or RECORDING_TRACK_ID_DEFAULT.
|
||||
*/
|
||||
long importFile(InputStream inputStream);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user