Cleanup: mainly code formatting and made LocationIterator implement autoclosable.

This commit is contained in:
Dennis Guse
2019-09-07 12:23:56 +02:00
parent 025dee6821
commit 87d92d25f9
104 changed files with 1076 additions and 1526 deletions
@@ -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()) + "\"";
}
}
@@ -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);
}