forked from upstream-mirrors/OpenTracks
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:
@@ -18,7 +18,6 @@ package de.dennisguse.opentracks.fragments;
|
|||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -69,17 +68,14 @@ public class ConfirmDeleteDialogFragment extends DialogFragment {
|
|||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final long[] trackIds = getArguments().getLongArray(KEY_TRACK_IDS);
|
final long[] trackIds = getArguments().getLongArray(KEY_TRACK_IDS);
|
||||||
|
|
||||||
int titleId;
|
int titleId = trackIds.length > 1 ? R.string.generic_delete_selected_confirm_title : R.string.track_delete_one_confirm_title;
|
||||||
int messageId;
|
int messageId = trackIds.length > 1 ? R.string.track_delete_multiple_confirm_message : R.string.track_delete_one_confirm_message;
|
||||||
titleId = trackIds.length > 1 ? R.string.generic_delete_selected_confirm_title : R.string.track_delete_one_confirm_title;
|
|
||||||
messageId = trackIds.length > 1 ? R.string.track_delete_multiple_confirm_message : R.string.track_delete_one_confirm_message;
|
|
||||||
return DialogUtils.createConfirmationDialog(
|
return DialogUtils.createConfirmationDialog(
|
||||||
getActivity(), titleId, getString(messageId), new DialogInterface.OnClickListener() {
|
getActivity(),
|
||||||
@Override
|
titleId,
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
getString(messageId),
|
||||||
caller.onConfirmDeleteDone(trackIds);
|
(dialog, which) -> caller.onConfirmDeleteDone(trackIds)
|
||||||
}
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,12 +85,6 @@ public class ConfirmDeleteDialogFragment extends DialogFragment {
|
|||||||
*/
|
*/
|
||||||
public interface ConfirmDeleteCaller {
|
public interface ConfirmDeleteCaller {
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when confirm delete is done.
|
|
||||||
*
|
|
||||||
* @param trackIds list of track ids to delete. To delete all, set to size 1
|
|
||||||
* with trackIds[0] == -1L
|
|
||||||
*/
|
|
||||||
void onConfirmDeleteDone(long[] trackIds);
|
void onConfirmDeleteDone(long[] trackIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.dennisguse.opentracks.fragments;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.R;
|
||||||
|
|
||||||
|
public class ImportFinishedDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
private static final String TAG = ImportFinishedDialogFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final String EXTRA_DIRECTORY_NAME_KEY = "directory_name";
|
||||||
|
private static final String EXTRA_IMPORTED_TRACK_COUNT = "imported_track_count";
|
||||||
|
private static final String EXTRA_FILE_COUNT = "file_count";
|
||||||
|
|
||||||
|
private static final String FINISHED_DIALOG_TAG = "finished_dialog_tag";
|
||||||
|
|
||||||
|
private DismissCallback caller;
|
||||||
|
|
||||||
|
public static void showDialog(FragmentManager fragmentManager, String directoryDisplayName, int successCount, int fileCount) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString(EXTRA_DIRECTORY_NAME_KEY, directoryDisplayName);
|
||||||
|
bundle.putInt(EXTRA_IMPORTED_TRACK_COUNT, successCount);
|
||||||
|
bundle.putInt(EXTRA_FILE_COUNT, fileCount);
|
||||||
|
|
||||||
|
ImportFinishedDialogFragment dialogFragment = new ImportFinishedDialogFragment();
|
||||||
|
dialogFragment.setArguments(bundle);
|
||||||
|
dialogFragment.show(fragmentManager, FINISHED_DIALOG_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
try {
|
||||||
|
caller = (DismissCallback) context;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new ClassCastException(context + " must implement " + DismissCallback.class.getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
String directoryDisplayName = getArguments().getString(EXTRA_DIRECTORY_NAME_KEY);
|
||||||
|
int importedTrackCount = getArguments().getInt(EXTRA_IMPORTED_TRACK_COUNT);
|
||||||
|
int totalTrackCount = getArguments().getInt(EXTRA_FILE_COUNT);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
Dialog dialog = new AlertDialog.Builder(getContext())
|
||||||
|
.setCancelable(true).setIcon(iconId)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton(R.string.generic_ok, (dialogInterface, which) -> {
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
caller.onDismissed();
|
||||||
|
})
|
||||||
|
.setTitle(titleId)
|
||||||
|
.create();
|
||||||
|
dialog.setCanceledOnTouchOutside(false);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
caller = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DismissCallback {
|
||||||
|
void onDismissed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.dennisguse.opentracks.fragments;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
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.io.file.importer.GpxFileTrackImporter;
|
||||||
|
import de.dennisguse.opentracks.io.file.importer.KmlFileTrackImporter;
|
||||||
|
import de.dennisguse.opentracks.io.file.importer.KmzTrackImporter;
|
||||||
|
import de.dennisguse.opentracks.io.file.importer.TrackImporter;
|
||||||
|
import de.dennisguse.opentracks.util.DialogUtils;
|
||||||
|
import de.dennisguse.opentracks.util.FileUtils;
|
||||||
|
|
||||||
|
public class ImportProgressDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
private static final String EXTRA_DIRECTORY_URI_KEY = "directory_uri";
|
||||||
|
|
||||||
|
private static final String TAG = ImportProgressDialogFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
public static final String IMPORT_DIALOG_TAG = "import_dialog_tag";
|
||||||
|
|
||||||
|
private DismissCallback caller;
|
||||||
|
|
||||||
|
private ImportThread importThread;
|
||||||
|
|
||||||
|
private String directoryDisplayName;
|
||||||
|
|
||||||
|
private int trackImportSuccessCount;
|
||||||
|
private int fileCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance.
|
||||||
|
*/
|
||||||
|
public static void showDialog(FragmentManager fragmentManager, Uri documentFileUri) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putParcelable(EXTRA_DIRECTORY_URI_KEY, documentFileUri);
|
||||||
|
|
||||||
|
ImportProgressDialogFragment dialogFragment = new ImportProgressDialogFragment();
|
||||||
|
dialogFragment.setArguments(bundle);
|
||||||
|
dialogFragment.setRetainInstance(true);
|
||||||
|
dialogFragment.show(fragmentManager, IMPORT_DIALOG_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// This fragment uses a background thread, so it should not be recreated during activity re-creation.
|
||||||
|
setRetainInstance(true);
|
||||||
|
|
||||||
|
Uri directoryUri = getArguments().getParcelable(EXTRA_DIRECTORY_URI_KEY);
|
||||||
|
DocumentFile documentFile = DocumentFile.fromTreeUri(getContext(), directoryUri);
|
||||||
|
|
||||||
|
directoryDisplayName = FileUtils.getPath(documentFile);
|
||||||
|
|
||||||
|
importThread = new ImportThread(documentFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
try {
|
||||||
|
caller = (DismissCallback) context;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new ClassCastException(context + " must implement " + DismissCallback.class.getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
ProgressDialog dialog = DialogUtils.createHorizontalProgressDialog(
|
||||||
|
getContext(), R.string.import_progress_message,
|
||||||
|
dialogInterface -> {
|
||||||
|
importThread.interrupt();
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
}, directoryDisplayName);
|
||||||
|
if (trackImportSuccessCount == 0) {
|
||||||
|
dialog.setIndeterminate(true);
|
||||||
|
} else {
|
||||||
|
setProgress();
|
||||||
|
}
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
setProgress();
|
||||||
|
if (!importThread.isAlive()) {
|
||||||
|
importThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
if (!importThread.isAlive()) {
|
||||||
|
importThread.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
caller = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onProgress(int trackImportSuccessCount, int fileCount) {
|
||||||
|
this.trackImportSuccessCount = trackImportSuccessCount;
|
||||||
|
this.fileCount = fileCount;
|
||||||
|
setProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setProgress() {
|
||||||
|
ProgressDialog dialog = (ProgressDialog) getDialog();
|
||||||
|
if (dialog != null) {
|
||||||
|
dialog.setIndeterminate(false);
|
||||||
|
dialog.setMax(fileCount);
|
||||||
|
dialog.setProgress(Math.min(trackImportSuccessCount, fileCount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onImportCompleted(int successCount, int fileCount) {
|
||||||
|
if (caller != null && !isDetached()) {
|
||||||
|
caller.onImportFinished(directoryDisplayName, successCount, fileCount);
|
||||||
|
}
|
||||||
|
dismissAllowingStateLoss();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ImportThread extends Thread {
|
||||||
|
|
||||||
|
private DocumentFile file;
|
||||||
|
|
||||||
|
ImportThread(DocumentFile file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Log.w(TAG, "" + this);
|
||||||
|
Context context = ImportProgressDialogFragment.this.getContext();
|
||||||
|
|
||||||
|
List<DocumentFile> files = FileUtils.getFiles(file);
|
||||||
|
|
||||||
|
int importedTrackCount = 0;
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
onProgress(i, files.size());
|
||||||
|
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (importFile(context, files.get(i))) {
|
||||||
|
importedTrackCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onImportCompleted(importedTrackCount, files.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports a file.
|
||||||
|
*
|
||||||
|
* @param file the file
|
||||||
|
*/
|
||||||
|
private boolean importFile(final Context context, final DocumentFile file) {
|
||||||
|
TrackImporter trackImporter;
|
||||||
|
String fileExtension = FileUtils.getExtension(file);
|
||||||
|
|
||||||
|
if (TrackFileFormat.GPX.getExtension().equals(fileExtension)) {
|
||||||
|
trackImporter = new GpxFileTrackImporter(context);
|
||||||
|
} else if (TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.getExtension().equals(fileExtension)) {
|
||||||
|
trackImporter = new KmlFileTrackImporter(ImportProgressDialogFragment.this.getContext(), -1L);
|
||||||
|
} else if (TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES.getExtension().equals(fileExtension)) {
|
||||||
|
trackImporter = new KmzTrackImporter(context, -1L, file.getUri());
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "Unsupported file format.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStream inputStream = context.getContentResolver().openInputStream(file.getUri())) {
|
||||||
|
return trackImporter.importFile(inputStream) != -1L;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Unable to import file", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DismissCallback {
|
||||||
|
void onImportFinished(String directoryDisplayName, int successCount, int fileCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,192 +16,53 @@
|
|||||||
|
|
||||||
package de.dennisguse.opentracks.io.file.importer;
|
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.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.documentfile.provider.DocumentFile;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
import java.io.IOException;
|
import de.dennisguse.opentracks.fragments.ImportFinishedDialogFragment;
|
||||||
import java.io.InputStream;
|
import de.dennisguse.opentracks.fragments.ImportProgressDialogFragment;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An activity to import files from the external storage.
|
* An activity to import files from the external storage.
|
||||||
*
|
*
|
||||||
* @author Rodrigo Damazio
|
* @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();
|
private static final String TAG = ImportActivity.class.getSimpleName();
|
||||||
|
|
||||||
public static final String EXTRA_DIRECTORY_URI_KEY = "directory_uri";
|
public static final String EXTRA_DIRECTORY_URI_KEY = "directory_uri";
|
||||||
|
|
||||||
private static final int DIALOG_PROGRESS_ID = 0;
|
private static final String BUNDLE_ACTIVITY_RECREATED = "activity_recreated";
|
||||||
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;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
Uri directoryUri = getIntent().getParcelableExtra(EXTRA_DIRECTORY_URI_KEY);
|
if (savedInstanceState == null || !savedInstanceState.getBoolean(BUNDLE_ACTIVITY_RECREATED, false)) {
|
||||||
pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri);
|
Uri directoryUri = getIntent().getParcelableExtra(EXTRA_DIRECTORY_URI_KEY);
|
||||||
directoryDisplayName = FileUtils.getPath(pickedDirectory);
|
ImportProgressDialogFragment.showDialog(getSupportFragmentManager(), directoryUri);
|
||||||
}
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Invokes when the associated AsyncTask completes.
|
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||||
*
|
super.onSaveInstanceState(outState);
|
||||||
* @param aSuccessCount the number of files successfully imported
|
outState.putBoolean(BUNDLE_ACTIVITY_RECREATED, true);
|
||||||
* @param aTotalCount the number of files to import
|
}
|
||||||
*/
|
|
||||||
public void onAsyncTaskCompleted(int aSuccessCount, int aTotalCount) {
|
@Override
|
||||||
|
public void onImportFinished(final String directoryDisplayName, final int successCount, final int fileCount) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
importedTrackCount = aSuccessCount;
|
ImportFinishedDialogFragment.showDialog(getSupportFragmentManager(), directoryDisplayName, successCount, fileCount);
|
||||||
totalTrackCount = aTotalCount;
|
|
||||||
removeDialog(DIALOG_PROGRESS_ID);
|
|
||||||
showDialog(DIALOG_RESULT_ID);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Sets the progress dialog value.
|
public void onDismissed() {
|
||||||
*
|
finish();
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 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.
|
* @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.context = context;
|
||||||
this.importTrackId = importTrackId;
|
this.importTrackId = importTrackId;
|
||||||
this.uriKmzFile = uriFile;
|
this.uriKmzFile = uriFile;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import java.io.InputStream;
|
|||||||
*
|
*
|
||||||
* @author Jimmy Shih
|
* @author Jimmy Shih
|
||||||
*/
|
*/
|
||||||
interface TrackImporter {
|
public interface TrackImporter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import a file.
|
* Import a file.
|
||||||
|
|||||||
@@ -309,6 +309,8 @@ public class FileUtils {
|
|||||||
public static ArrayList<DocumentFile> getFiles(DocumentFile file) {
|
public static ArrayList<DocumentFile> getFiles(DocumentFile file) {
|
||||||
ArrayList<DocumentFile> files = new ArrayList<>();
|
ArrayList<DocumentFile> files = new ArrayList<>();
|
||||||
|
|
||||||
|
if (!file.isDirectory()) return files;
|
||||||
|
|
||||||
for (DocumentFile candidate : file.listFiles()) {
|
for (DocumentFile candidate : file.listFiles()) {
|
||||||
if (!candidate.isDirectory()) {
|
if (!candidate.isDirectory()) {
|
||||||
files.add(candidate);
|
files.add(candidate);
|
||||||
|
|||||||
Reference in New Issue
Block a user