Add export progress & cancel

This commit is contained in:
Dima-1 2020-11-04 22:29:21 +02:00
parent 7d9dbb09ff
commit 312027db3c
5 changed files with 124 additions and 14 deletions

View file

@ -208,7 +208,7 @@ public class FileSettingsItem extends StreamSettingsItem {
}
public long getSize() {
return size;
return file != null && !file.isDirectory() ? file.length() : size;
}
public void setSize(long size) {
@ -273,6 +273,7 @@ public class FileSettingsItem extends StreamSettingsItem {
dest = renameFile(dest);
}
if (dest.getParentFile() != null && !dest.getParentFile().exists()) {
//noinspection ResultOfMethodCallIgnored
dest.getParentFile().mkdirs();
}
output = new FileOutputStream(dest);

View file

@ -21,6 +21,7 @@ class SettingsExporter {
private Map<String, SettingsItem> items;
private Map<String, String> additionalParams;
private boolean exportItemsFiles;
private boolean exportCancel;
SettingsExporter(boolean exportItemsFiles) {
this.exportItemsFiles = exportItemsFiles;
@ -35,11 +36,15 @@ class SettingsExporter {
items.put(item.getName(), item);
}
public void setExportCancel(boolean exportCancel) {
this.exportCancel = exportCancel;
}
void addAdditionalParam(String key, String value) {
additionalParams.put(key, value);
}
void exportSettings(File file) throws JSONException, IOException {
void exportSettings(File file, SettingsHelper.ExportProgress exportProgress) throws JSONException, IOException {
JSONObject json = createItemsJson();
OutputStream os = new BufferedOutputStream(new FileOutputStream(file), SettingsHelper.BUFFER);
ZipOutputStream zos = new ZipOutputStream(os);
@ -49,7 +54,7 @@ class SettingsExporter {
zos.write(json.toString(2).getBytes("UTF-8"));
zos.closeEntry();
if (exportItemsFiles) {
writeItemFiles(zos);
writeItemFiles(zos, exportProgress);
}
zos.flush();
zos.finish();
@ -59,7 +64,8 @@ class SettingsExporter {
}
}
private void writeItemFiles(ZipOutputStream zos) throws IOException {
private void writeItemFiles(ZipOutputStream zos, SettingsHelper.ExportProgress exportProgress) throws IOException {
int progress = 0;
for (SettingsItem item : items.values()) {
SettingsItemWriter<? extends SettingsItem> writer = item.getWriter();
if (writer != null) {
@ -69,6 +75,17 @@ class SettingsExporter {
}
writer.writeEntry(fileName, zos);
}
if (exportCancel) {
exportCancel = false;
return;
}
if (item instanceof FileSettingsItem) {
int size = (int) ((FileSettingsItem) item).getSize() / 1000000;
progress += size;
if (exportProgress != null) {
exportProgress.setProgress(progress);
}
}
}
}

View file

@ -111,6 +111,8 @@ public class SettingsHelper {
public interface SettingsExportListener {
void onSettingsExportFinished(@NonNull File file, boolean succeed);
void onSettingsExportProgressUpdate(int value);
}
public enum ImportType {
@ -139,6 +141,10 @@ public class SettingsHelper {
return importTask == null || importTask.isImportDone();
}
public ExportAsyncTask getExportAsyncTask(File file) {
return exportAsyncTasks.get(file);
}
public boolean isFileExporting(File file) {
return exportAsyncTasks.containsKey(file);
}
@ -200,28 +206,41 @@ public class SettingsHelper {
}
}
@SuppressLint("StaticFieldLeak")
private class ExportAsyncTask extends AsyncTask<Void, Void, Boolean> {
public interface ExportProgress {
void setProgress(int value);
}
private SettingsExporter exporter;
private File file;
@SuppressLint("StaticFieldLeak")
public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private final SettingsExporter exporter;
private final File file;
private SettingsExportListener listener;
private final ExportProgress exportProgress;
ExportAsyncTask(@NonNull File settingsFile,
@Nullable SettingsExportListener listener,
@NonNull List<SettingsItem> items, boolean exportItemsFiles) {
@Nullable SettingsExportListener listener,
@NonNull List<SettingsItem> items, boolean exportItemsFiles) {
this.file = settingsFile;
this.listener = listener;
this.exporter = new SettingsExporter(exportItemsFiles);
for (SettingsItem item : items) {
exporter.addSettingsItem(item);
}
exportProgress = new ExportProgress() {
@Override
public void setProgress(int value) {
exporter.setExportCancel(isCancelled());
publishProgress(value);
}
};
}
@Override
protected Boolean doInBackground(Void... voids) {
try {
exporter.exportSettings(file);
exporter.exportSettings(file, exportProgress);
return true;
} catch (JSONException e) {
LOG.error("Failed to export items to: " + file.getName(), e);
@ -231,6 +250,14 @@ public class SettingsHelper {
return false;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (listener != null) {
listener.onSettingsExportProgressUpdate(values[0]);
}
}
@Override
protected void onPostExecute(Boolean success) {
exportAsyncTasks.remove(file);
@ -238,6 +265,13 @@ public class SettingsHelper {
listener.onSettingsExportFinished(file, success);
}
}
@Override
protected void onCancelled() {
super.onCancelled();
//noinspection ResultOfMethodCallIgnored
file.delete();
}
}
@SuppressLint("StaticFieldLeak")
@ -416,6 +450,8 @@ public class SettingsHelper {
public void exportSettings(@NonNull File fileDir, @NonNull String fileName, @Nullable SettingsExportListener listener, @NonNull List<SettingsItem> items, boolean exportItemsFiles) {
File file = new File(fileDir, fileName + OSMAND_SETTINGS_FILE_EXT);
ExportAsyncTask exportAsyncTask = new ExportAsyncTask(file, listener, items, exportItemsFiles);
exportAsyncTasks.put(file, exportAsyncTask);
exportAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

View file

@ -2,6 +2,7 @@ package net.osmand.plus.settings.fragments;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.ColorDrawable;
@ -33,6 +34,7 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.backend.backup.FileSettingsItem;
import net.osmand.plus.settings.backend.backup.GlobalSettingsItem;
import net.osmand.plus.settings.backend.backup.ProfileSettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsExportListener;
@ -47,6 +49,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
@ -60,8 +63,10 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
private static final String EXPORTING_PROFILE_KEY = "exporting_profile_key";
private static final String INCLUDE_ADDITIONAL_DATA_KEY = "include_additional_data_key";
private static final String INCLUDE_GLOBAL_SETTINGS_KEY = "include_global_settings_key";
private static final String PROGRESS_MAX_KEY = "progress_max_key";
private static final String PROGRESS_VALUE_KEY = "progress_value_key";
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yy");
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yy", Locale.US);
private OsmandApplication app;
private Map<ExportSettingsType, List<?>> dataList = new HashMap<>();
@ -69,6 +74,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
private SettingsExportListener exportListener;
private ProgressDialog progress;
int progressMax;
int progressValue;
private long exportStartTime;
@ -87,6 +94,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
includeAdditionalData = savedInstanceState.getBoolean(INCLUDE_ADDITIONAL_DATA_KEY);
includeGlobalSettings = savedInstanceState.getBoolean(INCLUDE_GLOBAL_SETTINGS_KEY);
exportStartTime = savedInstanceState.getLong(EXPORT_START_TIME_KEY);
progressMax = savedInstanceState.getInt(PROGRESS_MAX_KEY);
progressValue = savedInstanceState.getInt(PROGRESS_VALUE_KEY);
}
dataList = app.getSettingsHelper().getAdditionalData(globalExport);
}
@ -99,6 +108,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
outState.putBoolean(INCLUDE_ADDITIONAL_DATA_KEY, includeAdditionalData);
outState.putBoolean(INCLUDE_GLOBAL_SETTINGS_KEY, includeGlobalSettings);
outState.putLong(EXPORT_START_TIME_KEY, exportStartTime);
outState.putInt(PROGRESS_MAX_KEY, progress.getMax());
outState.putInt(PROGRESS_VALUE_KEY, progress.getProgress());
}
@Override
@ -271,10 +282,22 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
showExportProgressDialog();
File tempDir = FileUtils.getTempDir(app);
String fileName = getFileName();
app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), prepareSettingsItemsForExport(), true);
List<SettingsItem> items = prepareSettingsItemsForExport();
progress.setMax(getMaxProgress(items));
app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), items, true);
}
}
private int getMaxProgress(List<SettingsItem> items) {
long maxProgress = 0;
for (SettingsItem item : items) {
if (item instanceof FileSettingsItem) {
maxProgress += ((FileSettingsItem) item).getSize();
}
}
return (int) maxProgress / 1000000;
}
private String getFileName() {
if (globalExport) {
if (exportStartTime == 0) {
@ -295,12 +318,33 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
progress.dismiss();
}
progress = new ProgressDialog(context);
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setCancelable(true);
progress.setTitle(app.getString(R.string.shared_string_export));
progress.setMessage(app.getString(R.string.shared_string_preparing));
progress.setCancelable(false);
progress.setButton(DialogInterface.BUTTON_NEGATIVE, app.getString(R.string.shared_string_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancelExport();
}
});
progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
cancelExport();
}
});
progress.show();
}
private void cancelExport() {
app.getSettingsHelper().getExportAsyncTask(getExportFile()).cancel(true);
//noinspection ResultOfMethodCallIgnored
getExportFile().delete();
progress.dismiss();
dismiss();
}
private SettingsExportListener getSettingsExportListener() {
if (exportListener == null) {
exportListener = new SettingsExportListener() {
@ -315,6 +359,11 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
app.showToastMessage(R.string.export_profile_failed);
}
}
@Override
public void onSettingsExportProgressUpdate(int value) {
progress.setProgress(value);
}
};
}
return exportListener;
@ -326,6 +375,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
boolean fileExporting = app.getSettingsHelper().isFileExporting(file);
if (fileExporting) {
showExportProgressDialog();
progress.setMax(progressMax);
progress.setProgress(progressValue);
app.getSettingsHelper().updateExportListener(file, getSettingsExportListener());
} else if (file.exists()) {
dismissExportProgressDialog();

View file

@ -735,6 +735,11 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment {
app.showToastMessage(R.string.profile_backup_failed);
}
}
@Override
public void onSettingsExportProgressUpdate(int value) {
}
};
}
return exportListener;