forked from upstream-mirrors/OpenTracks
Import files by track in memory (avoid clean track when error). Fixes #473.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-25
@@ -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 +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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user