Add export progress & cancel
This commit is contained in:
parent
7d9dbb09ff
commit
312027db3c
5 changed files with 124 additions and 14 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue