Loading app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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) } Loading app/src/main/java/app/fedilab/android/helper/SettingsStorage.java 0 → 100644 +134 −0 Original line number Diff line number Diff line 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; } } app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt +39 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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 } Loading @@ -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 -> {} } } } app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml 0 → 100644 +10 −0 Original line number Diff line number Diff line <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> app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml 0 → 100644 +10 −0 Original line number Diff line number Diff line <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> Loading
app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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) } Loading
app/src/main/java/app/fedilab/android/helper/SettingsStorage.java 0 → 100644 +134 −0 Original line number Diff line number Diff line 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; } }
app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentSettingsCategories.kt +39 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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 } Loading @@ -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 -> {} } } }
app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml 0 → 100644 +10 −0 Original line number Diff line number Diff line <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>
app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml 0 → 100644 +10 −0 Original line number Diff line number Diff line <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>