summaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2020-01-27 10:28:41 +0100
committerByteHamster <info@bytehamster.com>2020-01-29 11:08:06 +0100
commit8ecbe95e1654ba3e31408c39e57f80dcf6ead3cb (patch)
tree4ad61db5989cfa75dadfb731e426866b68a76612 /app/src/main
parent0c7dd3cc24e6ab8c2b529a00edb6a2057c048218 (diff)
downloadAntennaPod-8ecbe95e1654ba3e31408c39e57f80dcf6ead3cb.zip
Moved database import/export to settings
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/AndroidManifest.xml7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java218
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java157
-rw-r--r--app/src/main/res/xml/preferences_import_export.xml21
4 files changed, 132 insertions, 271 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ad68fcfe3..c17e2120a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -141,13 +141,6 @@
<activity android:name=".activity.StorageErrorActivity">
</activity>
<activity
- android:name=".activity.ImportExportActivity"
- android:label="@string/import_export">
- <meta-data
- android:name="android.support.PARENT_ACTIVITY"
- android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
- </activity>
- <activity
android:name=".activity.OpmlImportFromPathActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/opml_import_label">
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java
deleted file mode 100644
index f85a1cd77..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/ImportExportActivity.java
+++ /dev/null
@@ -1,218 +0,0 @@
-package de.danoeh.antennapod.activity;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import com.google.android.material.snackbar.Snackbar;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatActivity;
-import android.util.Log;
-import android.view.MenuItem;
-
-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;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
-
-/**
- * Displays the 'import/export' screen
- */
-public class ImportExportActivity extends AppCompatActivity {
- private static final int REQUEST_CODE_RESTORE = 43;
- private static final int REQUEST_CODE_BACKUP_DOCUMENT = 44;
- private static final String EXPORT_FILENAME = "AntennaPodBackup.db";
- private static final String TAG = ImportExportActivity.class.getSimpleName();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setTheme(UserPreferences.getTheme());
- super.onCreate(savedInstanceState);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayShowHomeEnabled(true);
- }
- setContentView(R.layout.import_export_activity);
-
- findViewById(R.id.button_export).setOnClickListener(view -> backup());
- findViewById(R.id.button_import).setOnClickListener(view -> restore());
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == android.R.id.home) {
- finish();
- return true;
- } else {
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void backup() {
- if (Build.VERSION.SDK_INT >= 19) {
- Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
- .addCategory(Intent.CATEGORY_OPENABLE)
- .setType("application/x-sqlite3")
- .putExtra(Intent.EXTRA_TITLE, EXPORT_FILENAME);
-
- startActivityForResult(intent, REQUEST_CODE_BACKUP_DOCUMENT);
- } else {
- try {
- File sd = Environment.getExternalStorageDirectory();
- File backupDB = new File(sd, EXPORT_FILENAME);
- writeBackupTo(new FileOutputStream(backupDB));
- } catch (IOException e) {
- Log.e(TAG, Log.getStackTraceString(e));
- Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
- }
- }
- }
-
- private void restore() {
- if (Build.VERSION.SDK_INT >= 19) {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.setType("*/*");
- startActivityForResult(intent, REQUEST_CODE_RESTORE);
- } else {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType("*/*");
- startActivityForResult(Intent.createChooser(intent,
- getString(R.string.import_select_file)), REQUEST_CODE_RESTORE);
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
- if (resultCode != RESULT_OK || resultData == null) {
- return;
- }
- Uri uri = resultData.getData();
-
- if (requestCode == REQUEST_CODE_RESTORE) {
- restoreFrom(uri);
- } else if (requestCode == REQUEST_CODE_BACKUP_DOCUMENT) {
- backupToDocument(uri);
- }
- }
-
- private void restoreFrom(Uri inputUri) {
- InputStream inputStream = null;
- try {
- if (!validateDB(inputUri)) {
- displayBadFileDialog();
- return;
- }
-
- File currentDB = getDatabasePath(PodDBAdapter.DATABASE_NAME);
- inputStream = getContentResolver().openInputStream(inputUri);
- FileUtils.copyInputStreamToFile(inputStream, currentDB);
- displayImportSuccessDialog();
- } catch (IOException e) {
- Log.e(TAG, Log.getStackTraceString(e));
- Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
- } finally {
- IOUtils.closeQuietly(inputStream);
- }
- }
-
- private static final byte[] SQLITE3_MAGIC = "SQLite format 3\0".getBytes();
- private boolean validateDB(Uri inputUri) throws IOException {
- try (InputStream inputStream = getContentResolver().openInputStream(inputUri)) {
- byte[] magicBuf = new byte[SQLITE3_MAGIC.length];
- if (inputStream.read(magicBuf) == magicBuf.length) {
- return Arrays.equals(SQLITE3_MAGIC, magicBuf);
- }
- }
-
- return false;
- }
-
- private void displayBadFileDialog() {
- AlertDialog.Builder d = new AlertDialog.Builder(ImportExportActivity.this);
- d.setMessage(R.string.import_bad_file)
- .setCancelable(false)
- .setPositiveButton(android.R.string.ok, ((dialogInterface, i) -> {
- // do nothing
- }))
- .show();
- }
-
- private void displayImportSuccessDialog() {
- AlertDialog.Builder d = new AlertDialog.Builder(ImportExportActivity.this);
- d.setMessage(R.string.import_ok);
- d.setCancelable(false);
- d.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
- Intent intent = new Intent(getApplicationContext(), SplashActivity.class);
- ComponentName cn = intent.getComponent();
- Intent mainIntent = Intent.makeRestartActivityTask(cn);
- startActivity(mainIntent);
- });
- d.show();
- }
-
- private void backupToDocument(Uri uri) {
- ParcelFileDescriptor pfd = null;
- FileOutputStream fileOutputStream = null;
- try {
- pfd = getContentResolver().openFileDescriptor(uri, "w");
- fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
- writeBackupTo(fileOutputStream);
-
- Snackbar.make(findViewById(R.id.import_export_layout),
- R.string.export_ok, Snackbar.LENGTH_SHORT).show();
- } catch (IOException e) {
- Log.e(TAG, Log.getStackTraceString(e));
- Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
- } finally {
- IOUtils.closeQuietly(fileOutputStream);
-
- if (pfd != null) {
- try {
- pfd.close();
- } catch (IOException e) {
- Log.d(TAG, "Unable to close ParcelFileDescriptor");
- }
- }
- }
- }
-
- private void writeBackupTo(FileOutputStream outFileStream) {
- FileChannel src = null;
- FileChannel dst = null;
- try {
- File currentDB = getDatabasePath(PodDBAdapter.DATABASE_NAME);
-
- if (currentDB.exists()) {
- src = new FileInputStream(currentDB).getChannel();
- dst = outFileStream.getChannel();
- dst.transferFrom(src, 0, src.size());
-
- Snackbar.make(findViewById(R.id.import_export_layout),
- R.string.export_ok, Snackbar.LENGTH_SHORT).show();
- } else {
- Snackbar.make(findViewById(R.id.import_export_layout),
- "Can not access current database", Snackbar.LENGTH_SHORT).show();
- }
- } catch (IOException e) {
- Log.e(TAG, Log.getStackTraceString(e));
- Snackbar.make(findViewById(R.id.import_export_layout), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
- } finally {
- IOUtils.closeQuietly(src);
- IOUtils.closeQuietly(dst);
- }
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java
index ca69414f1..9803e072c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java
@@ -1,9 +1,9 @@
package de.danoeh.antennapod.fragment.preferences;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -11,26 +11,30 @@ import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.FileProvider;
-import androidx.documentfile.provider.DocumentFile;
import androidx.preference.PreferenceFragmentCompat;
+import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.ImportExportActivity;
import de.danoeh.antennapod.activity.OpmlImportFromPathActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
+import de.danoeh.antennapod.activity.SplashActivity;
import de.danoeh.antennapod.asynctask.DocumentFileExportWorker;
import de.danoeh.antennapod.asynctask.ExportWorker;
import de.danoeh.antennapod.core.export.ExportWriter;
import de.danoeh.antennapod.core.export.html.HtmlWriter;
import de.danoeh.antennapod.core.export.opml.OpmlWriter;
+import de.danoeh.antennapod.core.storage.DatabaseExporter;
+import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import java.io.File;
+import java.io.FileOutputStream;
import java.util.List;
public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
@@ -38,19 +42,27 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
private static final String PREF_OPML_EXPORT = "prefOpmlExport";
private static final String PREF_OPML_IMPORT = "prefOpmlImport";
private static final String PREF_HTML_EXPORT = "prefHtmlExport";
- private static final String IMPORT_EXPORT = "importExport";
- private static final int CHOOSE_OPML_EXPORT_PATH = 1;
+ private static final String PREF_DATABASE_IMPORT = "prefDatabaseImport";
+ private static final String PREF_DATABASE_EXPORT = "prefDatabaseExport";
+ private static final int REQUEST_CODE_CHOOSE_OPML_EXPORT_PATH = 1;
private static final String DEFAULT_OPML_OUTPUT_NAME = "antennapod-feeds.opml";
private static final String CONTENT_TYPE_OPML = "text/x-opml";
- private static final int CHOOSE_HTML_EXPORT_PATH = 2;
+ private static final int REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH = 2;
private static final String DEFAULT_HTML_OUTPUT_NAME = "antennapod-feeds.html";
private static final String CONTENT_TYPE_HTML = "text/html";
+ private static final int REQUEST_CODE_RESTORE_DATABASE = 3;
+ private static final int REQUEST_CODE_BACKUP_DATABASE = 4;
+ private static final String DATABASE_EXPORT_FILENAME = "AntennaPodBackup.db";
private Disposable disposable;
+ private ProgressDialog progressDialog;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences_import_export);
setupStorageScreen();
+ progressDialog = new ProgressDialog(getContext());
+ progressDialog.setIndeterminate(true);
+ progressDialog.setMessage(getContext().getString(R.string.please_wait));
}
@Override
@@ -69,24 +81,17 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
private void setupStorageScreen() {
final Activity activity = getActivity();
-
- findPreference(IMPORT_EXPORT).setOnPreferenceClickListener(
- preference -> {
- activity.startActivity(new Intent(activity, ImportExportActivity.class));
- return true;
- }
- );
findPreference(PREF_OPML_EXPORT).setOnPreferenceClickListener(
preference -> {
openExportPathPicker(CONTENT_TYPE_OPML, DEFAULT_OPML_OUTPUT_NAME,
- CHOOSE_OPML_EXPORT_PATH, new OpmlWriter());
+ REQUEST_CODE_CHOOSE_OPML_EXPORT_PATH, new OpmlWriter());
return true;
}
);
findPreference(PREF_HTML_EXPORT).setOnPreferenceClickListener(
preference -> {
openExportPathPicker(CONTENT_TYPE_HTML, DEFAULT_HTML_OUTPUT_NAME,
- CHOOSE_HTML_EXPORT_PATH, new HtmlWriter());
+ REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH, new HtmlWriter());
return true;
});
findPreference(PREF_OPML_IMPORT).setOnPreferenceClickListener(
@@ -94,13 +99,20 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
activity.startActivity(new Intent(activity, OpmlImportFromPathActivity.class));
return true;
});
+ findPreference(PREF_DATABASE_IMPORT).setOnPreferenceClickListener(
+ preference -> {
+ importDatabase();
+ return true;
+ });
+ findPreference(PREF_DATABASE_EXPORT).setOnPreferenceClickListener(
+ preference -> {
+ exportDatabase();
+ return true;
+ });
}
- private boolean export(ExportWriter exportWriter, final Uri uri) {
+ private void exportWithWriter(ExportWriter exportWriter, final Uri uri) {
Context context = getActivity();
- final ProgressDialog progressDialog = new ProgressDialog(context);
- progressDialog.setMessage(context.getString(R.string.exporting_label));
- progressDialog.setIndeterminate(true);
progressDialog.show();
if (uri == null) {
Observable<File> observable = new ExportWorker(exportWriter, getContext()).exportObservable();
@@ -109,24 +121,73 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
.subscribe(output -> {
Uri fileUri = FileProvider.getUriForFile(context.getApplicationContext(),
context.getString(R.string.provider_authority), output);
- showExportSuccessDialog(context.getString(R.string.export_success_sum, output.toString()), fileUri);
+ showExportSuccessDialog(output.toString(), fileUri);
}, this::showExportErrorDialog, progressDialog::dismiss);
} else {
- Observable<DocumentFile> observable = new DocumentFileExportWorker(exportWriter, context, uri).exportObservable();
- disposable = observable.subscribeOn(Schedulers.io())
+ DocumentFileExportWorker worker = new DocumentFileExportWorker(exportWriter, context, uri);
+ disposable = worker.exportObservable()
+ .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(output -> {
- showExportSuccessDialog(context.getString(R.string.export_success_sum, output.getUri()), output.getUri());
- }, this::showExportErrorDialog, progressDialog::dismiss);
+ .subscribe(output ->
+ showExportSuccessDialog(output.getUri().toString(), output.getUri()),
+ this::showExportErrorDialog, progressDialog::dismiss);
}
- return true;
}
- private void showExportSuccessDialog(final String message, final Uri streamUri) {
- final AlertDialog.Builder alert = new AlertDialog.Builder(getContext())
- .setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
+ private void exportDatabase() {
+ if (Build.VERSION.SDK_INT >= 19) {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
+ .addCategory(Intent.CATEGORY_OPENABLE)
+ .setType("application/x-sqlite3")
+ .putExtra(Intent.EXTRA_TITLE, DATABASE_EXPORT_FILENAME);
+
+ startActivityForResult(intent, REQUEST_CODE_BACKUP_DATABASE);
+ } else {
+ File sd = Environment.getExternalStorageDirectory();
+ File backupDB = new File(sd, DATABASE_EXPORT_FILENAME);
+ progressDialog.show();
+ disposable = Completable.fromAction(() ->
+ DatabaseExporter.exportToStream(new FileOutputStream(backupDB), getContext()))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(() -> {
+ Snackbar.make(getView(), R.string.export_ok, Snackbar.LENGTH_LONG).show();
+ progressDialog.dismiss();
+ }, this::showExportErrorDialog);
+ }
+ }
+
+ private void importDatabase() {
+ if (Build.VERSION.SDK_INT >= 19) {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.setType("*/*");
+ startActivityForResult(intent, REQUEST_CODE_RESTORE_DATABASE);
+ } else {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("*/*");
+ startActivityForResult(Intent.createChooser(intent,
+ getString(R.string.import_select_file)), REQUEST_CODE_RESTORE_DATABASE);
+ }
+ }
+
+ private void showDatabaseImportSuccessDialog() {
+ AlertDialog.Builder d = new AlertDialog.Builder(getContext());
+ d.setMessage(R.string.import_ok);
+ d.setCancelable(false);
+ d.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
+ Intent intent = new Intent(getContext(), SplashActivity.class);
+ ComponentName cn = intent.getComponent();
+ Intent mainIntent = Intent.makeRestartActivityTask(cn);
+ startActivity(mainIntent);
+ });
+ d.show();
+ }
+
+ private void showExportSuccessDialog(final String path, final Uri streamUri) {
+ final AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
+ alert.setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
alert.setTitle(R.string.export_success_title);
- alert.setMessage(message);
+ alert.setMessage(getContext().getString(R.string.export_success_sum, path));
alert.setPositiveButton(R.string.send_label, (dialog, which) -> {
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.opml_export_label));
@@ -147,6 +208,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
}
private void showExportErrorDialog(final Throwable error) {
+ progressDialog.dismiss();
final AlertDialog.Builder alert = new AlertDialog.Builder(getContext())
.setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
alert.setTitle(R.string.export_error_label);
@@ -154,16 +216,35 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
alert.show();
}
- @SuppressLint("NewApi")
+ @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_OK && requestCode == CHOOSE_OPML_EXPORT_PATH) {
- Uri uri = data.getData();
- export(new OpmlWriter(), uri);
+ if (resultCode != Activity.RESULT_OK || data == null) {
+ return;
}
+ Uri uri = data.getData();
- if (resultCode == Activity.RESULT_OK && requestCode == CHOOSE_HTML_EXPORT_PATH) {
- Uri uri = data.getData();
- export(new HtmlWriter(), uri);
+ if (requestCode == REQUEST_CODE_CHOOSE_OPML_EXPORT_PATH) {
+ exportWithWriter(new OpmlWriter(), uri);
+ } else if (requestCode == REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH) {
+ exportWithWriter(new HtmlWriter(), uri);
+ } else if (requestCode == REQUEST_CODE_RESTORE_DATABASE) {
+ progressDialog.show();
+ disposable = Completable.fromAction(() -> DatabaseExporter.importBackup(uri, getContext()))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(() -> {
+ showDatabaseImportSuccessDialog();
+ progressDialog.dismiss();
+ }, this::showExportErrorDialog);
+ } else if (requestCode == REQUEST_CODE_BACKUP_DATABASE) {
+ progressDialog.show();
+ disposable = Completable.fromAction(() -> DatabaseExporter.exportToDocument(uri, getContext()))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(() -> {
+ Snackbar.make(getView(), R.string.export_ok, Snackbar.LENGTH_LONG).show();
+ progressDialog.dismiss();
+ }, this::showExportErrorDialog);
}
}
@@ -186,6 +267,6 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
// If we are using a SDK lower than API 21 or the implicit intent failed
// fallback to the legacy export process
- export(writer, null);
+ exportWithWriter(writer, null);
}
}
diff --git a/app/src/main/res/xml/preferences_import_export.xml b/app/src/main/res/xml/preferences_import_export.xml
index 6489ca493..7c576d194 100644
--- a/app/src/main/res/xml/preferences_import_export.xml
+++ b/app/src/main/res/xml/preferences_import_export.xml
@@ -14,18 +14,23 @@
android:summary="@string/opml_import_summary"/>
</PreferenceCategory>
+ <PreferenceCategory android:title="@string/database">
+ <Preference
+ android:key="prefDatabaseExport"
+ search:keywords="@string/import_export_search_keywords"
+ android:title="@string/database_export_label"
+ android:summary="@string/database_export_summary"/>
+ <Preference
+ android:key="prefDatabaseImport"
+ search:keywords="@string/import_export_search_keywords"
+ android:title="@string/database_import_label"
+ android:summary="@string/database_import_summary"/>
+ </PreferenceCategory>
+
<PreferenceCategory android:title="@string/html">
<Preference
android:key="prefHtmlExport"
android:title="@string/html_export_label"
android:summary="@string/html_export_summary"/>
</PreferenceCategory>
-
- <PreferenceCategory android:title="@string/database">
- <Preference
- android:key="importExport"
- search:keywords="@string/import_export_search_keywords"
- android:title="@string/import_export"
- android:summary="@string/database_export_summary"/>
- </PreferenceCategory>
</PreferenceScreen>