diff options
author | Thomas <tschneider.ac@gmail.com> | 2022-09-06 11:30:19 +0200 |
---|---|---|
committer | Thomas <tschneider.ac@gmail.com> | 2022-09-06 11:30:19 +0200 |
commit | 7f28d208a3a6b3ee360160ebab702b2bb556bfc0 (patch) | |
tree | 1d68f4e4f13de1ff991907cca21daab9a6dbeb80 | |
parent | 190b800a6efd0195c62bc46b9642bbe6496c2fc7 (diff) |
export settings
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> |