summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas <tschneider.ac@gmail.com>2022-09-06 11:30:19 +0200
committerThomas <tschneider.ac@gmail.com>2022-09-06 11:30:19 +0200
commit7f28d208a3a6b3ee360160ebab702b2bb556bfc0 (patch)
tree1d68f4e4f13de1ff991907cca21daab9a6dbeb80
parent190b800a6efd0195c62bc46b9642bbe6496c2fc7 (diff)
export settings
-rw-r--r--app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt2
-rw-r--r--app/src/main/java/app/fedilab/android/helper/SettingsStorage.java134
-rw-r--r--app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt39
-rw-r--r--app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml10
-rw-r--r--app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml10
-rw-r--r--app/src/main/res/values/strings.xml7
-rw-r--r--app/src/main/res/xml/pref_categories.xml15
7 files changed, 217 insertions, 0 deletions
diff --git a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt
index eb972cca7..ee7a7e2c6 100644
--- a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt
+++ b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt
@@ -36,6 +36,8 @@ class SettingsActivity : BaseActivity() {
val navController = findNavController(R.id.fragment_container)
appBarConfiguration = AppBarConfiguration(navController.graph)
+ supportActionBar?.setDisplayShowHomeEnabled(true)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupActionBarWithNavController(navController, appBarConfiguration)
}
diff --git a/app/src/main/java/app/fedilab/android/helper/SettingsStorage.java b/app/src/main/java/app/fedilab/android/helper/SettingsStorage.java
new file mode 100644
index 000000000..677e42fe8
--- /dev/null
+++ b/app/src/main/java/app/fedilab/android/helper/SettingsStorage.java
@@ -0,0 +1,134 @@
+package app.fedilab.android.helper;
+/* Copyright 2022 Thomas Schneider
+ *
+ * This file is a part of Fedilab
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Fedilab; if not,
+ * see <http://www.gnu.org/licenses>. */
+
+import static app.fedilab.android.BaseMainActivity.currentAccount;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Environment;
+
+import androidx.preference.PreferenceManager;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Date;
+import java.util.Map;
+
+import app.fedilab.android.R;
+
+
+//From https://stackoverflow.com/a/10864463
+
+public class SettingsStorage {
+
+
+ public static boolean saveSharedPreferencesToFile(Context context) {
+ boolean res = false;
+ ObjectOutputStream output = null;
+ String fileName = "Fedilab_settings_export_" + Helper.dateFileToString(context, new Date()) + ".txt";
+ String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
+ String fullPath = filePath + "/" + fileName;
+ File dst = new File(fullPath);
+ try {
+ output = new ObjectOutputStream(new FileOutputStream(dst));
+ SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ output.writeObject(sharedpreferences.getAll());
+ res = true;
+ String message = context.getString(R.string.data_export_theme_success);
+ Intent intentOpen = new Intent();
+ intentOpen.setAction(android.content.Intent.ACTION_VIEW);
+ Uri uri = Uri.parse("file://" + fullPath);
+ intentOpen.setDataAndType(uri, "text/txt");
+ String title = context.getString(R.string.data_export_settings);
+ Helper.notify_user(context, currentAccount, intentOpen, BitmapFactory.decodeResource(context.getResources(),
+ R.mipmap.ic_launcher), Helper.NotifType.BACKUP, title, message);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (output != null) {
+ output.flush();
+ output.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return res;
+ }
+
+ @SuppressLint("ApplySharedPref")
+ @SuppressWarnings({"unchecked", "UnnecessaryUnboxing"})
+ public static boolean loadSharedPreferencesFromFile(Context context, File src) {
+ boolean res = false;
+ ObjectInputStream input = null;
+ try {
+ input = new ObjectInputStream(new FileInputStream(src));
+ SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences.Editor prefEdit = sharedpreferences.edit();
+ prefEdit.clear();
+ Map<String, ?> entries = (Map<String, ?>) input.readObject();
+ for (Map.Entry<String, ?> entry : entries.entrySet()) {
+ Object v = entry.getValue();
+ String key = entry.getKey();
+ //We skip some values
+ if (key.compareTo(Helper.PREF_USER_ID) == 0) {
+ continue;
+ }
+ if (key.compareTo(Helper.PREF_INSTANCE) == 0) {
+ continue;
+ }
+ if (key.compareTo(Helper.PREF_USER_INSTANCE) == 0) {
+ continue;
+ }
+ if (key.compareTo(Helper.PREF_USER_TOKEN) == 0) {
+ continue;
+ }
+ if (v instanceof Boolean)
+ prefEdit.putBoolean(key, ((Boolean) v).booleanValue());
+ else if (v instanceof Float)
+ prefEdit.putFloat(key, ((Float) v).floatValue());
+ else if (v instanceof Integer)
+ prefEdit.putInt(key, ((Integer) v).intValue());
+ else if (v instanceof Long)
+ prefEdit.putLong(key, ((Long) v).longValue());
+ else if (v instanceof String)
+ prefEdit.putString(key, ((String) v));
+ }
+ prefEdit.commit();
+ res = true;
+ } catch (IOException | ClassNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return res;
+ }
+}
diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt b/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt
index 4205449a0..fcb96c744 100644
--- a/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt
+++ b/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt
@@ -14,15 +14,23 @@ package app.fedilab.android.ui.fragment.settings
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
+import android.Manifest
+import android.content.pm.PackageManager
import android.os.Bundle
+import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import app.fedilab.android.BaseMainActivity.currentAccount
import app.fedilab.android.R
+import app.fedilab.android.helper.SettingsStorage
+
class FragmentSettingsCategories : PreferenceFragmentCompat() {
+ private val REQUEST_CODE = 5412
+
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.pref_categories, rootKey)
@@ -61,6 +69,25 @@ class FragmentSettingsCategories : PreferenceFragmentCompat() {
false
}
+ findPreference<Preference>(getString(R.string.pref_export_settings))?.setOnPreferenceClickListener {
+ val permissionLauncher = registerForActivityResult(
+ ActivityResultContracts.RequestPermission()
+ ) { isGranted ->
+ if (isGranted) {
+ SettingsStorage.saveSharedPreferencesToFile(context)
+ } else {
+ requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_CODE)
+ }
+ }
+ permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ false
+ }
+
+ findPreference<Preference>(getString(R.string.pref_import_settings))?.setOnPreferenceClickListener {
+
+ false
+ }
+
val adminPreference = findPreference<Preference>(getString(R.string.pref_category_key_administration))
adminPreference?.isVisible = currentAccount.admin
adminPreference?.setOnPreferenceClickListener { false }
@@ -70,4 +97,16 @@ class FragmentSettingsCategories : PreferenceFragmentCompat() {
false
}
}
+
+ @Deprecated("Deprecated in Java")
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+ when (requestCode) {
+ REQUEST_CODE -> if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ SettingsStorage.saveSharedPreferencesToFile(context)
+ } else {
+ Toast.makeText(context, getString(R.string.permission_missing), Toast.LENGTH_SHORT).show()
+ }
+ else -> {}
+ }
+ }
}
diff --git a/app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml
new file mode 100644
index 000000000..8afaa1b7a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#FFFFFF"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6 1.41,-1.41z" />
+</vector>
diff --git a/app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml
new file mode 100644
index 000000000..6315ba8fd
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#FFFFFF"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z" />
+</vector>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b0845cab8..c58d7a911 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -616,6 +616,7 @@
<string name="pref_custom_theme">Use a custom theme</string>
<string name="theming">Theming</string>
<string name="data_export_theme">The theme was exported</string>
+ <string name="data_export_settings">The settings were exported</string>
<string name="data_export_theme_success">The theme has been successfully exported in CSV</string>
<string name="import_theme">Import a theme</string>
<string name="import_theme_title">Tap here to import a theme from a previous export</string>
@@ -1428,4 +1429,10 @@
<string name="pref_category_key_theming" translatable="false">pref_category_theming</string>
<string name="pref_category_key_administration" translatable="false">pref_category_administration</string>
<string name="pref_category_key_languages" translatable="false">pref_category_languages</string>
+ <string name="pref_export_settings" translatable="false">pref_export_settings</string>
+ <string name="pref_import_settings" translatable="false">pref_import_settings</string>
+
+ <string name="export_settings">Export settings</string>
+ <string name="import_settings">Import settings</string>
+ <string name="permission_missing">Permission not granted!</string>
</resources>
diff --git a/app/src/main/res/xml/pref_categories.xml b/app/src/main/res/xml/pref_categories.xml
index a1a10073c..a7e6dfb47 100644
--- a/app/src/main/res/xml/pref_categories.xml
+++ b/app/src/main/res/xml/pref_categories.xml
@@ -67,4 +67,19 @@
app:icon="@drawable/ic_language"
app:key="@string/pref_category_key_languages" />
+
+ <Preference
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:title="@string/export_settings"
+ app:icon="@drawable/ic_baseline_keyboard_arrow_down_24"
+ app:key="@string/pref_export_settings" />
+
+ <Preference
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:title="@string/import_settings"
+ app:icon="@drawable/ic_baseline_keyboard_arrow_up_24"
+ app:key="@string/pref_import_settings" />
+
</androidx.preference.PreferenceScreen>