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