Moved Import all/Export all functionality to Settings.

This commit is contained in:
Dennis Guse
2019-08-15 22:38:51 +02:00
parent 01ef5cfa6f
commit 8ca24b877c
9 changed files with 124 additions and 276 deletions
@@ -16,22 +16,22 @@
package de.dennisguse.opentracks.io.file.exporter;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import androidx.fragment.app.FragmentActivity;
import java.io.File;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.fragments.FileTypeDialogFragment;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.util.DialogUtils;
import de.dennisguse.opentracks.util.FileUtils;
import de.dennisguse.opentracks.util.IntentUtils;
/**
* An activity for saving tracks to the external storage. If saving a specific
@@ -39,20 +39,11 @@ import de.dennisguse.opentracks.util.IntentUtils;
*
* @author Rodrigo Damazio
*/
public class SaveActivity extends Activity {
public static final String EXTRA_TRACK_FILE_FORMAT = "track_file_format";
public static final String EXTRA_TRACK_IDS = "track_ids";
@Deprecated //TODO Seems to be a left over from Google Earth integration and can be removed.
public static final String EXTRA_PLAY_TRACK = "play_track";
public class ExportActivity extends FragmentActivity implements FileTypeDialogFragment.FileTypeCaller {
private static final int DIALOG_PROGRESS_ID = 0;
private static final int DIALOG_RESULT_ID = 1;
private TrackFileFormat trackFileFormat;
private long[] trackIds;
private boolean playTrack;
private String directoryDisplayName;
private SaveAsyncTask saveAsyncTask;
@@ -64,53 +55,41 @@ public class SaveActivity extends Activity {
// the number of tracks to save
private int totalCount;
// the last successfully saved path
private String savedPath;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
trackFileFormat = intent.getParcelableExtra(EXTRA_TRACK_FILE_FORMAT);
trackIds = intent.getLongArrayExtra(EXTRA_TRACK_IDS);
playTrack = intent.getBooleanExtra(EXTRA_PLAY_TRACK, false);
FileTypeDialogFragment
.newInstance(R.string.export_all_title, R.string.export_all_option)
.show(getSupportFragmentManager(), FileTypeDialogFragment.FILE_TYPE_DIALOG_TAG);
}
@Override
public void onFileTypeDone(TrackFileFormat trackFileFormat) {
if (!FileUtils.isExternalStorageWriteable()) {
Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show();
finish();
return;
}
File directory = playTrack ? new File(getCacheDir(), FileUtils.PLAY_TRACKS_DIR) : new File(FileUtils.getPath(trackFileFormat.getExtension()));
File directory = new File(FileUtils.getPath(trackFileFormat.getExtension()));
if (!FileUtils.ensureDirectoryExists(directory)) {
Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show();
finish();
return;
}
if (playTrack) {
for (File file : directory.listFiles()) {
file.delete();
}
}
directoryDisplayName = FileUtils.getPathDisplayName(trackFileFormat.getExtension());
directoryDisplayName = playTrack ? directory.getName() : FileUtils.getPathDisplayName(trackFileFormat.getExtension());
Object retained = getLastNonConfigurationInstance();
if (retained instanceof SaveAsyncTask) {
saveAsyncTask = (SaveAsyncTask) retained;
saveAsyncTask.setActivity(this);
} else {
saveAsyncTask = new SaveAsyncTask(this, trackIds, trackFileFormat, directory);
saveAsyncTask.execute();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
saveAsyncTask.setActivity(null);
return saveAsyncTask;
//TODO (still needed?): getLastNonConfiguration instance returned SaveAsyncTask before
// Object retained = getLastNonConfigurationInstance();
// if (retained instanceof SaveAsyncTask) {
// saveAsyncTask = (SaveAsyncTask) retained;
// saveAsyncTask.setActivity(this);
// } else {
saveAsyncTask = new SaveAsyncTask(this, trackFileFormat, directory);
saveAsyncTask.execute();
// }
}
@Override
@@ -159,26 +138,12 @@ public class SaveActivity extends Activity {
finish();
}
}).setTitle(titleId);
if (!playTrack && trackIds.length == 1 && trackIds[0] != -1L && successCount == totalCount
&& savedPath != null) {
builder.setNegativeButton(
R.string.share_track_share_file, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = IntentUtils.newShareFileIntent(
SaveActivity.this, trackIds[0], savedPath, trackFileFormat);
startActivity(
Intent.createChooser(intent, getString(R.string.share_track_picker_title)));
finish();
}
});
}
final Dialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
DialogUtils.setDialogTitleDivider(SaveActivity.this, dialog);
DialogUtils.setDialogTitleDivider(ExportActivity.this, dialog);
}
});
return dialog;
@@ -192,12 +157,10 @@ public class SaveActivity extends Activity {
*
* @param aSuccessCount the number of tracks successfully saved
* @param aTotalCount the number of tracks to save
* @param aSavedPath the last successfully saved path
*/
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount, String aSavedPath) {
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount) {
successCount = aSuccessCount;
totalCount = aTotalCount;
savedPath = aSavedPath;
removeDialog(DIALOG_PROGRESS_ID);
showDialog(DIALOG_RESULT_ID);
}
@@ -44,12 +44,11 @@ import de.dennisguse.opentracks.util.SystemUtils;
public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private static final String TAG = SaveAsyncTask.class.getSimpleName();
private final long[] trackIds;
private final TrackFileFormat trackFileFormat;
private final File directory;
private final Context context;
private final ContentProviderUtils contentProviderUtils;
private SaveActivity saveActivity;
private ExportActivity exportActivity;
private WakeLock wakeLock;
// true if the AsyncTask has completed
@@ -67,18 +66,15 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
/**
* Creates an AsyncTask.
*
* @param saveActivity the activity currently associated with this task
* @param trackIds the track ids to save. To save all, set to size 1 with
* trackIds[0] == -1L
* @param exportActivity the activity currently associated with this task
* @param trackFileFormat the track file format
* @param directory the directory to write the file
*/
public SaveAsyncTask(SaveActivity saveActivity, long[] trackIds, TrackFileFormat trackFileFormat, File directory) {
this.saveActivity = saveActivity;
this.trackIds = trackIds;
public SaveAsyncTask(ExportActivity exportActivity, TrackFileFormat trackFileFormat, File directory) {
this.exportActivity = exportActivity;
this.trackFileFormat = trackFileFormat;
this.directory = directory;
context = saveActivity.getApplicationContext();
context = exportActivity.getApplicationContext();
contentProviderUtils = ContentProviderUtils.Factory.get(context);
completed = false;
@@ -90,19 +86,19 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
/**
* Sets the current activity associated with this AsyncTask.
*
* @param saveActivity the current activity, can be null
* @param exportActivity the current activity, can be null
*/
public void setActivity(SaveActivity saveActivity) {
this.saveActivity = saveActivity;
if (completed && saveActivity != null) {
saveActivity.onAsyncTaskCompleted(successCount, totalCount, savedPath);
public void setActivity(ExportActivity exportActivity) {
this.exportActivity = exportActivity;
if (completed && exportActivity != null) {
exportActivity.onAsyncTaskCompleted(successCount, totalCount);
}
}
@Override
protected void onPreExecute() {
if (saveActivity != null) {
saveActivity.showProgressDialog();
if (exportActivity != null) {
exportActivity.showProgressDialog();
}
}
@@ -110,31 +106,13 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
protected Boolean doInBackground(Void... params) {
try {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
boolean isRecording = PreferencesUtils.getLong(saveActivity, R.string.recording_track_id_key) != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
boolean isPaused = PreferencesUtils.getBoolean(saveActivity, R.string.recording_track_paused_key, PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT);
boolean isRecording = PreferencesUtils.getLong(exportActivity, R.string.recording_track_id_key) != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
boolean isPaused = PreferencesUtils.getBoolean(exportActivity, R.string.recording_track_paused_key, PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT);
// Get the wake lock if not recording or paused
if (!isRecording || isPaused) {
wakeLock = SystemUtils.acquireWakeLock(saveActivity, wakeLock);
}
if (trackIds.length == 1 && trackIds[0] == -1L) {
return saveAllTracks();
} else {
totalCount = 1;
Track[] tracks = new Track[trackIds.length];
for (int i = 0; i < trackIds.length; i++) {
tracks[i] = contentProviderUtils.getTrack(trackIds[i]);
if (tracks[i] == null) {
Log.d(TAG, "No track for " + trackIds[i]);
return false;
}
}
if (saveTracks(tracks)) {
successCount = 1;
return true;
} else {
return false;
}
wakeLock = SystemUtils.acquireWakeLock(exportActivity, wakeLock);
}
return saveAllTracks();
} finally {
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
@@ -144,24 +122,24 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
@Override
protected void onProgressUpdate(Integer... values) {
if (saveActivity != null) {
saveActivity.setProgressDialogValue(values[0], values[1]);
if (exportActivity != null) {
exportActivity.setProgressDialogValue(values[0], values[1]);
}
}
@Override
protected void onPostExecute(Boolean result) {
completed = true;
if (saveActivity != null) {
saveActivity.onAsyncTaskCompleted(successCount, totalCount, savedPath);
if (exportActivity != null) {
exportActivity.onAsyncTaskCompleted(successCount, totalCount);
}
}
@Override
protected void onCancelled() {
completed = true;
if (saveActivity != null) {
saveActivity.onAsyncTaskCompleted(successCount, totalCount, null);
if (exportActivity != null) {
exportActivity.onAsyncTaskCompleted(successCount, totalCount);
}
}
@@ -179,14 +157,10 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
FileTrackExporter fileTrackExporter = new FileTrackExporter(contentProviderUtils, tracks,
trackFileFormat.newTrackWriter(context, tracks.length > 1),
new TrackExporterListener() {
@Override
public void onProgressUpdate(int number, int max) {
/*
* If only saving one track, update the progress dialog once every
* 500 points
*/
if (trackIds.length == 1 && trackIds[0] != -1L && number % 500 == 0) {
//Update the progress dialog once every 500 points.
if (number % 500 == 0) {
publishProgress(number, max);
}
}
@@ -16,27 +16,23 @@
package de.dennisguse.opentracks.io.file.importer;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.core.app.TaskStackBuilder;
import androidx.fragment.app.FragmentActivity;
import de.dennisguse.opentracks.TrackDetailActivity;
import java.io.File;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.fragments.FileTypeDialogFragment;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.util.DialogUtils;
import de.dennisguse.opentracks.util.FileUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.R;
import java.io.File;
/**
* An activity to import files from the external storage. Optionally to import
@@ -44,10 +40,7 @@ import java.io.File;
*
* @author Rodrigo Damazio
*/
public class ImportActivity extends Activity {
public static final String EXTRA_IMPORT_ALL = "import_all";
public static final String EXTRA_TRACK_FILE_FORMAT = "track_file_format";
public class ImportActivity extends FragmentActivity implements FileTypeDialogFragment.FileTypeCaller {
private static final String TAG = ImportActivity.class.getSimpleName();
private static final int DIALOG_PROGRESS_ID = 0;
@@ -56,8 +49,6 @@ public class ImportActivity extends Activity {
private ImportAsyncTask importAsyncTask;
private ProgressDialog progressDialog;
private boolean importAll;
// the path on the external storage to import
private String directoryDisplayName;
@@ -67,16 +58,19 @@ public class ImportActivity extends Activity {
// the number of files to import
private int totalCount;
// the last successfully imported track id
private long trackId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FileTypeDialogFragment
.newInstance(R.string.import_selection_title, R.string.import_selection_option)
.show(getSupportFragmentManager(), FileTypeDialogFragment.FILE_TYPE_DIALOG_TAG);
}
@Override
public void onFileTypeDone(TrackFileFormat trackFileFormat) {
Intent intent = getIntent();
importAll = intent.getBooleanExtra(EXTRA_IMPORT_ALL, false);
TrackFileFormat trackFileFormat = intent.getParcelableExtra(EXTRA_TRACK_FILE_FORMAT);
if (trackFileFormat == null) {
trackFileFormat = TrackFileFormat.GPX;
}
@@ -86,49 +80,26 @@ public class ImportActivity extends Activity {
finish();
return;
}
String directoryPath;
if (importAll) {
directoryDisplayName = FileUtils.getPathDisplayName(trackFileFormat.getExtension());
directoryPath = FileUtils.getPath(trackFileFormat.getExtension());
if (!FileUtils.isDirectory(new File(directoryPath))) {
Toast.makeText(
this, getString(R.string.import_no_directory, directoryDisplayName), Toast.LENGTH_LONG)
.show();
finish();
return;
}
} else {
String action = intent.getAction();
if (!(Intent.ACTION_ATTACH_DATA.equals(action) || Intent.ACTION_VIEW.equals(action))) {
Log.d(TAG, "Invalid action: " + intent);
finish();
return;
}
Uri data = intent.getData();
if ("file".equals(data.getScheme())) {
Log.d(TAG, "Invalid data: " + intent);
finish();
return;
}
directoryDisplayName = data.getPath();
directoryPath = data.getPath();
directoryDisplayName = FileUtils.getPathDisplayName(trackFileFormat.getExtension());
String directoryPath = FileUtils.getPath(trackFileFormat.getExtension());
if (!FileUtils.isDirectory(new File(directoryPath))) {
Toast.makeText(
this, getString(R.string.import_no_directory, directoryDisplayName), Toast.LENGTH_LONG)
.show();
finish();
return;
}
Object retained = getLastNonConfigurationInstance();
if (retained instanceof ImportAsyncTask) {
importAsyncTask = (ImportAsyncTask) retained;
importAsyncTask.setActivity(this);
} else {
importAsyncTask = new ImportAsyncTask(this, importAll, trackFileFormat, directoryPath);
importAsyncTask.execute();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
importAsyncTask.setActivity(null);
return importAsyncTask;
//TODO (still needed?): getLastNonConfiguration instance returned SaveAsyncTask before
// Object retained = getLastNonConfigurationInstance();
// if (retained instanceof ImportAsyncTask) {
// importAsyncTask = (ImportAsyncTask) retained;
// importAsyncTask.setActivity(this);
// } else {
importAsyncTask = new ImportAsyncTask(this, trackFileFormat, directoryPath);
importAsyncTask.execute();
// }
}
@Override
@@ -176,14 +147,6 @@ public class ImportActivity extends Activity {
}).setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
if (successCount == totalCount && !importAll && trackId != -1L) {
Intent intent = IntentUtils.newIntent(
ImportActivity.this, TrackDetailActivity.class)
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, trackId);
TaskStackBuilder.create(ImportActivity.this)
.addParentStack(TrackDetailActivity.class).addNextIntent(intent)
.startActivities();
}
dialogInterface.dismiss();
finish();
}
@@ -206,12 +169,10 @@ public class ImportActivity extends Activity {
*
* @param aSuccessCount the number of files successfully imported
* @param aTotalCount the number of files to import
* @param aTrackId the last successfully imported track id
*/
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount, long aTrackId) {
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount) {
successCount = aSuccessCount;
totalCount = aTotalCount;
trackId = aTrackId;
removeDialog(DIALOG_PROGRESS_ID);
showDialog(DIALOG_RESULT_ID);
}
@@ -22,6 +22,14 @@ import android.os.AsyncTask;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.ContentProviderUtils;
import de.dennisguse.opentracks.content.Track;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
@@ -29,14 +37,6 @@ import de.dennisguse.opentracks.io.file.exporter.KmzTrackExporter;
import de.dennisguse.opentracks.util.FileUtils;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.SystemUtils;
import de.dennisguse.opentracks.R;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* AsyncTask to import files from the external storage.
@@ -46,7 +46,6 @@ import java.util.List;
public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private static final String TAG = ImportAsyncTask.class.getSimpleName();
private final boolean importAll;
private final TrackFileFormat trackFileFormat;
private final String path;
private final Context context;
@@ -69,14 +68,11 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
* Creates an AsyncTask.
*
* @param importActivity the activity currently associated with this AsyncTask
* @param importAll true to import all GPX files
* @param trackFileFormat the track file format
* @param path path to import GPX files
*/
public ImportAsyncTask(ImportActivity importActivity, boolean importAll,
TrackFileFormat trackFileFormat, String path) {
public ImportAsyncTask(ImportActivity importActivity, TrackFileFormat trackFileFormat, String path) {
this.importActivity = importActivity;
this.importAll = importAll;
this.trackFileFormat = trackFileFormat;
this.path = path;
context = importActivity.getApplicationContext();
@@ -95,7 +91,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, trackId);
importActivity.onAsyncTaskCompleted(successCount, totalCount);
}
}
@@ -155,7 +151,7 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
protected void onPostExecute(Boolean result) {
completed = true;
if (importActivity != null) {
importActivity.onAsyncTaskCompleted(successCount, totalCount, trackId);
importActivity.onAsyncTaskCompleted(successCount, totalCount);
}
}
@@ -163,7 +159,7 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
protected void onCancelled() {
completed = true;
if (importActivity != null) {
importActivity.onAsyncTaskCompleted(successCount, totalCount, trackId);
importActivity.onAsyncTaskCompleted(successCount, totalCount);
}
}
@@ -215,26 +211,24 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private List<File> getFiles() {
List<File> files = new ArrayList<>();
File file = new File(path);
if (importAll) {
File[] candidates = file.listFiles();
if (candidates != null) {
for (File candidate : candidates) {
if (!FileUtils.isDirectory(candidate)) {
String extension = FileUtils.getExtension(candidate.getName());
if (trackFileFormat == TrackFileFormat.KML && (
TrackFileFormat.KML.getExtension().equals(extension)
|| KmzTrackExporter.KMZ_EXTENSION.equals(extension))) {
files.add(candidate);
} else if (trackFileFormat == TrackFileFormat.GPX
&& TrackFileFormat.GPX.getExtension().equals(extension)) {
files.add(candidate);
}
File[] candidates = file.listFiles();
if (candidates != null) {
for (File candidate : candidates) {
if (!FileUtils.isDirectory(candidate)) {
String extension = FileUtils.getExtension(candidate.getName());
if (trackFileFormat == TrackFileFormat.KML
&& (TrackFileFormat.KML.getExtension().equals(extension)
|| KmzTrackExporter.KMZ_EXTENSION.equals(extension))) {
files.add(candidate);
} else if (trackFileFormat == TrackFileFormat.GPX && TrackFileFormat.GPX.getExtension().equals(extension)) {
files.add(candidate);
}
}
}
} else {
files.add(file);
}
return files;
}
}