Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSM upload: Reuse export file if already exists #26

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 50 additions & 22 deletions src/me/guillaumin/android/osmtracker/gpx/ExportToStorageTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,21 @@ public ExportToStorageTask(Context context, long trackId) {
super(context, trackId);
}

/**
* Calculate a track's export directory, and create if it doesn't exist already.
* @param startDate The track's starting date, from
* {@link me.guillaumin.android.osmtracker.db.TrackContentProvider.Schema#COL_START_DATE Schema.COL_START_DATE}
* @return The export directory
* @throws ExportTrackException if the directory can't be created
* @see #getExportDirectory(Context, Date)
*/
@Override
protected File getExportDirectory(Date startDate) throws ExportTrackException {
File sdRoot = Environment.getExternalStorageDirectory();

// The location that the user has specified gpx files
// and associated content to be written
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String userGPXExportDirectoryName = prefs.getString(
OSMTracker.Preferences.KEY_STORAGE_DIR, OSMTracker.Preferences.VAL_STORAGE_DIR);

boolean directoryPerTrack = prefs.getBoolean(OSMTracker.Preferences.KEY_OUTPUT_DIR_PER_TRACK,
OSMTracker.Preferences.VAL_OUTPUT_GPX_OUTPUT_DIR_PER_TRACK);

// Create the path to the directory to which we will be writing
// Trim the directory name, as additional spaces at the end will
// not allow the directory to be created if required
String exportDirectoryPath = userGPXExportDirectoryName.trim();
String perTrackDirectory = "";
if (directoryPerTrack) {
// If the user wants a directory per track, then create a name for the destination directory
// based on the start date of the track
perTrackDirectory = File.separator + DataHelper.FILENAME_FORMATTER.format(startDate);
}
final String exportDirectoryPath = getExportDirectory(context, startDate);

// Create a file based on the path we've generated above
File trackGPXExportDirectory = new File(sdRoot + exportDirectoryPath + perTrackDirectory);
File trackGPXExportDirectory = new File(sdRoot + exportDirectoryPath);

// Create track directory if needed
if (! trackGPXExportDirectory.exists()) {
Expand All @@ -63,7 +52,7 @@ protected File getExportDirectory(Date startDate) throws ExportTrackException {
// Specific hack for Google Nexus S(See issue #168)
if (android.os.Build.MODEL.equals(OSMTracker.Devices.NEXUS_S)) {
// exportDirectoryPath always starts with "/"
trackGPXExportDirectory = new File(exportDirectoryPath + perTrackDirectory);
trackGPXExportDirectory = new File(exportDirectoryPath);
trackGPXExportDirectory.mkdirs();
}
}
Expand All @@ -86,4 +75,43 @@ protected boolean exportMediaFiles() {
protected boolean updateExportDate() {
return true;
}

/**
*<p>Calculate a track's export directory path. Does not create the directory if missing.</p>
*
*<p>The returned directory is relative to <tt>sdRoot</tt> because of bug #168
* mentioned in {@link #getExportDirectory(Date)}. If you can't find the
* returned directory at <tt>sdRoot + directory</tt>, try just <tt>directory</tt>.</p>
*
* @param context Calling activity context, for {@link PreferenceManager#getDefaultSharedPreferences(Context)}
* @param startDate The track's starting date, from
* {@link me.guillaumin.android.osmtracker.db.TrackContentProvider.Schema#COL_START_DATE Schema.COL_START_DATE}
* @return track export directory name within sdcard;
* The full path to dirname is {@link Environment#getExternalStorageDirectory()} + dirname
* @see #getExportDirectory(Date)
*/
public static String getExportDirectory(Context context, Date startDate) {

// The location that the user has specified gpx files
// and associated content to be written
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String userGPXExportDirectoryName = prefs.getString(
OSMTracker.Preferences.KEY_STORAGE_DIR, OSMTracker.Preferences.VAL_STORAGE_DIR);

boolean directoryPerTrack = prefs.getBoolean(OSMTracker.Preferences.KEY_OUTPUT_DIR_PER_TRACK,
OSMTracker.Preferences.VAL_OUTPUT_GPX_OUTPUT_DIR_PER_TRACK);

// Create the path to the directory to which we will be writing
// Trim the directory name, as additional spaces at the end will
// not allow the directory to be created if required
String exportDirectoryPath = userGPXExportDirectoryName.trim();
String perTrackDirectory = "";
if (directoryPerTrack) {
// If the user wants a directory per track, then create a name for the destination directory
// based on the start date of the track
perTrackDirectory = File.separator + DataHelper.FILENAME_FORMATTER.format(startDate);
}

return exportDirectoryPath + perTrackDirectory;
}
}
88 changes: 85 additions & 3 deletions src/me/guillaumin/android/osmtracker/gpx/ExportToTempFileTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,36 @@
import java.io.IOException;
import java.util.Date;

import me.guillaumin.android.osmtracker.db.TrackContentProvider;
import me.guillaumin.android.osmtracker.db.TrackContentProvider.Schema;
import me.guillaumin.android.osmtracker.exception.ExportTrackException;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.os.Environment;
import android.util.Log;

/**
* Exports to a temporary file. Will not export associated
* media, only the GPX file.
* If this track has already been exported, tries to find and re-use that file.
*
*/
public abstract class ExportToTempFileTask extends ExportTrackTask {

private static final String TAG = ExportToTempFileTask.class.getSimpleName();

private final File tmpFile;
/** Temp file created in constructor, or actual export file if found */
private File tmpFile;
private String filename;
/** True if a previous export file was found */
private boolean reusedRealExport = false;

public ExportToTempFileTask(Context context, long trackId) {
super(context, trackId);
tmpFile = checkForExportFile();
if (tmpFile != null)
return;
try {
tmpFile = File.createTempFile("osm-upload", ".gpx", context.getCacheDir());
Log.d(TAG, "Temporary file: " + tmpFile.getAbsolutePath());
Expand All @@ -32,15 +43,76 @@ public ExportToTempFileTask(Context context, long trackId) {
}
}


/**
* Checks whether this file's already been exported, based on the track
* db and our naming conventions. If so, we can reuse that GPX file,
* instead of creating a new temporary one.
* Sets {@link #reusedRealExport} but does not set {@link #tmpFile}.
* @return Export file if it exists
*/
private File checkForExportFile() {
reusedRealExport = false;

// Query the track columns needed by this method and buildGPXFilename
final String[] pro = { Schema.COL_EXPORT_DATE, Schema.COL_START_DATE, Schema.COL_NAME };
Cursor c = context.getContentResolver().query(ContentUris.withAppendedId(
TrackContentProvider.CONTENT_URI_TRACK, trackId), pro, null,
null, null);
if (null == c)
return null; // <--- Early return: could not query ---

// Get the exportDate and startDate of this track
Date exportDate = null, startDate = null;
if (1 <= c.getCount()) {
c.moveToFirst();
final int eidx = c.getColumnIndex(Schema.COL_EXPORT_DATE);
if (! c.isNull(eidx))
{
exportDate = new Date();
exportDate.setTime(c.getLong(eidx));
startDate = new Date();
startDate.setTime(c.getLong(c.getColumnIndex(Schema.COL_START_DATE)));
}
}

if (exportDate == null) {
c.close();
return null; // <--- Early return: Not exported ---
}

final String exportDirectoryPath = ExportToStorageTask.getExportDirectory(context, startDate);
final File sdRoot = Environment.getExternalStorageDirectory();
File expDir = new File(sdRoot + exportDirectoryPath);
if (! expDir.exists())
expDir = new File(exportDirectoryPath); // Specific hack for Google Nexus S (See issue #168)
if (! expDir.exists()) {
c.close();
return null; // <--- Early return: Export dir doesn't exist ---
}

// Export dir exists. Does the GPX file exist with the expected name?
final String filenameBase = super.buildGPXFilename(c);
c.close();
File f = new File(expDir, filenameBase);
if (f.exists()) {
reusedRealExport = true;
return f;
} else {
return null;
}
}

@Override
protected File getExportDirectory(Date startDate) throws ExportTrackException {
return tmpFile.getParentFile();
}

@Override
protected String buildGPXFilename(Cursor c) {
filename = super.buildGPXFilename(c);
if (reusedRealExport)
filename = tmpFile.getName();
else
filename = super.buildGPXFilename(c);
return tmpFile.getName();
}

Expand All @@ -62,6 +134,16 @@ public String getFilename() {
return filename;
}

@Override
protected Boolean doInBackground(Void... params) {
if (reusedRealExport) {
trackFile = tmpFile;
return true;
} else {
return super.doInBackground(params);
}
}

@Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
Expand Down
13 changes: 11 additions & 2 deletions src/me/guillaumin/android/osmtracker/gpx/ExportTrackTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public abstract class ExportTrackTask extends AsyncTask<Void, Integer, Boolean>
/**
* Path to the exported GPX file
*/
private File trackFile;
protected File trackFile;

/**
* Dialog to display while exporting
Expand Down Expand Up @@ -138,7 +138,11 @@ protected void onPreExecute() {
dialog.show();
}


/**
* Export the track to a new GPX file.
* Calls {@link #exportTrackAsGpx(long)} which sets {@link #trackFile} to the file.
* If any error occurs, sets {@link #errorMsg}.
*/
@Override
protected Boolean doInBackground(Void... params) {
try {
Expand Down Expand Up @@ -180,6 +184,11 @@ public void onClick(DialogInterface dialog, int which) {
}
}

/**
* Export the track to a new GPX file. Sets {@link #trackFile} to the file.
* @param trackId Track ID
* @throws ExportTrackException if any error occurs during export
*/
private void exportTrackAsGpx(long trackId) throws ExportTrackException {
File sdRoot = Environment.getExternalStorageDirectory();

Expand Down