Import files by track in memory (avoid clean track when error). Fixes #473.

This commit is contained in:
Román Martínez
2020-11-11 18:18:35 +01:00
parent ca2bc6426c
commit 9c9bdde6b9
7 changed files with 37 additions and 29 deletions
@@ -488,7 +488,7 @@ public class ContentProviderUtils {
private void deleteMarkerPhoto(Context context, Marker marker) { private void deleteMarkerPhoto(Context context, Marker marker) {
if (marker != null && marker.hasPhoto()) { if (marker != null && marker.hasPhoto()) {
Uri uri = marker.getPhotoURI(); Uri uri = marker.getPhotoURI();
File file = FileUtils.getPhotoFileIfExists(context, marker.getTrackId(), uri); File file = FileUtils.buildInternalPhotoFile(context, marker.getTrackId(), uri);
if (file.exists()) { if (file.exists()) {
File parent = file.getParentFile(); File parent = file.getParentFile();
file.delete(); file.delete();
@@ -616,7 +616,7 @@ public class ContentProviderUtils {
* @param trackId the trackPoints id * @param trackId the trackPoints id
* @return the number of trackPoints inserted * @return the number of trackPoints inserted
*/ */
//TODO Only used for testing and file import; might be better to replace it. //TODO Only used for testing; might be better to replace it.
public int bulkInsertTrackPoint(TrackPoint[] trackPoints, Track.Id trackId) { public int bulkInsertTrackPoint(TrackPoint[] trackPoints, Track.Id trackId) {
ContentValues[] values = new ContentValues[trackPoints.length]; ContentValues[] values = new ContentValues[trackPoints.length];
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
@@ -625,6 +625,15 @@ public class ContentProviderUtils {
return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values); return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values);
} }
//TODO Only used for file import; might be better to replace it.
public int bulkInsertTrackPoint(List<TrackPoint> trackPoints, Track.Id trackId) {
ContentValues[] values = new ContentValues[trackPoints.size()];
for (int i = 0; i < trackPoints.size(); i++) {
values[i] = createContentValues(trackPoints.get(i), trackId);
}
return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values);
}
/** /**
* Gets the first location id for a track. * Gets the first location id for a track.
* Returns null if it doesn't exist. * Returns null if it doesn't exist.
@@ -167,7 +167,7 @@ public class KmlTrackWriter implements TrackWriter {
@Override @Override
public void writeMarker(Marker marker) { public void writeMarker(Marker marker) {
if (printWriter != null && exportTrackDetail) { if (printWriter != null && exportTrackDetail) {
boolean existsPhoto = FileUtils.getPhotoFileIfExists(context, marker.getTrackId(), marker.getPhotoURI()) != null; boolean existsPhoto = FileUtils.buildInternalPhotoFile(context, marker.getTrackId(), marker.getPhotoURI()) != null;
if (marker.hasPhoto() && exportPhotos && existsPhoto) { if (marker.hasPhoto() && exportPhotos && existsPhoto) {
float heading = getHeading(marker.getTrackId(), marker.getLocation()); float heading = getHeading(marker.getTrackId(), marker.getLocation());
writePhotoOverlay(marker, heading); writePhotoOverlay(marker, heading);
@@ -108,7 +108,7 @@ public class KmzTrackExporter implements TrackExporter {
Marker marker = contentProviderUtils.createMarker(cursor); Marker marker = contentProviderUtils.createMarker(cursor);
if (marker.hasPhoto()) { if (marker.hasPhoto()) {
Uri uriPhoto = marker.getPhotoURI(); Uri uriPhoto = marker.getPhotoURI();
boolean existsPhoto = FileUtils.getPhotoFileIfExists(context, track.getId(), uriPhoto) != null; boolean existsPhoto = FileUtils.buildInternalPhotoFile(context, track.getId(), uriPhoto) != null;
if (existsPhoto) { if (existsPhoto) {
addImage(context, zipOutputStream, uriPhoto, marker); addImage(context, zipOutputStream, uriPhoto, marker);
} }
@@ -29,7 +29,6 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.UUID; import java.util.UUID;
@@ -61,9 +60,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
private static final String TAG = AbstractFileTrackImporter.class.getSimpleName(); 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 Context context;
private final ContentProviderUtils contentProviderUtils; private final ContentProviderUtils contentProviderUtils;
private final int recordingDistanceInterval; private final int recordingDistanceInterval;
@@ -127,10 +123,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
saxParser.parse(inputStream, this); saxParser.parse(inputStream, this);
Log.d(TAG, "Total import time: " + (System.currentTimeMillis() - start) + "ms"); Log.d(TAG, "Total import time: " + (System.currentTimeMillis() - start) + "ms");
if (trackIds.size() != 1) {
// TODO Multi track is not supported yet.
throw new ImportParserException("Multi track not supported");
}
return trackIds.get(0); return trackIds.get(0);
} catch (IOException | SAXException | ParserConfigurationException e) { } catch (IOException | SAXException | ParserConfigurationException e) {
Log.e(TAG, "Unable to import file", e); Log.e(TAG, "Unable to import file", e);
@@ -228,17 +220,12 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
*/ */
protected void onTrackStart() throws SAXException { protected void onTrackStart() throws SAXException {
trackData = new TrackData(); trackData = new TrackData();
Uri uri = contentProviderUtils.insertTrack(trackData.track);
Track.Id trackId = new Track.Id(Long.parseLong(uri.getLastPathSegment()));
trackIds.add(trackId);
trackData.track.setId(trackId);
} }
/** /**
* On track end. * On track end.
*/ */
protected void onTrackEnd() { protected void onTrackEnd() {
flushLocations(trackData);
if (name != null) { if (name != null) {
trackData.track.setName(name); trackData.track.setName(name);
} }
@@ -268,17 +255,27 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
} }
trackData.track.setTrackStatistics(trackData.trackStatisticsUpdater.getTrackStatistics()); trackData.track.setTrackStatistics(trackData.trackStatisticsUpdater.getTrackStatistics());
try { Track track = contentProviderUtils.getTrack(trackData.track.getUuid());
contentProviderUtils.updateTrack(trackData.track); if (track != null) {
} catch (SQLiteConstraintException e) {
if (PreferencesUtils.getPreventReimportTracks(context)) { if (PreferencesUtils.getPreventReimportTracks(context)) {
throw e; throw new ImportAlreadyExistsException(context.getString(R.string.import_prevent_reimport));
} }
//TODO This is a workaround until we have proper UI. //TODO This is a workaround until we have proper UI.
trackData.track.setUuid(UUID.randomUUID()); trackData.track.setUuid(UUID.randomUUID());
contentProviderUtils.updateTrack(trackData.track);
} }
if (trackIds.size() > 0) {
// TODO Multi track is not supported yet.
cleanImport();
throw new ImportParserException("Multi track not supported");
}
Uri uri = contentProviderUtils.insertTrack(trackData.track);
Track.Id trackId = new Track.Id(Long.parseLong(uri.getLastPathSegment()));
trackIds.add(trackId);
trackData.track.setId(trackId);
flushLocations(trackData);
} }
/** /**
@@ -482,13 +479,9 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
} }
trackData.trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval); trackData.trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
trackData.bufferedTrackPoints[trackData.numBufferedTrackPoints] = trackPoint; trackData.bufferedTrackPoints.add(trackPoint);
trackData.numBufferedTrackPoints++; trackData.numBufferedTrackPoints++;
trackData.numberOfLocations++; trackData.numberOfLocations++;
if (trackData.numBufferedTrackPoints >= MAX_BUFFERED_LOCATIONS) {
flushLocations(trackData);
}
} }
/** /**
@@ -500,7 +493,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
if (data.numBufferedTrackPoints <= 0) { if (data.numBufferedTrackPoints <= 0) {
return; return;
} }
contentProviderUtils.bulkInsertTrackPoint(Arrays.copyOfRange(data.bufferedTrackPoints, 0, data.numBufferedTrackPoints), data.track.getId()); contentProviderUtils.bulkInsertTrackPoint(data.bufferedTrackPoints, data.track.getId());
data.numBufferedTrackPoints = 0; data.numBufferedTrackPoints = 0;
} }
@@ -537,7 +530,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
final long importTime = System.currentTimeMillis(); final long importTime = System.currentTimeMillis();
// The buffered locations // The buffered locations
final TrackPoint[] bufferedTrackPoints = new TrackPoint[MAX_BUFFERED_LOCATIONS]; final List<TrackPoint> bufferedTrackPoints = new ArrayList<>();
// The number of buffered locations // The number of buffered locations
int numBufferedTrackPoints = 0; int numBufferedTrackPoints = 0;
@@ -4,4 +4,8 @@ class ImportAlreadyExistsException extends RuntimeException {
public ImportAlreadyExistsException(Exception e) { public ImportAlreadyExistsException(Exception e) {
super(e); super(e);
} }
public ImportAlreadyExistsException(String msg) {
super(msg);
}
} }
@@ -271,6 +271,7 @@ public class KmzTrackImporter implements TrackImporter {
* Reads an image file (zipInputStream) and save it in a file called fileName inside photo folder. * Reads an image file (zipInputStream) and save it in a file called fileName inside photo folder.
* *
* @param zipInputStream the zip input stream * @param zipInputStream the zip input stream
* @param trackId the track's id which image belongs to.
* @param fileName the file name * @param fileName the file name
*/ */
private void readAndSaveImageFile(ZipInputStream zipInputStream, Track.Id trackId, String fileName) throws IOException { private void readAndSaveImageFile(ZipInputStream zipInputStream, Track.Id trackId, String fileName) throws IOException {
+1
View File
@@ -294,6 +294,7 @@ limitations under the License.
<string name="import_error_list_dialog_title">Files not imported</string> <string name="import_error_list_dialog_title">Files not imported</string>
<string name="import_file_imported">File %1$s imported</string> <string name="import_file_imported">File %1$s imported</string>
<string name="import_error">Imported %1$d of %2$s from %3$s</string> <string name="import_error">Imported %1$d of %2$s from %3$s</string>
<string name="import_prevent_reimport">You have set prevent re-import track</string>
<string name="import_no_directory">%1$s does not exist</string> <string name="import_no_directory">%1$s does not exist</string>
<string name="import_no_file">There were no files to import. Connect your device to your computer and place the files to import in %1$s.</string> <string name="import_no_file">There were no files to import. Connect your device to your computer and place the files to import in %1$s.</string>
<string name="import_no_file_title">Import files</string> <string name="import_no_file_title">Import files</string>