summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorH. Lehmann <ByteHamster@users.noreply.github.com>2020-01-30 10:38:11 +0100
committerGitHub <noreply@github.com>2020-01-30 10:38:11 +0100
commita0491bd67e29a2a73db490e56075e4a8bedb43ba (patch)
tree150750d7558026015f0a7fba0cdbfd22895b3754 /core
parent8ed2102c85571efd2562a50c4cfedc0b2eb09459 (diff)
parent20d6838e5b0f39ab07ddae98994fd3e30404e454 (diff)
downloadAntennaPod-a0491bd67e29a2a73db490e56075e4a8bedb43ba.zip
Merge pull request #3794 from ByteHamster/import-export-settings
Import export settings
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java95
-rw-r--r--core/src/main/res/values/strings.xml31
2 files changed, 110 insertions, 16 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
new file mode 100644
index 000000000..af3d1206c
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java
@@ -0,0 +1,95 @@
+package de.danoeh.antennapod.core.storage;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+import de.danoeh.antennapod.core.R;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+
+public class DatabaseExporter {
+ private static final String TAG = "DatabaseExporter";
+ private static final byte[] SQLITE3_MAGIC = "SQLite format 3\0".getBytes();
+
+ public static boolean validateDB(Uri inputUri, Context context) throws IOException {
+ try (InputStream inputStream = context.getContentResolver().openInputStream(inputUri)) {
+ byte[] magicBuf = new byte[SQLITE3_MAGIC.length];
+ if (inputStream.read(magicBuf) == magicBuf.length) {
+ return Arrays.equals(SQLITE3_MAGIC, magicBuf);
+ }
+ }
+ return false;
+ }
+
+ public static void exportToDocument(Uri uri, Context context) throws IOException {
+ ParcelFileDescriptor pfd = null;
+ FileOutputStream fileOutputStream = null;
+ try {
+ pfd = context.getContentResolver().openFileDescriptor(uri, "w");
+ fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
+ exportToStream(fileOutputStream, context);
+ } catch (IOException e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ throw e;
+ } finally {
+ IOUtils.closeQuietly(fileOutputStream);
+
+ if (pfd != null) {
+ try {
+ pfd.close();
+ } catch (IOException e) {
+ Log.d(TAG, "Unable to close ParcelFileDescriptor");
+ }
+ }
+ }
+ }
+
+ public static void exportToStream(FileOutputStream outFileStream, Context context) throws IOException {
+ FileChannel src = null;
+ FileChannel dst = null;
+ try {
+ File currentDB = context.getDatabasePath(PodDBAdapter.DATABASE_NAME);
+
+ if (currentDB.exists()) {
+ src = new FileInputStream(currentDB).getChannel();
+ dst = outFileStream.getChannel();
+ dst.transferFrom(src, 0, src.size());
+ } else {
+ throw new IOException("Can not access current database");
+ }
+ } catch (IOException e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ throw e;
+ } finally {
+ IOUtils.closeQuietly(src);
+ IOUtils.closeQuietly(dst);
+ }
+ }
+
+ public static void importBackup(Uri inputUri, Context context) throws IOException {
+ InputStream inputStream = null;
+ try {
+ if (!validateDB(inputUri, context)) {
+ throw new IOException(context.getString(R.string.import_bad_file));
+ }
+
+ File currentDB = context.getDatabasePath(PodDBAdapter.DATABASE_NAME);
+ inputStream = context.getContentResolver().openInputStream(inputUri);
+ FileUtils.copyInputStreamToFile(inputStream, currentDB);
+ } catch (IOException e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ throw e;
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+}
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 88fa07049..d2774ac7a 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -544,24 +544,32 @@
<string name="found_in_title_label">Found in title</string>
<string name="no_results_for_query">No results were found for \"%1$s\"</string>
- <!-- OPML import and export -->
- <string name="opml_import_option">Option %1$d</string>
- <string name="opml_import_explanation_1">Choose a specific file path from the local filesystem.</string>
- <string name="opml_import_explanation_3">Many applications like Google Mail, Dropbox, Google Drive and most file managers can <i>open</i> OPML files <i>with</i> AntennaPod.</string>
+ <!-- import and export -->
+ <string name="import_export_summary">Move subscriptions and queue to another device</string>
+ <string name="database">Database</string>
+ <string name="opml">OPML</string>
+ <string name="html">HTML</string>
+ <string name="html_export_summary">Show your subscriptions to a friend</string>
+ <string name="opml_export_summary">Transfer your subscriptions to another podcast app</string>
+ <string name="opml_import_summary">Import your subscriptions from another podcast app</string>
+ <string name="database_export_summary">Transfer subscriptions, listened episodes and queue to AntennaPod on another device</string>
+ <string name="database_import_summary">Import AntennaPod database from another device</string>
<string name="opml_import_label">OPML Import</string>
- <string name="reading_opml_label">Reading OPML file</string>
<string name="opml_reader_error">An error has occurred while reading the OPML document:</string>
<string name="opml_import_error_no_file">No file selected!</string>
<string name="select_all_label">Select all</string>
<string name="deselect_all_label">Deselect all</string>
- <string name="choose_file_from_filesystem">From local filesystem</string>
<string name="opml_export_label">OPML export</string>
<string name="html_export_label">HTML export</string>
- <string name="exporting_label">Exporting&#8230;</string>
+ <string name="database_export_label">Database export</string>
+ <string name="database_import_label">Database import</string>
+ <string name="please_wait">Please wait&#8230;</string>
<string name="export_error_label">Export error</string>
<string name="export_success_title">Export successful</string>
<string name="export_success_sum">The exported file was written to:\n\n%1$s</string>
<string name="opml_import_ask_read_permission">Access to external storage is required to read the OPML file</string>
+ <string name="import_select_file">Select file to import</string>
+ <string name="import_ok">Import successful.\n\nPlease press OK to restart AntennaPod</string>
<!-- Sleep timer -->
<string name="set_sleeptimer_label">Set sleep timer</string>
@@ -755,15 +763,6 @@
<!-- Subscriptions fragment -->
<string name="subscription_num_columns">Number of columns</string>
- <!-- Database import/export -->
- <string name="import_export">Database import/export</string>
- <string name="import_export_warning">This experimental function can be used to transfer your subscriptions and played episodes to another device.\n\nExported databases can only be imported when using the same version of AntennaPod. Otherwise, this function will lead to unexpected behavior.\n\nAfter importing, episodes might be displayed as downloaded even though they are not. Just press the play button of the episodes to make AntennaPod detect this.</string>
- <string name="label_import">Import</string>
- <string name="label_export">Export</string>
- <string name="import_select_file">Select file to import</string>
- <string name="export_ok">Export successful.</string>
- <string name="import_ok">Import successful.\n\nPlease press OK to restart AntennaPod</string>
-
<!-- Casting -->
<string name="cast_media_route_menu_title">Play on&#8230;</string>
<string name="cast_disconnect_label">Disconnect the cast session</string>