Working on settings import/export

This commit is contained in:
max-klaus 2019-10-11 15:56:46 +03:00
parent 6b221be979
commit 6ca269359e
6 changed files with 551 additions and 74 deletions

View file

@ -499,6 +499,7 @@ public class AppInitializer implements IProgress {
}
app.travelDbHelper = startupInit(app.travelDbHelper, TravelDbHelper.class);
app.lockHelper = startupInit(new LockHelper(app), LockHelper.class);
app.settingsHelper = startupInit(new SettingsHelper(app), SettingsHelper.class);
initOpeningHoursParser();

View file

@ -183,6 +183,10 @@ public class ApplicationMode {
public static class ApplicationModeBuilder {
private ApplicationMode applicationMode;
public ApplicationMode getApplicationMode() {
return applicationMode;
}
private ApplicationMode reg() {
values.add(applicationMode);
defaultValues.add(applicationMode);
@ -347,7 +351,7 @@ public class ApplicationMode {
}
public static ApplicationModeBuilder createCustomMode(ApplicationMode parent, String userProfileTitle, String stringKey) {
return create(parent,-1, stringKey).userProfileTitle(userProfileTitle);
return create(parent, -1, stringKey).userProfileTitle(userProfileTitle);
}
@ -622,6 +626,31 @@ public class ApplicationMode {
}
}
public static ApplicationModeBuilder fromJson(OsmandApplication app, String json) {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
ApplicationModeBean mb = gson.fromJson(json, ApplicationModeBean.class);
ApplicationModeBuilder b = createCustomMode(valueOfStringKey(mb.parent, CAR),
mb.userProfileName, mb.stringKey);
b.setRouteService(mb.routeService).setRoutingProfile(mb.routingProfile);
b.icon(app, mb.iconName);
b.setColor(mb.iconColor);
return b;
}
public String toJson() {
ApplicationModeBean mb = new ApplicationModeBean();
mb.userProfileName = userProfileName;
mb.iconColor = iconColor;
mb.iconName = iconResName;
mb.parent = parentAppMode != null ? parentAppMode.getStringKey() : null;
mb.stringKey = stringKey;
mb.routeService = routeService;
mb.routingProfile = routingProfile;
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
return gson.toJson(mb);
}
private static void initCustomModes(OsmandApplication app){
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Type t = new TypeToken<ArrayList<ApplicationModeBean>>() {}.getType();
@ -640,7 +669,6 @@ public class ApplicationMode {
}
private static void saveCustomModeToSettings(OsmandSettings settings){
List<ApplicationModeBean> customModes = new ArrayList<>();
for (ApplicationMode mode : values) {

View file

@ -136,6 +136,7 @@ public class OsmandApplication extends MultiDexApplication {
InAppPurchaseHelper inAppPurchaseHelper;
MapViewTrackingUtilities mapViewTrackingUtilities;
LockHelper lockHelper;
SettingsHelper settingsHelper;
private RoutingConfiguration.Builder routingConfig;
private Locale preferredLocale = null;
@ -335,6 +336,10 @@ public class OsmandApplication extends MultiDexApplication {
return lockHelper;
}
public SettingsHelper getSettingsHelper() {
return settingsHelper;
}
public synchronized DownloadIndexesThread getDownloadThread() {
if(downloadIndexesThread == null) {
downloadIndexesThread = new DownloadIndexesThread(this);

View file

@ -686,15 +686,9 @@ public class OsmandSettings {
set(parseString(globalValue));
}
} else {
Object jsonModeValuesObj = json.get(getId());
if (jsonModeValuesObj instanceof JSONObject) {
JSONObject jsonModeValues = (JSONObject) jsonModeValuesObj;
for (ApplicationMode m : ApplicationMode.allPossibleValues()) {
String modeValue = jsonModeValues.getString(m.getStringKey());
if (modeValue != null) {
setModeValue(m, parseString(modeValue));
}
}
String modeValue = json.getString(getId());
if (modeValue != null) {
setModeValue(appMode, parseString(modeValue));
}
}
}

View file

@ -1,13 +1,20 @@
package net.osmand.plus;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import net.osmand.PlatformUtil;
import net.osmand.plus.ApplicationMode.ApplicationModeBuilder;
import net.osmand.plus.OsmandSettings.OsmandPreference;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -25,7 +32,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
@ -39,6 +45,37 @@ public class SettingsHelper {
private static final Log LOG = PlatformUtil.getLog(SettingsHelper.class);
private static final int BUFFER = 1024;
private OsmandApplication app;
private Activity activity;
private boolean importing;
private ImportAsyncTask importTask;
public SettingsHelper(OsmandApplication app) {
this.app = app;
}
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
if (importing) {
importTask.processNextItem();
}
}
public void resetActivity(Activity activity) {
if (this.activity == activity) {
this.activity = null;
}
}
public boolean isImporting() {
return importing;
}
public enum SettingsItemType {
GLOBAL,
PROFILE,
@ -55,15 +92,71 @@ public class SettingsHelper {
this.type = type;
}
SettingsItem(@NonNull SettingsItemType type, @NonNull JSONObject json) throws JSONException {
this.type = type;
readFromJson(json);
}
@NonNull
public SettingsItemType getType() {
return type;
}
@NonNull
public abstract String getName();
public abstract SettingsItemReader getReader();
@NonNull
public abstract String getFileName();
public abstract SettingsItemWriter getWriter();
static SettingsItemType parseItemType(@NonNull JSONObject json) throws IllegalArgumentException, JSONException {
return SettingsItemType.valueOf(json.getString("type"));
}
public boolean exists() {
return false;
}
public void apply() {
// non implemented
}
void readFromJson(@NonNull JSONObject json) throws JSONException {
}
void writeToJson(@NonNull JSONObject json) throws JSONException {
json.put("type", type.name());
json.put("name", getName());
}
String toJson() throws JSONException {
JSONObject json = new JSONObject();
writeToJson(json);
return json.toString();
}
@NonNull
abstract SettingsItemReader getReader();
@NonNull
abstract SettingsItemWriter getWriter();
@Override
public int hashCode() {
return (getType().name() + getName()).hashCode();
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof SettingsItem)) {
return false;
}
SettingsItem item = (SettingsItem) other;
return item.getType() == getType() && item.getName().equals(getName());
}
}
public abstract static class SettingsItemReader<T extends SettingsItem> {
@ -101,6 +194,11 @@ public class SettingsHelper {
this.settings = settings;
}
protected OsmandSettingsItem(@NonNull SettingsItemType type, @NonNull OsmandSettings settings, @NonNull JSONObject json) throws JSONException {
super(type, json);
this.settings = settings;
}
public OsmandSettings getSettings() {
return settings;
}
@ -128,7 +226,7 @@ public class SettingsHelper {
buf.append(str);
}
} catch (IOException e) {
throw new IllegalArgumentException("Cannot read json body", e);
throw new IOException("Cannot read json body", e);
}
String jsonStr = buf.toString();
if (Algorithms.isEmpty(jsonStr)) {
@ -148,7 +246,7 @@ public class SettingsHelper {
try {
readPreferenceFromJson(p, json);
} catch (JSONException e) {
LOG.error(null, e);
LOG.error("Failed to read preference: " + p.getId(), e);
}
}
}
@ -174,7 +272,7 @@ public class SettingsHelper {
try {
writePreferenceToJson(pref, json);
} catch (JSONException e) {
LOG.error(null, e);
LOG.error("Failed to write preference: " + pref.getId(), e);
}
}
if (json.length() > 0) {
@ -182,7 +280,7 @@ public class SettingsHelper {
String s = json.toString(2);
outputStream.write(s.getBytes("UTF-8"));
} catch (JSONException e) {
LOG.error(null, e);
LOG.error("Failed to write json to stream", e);
}
return true;
}
@ -196,13 +294,26 @@ public class SettingsHelper {
super(SettingsItemType.GLOBAL, settings);
}
@NonNull
@Override
public String getName() {
return "global";
return "general_settings";
}
@NonNull
@Override
public String getFileName() {
return getName() + ".json";
}
@Override
public SettingsItemReader getReader() {
public boolean exists() {
return true;
}
@NonNull
@Override
SettingsItemReader getReader() {
return new OsmandSettingsItemReader(this, getSettings()) {
@Override
protected void readPreferenceFromJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
@ -211,8 +322,9 @@ public class SettingsHelper {
};
}
@NonNull
@Override
public SettingsItemWriter getWriter() {
SettingsItemWriter getWriter() {
return new OsmandSettingsItemWriter(this, getSettings()) {
@Override
protected void writePreferenceToJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
@ -225,19 +337,56 @@ public class SettingsHelper {
public static class ProfileSettingsItem extends OsmandSettingsItem {
private ApplicationMode appMode;
private ApplicationModeBuilder builder;
public ProfileSettingsItem(@NonNull OsmandSettings settings, @NonNull ApplicationMode appMode) {
super(SettingsItemType.PROFILE, settings);
this.appMode = appMode;
}
public ProfileSettingsItem(@NonNull OsmandSettings settings, @NonNull JSONObject json) throws JSONException {
super(SettingsItemType.PROFILE, settings, json);
readFromJson(settings.getContext(), json);
}
@NonNull
@Override
public String getName() {
return appMode.getStringKey();
}
@NonNull
@Override
public SettingsItemReader getReader() {
public String getFileName() {
return "profile_" + getName() + ".json";
}
void readFromJson(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
String appModeJson = json.getString("appMode");
builder = ApplicationMode.fromJson(app, appModeJson);
this.appMode = builder.getApplicationMode();
}
@Override
public boolean exists() {
return builder != null && ApplicationMode.valueOfStringKey(getName(), null) != null;
}
@Override
public void apply() {
appMode = ApplicationMode.saveCustomProfile(builder, getSettings().getContext());
}
@Override
void writeToJson(@NonNull JSONObject json) throws JSONException {
super.writeToJson(json);
json.put("appMode", new JSONObject(appMode.toJson()));
}
@NonNull
@Override
SettingsItemReader getReader() {
return new OsmandSettingsItemReader(this, getSettings()) {
@Override
protected void readPreferenceFromJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
@ -246,8 +395,9 @@ public class SettingsHelper {
};
}
@NonNull
@Override
public SettingsItemWriter getWriter() {
SettingsItemWriter getWriter() {
return new OsmandSettingsItemWriter(this, getSettings()) {
@Override
protected void writePreferenceToJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
@ -294,13 +444,17 @@ public class SettingsHelper {
@Nullable
private InputStream inputStream;
private String name;
protected String name;
public StreamSettingsItem(@NonNull SettingsItemType type, @NonNull String name) {
super(type);
this.name = name;
}
StreamSettingsItem(@NonNull SettingsItemType type, @NonNull JSONObject json) throws JSONException {
super(type, json);
}
public StreamSettingsItem(@NonNull SettingsItemType type, @NonNull InputStream inputStream, @NonNull String name) {
super(type);
this.inputStream = inputStream;
@ -316,11 +470,19 @@ public class SettingsHelper {
this.inputStream = inputStream;
}
@NonNull
@Override
public String getName() {
return name;
}
@Override
void readFromJson(@NonNull JSONObject json) throws JSONException {
super.readFromJson(json);
name = json.getString("name");
}
@NonNull
@Override
public SettingsItemWriter getWriter() {
return new StreamSettingsItemWriter(this);
@ -336,18 +498,29 @@ public class SettingsHelper {
super(SettingsItemType.DATA, name);
}
DataSettingsItem(@NonNull JSONObject json) throws JSONException {
super(SettingsItemType.DATA, json);
}
public DataSettingsItem(@NonNull byte[] data, @NonNull String name) {
super(SettingsItemType.DATA, name);
this.data = data;
}
@NonNull
@Override
public String getFileName() {
return getName() + ".dat";
}
@Nullable
public byte[] getData() {
return data;
}
@NonNull
@Override
public SettingsItemReader getReader() {
SettingsItemReader getReader() {
return new StreamSettingsItemReader(this) {
@Override
public void readFromStream(@NonNull InputStream inputStream) throws IOException, IllegalArgumentException {
@ -364,6 +537,7 @@ public class SettingsHelper {
};
}
@NonNull
@Override
public SettingsItemWriter getWriter() {
setInputStream(new ByteArrayInputStream(data));
@ -380,12 +554,29 @@ public class SettingsHelper {
this.file = file;
}
FileSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(SettingsItemType.FILE, json);
this.file = new File(app.getAppPath(null), name);
}
@NonNull
@Override
public String getFileName() {
return getName();
}
public File getFile() {
return file;
}
@Override
public SettingsItemReader getReader() {
public boolean exists() {
return file.exists();
}
@NonNull
@Override
SettingsItemReader getReader() {
return new StreamSettingsItemReader(this) {
@Override
public void readFromStream(@NonNull InputStream inputStream) throws IOException, IllegalArgumentException {
@ -400,12 +591,13 @@ public class SettingsHelper {
};
}
@NonNull
@Override
public SettingsItemWriter getWriter() {
try {
setInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
LOG.error(null, e);
LOG.error("Failed to set input stream from file: " + file.getName(), e);
}
return super.getWriter();
}
@ -414,64 +606,105 @@ public class SettingsHelper {
private static class SettingsItemsFactory {
private OsmandApplication app;
private List<SettingsItem> items = new ArrayList<>();
SettingsItemsFactory(OsmandApplication app) {
SettingsItemsFactory(OsmandApplication app, String jsonStr) throws IllegalArgumentException, JSONException {
this.app = app;
JSONObject json = new JSONObject(jsonStr);
JSONArray itemsJson = json.getJSONArray("items");
for (int i = 0; i < itemsJson.length(); i++) {
JSONObject itemJson = itemsJson.getJSONObject(i);
SettingsItem item = createItem(itemJson);
if (item != null) {
items.add(item);
}
}
if (items.size() == 0) {
throw new IllegalArgumentException("No items");
}
}
@NonNull
public List<SettingsItem> getItems() {
return items;
}
@Nullable
public SettingsItem createItem(@NonNull SettingsItemType type, @NonNull String name) {
OsmandSettings settings = app.getSettings();
switch (type) {
case GLOBAL:
return new GlobalSettingsItem(settings);
case PROFILE:
ApplicationMode appMode = ApplicationMode.valueOfStringKey(name, null);
return appMode != null ? new ProfileSettingsItem(settings, appMode) : null;
case PLUGIN:
return null;
case DATA:
return new DataSettingsItem(name);
case FILE:
return new FileSettingsItem(app, new File(app.getAppPath(null), name));
public SettingsItem getItemByFileName(@NonNull String fileName) {
for (SettingsItem item : items) {
if (item.getFileName().equals(fileName)) {
return item;
}
}
return null;
}
@Nullable
private SettingsItem createItem(@NonNull JSONObject json) throws IllegalArgumentException, JSONException {
SettingsItem item = null;
SettingsItemType type = SettingsItem.parseItemType(json);
OsmandSettings settings = app.getSettings();
switch (type) {
case GLOBAL:
item = new GlobalSettingsItem(settings);
break;
case PROFILE:
item = new ProfileSettingsItem(settings, json);
break;
case PLUGIN:
break;
case DATA:
item = new DataSettingsItem(json);
break;
case FILE:
item = new FileSettingsItem(app, json);
break;
}
return item;
}
}
public static class SettingsExporter {
private static class SettingsExporter {
private Map<String, SettingsItem> items;
private Map<String, String> additionalParams;
public SettingsExporter() {
SettingsExporter() {
items = new LinkedHashMap<>();
additionalParams = new LinkedHashMap<>();
}
public void addSettingsItem(SettingsItem item) throws IllegalArgumentException {
void addSettingsItem(SettingsItem item) throws IllegalArgumentException {
if (items.containsKey(item.getName())) {
throw new IllegalArgumentException("Already has such item: " + item.getName());
}
items.put(item.getName(), item);
}
public void addAdditionalParam(String key, String value) {
void addAdditionalParam(String key, String value) {
additionalParams.put(key, value);
}
public void exportSettings(File zipFile) throws JSONException, IOException {
void exportSettings(File zipFile) throws JSONException, IOException {
JSONObject json = new JSONObject();
json.put("osmand_settings_version", OsmandSettings.VERSION);
for (Map.Entry<String, String> param : additionalParams.entrySet()) {
json.put(param.getKey(), param.getValue());
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(zipFile), BUFFER);
ZipOutputStream zos = new ZipOutputStream(bos);
JSONArray itemsJson = new JSONArray();
for (SettingsItem item : items.values()) {
itemsJson.put(new JSONObject(item.toJson()));
}
json.put("items", itemsJson);
OutputStream os = new BufferedOutputStream(new FileOutputStream(zipFile), BUFFER);
ZipOutputStream zos = new ZipOutputStream(os);
try {
ZipEntry entry = new ZipEntry("items.json");
zos.putNextEntry(entry);
zos.write(json.toString(2).getBytes("UTF-8"));
zos.closeEntry();
for (SettingsItem item : items.values()) {
ZipEntry entry = new ZipEntry(item.getName());
entry.setExtra(item.getType().name().getBytes());
entry = new ZipEntry(item.getFileName());
zos.putNextEntry(entry);
item.getWriter().writeToStream(zos);
zos.closeEntry();
@ -480,54 +713,268 @@ public class SettingsHelper {
zos.finish();
} finally {
Algorithms.closeStream(zos);
Algorithms.closeStream(bos);
Algorithms.closeStream(os);
}
}
}
public static class SettingsImporter {
private static class SettingsImporter {
private OsmandApplication app;
private List<SettingsItem> items;
public SettingsImporter(@NonNull OsmandApplication app) {
SettingsImporter(@NonNull OsmandApplication app) {
this.app = app;
}
public List<SettingsItem> getItems() {
return Collections.unmodifiableList(items);
List<SettingsItem> collectItems(@NonNull File zipFile) throws IllegalArgumentException, IOException {
return processItems(zipFile, null);
}
public void importSettings(File zipFile) throws IllegalArgumentException, IOException {
items = new ArrayList<>();
void importItems(@NonNull File zipFile, @NonNull List<SettingsItem> items) throws IllegalArgumentException, IOException {
processItems(zipFile, items);
}
private List<SettingsItem> processItems(@NonNull File zipFile, @Nullable List<SettingsItem> items) throws IllegalArgumentException, IOException {
boolean collecting = items == null;
if (collecting) {
items = new ArrayList<>();
} else {
if (items.size() == 0) {
throw new IllegalArgumentException("No items");
}
}
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
InputStream ois = new BufferedInputStream(zis);
SettingsItemsFactory itemsFactory = new SettingsItemsFactory(app);
try {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
String itemTypeStr = new String(entry.getExtra());
if (!Algorithms.isEmpty(itemTypeStr)) {
try {
SettingsItemType type = SettingsItemType.valueOf(itemTypeStr);
SettingsItem item = itemsFactory.createItem(type, entry.getName());
if (item != null) {
ZipEntry entry = zis.getNextEntry();
if (entry != null && entry.getName().equals("items.json")) {
String itemsJson = null;
try {
itemsJson = Algorithms.readFromInputStream(ois).toString();
} catch (IOException e) {
LOG.error("Error reading items.json: " + itemsJson, e);
throw new IllegalArgumentException("No items");
} finally {
zis.closeEntry();
}
SettingsItemsFactory itemsFactory;
try {
itemsFactory = new SettingsItemsFactory(app, itemsJson);
if (collecting) {
items.addAll(itemsFactory.getItems());
}
} catch (IllegalArgumentException e) {
LOG.error("Error parsing items: " + itemsJson, e);
throw new IllegalArgumentException("No items");
} catch (JSONException e) {
LOG.error("Error parsing items: " + itemsJson, e);
throw new IllegalArgumentException("No items");
}
while ((entry = zis.getNextEntry()) != null && !collecting) {
String fileName = entry.getName();
SettingsItem item = itemsFactory.getItemByFileName(fileName);
if (item != null) {
try {
item.getReader().readFromStream(ois);
items.add(item);
} catch (IllegalArgumentException e) {
LOG.error("Error reading item data: " + item.getName(), e);
} catch (IOException e) {
LOG.error("Error reading item data: " + item.getName(), e);
} finally {
zis.closeEntry();
}
} catch (IllegalArgumentException e) {
LOG.error("Wrong SettingsItemType: " + itemTypeStr, e);
} finally {
zis.closeEntry();
}
}
} else {
throw new IllegalArgumentException("No items found");
}
} catch (IOException ex) {
LOG.error(ex);
LOG.error("Failed to read next entry", ex);
} finally {
Algorithms.closeStream(ois);
Algorithms.closeStream(zis);
}
return items;
}
}
@SuppressLint("StaticFieldLeak")
private class ImportAsyncTask extends AsyncTask<Void, Void, List<SettingsItem>> {
private File zipFile;
private SettingsImporter importer;
private List<SettingsItem> items;
private List<SettingsItem> processedItems = new ArrayList<>();
ImportAsyncTask(@NonNull File zipFile) {
this.zipFile = zipFile;
importer = new SettingsImporter(app);
}
@Override
protected void onPreExecute() {
if (importing) {
finishImport(false);
}
importing = true;
importTask = this;
}
@Override
protected List<SettingsItem> doInBackground(Void... voids) {
try {
return importer.collectItems(zipFile);
} catch (IllegalArgumentException e) {
LOG.error("Failed to collect items from: " + zipFile.getName(), e);
} catch (IOException e) {
LOG.error("Failed to collect items from: " + zipFile.getName(), e);
}
return null;
}
@Override
protected void onPostExecute(List<SettingsItem> items) {
this.items = items;
if (items != null && items.size() > 0) {
processNextItem();
}
}
private void processNextItem() {
if (activity == null) {
return;
}
if (items.size() == 0) {
if (processedItems.size() > 0) {
new ImportItemsAsyncTask(zipFile, processedItems).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
finishImport(false);
}
}
final SettingsItem item = items.remove(0);
if (item.exists()) {
switch (item.getType()) {
case PROFILE: {
AlertDialog.Builder b = new AlertDialog.Builder(activity);
b.setMessage("Profile \"" + item.getName() + "\" is already exists. Overwrite?");
b.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
acceptItem(item);
}
});
b.setNegativeButton(R.string.shared_string_no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
processNextItem();
}
});
b.setCancelable(false);
b.show();
break;
}
case FILE:
break;
default:
acceptItem(item);
break;
}
} else {
acceptItem(item);
}
}
private void acceptItem(SettingsItem item) {
item.apply();
processedItems.add(item);
processNextItem();
}
}
@SuppressLint("StaticFieldLeak")
private class ImportItemsAsyncTask extends AsyncTask<Void, Void, Boolean> {
private SettingsImporter importer;
private File zipFile;
private List<SettingsItem> items;
ImportItemsAsyncTask(@NonNull File zipFile, @NonNull List<SettingsItem> items) {
importer = new SettingsImporter(app);
this.zipFile = zipFile;
this.items = items;
}
@Override
protected Boolean doInBackground(Void... voids) {
try {
importer.importItems(zipFile, items);
return true;
} catch (IllegalArgumentException e) {
LOG.error("Failed to import items from: " + zipFile.getName(), e);
} catch (IOException e) {
LOG.error("Failed to import items from: " + zipFile.getName(), e);
}
return false;
}
@Override
protected void onPostExecute(Boolean success) {
finishImport(success);
}
}
private void finishImport(boolean success) {
importing = false;
importTask = null;
if (success) {
app.showShortToastMessage("Import succeed");
} else {
app.showShortToastMessage("Import failed");
}
}
@SuppressLint("StaticFieldLeak")
private class ExportAsyncTask extends AsyncTask<Void, Void, Boolean> {
private SettingsExporter exporter;
private File zipFile;
ExportAsyncTask(@NonNull File zipFile, @NonNull List<SettingsItem> items) {
this.zipFile = zipFile;
this.exporter = new SettingsExporter();
for (SettingsItem item : items) {
exporter.addSettingsItem(item);
}
}
@Override
protected Boolean doInBackground(Void... voids) {
try {
exporter.exportSettings(zipFile);
return true;
} catch (JSONException e) {
LOG.error("Failed to export items to: " + zipFile.getName(), e);
} catch (IOException e) {
LOG.error("Failed to export items to: " + zipFile.getName(), e);
}
return false;
}
@Override
protected void onPostExecute(Boolean success) {
if (success) {
app.showShortToastMessage("Export succeed");
} else {
app.showShortToastMessage("Export failed");
}
}
}
public void importSettings(@NonNull File zipFile) {
new ImportAsyncTask(zipFile).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void exportSettings(@NonNull File zipFile, @NonNull List<SettingsItem> items) {
new ExportAsyncTask(zipFile, items).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

View file

@ -840,6 +840,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
app.getDownloadThread().setUiActivity(this);
app.getSettingsHelper().setActivity(this);
boolean routeWasFinished = routingHelper.isRouteWasFinished();
if (routeWasFinished && !DestinationReachedMenu.wasShown()) {
@ -1428,6 +1429,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
app.getMapMarkersHelper().removeListener(this);
app.getRoutingHelper().removeListener(this);
app.getDownloadThread().resetUiActivity(this);
app.getSettingsHelper().resetActivity(this);
if (atlasMapRendererView != null) {
atlasMapRendererView.handleOnPause();
}