From 48dbb64d09610243ef6956678e1920db7d9cab2b Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 1 Jun 2020 15:47:01 +0300 Subject: [PATCH 1/7] Fix kmz file import --- .../net/osmand/plus/helpers/ImportHelper.java | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index c57f53a0fa..a8d621f9ed 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -71,6 +71,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import static android.app.Activity.RESULT_OK; @@ -314,13 +315,17 @@ public class ImportHelper { } else if (fileName != null && fileName.endsWith(KMZ_SUFFIX)) { try { zis = new ZipInputStream(is); - zis.getNextEntry(); - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(KML_SUFFIX)) { + final String result = Kml2Gpx.toGpx(zis); + if (result != null) { + try { + return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + return null; + } + } } } } catch (Exception e) { @@ -418,13 +423,18 @@ public class ImportHelper { is = app.getContentResolver().openInputStream(kmzFile); if (is != null) { zis = new ZipInputStream(is); - zis.getNextEntry(); - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; + + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(KML_SUFFIX)) { + final String result = Kml2Gpx.toGpx(zis); + if (result != null) { + try { + return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + return null; + } + } } } } From 38ba94ee1c9b9bb4a9d994bceee44266c2ef0b16 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 2 Oct 2020 11:56:07 +0300 Subject: [PATCH 2/7] Add base import task --- .../net/osmand/plus/helpers/ImportHelper.java | 258 ++++++------------ 1 file changed, 89 insertions(+), 169 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java index a8d621f9ed..febffa73bf 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java @@ -75,13 +75,13 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import static android.app.Activity.RESULT_OK; -import static net.osmand.IndexConstants.WPT_CHART_FILE_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_CHART_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_EXT; +import static net.osmand.IndexConstants.WPT_CHART_FILE_EXT; import static net.osmand.data.FavouritePoint.DEFAULT_BACKGROUND_TYPE; import static net.osmand.plus.AppInitializer.loadRoutingFiles; import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB; @@ -92,17 +92,20 @@ import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; * @author Koen Rabaey */ public class ImportHelper { - public final static Log log = PlatformUtil.getLog(ImportHelper.class); + + public static final Log log = PlatformUtil.getLog(ImportHelper.class); + public static final String KML_SUFFIX = ".kml"; public static final String KMZ_SUFFIX = ".kmz"; - private final AppCompatActivity activity; + public static final int IMPORT_FILE_REQUEST = 1006; + private final OsmandApplication app; private final OsmandMapTileView mapView; + private final AppCompatActivity activity; + private OnGpxImportCompleteListener gpxImportCompleteListener; - public final static int IMPORT_FILE_REQUEST = 1006; - public enum ImportType { SETTINGS(OSMAND_SETTINGS_FILE_EXT), ROUTING(ROUTING_FILE_EXT), @@ -189,20 +192,19 @@ public class ImportHelper { } public void handleFileImport(Uri intentUri, String fileName, Bundle extras, boolean useImportDir) { - final boolean isFileIntent = "file".equals(intentUri.getScheme()); - final boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath())); - - final boolean saveFile = !isFileIntent || !isOsmandSubdir; + boolean isFileIntent = "file".equals(intentUri.getScheme()); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath())); + boolean saveFile = !isFileIntent || !isOsmandSubdir; if (fileName == null) { handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false, false); - } else if (fileName.endsWith(KML_SUFFIX)) { + } else if (fileName.endsWith(KML_SUFFIX)) { handleKmlImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(KMZ_SUFFIX)) { handleKmzImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { handleObfImport(intentUri, fileName); - } else if (fileName.endsWith(IndexConstants.SQLITE_EXT)) { + } else if (fileName.endsWith(SQLITE_EXT)) { handleSqliteTileImport(intentUri, fileName); } else if (fileName.endsWith(OSMAND_SETTINGS_FILE_EXT)) { handleOsmAndSettingsImport(intentUri, fileName, extras, null); @@ -220,7 +222,8 @@ public class ImportHelper { public static String getNameFromContentUri(OsmandApplication app, Uri contentUri) { try { final String name; - final Cursor returnCursor = app.getContentResolver().query(contentUri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null); + final Cursor returnCursor = app.getContentResolver().query(contentUri, + new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); if (returnCursor != null && returnCursor.moveToFirst()) { int columnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (columnIndex != -1) { @@ -239,19 +242,12 @@ public class ImportHelper { log.error(e.getMessage(), e); return null; } - } @SuppressLint("StaticFieldLeak") private void handleGpxImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir, final boolean showInDetailsActivity) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask gpxImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -266,35 +262,25 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException ignore) { - } + Algorithms.closeStream(is); } return null; } @Override protected void onPostExecute(GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(gpxImportTask); } @SuppressLint("StaticFieldLeak") private void handleGpxOrFavouritesImport(final Uri fileUri, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + final boolean useImportDir, final boolean forceImportFavourites, + final boolean forceImportGpx) { + AsyncTask gpxOrFavouritesImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -340,40 +326,24 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException ignore) { - } - if (zis != null) try { - zis.close(); - } catch (IOException ignore) { - } + Algorithms.closeStream(is); + Algorithms.closeStream(zis); } return null; } @Override protected void onPostExecute(final GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(gpxOrFavouritesImportTask); } @SuppressLint("StaticFieldLeak") private void importFavoritesImpl(final GPXFile gpxFile, final String fileName, final boolean forceImportFavourites) { - final AsyncTask favoritesImportTask = new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), - app.getString(R.string.loading_data)); - } - } + AsyncTask favoritesImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -391,9 +361,7 @@ public class ImportHelper { @Override protected void onPostExecute(GPXFile result) { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG).show(); final Intent newIntent = new Intent(activity, app.getAppCustomization().getFavoritesActivity()); @@ -407,13 +375,7 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleKmzImport(final Uri kmzFile, final String name, final boolean save, final boolean useImportDir) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask kmzImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... voids) { @@ -441,39 +403,25 @@ public class ImportHelper { } catch (Exception e) { log.error(e.getMessage(), e); } finally { - try { - if (is != null) { - is.close(); - } - if (zis != null) { - zis.close(); - } - } catch (IOException ignore) { - } + Algorithms.closeStream(is); + Algorithms.closeStream(zis); } return null; } @Override protected void onPostExecute(GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); handleResult(result, name, save, useImportDir, false); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(kmzImportTask); } @SuppressLint("StaticFieldLeak") private void handleKmlImport(final Uri kmlFile, final String name, final boolean save, final boolean useImportDir) { - new AsyncTask() { - ProgressDialog progress = null; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask kmlImportTask = new BaseImportAsyncTask() { @Override protected GPXFile doInBackground(Void... nothing) { @@ -495,34 +443,23 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException ignore) { - } + Algorithms.closeStream(is); } return null; } @Override protected void onPostExecute(GPXFile result) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); handleResult(result, name, save, useImportDir, false); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(kmlImportTask); } @SuppressLint("StaticFieldLeak") private void handleObfImport(final Uri obfFile, final String name) { - new AsyncTask() { - - ProgressDialog progress; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask obfImportTask = new BaseImportAsyncTask() { @Override protected String doInBackground(Void... voids) { @@ -537,12 +474,11 @@ public class ImportHelper { @Override protected void onPostExecute(String message) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - Toast.makeText(app, message, Toast.LENGTH_SHORT).show(); + hideProgress(); + app.showShortToastMessage(message); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(obfImportTask); } @NonNull @@ -583,7 +519,7 @@ public class ImportHelper { } catch (SecurityException e) { e.printStackTrace(); error = e.getMessage(); - } finally { + } finally { if (in != null) { try { in.close(); @@ -604,14 +540,7 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleSqliteTileImport(final Uri uri, final String name) { - new AsyncTask() { - - ProgressDialog progress; - - @Override - protected void onPreExecute() { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + AsyncTask sqliteTileImportTask = new BaseImportAsyncTask() { @Override protected String doInBackground(Void... voids) { @@ -620,9 +549,7 @@ public class ImportHelper { @Override protected void onPostExecute(String error) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); if (error == null) { OsmandRasterMapsPlugin plugin = OsmandPlugin.getPlugin(OsmandRasterMapsPlugin.class); if (plugin != null && !plugin.isActive() && !plugin.needsInstallation()) { @@ -637,7 +564,8 @@ public class ImportHelper { Toast.makeText(app, app.getString(R.string.map_import_error) + ": " + error, Toast.LENGTH_SHORT).show(); } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }; + executeImportTask(sqliteTileImportTask); } public void chooseFileToImport(final ImportType importType, final CallbackWithObject callback) { @@ -667,21 +595,21 @@ public class ImportHelper { } else if ("content".equals(scheme)) { fileName = getNameFromContentUri(app, data); } - + if (fileName.endsWith(importType.getExtension())) { if (importType.equals(ImportType.SETTINGS)) { handleOsmAndSettingsImport(data, fileName, resultData.getExtras(), callback); - } else if (importType.equals(ImportType.ROUTING)){ + } else if (importType.equals(ImportType.ROUTING)) { handleXmlFileImport(data, fileName, callback); } } else { - app.showToastMessage(app.getString(R.string.not_support_file_type_with_ext, + app.showToastMessage(app.getString(R.string.not_support_file_type_with_ext, importType.getExtension().replaceAll("\\.", "").toUpperCase())); } } } }); - + mapActivity.registerActivityResultListener(listener); mapActivity.startActivityForResult(intent, IMPORT_FILE_REQUEST); } @@ -712,16 +640,7 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, final CallbackWithObject> callback) { - final AsyncTask settingsImportTask = new AsyncTask() { - - ProgressDialog progress; - - @Override - protected void onPreExecute() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } - } + AsyncTask settingsImportTask = new BaseImportAsyncTask() { @Override protected String doInBackground(Void... voids) { @@ -741,9 +660,7 @@ public class ImportHelper { app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { @Override public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List items) { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); if (succeed) { List pluginIndependentItems = new ArrayList<>(); List pluginSettingsItems = new ArrayList<>(); @@ -767,9 +684,7 @@ public class ImportHelper { } }); } else { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } + hideProgress(); app.showShortToastMessage(app.getString(R.string.file_import_error, name, error)); } } @@ -835,17 +750,14 @@ public class ImportHelper { @SuppressLint("StaticFieldLeak") private void handleXmlFileImport(final Uri intentUri, final String fileName, final CallbackWithObject routingCallback) { - final AsyncTask renderingImportTask = new AsyncTask() { + AsyncTask renderingImportTask = new BaseImportAsyncTask() { private String destFileName; private ImportType importType; - private ProgressDialog progress; @Override protected void onPreExecute() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); - } + showProgress(); destFileName = fileName; } @@ -893,12 +805,6 @@ public class ImportHelper { } } - private void hideProgress() { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - } - private File getDestinationDir() { if (importType == ImportType.ROUTING) { return app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); @@ -947,11 +853,7 @@ public class ImportHelper { break; } } - try { - is.close(); - } catch (IOException e) { - log.error(e); - } + Algorithms.closeStream(is); } } catch (FileNotFoundException | XmlPullParserException e) { log.error(e); @@ -960,11 +862,7 @@ public class ImportHelper { } catch (SecurityException e) { log.error(e.getMessage(), e); } finally { - if (is != null) try { - is.close(); - } catch (IOException e) { - log.error(e); - } + Algorithms.closeStream(is); } } }; @@ -986,9 +884,8 @@ public class ImportHelper { } } else { if (save) { - new SaveAsyncTask(result, name, useImportDir, showInDetailsActivity) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else if (showInDetailsActivity) { + executeImportTask(new SaveAsyncTask(result, name, useImportDir, showInDetailsActivity)); + } else { showGpxInDetailsActivity(result); } if (gpxImportCompleteListener != null) { @@ -1162,8 +1059,8 @@ public class ImportHelper { } private void importGpxOrFavourites(final GPXFile gpxFile, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { + final boolean useImportDir, final boolean forceImportFavourites, + final boolean forceImportGpx) { if (gpxFile == null || gpxFile.isPointsEmpty()) { if (forceImportFavourites) { final DialogInterface.OnClickListener importAsTrackListener = new DialogInterface.OnClickListener() { @@ -1258,4 +1155,27 @@ public class ImportHelper { importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); } } + + protected abstract class BaseImportAsyncTask extends AsyncTask { + + protected ProgressDialog progress; + + @Override + protected void onPreExecute() { + showProgress(); + } + + protected void showProgress() { + if (AndroidUtils.isActivityNotDestroyed(activity)) { + String title = app.getString(R.string.loading_smth, ""); + progress = ProgressDialog.show(activity, title, app.getString(R.string.loading_data)); + } + } + + protected void hideProgress() { + if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { + progress.dismiss(); + } + } + } } \ No newline at end of file From 4774382258c4d89dce9dd36f02a940b43ab5e95d Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 6 Oct 2020 19:48:33 +0300 Subject: [PATCH 3/7] Move import async tasks and ImportHelper to separate package --- .../osmand/plus/activities/MapActivity.java | 2 +- .../ImportGpxBottomSheetDialogFragment.java | 2 +- .../plus/importfiles/BaseImportAsyncTask.java | 45 ++ .../plus/importfiles/FavoritesImportTask.java | 59 ++ .../plus/importfiles/GpxImportTask.java | 59 ++ .../GpxOrFavouritesImportTask.java | 83 +++ .../ImportHelper.java | 625 ++---------------- .../plus/importfiles/KmlImportTask.java | 71 ++ .../plus/importfiles/KmzImportTask.java | 67 ++ .../plus/importfiles/ObfImportTask.java | 52 ++ .../plus/importfiles/SettingsImportTask.java | 158 +++++ .../importfiles/SqliteTileImportTask.java | 50 ++ .../plus/importfiles/XmlImportTask.java | 149 +++++ .../StartPlanRouteBottomSheet.java | 4 +- .../plus/myplaces/FavoritesActivity.java | 4 +- ...electProfileBottomSheetDialogFragment.java | 2 +- .../FollowTrackFragment.java | 4 +- .../backend/OsmAndAppCustomization.java | 2 +- .../fragments/MainSettingsFragment.java | 2 +- 19 files changed, 858 insertions(+), 582 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java rename OsmAnd/src/net/osmand/plus/{helpers => importfiles}/ImportHelper.java (50%) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 2816e7d5b0..2e840f8b64 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -99,7 +99,7 @@ import net.osmand.plus.firstusage.FirstUsageWelcomeFragment; import net.osmand.plus.firstusage.FirstUsageWizardFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.DiscountHelper; -import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper; import net.osmand.plus.helpers.IntentHelper; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.LockHelper.LockUIAdapter; diff --git a/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java index cf371f006e..4bc4e1589a 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/ImportGpxBottomSheetDialogFragment.java @@ -13,7 +13,7 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; -import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper; public class ImportGpxBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java b/OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java new file mode 100644 index 0000000000..4ebafcb8cc --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/BaseImportAsyncTask.java @@ -0,0 +1,45 @@ +package net.osmand.plus.importfiles; + +import android.app.ProgressDialog; +import android.os.AsyncTask; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; + +import java.lang.ref.WeakReference; + +abstract class BaseImportAsyncTask extends AsyncTask { + + protected OsmandApplication app; + protected WeakReference activityRef; + protected ProgressDialog progress; + + public BaseImportAsyncTask(@NonNull FragmentActivity activity) { + app = (OsmandApplication) activity.getApplicationContext(); + activityRef = new WeakReference<>(activity); + } + + @Override + protected void onPreExecute() { + showProgress(); + } + + protected void showProgress() { + FragmentActivity activity = activityRef.get(); + if (AndroidUtils.isActivityNotDestroyed(activity)) { + String title = app.getString(R.string.loading_smth, ""); + progress = ProgressDialog.show(activity, title, app.getString(R.string.loading_data)); + } + } + + protected void hideProgress() { + FragmentActivity activity = activityRef.get(); + if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { + progress.dismiss(); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java new file mode 100644 index 0000000000..2793e1e0ab --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java @@ -0,0 +1,59 @@ +package net.osmand.plus.importfiles; + +import android.content.Intent; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.data.FavouritePoint; +import net.osmand.plus.FavouritesDbHelper; +import net.osmand.plus.R; + +import java.util.List; + +import static net.osmand.plus.importfiles.ImportHelper.asFavourites; +import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB; +import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; + +class FavoritesImportTask extends BaseImportAsyncTask { + + private GPXFile gpxFile; + private String fileName; + private boolean forceImportFavourites; + + public FavoritesImportTask(@NonNull FragmentActivity activity, @NonNull GPXFile gpxFile, + @NonNull String fileName, boolean forceImportFavourites) { + super(activity); + this.gpxFile = gpxFile; + this.fileName = fileName; + this.forceImportFavourites = forceImportFavourites; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + List favourites = asFavourites(app, gpxFile.getPoints(), fileName, forceImportFavourites); + FavouritesDbHelper favoritesHelper = app.getFavorites(); + for (FavouritePoint favourite : favourites) { + favoritesHelper.deleteFavourite(favourite, false); + favoritesHelper.addFavourite(favourite, false); + } + favoritesHelper.sortAll(); + favoritesHelper.saveCurrentPointsIntoFile(); + return null; + } + + @Override + protected void onPostExecute(GPXUtilities.GPXFile result) { + hideProgress(); + FragmentActivity activity = activityRef.get(); + if (activity != null) { + app.showToastMessage(R.string.fav_imported_sucessfully); + Intent newIntent = new Intent(activity, app.getAppCustomization().getFavoritesActivity()); + newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + newIntent.putExtra(TAB_ID, FAV_TAB); + activity.startActivity(newIntent); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java new file mode 100644 index 0000000000..1e76f15a26 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java @@ -0,0 +1,59 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.util.Algorithms; + +import java.io.FileNotFoundException; +import java.io.InputStream; + +class GpxImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri gpxFile; + private String fileName; + private boolean save; + private boolean useImportDir; + private boolean showInDetailsActivity; + + public GpxImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri gpxFile, @NonNull String fileName, boolean save, boolean useImportDir, + boolean showInDetailsActivity) { + super(activity); + this.importHelper = importHelper; + this.gpxFile = gpxFile; + this.fileName = fileName; + this.save = save; + this.useImportDir = useImportDir; + this.showInDetailsActivity = showInDetailsActivity; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + InputStream is = null; + try { + is = app.getContentResolver().openInputStream(gpxFile); + if (is != null) { + return GPXUtilities.loadGPXFile(is); + } + } catch (FileNotFoundException e) { + // + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + } + return null; + } + + @Override + protected void onPostExecute(GPXUtilities.GPXFile result) { + hideProgress(); + importHelper.handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java new file mode 100644 index 0000000000..48eadfb5b1 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java @@ -0,0 +1,83 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.util.Algorithms; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml; + +class GpxOrFavouritesImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri fileUri; + private String fileName; + private boolean save; + private boolean useImportDir; + private boolean forceImportFavourites; + private boolean forceImportGpx; + + public GpxOrFavouritesImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri fileUri, String fileName, boolean save, boolean useImportDir, + boolean forceImportFavourites, boolean forceImportGpx) { + super(activity); + this.importHelper = importHelper; + this.fileUri = fileUri; + this.fileName = fileName; + this.save = save; + this.useImportDir = useImportDir; + this.forceImportFavourites = forceImportFavourites; + this.forceImportGpx = forceImportGpx; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + InputStream is = null; + ZipInputStream zis = null; + try { + is = app.getContentResolver().openInputStream(fileUri); + if (is != null) { + if (fileName != null && fileName.endsWith(ImportHelper.KML_SUFFIX)) { + return loadGpxFromKml(is); + } else if (fileName != null && fileName.endsWith(ImportHelper.KMZ_SUFFIX)) { + try { + zis = new ZipInputStream(is); + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(ImportHelper.KML_SUFFIX)) { + return loadGpxFromKml(zis); + } + } + } catch (Exception e) { + return null; + } + } else { + return GPXUtilities.loadGPXFile(is); + } + } + } catch (FileNotFoundException e) { + // + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(zis); + } + return null; + } + + @Override + protected void onPostExecute(final GPXUtilities.GPXFile result) { + hideProgress(); + importHelper.importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java similarity index 50% rename from OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java rename to OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index febffa73bf..f5b47604ac 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -1,7 +1,5 @@ -package net.osmand.plus.helpers; +package net.osmand.plus.importfiles; -import android.annotation.SuppressLint; -import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; @@ -17,65 +15,47 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.FragmentManager; -import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; -import net.osmand.IProgress; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint.BackgroundType; import net.osmand.plus.AppInitializer; -import net.osmand.plus.CustomOsmandPlugin; -import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment; import net.osmand.plus.measurementtool.MeasurementToolFragment; -import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; import net.osmand.plus.settings.backend.SettingsHelper; -import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener; -import net.osmand.plus.settings.backend.SettingsHelper.PluginSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem; -import net.osmand.plus.settings.backend.SettingsHelper.SettingsCollectListener; -import net.osmand.plus.settings.backend.SettingsHelper.SettingsImportListener; import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; -import net.osmand.plus.settings.fragments.ImportSettingsFragment; import net.osmand.plus.views.OsmandMapTileView; -import net.osmand.router.RoutingConfiguration; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; import static android.app.Activity.RESULT_OK; +import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT; +import static net.osmand.IndexConstants.GPX_INDEX_DIR; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; @@ -83,8 +63,6 @@ import static net.osmand.IndexConstants.SQLITE_CHART_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_EXT; import static net.osmand.IndexConstants.WPT_CHART_FILE_EXT; import static net.osmand.data.FavouritePoint.DEFAULT_BACKGROUND_TYPE; -import static net.osmand.plus.AppInitializer.loadRoutingFiles; -import static net.osmand.plus.myplaces.FavoritesActivity.FAV_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.GPX_TAB; import static net.osmand.plus.myplaces.FavoritesActivity.TAB_ID; @@ -124,6 +102,7 @@ public class ImportHelper { public interface OnGpxImportCompleteListener { void onImportComplete(boolean success); + void onSaveComplete(boolean success, GPXFile result); } @@ -138,7 +117,7 @@ public class ImportHelper { } public void handleContentImport(final Uri contentUri, Bundle extras, final boolean useImportDir) { - final String name = getNameFromContentUri(app, contentUri); + String name = getNameFromContentUri(app, contentUri); handleFileImport(contentUri, name, extras, useImportDir); } @@ -156,7 +135,7 @@ public class ImportHelper { public boolean handleGpxImport(final Uri contentUri, final boolean useImportDir, boolean showInDetailsActivity) { String name = getNameFromContentUri(app, contentUri); - boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(contentUri.getPath())); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(GPX_INDEX_DIR), new File(contentUri.getPath())); if (!isOsmandSubdir && name != null) { String nameLC = name.toLowerCase(); if (nameLC.endsWith(GPX_FILE_EXT)) { @@ -180,7 +159,7 @@ public class ImportHelper { String scheme = uri.getScheme(); boolean isFileIntent = "file".equals(scheme); boolean isContentIntent = "content".equals(scheme); - boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(uri.getPath())); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(GPX_INDEX_DIR), new File(uri.getPath())); final boolean saveFile = !isFileIntent || !isOsmandSubdir; String fileName = ""; if (isFileIntent) { @@ -193,7 +172,7 @@ public class ImportHelper { public void handleFileImport(Uri intentUri, String fileName, Bundle extras, boolean useImportDir) { boolean isFileIntent = "file".equals(intentUri.getScheme()); - boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(IndexConstants.GPX_INDEX_DIR), new File(intentUri.getPath())); + boolean isOsmandSubdir = Algorithms.isSubDirectory(app.getAppPath(GPX_INDEX_DIR), new File(intentUri.getPath())); boolean saveFile = !isFileIntent || !isOsmandSubdir; if (fileName == null) { @@ -202,7 +181,7 @@ public class ImportHelper { handleKmlImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(KMZ_SUFFIX)) { handleKmzImport(intentUri, fileName, saveFile, useImportDir); - } else if (fileName.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { + } else if (fileName.endsWith(BINARY_MAP_INDEX_EXT)) { handleObfImport(intentUri, fileName); } else if (fileName.endsWith(SQLITE_EXT)) { handleSqliteTileImport(intentUri, fileName); @@ -221,9 +200,8 @@ public class ImportHelper { public static String getNameFromContentUri(OsmandApplication app, Uri contentUri) { try { - final String name; - final Cursor returnCursor = app.getContentResolver().query(contentUri, - new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); + String name; + Cursor returnCursor = app.getContentResolver().query(contentUri, new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); if (returnCursor != null && returnCursor.moveToFirst()) { int columnIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (columnIndex != -1) { @@ -244,251 +222,52 @@ public class ImportHelper { } } - @SuppressLint("StaticFieldLeak") - private void handleGpxImport(final Uri gpxFile, final String fileName, final boolean save, final boolean useImportDir, - final boolean showInDetailsActivity) { - AsyncTask gpxImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - InputStream is = null; - try { - is = app.getContentResolver().openInputStream(gpxFile); - if (is != null) { - return GPXUtilities.loadGPXFile(is); - } - } catch (FileNotFoundException e) { - // - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - } - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); - } - }; - executeImportTask(gpxImportTask); + private void handleGpxImport(Uri gpxFile, String fileName, boolean save, boolean useImportDir, boolean showInDetailsActivity) { + executeImportTask(new GpxImportTask(this, activity, gpxFile, fileName, save, useImportDir, showInDetailsActivity)); } - @SuppressLint("StaticFieldLeak") - private void handleGpxOrFavouritesImport(final Uri fileUri, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { - AsyncTask gpxOrFavouritesImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - InputStream is = null; - ZipInputStream zis = null; - try { - is = app.getContentResolver().openInputStream(fileUri); - if (is != null) { - if (fileName != null && fileName.endsWith(KML_SUFFIX)) { - final String result = Kml2Gpx.toGpx(is); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } else if (fileName != null && fileName.endsWith(KMZ_SUFFIX)) { - try { - zis = new ZipInputStream(is); - ZipEntry entry; - while ((entry = zis.getNextEntry()) != null) { - if (entry.getName().endsWith(KML_SUFFIX)) { - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } - } - } catch (Exception e) { - return null; - } - } else { - return GPXUtilities.loadGPXFile(is); - } - } - } catch (FileNotFoundException e) { - // - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - Algorithms.closeStream(zis); - } - return null; - } - - @Override - protected void onPostExecute(final GPXFile result) { - hideProgress(); - importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); - } - }; - executeImportTask(gpxOrFavouritesImportTask); + private void handleGpxOrFavouritesImport(Uri fileUri, String fileName, boolean save, boolean useImportDir, + boolean forceImportFavourites, boolean forceImportGpx) { + executeImportTask(new GpxOrFavouritesImportTask(this, activity, fileUri, fileName, save, useImportDir, forceImportFavourites, forceImportGpx)); } - @SuppressLint("StaticFieldLeak") - private void importFavoritesImpl(final GPXFile gpxFile, final String fileName, final boolean forceImportFavourites) { - AsyncTask favoritesImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - final List favourites = asFavourites(gpxFile.getPoints(), - fileName, forceImportFavourites); - final FavouritesDbHelper favoritesHelper = app.getFavorites(); - for (final FavouritePoint favourite : favourites) { - favoritesHelper.deleteFavourite(favourite, false); - favoritesHelper.addFavourite(favourite, false); - } - favoritesHelper.sortAll(); - favoritesHelper.saveCurrentPointsIntoFile(); - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG).show(); - final Intent newIntent = new Intent(activity, - app.getAppCustomization().getFavoritesActivity()); - newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - newIntent.putExtra(TAB_ID, FAV_TAB); - activity.startActivity(newIntent); - } - }; - executeImportTask(favoritesImportTask); + private void importFavoritesImpl(GPXFile gpxFile, String fileName, boolean forceImportFavourites) { + executeImportTask(new FavoritesImportTask(activity, gpxFile, fileName, forceImportFavourites)); } - @SuppressLint("StaticFieldLeak") - private void handleKmzImport(final Uri kmzFile, final String name, final boolean save, final boolean useImportDir) { - AsyncTask kmzImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... voids) { - InputStream is = null; - ZipInputStream zis = null; - try { - is = app.getContentResolver().openInputStream(kmzFile); - if (is != null) { - zis = new ZipInputStream(is); - - ZipEntry entry; - while ((entry = zis.getNextEntry()) != null) { - if (entry.getName().endsWith(KML_SUFFIX)) { - final String result = Kml2Gpx.toGpx(zis); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } - } - } - } catch (Exception e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - Algorithms.closeStream(zis); - } - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - handleResult(result, name, save, useImportDir, false); - } - - }; - executeImportTask(kmzImportTask); + private void handleKmzImport(Uri kmzFile, String name, boolean save, boolean useImportDir) { + executeImportTask(new KmzImportTask(this, activity, kmzFile, name, save, useImportDir)); } - @SuppressLint("StaticFieldLeak") - private void handleKmlImport(final Uri kmlFile, final String name, final boolean save, final boolean useImportDir) { - AsyncTask kmlImportTask = new BaseImportAsyncTask() { - - @Override - protected GPXFile doInBackground(Void... nothing) { - InputStream is = null; - try { - is = app.getContentResolver().openInputStream(kmlFile); - if (is != null) { - final String result = Kml2Gpx.toGpx(is); - if (result != null) { - try { - return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - return null; - } - } - } - } catch (FileNotFoundException e) { - // - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - } - return null; - } - - @Override - protected void onPostExecute(GPXFile result) { - hideProgress(); - handleResult(result, name, save, useImportDir, false); - } - }; - executeImportTask(kmlImportTask); + private void handleKmlImport(Uri kmlFile, String name, boolean save, boolean useImportDir) { + executeImportTask(new KmlImportTask(this, activity, kmlFile, name, save, useImportDir)); } - @SuppressLint("StaticFieldLeak") - private void handleObfImport(final Uri obfFile, final String name) { - AsyncTask obfImportTask = new BaseImportAsyncTask() { - - @Override - protected String doInBackground(Void... voids) { - String error = copyFile(app, getObfDestFile(name), obfFile, false); - if (error == null) { - app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList()); - app.getDownloadThread().updateLoadedFiles(); - return app.getString(R.string.map_imported_successfully); - } - return app.getString(R.string.map_import_error) + ": " + error; - } - - @Override - protected void onPostExecute(String message) { - hideProgress(); - app.showShortToastMessage(message); - } - }; - executeImportTask(obfImportTask); + private void handleObfImport(Uri obfFile, String name) { + executeImportTask(new ObfImportTask(activity, obfFile, name)); } - @NonNull - private File getObfDestFile(@NonNull String name) { - if (name.endsWith(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT)) { - return app.getAppPath(IndexConstants.ROADS_INDEX_DIR + name); - } else if (name.endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) { - return app.getAppPath(IndexConstants.WIKI_INDEX_DIR + name); + private void handleSqliteTileImport(Uri uri, String name) { + executeImportTask(new SqliteTileImportTask(activity, uri, name)); + } + + private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject> callback) { + if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) { + int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1); + String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY); + handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, callback); + } else { + handleOsmAndSettingsImport(intentUri, fileName, null, -1, callback); } - return app.getAppPath(name); + } + + private void handleOsmAndSettingsImport(Uri uri, String name, String latestChanges, int version, + CallbackWithObject> callback) { + executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback)); + } + + private void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) { + executeImportTask(new XmlImportTask(activity, intentUri, fileName, routingCallback)); } @Nullable @@ -538,36 +317,6 @@ public class ImportHelper { return error; } - @SuppressLint("StaticFieldLeak") - private void handleSqliteTileImport(final Uri uri, final String name) { - AsyncTask sqliteTileImportTask = new BaseImportAsyncTask() { - - @Override - protected String doInBackground(Void... voids) { - return copyFile(app, app.getAppPath(IndexConstants.TILES_INDEX_DIR + name), uri, false); - } - - @Override - protected void onPostExecute(String error) { - hideProgress(); - if (error == null) { - OsmandRasterMapsPlugin plugin = OsmandPlugin.getPlugin(OsmandRasterMapsPlugin.class); - if (plugin != null && !plugin.isActive() && !plugin.needsInstallation()) { - OsmandPlugin.enablePlugin(getMapActivity(), app, plugin, true); - } - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - mapActivity.getMapLayers().selectMapLayer(mapActivity.getMapView(), null, null); - } - Toast.makeText(app, app.getString(R.string.map_imported_successfully), Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(app, app.getString(R.string.map_import_error) + ": " + error, Toast.LENGTH_SHORT).show(); - } - } - }; - executeImportTask(sqliteTileImportTask); - } - public void chooseFileToImport(final ImportType importType, final CallbackWithObject callback) { final MapActivity mapActivity = getMapActivity(); if (mapActivity == null) { @@ -627,255 +376,13 @@ public class ImportHelper { return intent; } - private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject> callback) { - if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) { - int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1); - String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY); - handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, callback); - } else { - handleOsmAndSettingsImport(intentUri, fileName, null, -1, callback); - } - } - - @SuppressLint("StaticFieldLeak") - private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version, - final CallbackWithObject> callback) { - AsyncTask settingsImportTask = new BaseImportAsyncTask() { - - @Override - protected String doInBackground(Void... voids) { - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } - File dest = new File(tempDir, name); - return copyFile(app, dest, uri, true); - } - - @Override - protected void onPostExecute(String error) { - File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); - final File file = new File(tempDir, name); - if (error == null && file.exists()) { - app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { - @Override - public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List items) { - hideProgress(); - if (succeed) { - List pluginIndependentItems = new ArrayList<>(); - List pluginSettingsItems = new ArrayList<>(); - for (SettingsItem item : items) { - if (item instanceof PluginSettingsItem) { - pluginSettingsItems.add((PluginSettingsItem) item); - } else if (Algorithms.isEmpty(item.getPluginId())) { - pluginIndependentItems.add(item); - } - } - for (PluginSettingsItem pluginItem : pluginSettingsItems) { - handlePluginImport(pluginItem, file); - } - if (!pluginIndependentItems.isEmpty()) { - FragmentManager fragmentManager = activity.getSupportFragmentManager(); - ImportSettingsFragment.showInstance(fragmentManager, pluginIndependentItems, file); - } - } else if (empty) { - app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error))); - } - } - }); - } else { - hideProgress(); - app.showShortToastMessage(app.getString(R.string.file_import_error, name, error)); - } - } - }; - executeImportTask(settingsImportTask); - } - - private void handlePluginImport(final PluginSettingsItem pluginItem, final File file) { - final ProgressDialog progress = new ProgressDialog(activity); - progress.setTitle(app.getString(R.string.loading_smth, "")); - progress.setMessage(app.getString(R.string.importing_from, pluginItem.getPublicName(app))); - progress.setIndeterminate(true); - progress.setCancelable(false); - - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.show(); - } - - final SettingsImportListener importListener = new SettingsImportListener() { - @Override - public void onSettingsImportFinished(boolean succeed, @NonNull List items) { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - CustomOsmandPlugin plugin = pluginItem.getPlugin(); - plugin.loadResources(); - - for (SettingsItem item : items) { - if (item instanceof ProfileSettingsItem) { - ((ProfileSettingsItem) item).applyAdditionalPrefs(); - } - } - if (!Algorithms.isEmpty(plugin.getDownloadMaps())) { - app.getDownloadThread().runReloadIndexFilesSilent(); - } - if (!Algorithms.isEmpty(plugin.getRendererNames())) { - app.getRendererRegistry().updateExternalRenderers(); - } - if (!Algorithms.isEmpty(plugin.getRouterNames())) { - loadRoutingFiles(app, null); - } - if (activity != null) { - plugin.onInstall(app, activity); - } - String pluginId = pluginItem.getPluginId(); - File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginId); - app.getSettingsHelper().exportSettings(pluginDir, "items", null, items, false); - } - }; - List pluginItems = new ArrayList<>(pluginItem.getPluginDependentItems()); - pluginItems.add(0, pluginItem); - app.getSettingsHelper().checkDuplicates(file, pluginItems, pluginItems, new CheckDuplicatesListener() { - @Override - public void onDuplicatesChecked(@NonNull List duplicates, List items) { - for (SettingsItem item : items) { - item.setShouldReplace(true); - } - app.getSettingsHelper().importSettings(file, items, "", 1, importListener); - } - }); - } - - @SuppressLint("StaticFieldLeak") - private void handleXmlFileImport(final Uri intentUri, final String fileName, - final CallbackWithObject routingCallback) { - AsyncTask renderingImportTask = new BaseImportAsyncTask() { - - private String destFileName; - private ImportType importType; - - @Override - protected void onPreExecute() { - showProgress(); - destFileName = fileName; - } - - @Override - protected String doInBackground(Void... voids) { - checkImportType(); - if (importType != null) { - File dest = getDestinationFile(); - if (dest != null) { - return copyFile(app, dest, intentUri, true); - } - } - return app.getString(R.string.file_import_error, destFileName, app.getString(R.string.unsupported_type_error)); - } - - @Override - protected void onPostExecute(String error) { - File destDir = getDestinationDir(); - File file = new File(destDir, destFileName); - if (error == null && file.exists()) { - if (importType == ImportType.RENDERING) { - app.getRendererRegistry().updateExternalRenderers(); - app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); - hideProgress(); - } else if (importType == ImportType.ROUTING) { - loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { - @Override - public void onRoutingFilesLoaded() { - hideProgress(); - RoutingConfiguration.Builder builder = app.getCustomRoutingConfig(destFileName); - if (builder != null) { - if (routingCallback != null) { - routingCallback.processResult(builder); - } - app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); - } else { - app.showToastMessage(app.getString(R.string.file_does_not_contain_routing_rules, destFileName)); - } - } - }); - } - } else { - hideProgress(); - app.showShortToastMessage(app.getString(R.string.file_import_error, destFileName, error)); - } - } - - private File getDestinationDir() { - if (importType == ImportType.ROUTING) { - return app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); - } else if (importType == ImportType.RENDERING) { - return app.getAppPath(IndexConstants.RENDERERS_DIR); - } - return null; - } - - private File getDestinationFile() { - File destDir = getDestinationDir(); - if (destDir != null) { - if (!destDir.exists()) { - destDir.mkdirs(); - } - if (importType == ImportType.RENDERING && !destFileName.endsWith(RENDERER_INDEX_EXT)) { - String fileName = Algorithms.getFileNameWithoutExtension(destFileName); - destFileName = fileName + RENDERER_INDEX_EXT; - } - File destFile = new File(destDir, destFileName); - while (destFile.exists()) { - destFileName = AndroidUtils.createNewFileName(destFileName); - destFile = new File(destDir, destFileName); - } - return destFile; - } - return null; - } - - private void checkImportType() { - InputStream is = null; - try { - is = app.getContentResolver().openInputStream(intentUri); - if (is != null) { - XmlPullParser parser = PlatformUtil.newXMLPullParser(); - parser.setInput(is, "UTF-8"); - int tok; - while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) { - if (tok == XmlPullParser.START_TAG) { - String name = parser.getName(); - if ("osmand_routing_config".equals(name)) { - importType = ImportType.ROUTING; - } else if ("renderingStyle".equals(name)) { - importType = ImportType.RENDERING; - } - break; - } - } - Algorithms.closeStream(is); - } - } catch (FileNotFoundException | XmlPullParserException e) { - log.error(e); - } catch (IOException e) { - log.error(e); - } catch (SecurityException e) { - log.error(e.getMessage(), e); - } finally { - Algorithms.closeStream(is); - } - } - }; - executeImportTask(renderingImportTask); - } - - private void handleResult(GPXFile result, String name, boolean save, - boolean useImportDir, boolean forceImportFavourites) { + protected void handleResult(GPXFile result, String name, boolean save, + boolean useImportDir, boolean forceImportFavourites) { handleResult(result, name, save, useImportDir, forceImportFavourites, true); } - private void handleResult(final GPXFile result, final String name, final boolean save, - final boolean useImportDir, boolean forceImportFavourites, boolean showInDetailsActivity) { + protected void handleResult(final GPXFile result, final String name, final boolean save, + final boolean useImportDir, boolean forceImportFavourites, boolean showInDetailsActivity) { if (result != null) { if (result.error != null) { Toast.makeText(activity, result.error.getMessage(), Toast.LENGTH_LONG).show(); @@ -937,7 +444,7 @@ public class ImportHelper { if (useImportDir) { importDir = app.getAppPath(IndexConstants.GPX_IMPORT_DIR); } else { - importDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR); + importDir = app.getAppPath(GPX_INDEX_DIR); } //noinspection ResultOfMethodCallIgnored importDir.mkdirs(); @@ -1058,9 +565,9 @@ public class ImportHelper { } } - private void importGpxOrFavourites(final GPXFile gpxFile, final String fileName, final boolean save, - final boolean useImportDir, final boolean forceImportFavourites, - final boolean forceImportGpx) { + protected void importGpxOrFavourites(final GPXFile gpxFile, final String fileName, final boolean save, + final boolean useImportDir, final boolean forceImportFavourites, + final boolean forceImportGpx) { if (gpxFile == null || gpxFile.isPointsEmpty()) { if (forceImportFavourites) { final DialogInterface.OnClickListener importAsTrackListener = new DialogInterface.OnClickListener() { @@ -1083,11 +590,10 @@ public class ImportHelper { .setPositiveButton(R.string.shared_string_import, importAsTrackListener) .setNegativeButton(R.string.shared_string_cancel, importAsTrackListener) .show(); - return; } else { handleResult(gpxFile, fileName, save, useImportDir, false); - return; } + return; } if (forceImportFavourites) { @@ -1110,7 +616,7 @@ public class ImportHelper { } } - private List asFavourites(final List wptPts, String fileName, boolean forceImportFavourites) { + protected static List asFavourites(OsmandApplication app, List wptPts, String fileName, boolean forceImportFavourites) { final List favourites = new ArrayList<>(); for (WptPt p : wptPts) { if (p.name != null) { @@ -1155,27 +661,4 @@ public class ImportHelper { importTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests); } } - - protected abstract class BaseImportAsyncTask extends AsyncTask { - - protected ProgressDialog progress; - - @Override - protected void onPreExecute() { - showProgress(); - } - - protected void showProgress() { - if (AndroidUtils.isActivityNotDestroyed(activity)) { - String title = app.getString(R.string.loading_smth, ""); - progress = ProgressDialog.show(activity, title, app.getString(R.string.loading_data)); - } - } - - protected void hideProgress() { - if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { - progress.dismiss(); - } - } - } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java new file mode 100644 index 0000000000..38c557e8c7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java @@ -0,0 +1,71 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.plus.helpers.Kml2Gpx; +import net.osmand.util.Algorithms; + +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +class KmlImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private String name; + private boolean save; + private boolean useImportDir; + + public KmlImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, String name, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.name = name; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected GPXFile doInBackground(Void... nothing) { + InputStream is = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + return loadGpxFromKml(is); + } + } catch (FileNotFoundException e) { + // + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + } + return null; + } + + @Override + protected void onPostExecute(GPXFile result) { + hideProgress(); + importHelper.handleResult(result, name, save, useImportDir, false); + } + + protected static GPXFile loadGpxFromKml(@NonNull InputStream is) { + String result = Kml2Gpx.toGpx(is); + if (result != null) { + try { + return GPXUtilities.loadGPXFile(new ByteArrayInputStream(result.getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + return null; + } + } + return null; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java new file mode 100644 index 0000000000..420f4feff4 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java @@ -0,0 +1,67 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.util.Algorithms; + +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX; +import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml; + +class KmzImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private String name; + private boolean save; + private boolean useImportDir; + + public KmzImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, @NonNull String name, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.name = name; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected GPXFile doInBackground(Void... voids) { + InputStream is = null; + ZipInputStream zis = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + zis = new ZipInputStream(is); + + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (entry.getName().endsWith(KML_SUFFIX)) { + return loadGpxFromKml(is); + } + } + } + } catch (Exception e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(zis); + } + return null; + } + + @Override + protected void onPostExecute(GPXUtilities.GPXFile result) { + hideProgress(); + importHelper.handleResult(result, name, save, useImportDir, false); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java new file mode 100644 index 0000000000..e4a82faff9 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/ObfImportTask.java @@ -0,0 +1,52 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.IProgress; +import net.osmand.IndexConstants; +import net.osmand.plus.R; + +import java.io.File; +import java.util.ArrayList; + +class ObfImportTask extends BaseImportAsyncTask { + + private Uri uri; + private String name; + + public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, String name) { + super(activity); + this.uri = uri; + this.name = name; + } + + @Override + protected String doInBackground(Void... voids) { + String error = ImportHelper.copyFile(app, getObfDestFile(name), uri, false); + if (error == null) { + app.getResourceManager().reloadIndexes(IProgress.EMPTY_PROGRESS, new ArrayList()); + app.getDownloadThread().updateLoadedFiles(); + return app.getString(R.string.map_imported_successfully); + } + return app.getString(R.string.map_import_error) + ": " + error; + } + + @Override + protected void onPostExecute(String message) { + hideProgress(); + app.showShortToastMessage(message); + } + + @NonNull + private File getObfDestFile(@NonNull String name) { + if (name.endsWith(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT)) { + return app.getAppPath(IndexConstants.ROADS_INDEX_DIR + name); + } else if (name.endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) { + return app.getAppPath(IndexConstants.WIKI_INDEX_DIR + name); + } + return app.getAppPath(name); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java new file mode 100644 index 0000000000..7800714610 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java @@ -0,0 +1,158 @@ +package net.osmand.plus.importfiles; + +import android.app.ProgressDialog; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + +import net.osmand.AndroidUtils; +import net.osmand.CallbackWithObject; +import net.osmand.IndexConstants; +import net.osmand.plus.CustomOsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener; +import net.osmand.plus.settings.backend.SettingsHelper.PluginSettingsItem; +import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem; +import net.osmand.plus.settings.backend.SettingsHelper.SettingsCollectListener; +import net.osmand.plus.settings.backend.SettingsHelper.SettingsImportListener; +import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; +import net.osmand.plus.settings.fragments.ImportSettingsFragment; +import net.osmand.util.Algorithms; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static net.osmand.IndexConstants.TEMP_DIR; +import static net.osmand.plus.AppInitializer.loadRoutingFiles; + +class SettingsImportTask extends BaseImportAsyncTask { + + private Uri uri; + private String name; + private String latestChanges; + private int version; + private CallbackWithObject> callback; + + public SettingsImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, + @NonNull String name, String latestChanges, int version, + CallbackWithObject> callback) { + super(activity); + this.uri = uri; + this.name = name; + this.latestChanges = latestChanges; + this.version = version; + this.callback = callback; + } + + @Override + protected String doInBackground(Void... voids) { + File tempDir = app.getAppPath(TEMP_DIR); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + File dest = new File(tempDir, name); + return ImportHelper.copyFile(app, dest, uri, true); + } + + @Override + protected void onPostExecute(String error) { + File tempDir = app.getAppPath(TEMP_DIR); + final File file = new File(tempDir, name); + if (error == null && file.exists()) { + app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { + @Override + public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List items) { + hideProgress(); + if (succeed) { + List pluginIndependentItems = new ArrayList<>(); + List pluginSettingsItems = new ArrayList<>(); + for (SettingsItem item : items) { + if (item instanceof PluginSettingsItem) { + pluginSettingsItems.add((PluginSettingsItem) item); + } else if (Algorithms.isEmpty(item.getPluginId())) { + pluginIndependentItems.add(item); + } + } + for (PluginSettingsItem pluginItem : pluginSettingsItems) { + handlePluginImport(pluginItem, file); + } + if (!pluginIndependentItems.isEmpty()) { + FragmentActivity activity = activityRef.get(); + if (activity != null) { + FragmentManager fragmentManager = activity.getSupportFragmentManager(); + ImportSettingsFragment.showInstance(fragmentManager, pluginIndependentItems, file); + } + } + } else if (empty) { + app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error))); + } + } + }); + } else { + hideProgress(); + app.showShortToastMessage(app.getString(R.string.file_import_error, name, error)); + } + } + + private void handlePluginImport(final PluginSettingsItem pluginItem, final File file) { + FragmentActivity activity = activityRef.get(); + final ProgressDialog progress; + if (AndroidUtils.isActivityNotDestroyed(activity)) { + progress = new ProgressDialog(activity); + progress.setTitle(app.getString(R.string.loading_smth, "")); + progress.setMessage(app.getString(R.string.importing_from, pluginItem.getPublicName(app))); + progress.setIndeterminate(true); + progress.setCancelable(false); + progress.show(); + } else { + progress = null; + } + + final SettingsImportListener importListener = new SettingsImportListener() { + @Override + public void onSettingsImportFinished(boolean succeed, @NonNull List items) { + FragmentActivity activity = activityRef.get(); + if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) { + progress.dismiss(); + } + CustomOsmandPlugin plugin = pluginItem.getPlugin(); + plugin.loadResources(); + + for (SettingsItem item : items) { + if (item instanceof ProfileSettingsItem) { + ((ProfileSettingsItem) item).applyAdditionalPrefs(); + } + } + if (!Algorithms.isEmpty(plugin.getDownloadMaps())) { + app.getDownloadThread().runReloadIndexFilesSilent(); + } + if (!Algorithms.isEmpty(plugin.getRendererNames())) { + app.getRendererRegistry().updateExternalRenderers(); + } + if (!Algorithms.isEmpty(plugin.getRouterNames())) { + loadRoutingFiles(app, null); + } + if (activity != null) { + plugin.onInstall(app, activity); + } + String pluginId = pluginItem.getPluginId(); + File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginId); + app.getSettingsHelper().exportSettings(pluginDir, "items", null, items, false); + } + }; + List pluginItems = new ArrayList<>(pluginItem.getPluginDependentItems()); + pluginItems.add(0, pluginItem); + app.getSettingsHelper().checkDuplicates(file, pluginItems, pluginItems, new CheckDuplicatesListener() { + @Override + public void onDuplicatesChecked(@NonNull List duplicates, List items) { + for (SettingsItem item : items) { + item.setShouldReplace(true); + } + app.getSettingsHelper().importSettings(file, items, "", 1, importListener); + } + }); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java new file mode 100644 index 0000000000..d9a177a016 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/SqliteTileImportTask.java @@ -0,0 +1,50 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin; + +import static net.osmand.IndexConstants.TILES_INDEX_DIR; + +class SqliteTileImportTask extends BaseImportAsyncTask { + + private Uri uri; + private String name; + + public SqliteTileImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, @NonNull String name) { + super(activity); + this.uri = uri; + this.name = name; + } + + @Override + protected String doInBackground(Void... voids) { + return ImportHelper.copyFile(app, app.getAppPath(TILES_INDEX_DIR + name), uri, false); + } + + @Override + protected void onPostExecute(String error) { + hideProgress(); + if (error == null) { + FragmentActivity activity = activityRef.get(); + OsmandRasterMapsPlugin plugin = OsmandPlugin.getPlugin(OsmandRasterMapsPlugin.class); + if (plugin != null && !plugin.isActive() && !plugin.needsInstallation()) { + OsmandPlugin.enablePlugin(activity, app, plugin, true); + } + if (activity instanceof MapActivity) { + MapActivity mapActivity = (MapActivity) activity; + mapActivity.getMapLayers().selectMapLayer(mapActivity.getMapView(), null, null); + } + Toast.makeText(app, app.getString(R.string.map_imported_successfully), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(app, app.getString(R.string.map_import_error) + ": " + error, Toast.LENGTH_SHORT).show(); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java new file mode 100644 index 0000000000..bc66d77a76 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java @@ -0,0 +1,149 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.CallbackWithObject; +import net.osmand.IndexConstants; +import net.osmand.PlatformUtil; +import net.osmand.plus.AppInitializer.LoadRoutingFilesCallback; +import net.osmand.plus.R; +import net.osmand.plus.importfiles.ImportHelper.ImportType; +import net.osmand.router.RoutingConfiguration.Builder; +import net.osmand.util.Algorithms; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; +import static net.osmand.plus.AppInitializer.loadRoutingFiles; + +class XmlImportTask extends BaseImportAsyncTask { + + private Uri intentUri; + private String destFileName; + private ImportType importType; + private CallbackWithObject routingCallback; + + public XmlImportTask(@NonNull FragmentActivity activity, @NonNull Uri intentUri, + @NonNull String fileName, @Nullable CallbackWithObject routingCallback) { + super(activity); + this.intentUri = intentUri; + this.destFileName = fileName; + this.routingCallback = routingCallback; + } + + @Override + protected String doInBackground(Void... voids) { + checkImportType(); + if (importType != null) { + File dest = getDestinationFile(); + if (dest != null) { + return ImportHelper.copyFile(app, dest, intentUri, true); + } + } + return app.getString(R.string.file_import_error, destFileName, app.getString(R.string.unsupported_type_error)); + } + + @Override + protected void onPostExecute(String error) { + File destDir = getDestinationDir(); + File file = new File(destDir, destFileName); + if (error == null && file.exists()) { + if (importType == ImportType.RENDERING) { + app.getRendererRegistry().updateExternalRenderers(); + app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); + hideProgress(); + } else if (importType == ImportType.ROUTING) { + loadRoutingFiles(app, new LoadRoutingFilesCallback() { + @Override + public void onRoutingFilesLoaded() { + hideProgress(); + Builder builder = app.getCustomRoutingConfig(destFileName); + if (builder != null) { + if (routingCallback != null) { + routingCallback.processResult(builder); + } + app.showShortToastMessage(app.getString(R.string.file_imported_successfully, destFileName)); + } else { + app.showToastMessage(app.getString(R.string.file_does_not_contain_routing_rules, destFileName)); + } + } + }); + } + } else { + hideProgress(); + app.showShortToastMessage(app.getString(R.string.file_import_error, destFileName, error)); + } + } + + private File getDestinationDir() { + if (importType == ImportType.ROUTING) { + return app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); + } else if (importType == ImportType.RENDERING) { + return app.getAppPath(IndexConstants.RENDERERS_DIR); + } + return null; + } + + private File getDestinationFile() { + File destDir = getDestinationDir(); + if (destDir != null) { + if (!destDir.exists()) { + destDir.mkdirs(); + } + if (importType == ImportType.RENDERING && !destFileName.endsWith(RENDERER_INDEX_EXT)) { + String fileName = Algorithms.getFileNameWithoutExtension(destFileName); + destFileName = fileName + RENDERER_INDEX_EXT; + } + File destFile = new File(destDir, destFileName); + while (destFile.exists()) { + destFileName = AndroidUtils.createNewFileName(destFileName); + destFile = new File(destDir, destFileName); + } + return destFile; + } + return null; + } + + private void checkImportType() { + InputStream is = null; + try { + is = app.getContentResolver().openInputStream(intentUri); + if (is != null) { + XmlPullParser parser = PlatformUtil.newXMLPullParser(); + parser.setInput(is, "UTF-8"); + int tok; + while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) { + if (tok == XmlPullParser.START_TAG) { + String name = parser.getName(); + if ("osmand_routing_config".equals(name)) { + importType = ImportType.ROUTING; + } else if ("renderingStyle".equals(name)) { + importType = ImportType.RENDERING; + } + break; + } + } + Algorithms.closeStream(is); + } + } catch (FileNotFoundException | XmlPullParserException e) { + ImportHelper.log.error(e); + } catch (IOException e) { + ImportHelper.log.error(e); + } catch (SecurityException e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java index b81b015f32..fe02db28b8 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/StartPlanRouteBottomSheet.java @@ -28,8 +28,8 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.helpers.GpxTrackAdapter; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; -import net.osmand.plus.helpers.ImportHelper; -import net.osmand.plus.helpers.ImportHelper.OnGpxImportCompleteListener; +import net.osmand.plus.importfiles.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener; import org.apache.commons.logging.Log; diff --git a/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java b/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java index f310802c44..c77cfbfc0d 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/FavoritesActivity.java @@ -30,8 +30,8 @@ import net.osmand.plus.R; import net.osmand.plus.activities.FavoritesTreeFragment; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.TabActivity; -import net.osmand.plus.helpers.ImportHelper; -import net.osmand.plus.helpers.ImportHelper.OnGpxImportCompleteListener; +import net.osmand.plus.importfiles.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener; import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.controls.PagerSlidingTabStrip; diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java index c7d7ec843c..743c9897ad 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheetDialogFragment.java @@ -40,7 +40,7 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; -import static net.osmand.plus.helpers.ImportHelper.ImportType.ROUTING; +import static net.osmand.plus.importfiles.ImportHelper.ImportType.ROUTING; public class SelectProfileBottomSheetDialogFragment extends BasePreferenceBottomSheet { diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java index ee2bf6b38e..48eba555cb 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/FollowTrackFragment.java @@ -40,8 +40,8 @@ import net.osmand.plus.base.ContextMenuScrollFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; -import net.osmand.plus.helpers.ImportHelper; -import net.osmand.plus.helpers.ImportHelper.OnGpxImportCompleteListener; +import net.osmand.plus.importfiles.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper.OnGpxImportCompleteListener; import net.osmand.plus.measurementtool.GpxData; import net.osmand.plus.measurementtool.GpxData.ActionType; import net.osmand.plus.measurementtool.MeasurementEditingContext; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java index b23edbbea1..c8025bc2d5 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmAndAppCustomization.java @@ -31,7 +31,7 @@ import net.osmand.plus.activities.PluginsActivity; import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.download.DownloadActivity; -import net.osmand.plus.helpers.ImportHelper; +import net.osmand.plus.importfiles.ImportHelper; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.routing.RouteCalculationResult; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java index 6aac50bc9c..2428290517 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java @@ -31,7 +31,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import static net.osmand.plus.helpers.ImportHelper.ImportType.SETTINGS; +import static net.osmand.plus.importfiles.ImportHelper.ImportType.SETTINGS; import static net.osmand.plus.profiles.SelectProfileBottomSheetDialogFragment.DIALOG_TYPE; import static net.osmand.plus.profiles.SelectProfileBottomSheetDialogFragment.IS_PROFILE_IMPORTED_ARG; import static net.osmand.plus.profiles.SelectProfileBottomSheetDialogFragment.PROFILE_KEY_ARG; From 27b235cb39399c855e61f258f608335dff455232 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 7 Oct 2020 03:17:16 +0300 Subject: [PATCH 4/7] Add import with file signature check --- .../main/java/net/osmand/IndexConstants.java | 5 +- .../main/java/net/osmand/util/Algorithms.java | 9 +- .../plus/importfiles/FavoritesImportTask.java | 3 +- .../plus/importfiles/GpxImportTask.java | 2 +- .../GpxOrFavouritesImportTask.java | 2 +- .../osmand/plus/importfiles/ImportHelper.java | 16 ++- .../plus/importfiles/KmlImportTask.java | 2 +- .../plus/importfiles/KmzImportTask.java | 5 +- .../plus/importfiles/ObfImportTask.java | 2 +- .../plus/importfiles/UriImportTask.java | 129 ++++++++++++++++++ 10 files changed, 156 insertions(+), 19 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java diff --git a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java index 93569dfddd..c8ffd2d96b 100644 --- a/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java +++ b/OsmAnd-java/src/main/java/net/osmand/IndexConstants.java @@ -14,7 +14,8 @@ public class IndexConstants { public static final String TEMP_SOURCE_TO_LOAD = "temp"; public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$ - + + public static final String ZIP_EXT = ".zip"; //$NON-NLS-1$ public static final String BINARY_MAP_INDEX_EXT = ".obf"; //$NON-NLS-1$ public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$NON-NLS-1$ @@ -71,7 +72,7 @@ public class IndexConstants { public static final String FONT_INDEX_DIR = "fonts/"; //$NON-NLS-1$ public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$ public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$ - public static final String ROUTING_XML_FILE= "routing.xml"; + public static final String ROUTING_XML_FILE = "routing.xml"; public static final String SETTINGS_DIR = "settings/"; //$NON-NLS-1$ public static final String TEMP_DIR = "temp/"; public static final String ROUTING_PROFILES_DIR = "routing/"; diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index ea2869aaa3..d890d5edea 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -49,6 +49,11 @@ public class Algorithms { private static char[] CHARS_TO_NORMALIZE_KEY = new char['’']; private static char[] CHARS_TO_NORMALIZE_VALUE = new char['\'']; + public static final int ZIP_FILE_SIGNATURE = 0x504b0304; + public static final int XML_FILE_SIGNATURE = 0x3c3f786d; + public static final int OBF_FILE_SIGNATURE = 0x08029001; + public static final int SQLITE_FILE_SIGNATURE = 0x53514C69; + public static String normalizeSearchText(String s) { boolean norm = false; for (int i = 0; i < s.length() && !norm; i++) { @@ -293,7 +298,7 @@ public class Algorithms { FileInputStream in = new FileInputStream(file); int test = readInt(in); in.close(); - return test == 0x504b0304; + return test == ZIP_FILE_SIGNATURE; } /** @@ -322,7 +327,7 @@ public class Algorithms { return false; } - private static int readInt(InputStream in) throws IOException { + public static int readInt(InputStream in) throws IOException { int ch1 = in.read(); int ch2 = in.read(); int ch3 = in.read(); diff --git a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java index 2793e1e0ab..9047baeb59 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/FavoritesImportTask.java @@ -5,7 +5,6 @@ import android.content.Intent; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; -import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.data.FavouritePoint; import net.osmand.plus.FavouritesDbHelper; @@ -45,7 +44,7 @@ class FavoritesImportTask extends BaseImportAsyncTask { } @Override - protected void onPostExecute(GPXUtilities.GPXFile result) { + protected void onPostExecute(GPXFile result) { hideProgress(); FragmentActivity activity = activityRef.get(); if (activity != null) { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java index 1e76f15a26..4a410172a7 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxImportTask.java @@ -52,7 +52,7 @@ class GpxImportTask extends BaseImportAsyncTask { } @Override - protected void onPostExecute(GPXUtilities.GPXFile result) { + protected void onPostExecute(GPXFile result) { hideProgress(); importHelper.handleResult(result, fileName, save, useImportDir, false, showInDetailsActivity); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java index 48eadfb5b1..ed1a16c3b1 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/GpxOrFavouritesImportTask.java @@ -76,7 +76,7 @@ class GpxOrFavouritesImportTask extends BaseImportAsyncTask } @Override - protected void onPostExecute(final GPXUtilities.GPXFile result) { + protected void onPostExecute(GPXFile result) { hideProgress(); importHelper.importGpxOrFavourites(result, fileName, save, useImportDir, forceImportFavourites, forceImportGpx); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index f5b47604ac..d8bca201b4 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -20,7 +20,6 @@ import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; -import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint.BackgroundType; @@ -55,6 +54,7 @@ import java.util.Locale; import static android.app.Activity.RESULT_OK; import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; import static net.osmand.IndexConstants.GPX_FILE_EXT; +import static net.osmand.IndexConstants.GPX_IMPORT_DIR; import static net.osmand.IndexConstants.GPX_INDEX_DIR; import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; @@ -176,7 +176,7 @@ public class ImportHelper { boolean saveFile = !isFileIntent || !isOsmandSubdir; if (fileName == null) { - handleGpxOrFavouritesImport(intentUri, fileName, saveFile, useImportDir, false, false); + handleUriImport(intentUri, saveFile, useImportDir); } else if (fileName.endsWith(KML_SUFFIX)) { handleKmlImport(intentUri, fileName, saveFile, useImportDir); } else if (fileName.endsWith(KMZ_SUFFIX)) { @@ -243,11 +243,11 @@ public class ImportHelper { executeImportTask(new KmlImportTask(this, activity, kmlFile, name, save, useImportDir)); } - private void handleObfImport(Uri obfFile, String name) { + protected void handleObfImport(Uri obfFile, String name) { executeImportTask(new ObfImportTask(activity, obfFile, name)); } - private void handleSqliteTileImport(Uri uri, String name) { + protected void handleSqliteTileImport(Uri uri, String name) { executeImportTask(new SqliteTileImportTask(activity, uri, name)); } @@ -266,10 +266,14 @@ public class ImportHelper { executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback)); } - private void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) { + protected void handleXmlFileImport(Uri intentUri, String fileName, CallbackWithObject routingCallback) { executeImportTask(new XmlImportTask(activity, intentUri, fileName, routingCallback)); } + private void handleUriImport(Uri uri, boolean save, boolean useImportDir) { + executeImportTask(new UriImportTask(this, activity, uri, save, useImportDir)); + } + @Nullable public static String copyFile(OsmandApplication app, @NonNull File dest, @NonNull Uri uri, boolean overwrite) { if (dest.exists() && !overwrite) { @@ -442,7 +446,7 @@ public class ImportHelper { } else { final File importDir; if (useImportDir) { - importDir = app.getAppPath(IndexConstants.GPX_IMPORT_DIR); + importDir = app.getAppPath(GPX_IMPORT_DIR); } else { importDir = app.getAppPath(GPX_INDEX_DIR); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java index 38c557e8c7..8d48485b33 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmlImportTask.java @@ -15,7 +15,7 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.io.UnsupportedEncodingException; -class KmlImportTask extends BaseImportAsyncTask { +class KmlImportTask extends BaseImportAsyncTask { private ImportHelper importHelper; private Uri uri; diff --git a/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java index 420f4feff4..41d01be264 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/KmzImportTask.java @@ -5,7 +5,6 @@ import android.net.Uri; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; -import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.util.Algorithms; @@ -16,7 +15,7 @@ import java.util.zip.ZipInputStream; import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX; import static net.osmand.plus.importfiles.KmlImportTask.loadGpxFromKml; -class KmzImportTask extends BaseImportAsyncTask { +class KmzImportTask extends BaseImportAsyncTask { private ImportHelper importHelper; private Uri uri; @@ -60,7 +59,7 @@ class KmzImportTask extends BaseImportAsyncTask { private Uri uri; private String name; - public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, String name) { + public ObfImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, @NonNull String name) { super(activity); this.uri = uri; this.name = name; diff --git a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java new file mode 100644 index 0000000000..0bc9909643 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java @@ -0,0 +1,129 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.plus.R; +import net.osmand.util.Algorithms; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import static net.osmand.FileUtils.createUniqueFileName; +import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; +import static net.osmand.IndexConstants.MAPS_PATH; +import static net.osmand.IndexConstants.ROUTING_FILE_EXT; +import static net.osmand.IndexConstants.SQLITE_EXT; +import static net.osmand.IndexConstants.TEMP_DIR; +import static net.osmand.IndexConstants.TILES_INDEX_DIR; +import static net.osmand.IndexConstants.ZIP_EXT; +import static net.osmand.util.Algorithms.OBF_FILE_SIGNATURE; +import static net.osmand.util.Algorithms.SQLITE_FILE_SIGNATURE; +import static net.osmand.util.Algorithms.XML_FILE_SIGNATURE; +import static net.osmand.util.Algorithms.ZIP_FILE_SIGNATURE; + +class UriImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private String tempFileName; + + private int fileSignature; + + private boolean save; + private boolean useImportDir; + + public UriImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected String doInBackground(Void... nothing) { + String error = null; + InputStream is = null; + OutputStream out = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + fileSignature = Algorithms.readInt(is); + if (isSupportedFileSignature()) { + File tempDir = app.getAppPath(TEMP_DIR); + if (!tempDir.exists()) { + tempDir.mkdirs(); + } + tempFileName = getTempFileName(); + File dest = new File(tempDir, tempFileName); + + out = new FileOutputStream(dest); + Algorithms.writeInt(out, Integer.reverseBytes(fileSignature)); + Algorithms.streamCopy(is, out); + } + } + } catch (FileNotFoundException e) { + ImportHelper.log.error(e); + error = e.getMessage(); + } catch (SecurityException e) { + ImportHelper.log.error(e); + error = e.getMessage(); + } catch (IOException e) { + ImportHelper.log.error(e); + error = e.getMessage(); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(out); + } + return error; + } + + private boolean isSupportedFileSignature() { + return fileSignature == XML_FILE_SIGNATURE || fileSignature == OBF_FILE_SIGNATURE + || fileSignature == ZIP_FILE_SIGNATURE || fileSignature == SQLITE_FILE_SIGNATURE; + } + + @Override + protected void onPostExecute(String error) { + hideProgress(); + File file = app.getAppPath(TEMP_DIR + tempFileName); + if (error == null && file.exists()) { + Uri tempUri = AndroidUtils.getUriForFile(app, file); + if (XML_FILE_SIGNATURE == fileSignature) { + importHelper.handleXmlFileImport(tempUri, null, null); + } else if (OBF_FILE_SIGNATURE == fileSignature) { + String name = createUniqueFileName(app, "map", MAPS_PATH, BINARY_MAP_INDEX_EXT); + importHelper.handleObfImport(tempUri, name); + } else if (ZIP_FILE_SIGNATURE == fileSignature) { +// importHelper.handleKmzImport(tempUri, null, save, useImportDir); + } else if (SQLITE_FILE_SIGNATURE == fileSignature) { + String name = createUniqueFileName(app, "online_map", TILES_INDEX_DIR, SQLITE_EXT); + importHelper.handleSqliteTileImport(tempUri, name); + } + } else { + app.showShortToastMessage(app.getString(R.string.file_import_error, tempFileName, error)); + } + } + + private String getTempFileName() { + if (XML_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "xml_file", TEMP_DIR, ROUTING_FILE_EXT); + } else if (OBF_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "map", TEMP_DIR, BINARY_MAP_INDEX_EXT); + } else if (ZIP_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "zip_file", TEMP_DIR, ZIP_EXT); + } else if (SQLITE_FILE_SIGNATURE == fileSignature) { + return createUniqueFileName(app, "online_map", TEMP_DIR, SQLITE_EXT); + } + return ""; + } +} \ No newline at end of file From fea6b424ca3b4ede41e432fe45848c13d3659699 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 7 Oct 2020 04:06:52 +0300 Subject: [PATCH 5/7] Add xml files import after check for file signature --- .../osmand/plus/importfiles/ImportHelper.java | 8 ++++--- .../plus/importfiles/UriImportTask.java | 10 +++++++- .../plus/importfiles/XmlImportTask.java | 23 ++++++++++++------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index d8bca201b4..62e0f1dbd0 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -87,7 +87,9 @@ public class ImportHelper { public enum ImportType { SETTINGS(OSMAND_SETTINGS_FILE_EXT), ROUTING(ROUTING_FILE_EXT), - RENDERING(RENDERER_INDEX_EXT); + RENDERING(RENDERER_INDEX_EXT), + GPX(GPX_FILE_EXT), + KML(KML_SUFFIX); ImportType(String extension) { this.extension = extension; @@ -226,8 +228,8 @@ public class ImportHelper { executeImportTask(new GpxImportTask(this, activity, gpxFile, fileName, save, useImportDir, showInDetailsActivity)); } - private void handleGpxOrFavouritesImport(Uri fileUri, String fileName, boolean save, boolean useImportDir, - boolean forceImportFavourites, boolean forceImportGpx) { + protected void handleGpxOrFavouritesImport(Uri fileUri, String fileName, boolean save, boolean useImportDir, + boolean forceImportFavourites, boolean forceImportGpx) { executeImportTask(new GpxOrFavouritesImportTask(this, activity, fileUri, fileName, save, useImportDir, forceImportFavourites, forceImportGpx)); } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java index 0bc9909643..27b4a0fa73 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java @@ -7,6 +7,7 @@ import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.plus.R; +import net.osmand.plus.importfiles.ImportHelper.ImportType; import net.osmand.util.Algorithms; import java.io.File; @@ -19,6 +20,7 @@ import java.io.OutputStream; import static net.osmand.FileUtils.createUniqueFileName; import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT; import static net.osmand.IndexConstants.MAPS_PATH; +import static net.osmand.IndexConstants.RENDERER_INDEX_EXT; import static net.osmand.IndexConstants.ROUTING_FILE_EXT; import static net.osmand.IndexConstants.SQLITE_EXT; import static net.osmand.IndexConstants.TEMP_DIR; @@ -99,7 +101,13 @@ class UriImportTask extends BaseImportAsyncTask { if (error == null && file.exists()) { Uri tempUri = AndroidUtils.getUriForFile(app, file); if (XML_FILE_SIGNATURE == fileSignature) { - importHelper.handleXmlFileImport(tempUri, null, null); + ImportType importType = XmlImportTask.checkImportType(app, tempUri); + if (importType == ImportType.RENDERING || importType == ImportType.ROUTING) { + String name = importType == ImportType.RENDERING ? "renderer" + RENDERER_INDEX_EXT : "router" + ROUTING_FILE_EXT; + importHelper.handleXmlFileImport(tempUri, name, null); + } else if (importType == ImportType.GPX || importType == ImportType.KML) { + importHelper.handleGpxOrFavouritesImport(tempUri, tempFileName, save, useImportDir, false, false); + } } else if (OBF_FILE_SIGNATURE == fileSignature) { String name = createUniqueFileName(app, "map", MAPS_PATH, BINARY_MAP_INDEX_EXT); importHelper.handleObfImport(tempUri, name); diff --git a/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java index bc66d77a76..6d45466bab 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/XmlImportTask.java @@ -11,6 +11,7 @@ import net.osmand.CallbackWithObject; import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.plus.AppInitializer.LoadRoutingFilesCallback; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.importfiles.ImportHelper.ImportType; import net.osmand.router.RoutingConfiguration.Builder; @@ -29,26 +30,26 @@ import static net.osmand.plus.AppInitializer.loadRoutingFiles; class XmlImportTask extends BaseImportAsyncTask { - private Uri intentUri; + private Uri uri; private String destFileName; private ImportType importType; private CallbackWithObject routingCallback; - public XmlImportTask(@NonNull FragmentActivity activity, @NonNull Uri intentUri, - @NonNull String fileName, @Nullable CallbackWithObject routingCallback) { + public XmlImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, + @NonNull String fileName, @Nullable CallbackWithObject routingCallback) { super(activity); - this.intentUri = intentUri; + this.uri = uri; this.destFileName = fileName; this.routingCallback = routingCallback; } @Override protected String doInBackground(Void... voids) { - checkImportType(); + importType = checkImportType(app, uri); if (importType != null) { File dest = getDestinationFile(); if (dest != null) { - return ImportHelper.copyFile(app, dest, intentUri, true); + return ImportHelper.copyFile(app, dest, uri, true); } } return app.getString(R.string.file_import_error, destFileName, app.getString(R.string.unsupported_type_error)); @@ -115,10 +116,11 @@ class XmlImportTask extends BaseImportAsyncTask { return null; } - private void checkImportType() { + protected static ImportType checkImportType(OsmandApplication app, Uri uri) { + ImportType importType = null; InputStream is = null; try { - is = app.getContentResolver().openInputStream(intentUri); + is = app.getContentResolver().openInputStream(uri); if (is != null) { XmlPullParser parser = PlatformUtil.newXMLPullParser(); parser.setInput(is, "UTF-8"); @@ -130,6 +132,10 @@ class XmlImportTask extends BaseImportAsyncTask { importType = ImportType.ROUTING; } else if ("renderingStyle".equals(name)) { importType = ImportType.RENDERING; + } else if ("gpx".equals(name)) { + importType = ImportType.GPX; + } else if ("kml".equals(name)) { + importType = ImportType.KML; } break; } @@ -145,5 +151,6 @@ class XmlImportTask extends BaseImportAsyncTask { } finally { Algorithms.closeStream(is); } + return importType; } } \ No newline at end of file From 62c119731978546079d97595b3de7ddf78ebcbd5 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 7 Oct 2020 05:23:02 +0300 Subject: [PATCH 6/7] Add zip files import with check for file signature --- .../osmand/plus/importfiles/ImportHelper.java | 13 ++- .../plus/importfiles/UriImportTask.java | 14 +-- .../plus/importfiles/ZipImportTask.java | 90 +++++++++++++++++++ 3 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java index 62e0f1dbd0..c67ae8834e 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/ImportHelper.java @@ -89,7 +89,8 @@ public class ImportHelper { ROUTING(ROUTING_FILE_EXT), RENDERING(RENDERER_INDEX_EXT), GPX(GPX_FILE_EXT), - KML(KML_SUFFIX); + KML(KML_SUFFIX), + KMZ(KMZ_SUFFIX); ImportType(String extension) { this.extension = extension; @@ -237,7 +238,7 @@ public class ImportHelper { executeImportTask(new FavoritesImportTask(activity, gpxFile, fileName, forceImportFavourites)); } - private void handleKmzImport(Uri kmzFile, String name, boolean save, boolean useImportDir) { + protected void handleKmzImport(Uri kmzFile, String name, boolean save, boolean useImportDir) { executeImportTask(new KmzImportTask(this, activity, kmzFile, name, save, useImportDir)); } @@ -263,8 +264,8 @@ public class ImportHelper { } } - private void handleOsmAndSettingsImport(Uri uri, String name, String latestChanges, int version, - CallbackWithObject> callback) { + protected void handleOsmAndSettingsImport(Uri uri, String name, String latestChanges, int version, + CallbackWithObject> callback) { executeImportTask(new SettingsImportTask(activity, uri, name, latestChanges, version, callback)); } @@ -276,6 +277,10 @@ public class ImportHelper { executeImportTask(new UriImportTask(this, activity, uri, save, useImportDir)); } + protected void handleZipImport(Uri uri, boolean save, boolean useImportDir) { + executeImportTask(new ZipImportTask(this, activity, uri, save, useImportDir)); + } + @Nullable public static String copyFile(OsmandApplication app, @NonNull File dest, @NonNull Uri uri, boolean overwrite) { if (dest.exists() && !overwrite) { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java index 27b4a0fa73..c2de2d072f 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java @@ -110,12 +110,12 @@ class UriImportTask extends BaseImportAsyncTask { } } else if (OBF_FILE_SIGNATURE == fileSignature) { String name = createUniqueFileName(app, "map", MAPS_PATH, BINARY_MAP_INDEX_EXT); - importHelper.handleObfImport(tempUri, name); + importHelper.handleObfImport(tempUri, name + BINARY_MAP_INDEX_EXT); } else if (ZIP_FILE_SIGNATURE == fileSignature) { -// importHelper.handleKmzImport(tempUri, null, save, useImportDir); + importHelper.handleZipImport(tempUri, save, useImportDir); } else if (SQLITE_FILE_SIGNATURE == fileSignature) { String name = createUniqueFileName(app, "online_map", TILES_INDEX_DIR, SQLITE_EXT); - importHelper.handleSqliteTileImport(tempUri, name); + importHelper.handleSqliteTileImport(tempUri, name + SQLITE_EXT); } } else { app.showShortToastMessage(app.getString(R.string.file_import_error, tempFileName, error)); @@ -124,13 +124,13 @@ class UriImportTask extends BaseImportAsyncTask { private String getTempFileName() { if (XML_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "xml_file", TEMP_DIR, ROUTING_FILE_EXT); + return createUniqueFileName(app, "xml_file", TEMP_DIR, ROUTING_FILE_EXT) + ROUTING_FILE_EXT; } else if (OBF_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "map", TEMP_DIR, BINARY_MAP_INDEX_EXT); + return createUniqueFileName(app, "map", TEMP_DIR, BINARY_MAP_INDEX_EXT) + BINARY_MAP_INDEX_EXT; } else if (ZIP_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "zip_file", TEMP_DIR, ZIP_EXT); + return createUniqueFileName(app, "zip_file", TEMP_DIR, ZIP_EXT) + ZIP_EXT; } else if (SQLITE_FILE_SIGNATURE == fileSignature) { - return createUniqueFileName(app, "online_map", TEMP_DIR, SQLITE_EXT); + return createUniqueFileName(app, "online_map", TEMP_DIR, SQLITE_EXT) + SQLITE_EXT; } return ""; } diff --git a/OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java new file mode 100644 index 0000000000..3704f2192b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/importfiles/ZipImportTask.java @@ -0,0 +1,90 @@ +package net.osmand.plus.importfiles; + +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import net.osmand.plus.importfiles.ImportHelper.ImportType; +import net.osmand.util.Algorithms; + +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import static net.osmand.FileUtils.createUniqueFileName; +import static net.osmand.IndexConstants.GPX_FILE_EXT; +import static net.osmand.IndexConstants.GPX_IMPORT_DIR; +import static net.osmand.IndexConstants.GPX_INDEX_DIR; +import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT; +import static net.osmand.IndexConstants.TEMP_DIR; +import static net.osmand.plus.importfiles.ImportHelper.KML_SUFFIX; + +public class ZipImportTask extends BaseImportAsyncTask { + + private ImportHelper importHelper; + private Uri uri; + private boolean save; + private boolean useImportDir; + + public ZipImportTask(@NonNull ImportHelper importHelper, @NonNull FragmentActivity activity, + @NonNull Uri uri, boolean save, boolean useImportDir) { + super(activity); + this.importHelper = importHelper; + this.uri = uri; + this.save = save; + this.useImportDir = useImportDir; + } + + @Override + protected ImportType doInBackground(Void... voids) { + ImportType importType = null; + InputStream is = null; + ZipInputStream zis = null; + try { + is = app.getContentResolver().openInputStream(uri); + if (is != null) { + zis = new ZipInputStream(is); + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + String fileName = checkEntryName(entry.getName()); + if (fileName.endsWith(KML_SUFFIX)) { + importType = ImportType.KMZ; + break; + } else if (fileName.equals("items.json")) { + importType = ImportType.SETTINGS; + break; + } + } + } + } catch (Exception e) { + ImportHelper.log.error(e.getMessage(), e); + } finally { + Algorithms.closeStream(is); + Algorithms.closeStream(zis); + } + return importType; + } + + private String checkEntryName(String entryName) { + String fileExt = OSMAND_SETTINGS_FILE_EXT + "/"; + int index = entryName.indexOf(fileExt); + if (index != -1) { + entryName = entryName.substring(index + fileExt.length()); + } + return entryName; + } + + @Override + protected void onPostExecute(ImportType importType) { + hideProgress(); + if (importType == ImportType.KMZ) { + String dir = useImportDir ? GPX_IMPORT_DIR : GPX_INDEX_DIR; + String name = createUniqueFileName(app, "track", dir, GPX_FILE_EXT); + importHelper.handleKmzImport(uri, name + GPX_FILE_EXT, save, useImportDir); + } else if (importType == ImportType.SETTINGS) { + String name = createUniqueFileName(app, "settings", TEMP_DIR, OSMAND_SETTINGS_FILE_EXT); + importHelper.handleOsmAndSettingsImport(uri, name + OSMAND_SETTINGS_FILE_EXT, null, -1, null); + } + } +} \ No newline at end of file From 13a17d3a5b2fd78bd1c36aa0091a77cc8df9eb1a Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 9 Oct 2020 14:16:25 +0300 Subject: [PATCH 7/7] Fix merging import helper --- .../plus/importfiles/SettingsImportTask.java | 13 ++- .../plus/importfiles/UriImportTask.java | 6 +- .../plus/settings/backend/SettingsHelper.java | 83 +++++++++++++++++++ .../fragments/ImportCompleteFragment.java | 8 +- .../fragments/ImportSettingsFragment.java | 17 ++-- 5 files changed, 102 insertions(+), 25 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java index 7800714610..55135832e5 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/SettingsImportTask.java @@ -9,6 +9,7 @@ import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; +import net.osmand.FileUtils; import net.osmand.IndexConstants; import net.osmand.plus.CustomOsmandPlugin; import net.osmand.plus.R; @@ -25,7 +26,6 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -import static net.osmand.IndexConstants.TEMP_DIR; import static net.osmand.plus.AppInitializer.loadRoutingFiles; class SettingsImportTask extends BaseImportAsyncTask { @@ -37,8 +37,8 @@ class SettingsImportTask extends BaseImportAsyncTask { private CallbackWithObject> callback; public SettingsImportTask(@NonNull FragmentActivity activity, @NonNull Uri uri, - @NonNull String name, String latestChanges, int version, - CallbackWithObject> callback) { + @NonNull String name, String latestChanges, int version, + CallbackWithObject> callback) { super(activity); this.uri = uri; this.name = name; @@ -49,17 +49,14 @@ class SettingsImportTask extends BaseImportAsyncTask { @Override protected String doInBackground(Void... voids) { - File tempDir = app.getAppPath(TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } + File tempDir = FileUtils.getTempDir(app); File dest = new File(tempDir, name); return ImportHelper.copyFile(app, dest, uri, true); } @Override protected void onPostExecute(String error) { - File tempDir = app.getAppPath(TEMP_DIR); + File tempDir = FileUtils.getTempDir(app); final File file = new File(tempDir, name); if (error == null && file.exists()) { app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() { diff --git a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java index c2de2d072f..90c4ac9e8e 100644 --- a/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java +++ b/OsmAnd/src/net/osmand/plus/importfiles/UriImportTask.java @@ -6,6 +6,7 @@ import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; +import net.osmand.FileUtils; import net.osmand.plus.R; import net.osmand.plus.importfiles.ImportHelper.ImportType; import net.osmand.util.Algorithms; @@ -61,10 +62,7 @@ class UriImportTask extends BaseImportAsyncTask { if (is != null) { fileSignature = Algorithms.readInt(is); if (isSupportedFileSignature()) { - File tempDir = app.getAppPath(TEMP_DIR); - if (!tempDir.exists()) { - tempDir.mkdirs(); - } + File tempDir = FileUtils.getTempDir(app); tempFileName = getTempFileName(); File dest = new File(tempDir, tempFileName); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java index 60a411121a..a708f92a46 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/SettingsHelper.java @@ -2637,6 +2637,89 @@ public class SettingsHelper { } } + public static Map> getSettingsToOperate(List settingsItems, boolean importComplete) { + Map> settingsToOperate = new HashMap<>(); + List profiles = new ArrayList<>(); + List quickActions = new ArrayList<>(); + List poiUIFilters = new ArrayList<>(); + List tileSourceTemplates = new ArrayList<>(); + List routingFilesList = new ArrayList<>(); + List renderFilesList = new ArrayList<>(); + List avoidRoads = new ArrayList<>(); + for (SettingsItem item : settingsItems) { + switch (item.getType()) { + case PROFILE: + profiles.add(((ProfileSettingsItem) item).getModeBean()); + break; + case FILE: + FileSettingsItem fileItem = (FileSettingsItem) item; + if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.RENDERING_STYLE) { + renderFilesList.add(fileItem.getFile()); + } else if (fileItem.getSubtype() == FileSettingsItem.FileSubtype.ROUTING_CONFIG) { + routingFilesList.add(fileItem.getFile()); + } + break; + case QUICK_ACTIONS: + QuickActionsSettingsItem quickActionsItem = (QuickActionsSettingsItem) item; + if (importComplete) { + quickActions.addAll(quickActionsItem.getAppliedItems()); + } else { + quickActions.addAll(quickActionsItem.getItems()); + } + break; + case POI_UI_FILTERS: + PoiUiFiltersSettingsItem poiUiFilterItem = (PoiUiFiltersSettingsItem) item; + if (importComplete) { + poiUIFilters.addAll(poiUiFilterItem.getAppliedItems()); + } else { + poiUIFilters.addAll(poiUiFilterItem.getItems()); + } + break; + case MAP_SOURCES: + MapSourcesSettingsItem mapSourcesItem = (MapSourcesSettingsItem) item; + if (importComplete) { + tileSourceTemplates.addAll(mapSourcesItem.getAppliedItems()); + } else { + tileSourceTemplates.addAll(mapSourcesItem.getItems()); + } + break; + case AVOID_ROADS: + AvoidRoadsSettingsItem avoidRoadsItem = (AvoidRoadsSettingsItem) item; + if (importComplete) { + avoidRoads.addAll(avoidRoadsItem.getAppliedItems()); + } else { + avoidRoads.addAll(avoidRoadsItem.getItems()); + } + break; + default: + break; + } + } + + if (!profiles.isEmpty()) { + settingsToOperate.put(ExportSettingsType.PROFILE, profiles); + } + if (!quickActions.isEmpty()) { + settingsToOperate.put(ExportSettingsType.QUICK_ACTIONS, quickActions); + } + if (!poiUIFilters.isEmpty()) { + settingsToOperate.put(ExportSettingsType.POI_TYPES, poiUIFilters); + } + if (!tileSourceTemplates.isEmpty()) { + settingsToOperate.put(ExportSettingsType.MAP_SOURCES, tileSourceTemplates); + } + if (!renderFilesList.isEmpty()) { + settingsToOperate.put(ExportSettingsType.CUSTOM_RENDER_STYLE, renderFilesList); + } + if (!routingFilesList.isEmpty()) { + settingsToOperate.put(ExportSettingsType.CUSTOM_ROUTING, routingFilesList); + } + if (!avoidRoads.isEmpty()) { + settingsToOperate.put(ExportSettingsType.AVOID_ROADS, avoidRoads); + } + return settingsToOperate; + } + @SuppressLint("StaticFieldLeak") public class ImportAsyncTask extends AsyncTask> { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java index e152d5ea68..a8e7acc8e3 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportCompleteFragment.java @@ -22,9 +22,6 @@ import androidx.recyclerview.widget.RecyclerView; import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.helpers.ImportHelper; -import net.osmand.plus.settings.backend.ExportSettingsType; -import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; @@ -33,6 +30,9 @@ import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment; import net.osmand.plus.quickaction.QuickActionListFragment; import net.osmand.plus.routepreparationmenu.AvoidRoadsBottomSheetDialogFragment; import net.osmand.plus.search.QuickSearchDialogFragment; +import net.osmand.plus.settings.backend.ExportSettingsType; +import net.osmand.plus.settings.backend.SettingsHelper; +import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; import java.util.List; @@ -118,7 +118,7 @@ public class ImportCompleteFragment extends BaseOsmAndFragment { if (settingsItems != null) { ImportedSettingsItemsAdapter adapter = new ImportedSettingsItemsAdapter( app, - ImportHelper.getSettingsToOperate(settingsItems, true), + SettingsHelper.getSettingsToOperate(settingsItems, true), nightMode, new ImportedSettingsItemsAdapter.OnItemClickListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java index 7e8f6bb934..dd02f3f716 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ImportSettingsFragment.java @@ -34,8 +34,14 @@ import net.osmand.plus.AppInitializer; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.SQLiteTileSource; -import net.osmand.plus.settings.backend.ExportSettingsType; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; +import net.osmand.plus.poi.PoiUIFilter; +import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean; +import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.SettingsHelper; import net.osmand.plus.settings.backend.SettingsHelper.AvoidRoadsSettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.FileSettingsItem; @@ -47,12 +53,6 @@ import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.QuickActionsSettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem; import net.osmand.plus.settings.backend.SettingsHelper.SettingsItemType; -import net.osmand.plus.UiUtilities; -import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; -import net.osmand.plus.poi.PoiUIFilter; -import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; @@ -64,7 +64,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import static net.osmand.plus.helpers.ImportHelper.getSettingsToOperate; public class ImportSettingsFragment extends BaseOsmAndFragment implements View.OnClickListener { @@ -183,7 +182,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment adapter = new ExportImportSettingsAdapter(app, nightMode, true); Map> itemsMap = new HashMap<>(); if (settingsItems != null) { - itemsMap = getSettingsToOperate(settingsItems, false); + itemsMap = SettingsHelper.getSettingsToOperate(settingsItems, false); adapter.updateSettingsList(itemsMap); } expandableList.setAdapter(adapter);