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

View file

@ -21,6 +21,7 @@ class SettingsExporter {
private Map<String, SettingsItem> items; private Map<String, SettingsItem> items;
private Map<String, String> additionalParams; private Map<String, String> additionalParams;
private boolean exportItemsFiles; private boolean exportItemsFiles;
private boolean exportCancel;
SettingsExporter(boolean exportItemsFiles) { SettingsExporter(boolean exportItemsFiles) {
this.exportItemsFiles = exportItemsFiles; this.exportItemsFiles = exportItemsFiles;
@ -35,11 +36,15 @@ class SettingsExporter {
items.put(item.getName(), item); items.put(item.getName(), item);
} }
public void setExportCancel(boolean exportCancel) {
this.exportCancel = exportCancel;
}
void addAdditionalParam(String key, String value) { void addAdditionalParam(String key, String value) {
additionalParams.put(key, 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(); JSONObject json = createItemsJson();
OutputStream os = new BufferedOutputStream(new FileOutputStream(file), SettingsHelper.BUFFER); OutputStream os = new BufferedOutputStream(new FileOutputStream(file), SettingsHelper.BUFFER);
ZipOutputStream zos = new ZipOutputStream(os); ZipOutputStream zos = new ZipOutputStream(os);
@ -49,7 +54,7 @@ class SettingsExporter {
zos.write(json.toString(2).getBytes("UTF-8")); zos.write(json.toString(2).getBytes("UTF-8"));
zos.closeEntry(); zos.closeEntry();
if (exportItemsFiles) { if (exportItemsFiles) {
writeItemFiles(zos); writeItemFiles(zos, exportProgress);
} }
zos.flush(); zos.flush();
zos.finish(); 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()) { for (SettingsItem item : items.values()) {
SettingsItemWriter<? extends SettingsItem> writer = item.getWriter(); SettingsItemWriter<? extends SettingsItem> writer = item.getWriter();
if (writer != null) { if (writer != null) {
@ -69,6 +75,17 @@ class SettingsExporter {
} }
writer.writeEntry(fileName, zos); 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 { public interface SettingsExportListener {
void onSettingsExportFinished(@NonNull File file, boolean succeed); void onSettingsExportFinished(@NonNull File file, boolean succeed);
void onSettingsExportProgressUpdate(int value);
} }
public enum ImportType { public enum ImportType {
@ -139,6 +141,10 @@ public class SettingsHelper {
return importTask == null || importTask.isImportDone(); return importTask == null || importTask.isImportDone();
} }
public ExportAsyncTask getExportAsyncTask(File file) {
return exportAsyncTasks.get(file);
}
public boolean isFileExporting(File file) { public boolean isFileExporting(File file) {
return exportAsyncTasks.containsKey(file); return exportAsyncTasks.containsKey(file);
} }
@ -200,12 +206,18 @@ public class SettingsHelper {
} }
} }
@SuppressLint("StaticFieldLeak") public interface ExportProgress {
private class ExportAsyncTask extends AsyncTask<Void, Void, Boolean> { void setProgress(int value);
}
private SettingsExporter exporter; @SuppressLint("StaticFieldLeak")
private File file; public class ExportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private final SettingsExporter exporter;
private final File file;
private SettingsExportListener listener; private SettingsExportListener listener;
private final ExportProgress exportProgress;
ExportAsyncTask(@NonNull File settingsFile, ExportAsyncTask(@NonNull File settingsFile,
@Nullable SettingsExportListener listener, @Nullable SettingsExportListener listener,
@ -216,12 +228,19 @@ public class SettingsHelper {
for (SettingsItem item : items) { for (SettingsItem item : items) {
exporter.addSettingsItem(item); exporter.addSettingsItem(item);
} }
exportProgress = new ExportProgress() {
@Override
public void setProgress(int value) {
exporter.setExportCancel(isCancelled());
publishProgress(value);
}
};
} }
@Override @Override
protected Boolean doInBackground(Void... voids) { protected Boolean doInBackground(Void... voids) {
try { try {
exporter.exportSettings(file); exporter.exportSettings(file, exportProgress);
return true; return true;
} catch (JSONException e) { } catch (JSONException e) {
LOG.error("Failed to export items to: " + file.getName(), e); LOG.error("Failed to export items to: " + file.getName(), e);
@ -231,6 +250,14 @@ public class SettingsHelper {
return false; return false;
} }
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (listener != null) {
listener.onSettingsExportProgressUpdate(values[0]);
}
}
@Override @Override
protected void onPostExecute(Boolean success) { protected void onPostExecute(Boolean success) {
exportAsyncTasks.remove(file); exportAsyncTasks.remove(file);
@ -238,6 +265,13 @@ public class SettingsHelper {
listener.onSettingsExportFinished(file, success); listener.onSettingsExportFinished(file, success);
} }
} }
@Override
protected void onCancelled() {
super.onCancelled();
//noinspection ResultOfMethodCallIgnored
file.delete();
}
} }
@SuppressLint("StaticFieldLeak") @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) { 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); File file = new File(fileDir, fileName + OSMAND_SETTINGS_FILE_EXT);
ExportAsyncTask exportAsyncTask = new ExportAsyncTask(file, listener, items, exportItemsFiles); ExportAsyncTask exportAsyncTask = new ExportAsyncTask(file, listener, items, exportItemsFiles);
exportAsyncTasks.put(file, exportAsyncTask); exportAsyncTasks.put(file, exportAsyncTask);
exportAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); exportAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }

View file

@ -2,6 +2,7 @@ package net.osmand.plus.settings.fragments;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.drawable.ColorDrawable; 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.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.ExportSettingsType; 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.GlobalSettingsItem;
import net.osmand.plus.settings.backend.backup.ProfileSettingsItem; import net.osmand.plus.settings.backend.backup.ProfileSettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsExportListener; import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsExportListener;
@ -47,6 +49,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
public class ExportProfileBottomSheet extends BasePreferenceBottomSheet { 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 EXPORTING_PROFILE_KEY = "exporting_profile_key";
private static final String INCLUDE_ADDITIONAL_DATA_KEY = "include_additional_data_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 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 OsmandApplication app;
private Map<ExportSettingsType, List<?>> dataList = new HashMap<>(); private Map<ExportSettingsType, List<?>> dataList = new HashMap<>();
@ -69,6 +74,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
private SettingsExportListener exportListener; private SettingsExportListener exportListener;
private ProgressDialog progress; private ProgressDialog progress;
int progressMax;
int progressValue;
private long exportStartTime; private long exportStartTime;
@ -87,6 +94,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
includeAdditionalData = savedInstanceState.getBoolean(INCLUDE_ADDITIONAL_DATA_KEY); includeAdditionalData = savedInstanceState.getBoolean(INCLUDE_ADDITIONAL_DATA_KEY);
includeGlobalSettings = savedInstanceState.getBoolean(INCLUDE_GLOBAL_SETTINGS_KEY); includeGlobalSettings = savedInstanceState.getBoolean(INCLUDE_GLOBAL_SETTINGS_KEY);
exportStartTime = savedInstanceState.getLong(EXPORT_START_TIME_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); dataList = app.getSettingsHelper().getAdditionalData(globalExport);
} }
@ -99,6 +108,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
outState.putBoolean(INCLUDE_ADDITIONAL_DATA_KEY, includeAdditionalData); outState.putBoolean(INCLUDE_ADDITIONAL_DATA_KEY, includeAdditionalData);
outState.putBoolean(INCLUDE_GLOBAL_SETTINGS_KEY, includeGlobalSettings); outState.putBoolean(INCLUDE_GLOBAL_SETTINGS_KEY, includeGlobalSettings);
outState.putLong(EXPORT_START_TIME_KEY, exportStartTime); outState.putLong(EXPORT_START_TIME_KEY, exportStartTime);
outState.putInt(PROGRESS_MAX_KEY, progress.getMax());
outState.putInt(PROGRESS_VALUE_KEY, progress.getProgress());
} }
@Override @Override
@ -271,10 +282,22 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
showExportProgressDialog(); showExportProgressDialog();
File tempDir = FileUtils.getTempDir(app); File tempDir = FileUtils.getTempDir(app);
String fileName = getFileName(); 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() { private String getFileName() {
if (globalExport) { if (globalExport) {
if (exportStartTime == 0) { if (exportStartTime == 0) {
@ -295,12 +318,33 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
progress.dismiss(); progress.dismiss();
} }
progress = new ProgressDialog(context); progress = new ProgressDialog(context);
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setCancelable(true);
progress.setTitle(app.getString(R.string.shared_string_export)); progress.setTitle(app.getString(R.string.shared_string_export));
progress.setMessage(app.getString(R.string.shared_string_preparing)); 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(); progress.show();
} }
private void cancelExport() {
app.getSettingsHelper().getExportAsyncTask(getExportFile()).cancel(true);
//noinspection ResultOfMethodCallIgnored
getExportFile().delete();
progress.dismiss();
dismiss();
}
private SettingsExportListener getSettingsExportListener() { private SettingsExportListener getSettingsExportListener() {
if (exportListener == null) { if (exportListener == null) {
exportListener = new SettingsExportListener() { exportListener = new SettingsExportListener() {
@ -315,6 +359,11 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
app.showToastMessage(R.string.export_profile_failed); app.showToastMessage(R.string.export_profile_failed);
} }
} }
@Override
public void onSettingsExportProgressUpdate(int value) {
progress.setProgress(value);
}
}; };
} }
return exportListener; return exportListener;
@ -326,6 +375,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
boolean fileExporting = app.getSettingsHelper().isFileExporting(file); boolean fileExporting = app.getSettingsHelper().isFileExporting(file);
if (fileExporting) { if (fileExporting) {
showExportProgressDialog(); showExportProgressDialog();
progress.setMax(progressMax);
progress.setProgress(progressValue);
app.getSettingsHelper().updateExportListener(file, getSettingsExportListener()); app.getSettingsHelper().updateExportListener(file, getSettingsExportListener());
} else if (file.exists()) { } else if (file.exists()) {
dismissExportProgressDialog(); dismissExportProgressDialog();

View file

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