mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-11 13:33:07 +02:00
Import: split ImportActivity into fragments.
The fragements keep the state while the activity is re-created (e.g., orientation change).
This commit is contained in:
@@ -16,192 +16,53 @@
|
||||
|
||||
package de.dennisguse.opentracks.io.file.importer;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.util.DialogUtils;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
import de.dennisguse.opentracks.fragments.ImportFinishedDialogFragment;
|
||||
import de.dennisguse.opentracks.fragments.ImportProgressDialogFragment;
|
||||
|
||||
/**
|
||||
* An activity to import files from the external storage.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class ImportActivity extends FragmentActivity {
|
||||
public class ImportActivity extends FragmentActivity implements ImportProgressDialogFragment.DismissCallback, ImportFinishedDialogFragment.DismissCallback {
|
||||
|
||||
private static final String TAG = ImportActivity.class.getSimpleName();
|
||||
|
||||
public static final String EXTRA_DIRECTORY_URI_KEY = "directory_uri";
|
||||
|
||||
private static final int DIALOG_PROGRESS_ID = 0;
|
||||
private static final int DIALOG_RESULT_ID = 1;
|
||||
|
||||
private DocumentFile pickedDirectory;
|
||||
private String directoryDisplayName;
|
||||
|
||||
|
||||
private Thread importTask = new ImportThread();
|
||||
private ProgressDialog progressDialog;
|
||||
|
||||
private int importedTrackCount;
|
||||
private int totalTrackCount;
|
||||
private static final String BUNDLE_ACTIVITY_RECREATED = "activity_recreated";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Uri directoryUri = getIntent().getParcelableExtra(EXTRA_DIRECTORY_URI_KEY);
|
||||
pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri);
|
||||
directoryDisplayName = FileUtils.getPath(pickedDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
showDialog(DIALOG_PROGRESS_ID);
|
||||
importTask.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
importTask.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case DIALOG_PROGRESS_ID:
|
||||
progressDialog = DialogUtils.createHorizontalProgressDialog(
|
||||
this, R.string.import_progress_message, dialog -> {
|
||||
importTask.interrupt();
|
||||
dialog.dismiss();
|
||||
finish();
|
||||
}, directoryDisplayName);
|
||||
return progressDialog;
|
||||
case DIALOG_RESULT_ID:
|
||||
int iconId;
|
||||
int titleId;
|
||||
String message;
|
||||
String totalFiles = getResources()
|
||||
.getQuantityString(R.plurals.files, totalTrackCount, totalTrackCount);
|
||||
if (importedTrackCount == totalTrackCount) {
|
||||
if (totalTrackCount == 0) {
|
||||
iconId = R.drawable.ic_dialog_info_24dp;
|
||||
titleId = R.string.import_no_file_title;
|
||||
message = getString(R.string.import_no_file, directoryDisplayName);
|
||||
} else {
|
||||
iconId = R.drawable.ic_dialog_success_24dp;
|
||||
titleId = R.string.generic_success_title;
|
||||
message = getString(R.string.import_success, totalFiles, directoryDisplayName);
|
||||
}
|
||||
} else {
|
||||
iconId = R.drawable.ic_dialog_error_24dp;
|
||||
titleId = R.string.generic_error_title;
|
||||
message = getString(R.string.import_error, importedTrackCount, totalFiles, directoryDisplayName);
|
||||
}
|
||||
return new AlertDialog.Builder(this).setCancelable(true).setIcon(iconId)
|
||||
.setMessage(message).setOnCancelListener(dialogInterface -> {
|
||||
dialogInterface.dismiss();
|
||||
finish();
|
||||
}).setPositiveButton(R.string.generic_ok, (dialogInterface, which) -> {
|
||||
dialogInterface.dismiss();
|
||||
finish();
|
||||
}).setTitle(titleId).create();
|
||||
default:
|
||||
return null;
|
||||
if (savedInstanceState == null || !savedInstanceState.getBoolean(BUNDLE_ACTIVITY_RECREATED, false)) {
|
||||
Uri directoryUri = getIntent().getParcelableExtra(EXTRA_DIRECTORY_URI_KEY);
|
||||
ImportProgressDialogFragment.showDialog(getSupportFragmentManager(), directoryUri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes when the associated AsyncTask completes.
|
||||
*
|
||||
* @param aSuccessCount the number of files successfully imported
|
||||
* @param aTotalCount the number of files to import
|
||||
*/
|
||||
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount) {
|
||||
@Override
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(BUNDLE_ACTIVITY_RECREATED, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImportFinished(final String directoryDisplayName, final int successCount, final int fileCount) {
|
||||
runOnUiThread(() -> {
|
||||
importedTrackCount = aSuccessCount;
|
||||
totalTrackCount = aTotalCount;
|
||||
removeDialog(DIALOG_PROGRESS_ID);
|
||||
showDialog(DIALOG_RESULT_ID);
|
||||
ImportFinishedDialogFragment.showDialog(getSupportFragmentManager(), directoryDisplayName, successCount, fileCount);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the progress dialog value.
|
||||
*
|
||||
* @param number the number of files imported
|
||||
* @param max the maximum number of files
|
||||
*/
|
||||
public void setProgressDialogValue(int number, int max) {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.setIndeterminate(false);
|
||||
progressDialog.setMax(max);
|
||||
progressDialog.setProgress(Math.min(number, max));
|
||||
}
|
||||
}
|
||||
|
||||
public class ImportThread extends Thread {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<DocumentFile> files = FileUtils.getFiles(pickedDirectory);
|
||||
int totalTrackCount = files.size();
|
||||
int importedTrackCount = 0;
|
||||
|
||||
for (int i = 0; i < totalTrackCount; i++) {
|
||||
if (Thread.interrupted()) {
|
||||
return;
|
||||
}
|
||||
if (importFile(files.get(i))) {
|
||||
importedTrackCount++;
|
||||
}
|
||||
setProgressDialogValue(i + 1, totalTrackCount);
|
||||
}
|
||||
|
||||
onAsyncTaskCompleted(importedTrackCount, totalTrackCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a file.
|
||||
*
|
||||
* @param file the file
|
||||
*/
|
||||
private boolean importFile(final DocumentFile file) {
|
||||
TrackImporter trackImporter;
|
||||
String fileExtension = FileUtils.getExtension(file);
|
||||
|
||||
if (TrackFileFormat.GPX.getExtension().equals(fileExtension)) {
|
||||
trackImporter = new GpxFileTrackImporter(ImportActivity.this);
|
||||
} else if (TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.getExtension().equals(fileExtension)) {
|
||||
trackImporter = new KmlFileTrackImporter(ImportActivity.this, -1L);
|
||||
} else if (TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES.getExtension().equals(fileExtension)) {
|
||||
trackImporter = new KmzTrackImporter(ImportActivity.this, -1L, file.getUri());
|
||||
} else {
|
||||
Log.i(TAG, "Unsupported file format.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try (InputStream inputStream = ImportActivity.this.getContentResolver().openInputStream(file.getUri())) {
|
||||
return trackImporter.importFile(inputStream) != -1L;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Unable to import file", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onDismissed() {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class KmzTrackImporter implements TrackImporter {
|
||||
* @param importTrackId track id to import to. This should not be -1L so that images in the kmz file can be imported.
|
||||
* @param uriFile URI of the kmz file.
|
||||
*/
|
||||
KmzTrackImporter(Context context, long importTrackId, Uri uriFile) {
|
||||
public KmzTrackImporter(Context context, long importTrackId, Uri uriFile) {
|
||||
this.context = context;
|
||||
this.importTrackId = importTrackId;
|
||||
this.uriKmzFile = uriFile;
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.io.InputStream;
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
interface TrackImporter {
|
||||
public interface TrackImporter {
|
||||
|
||||
/**
|
||||
* Import a file.
|
||||
|
||||
Reference in New Issue
Block a user