mirror of
https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
synced 2024-12-30 12:57:12 +01:00
Backup settings.
This commit is contained in:
parent
2ef72bc798
commit
65e654a23c
@ -170,6 +170,9 @@ dependencies {
|
|||||||
// Crash screen
|
// Crash screen
|
||||||
implementation 'com.melegy.redscreenofdeath:red-screen-of-death:0.1.2'
|
implementation 'com.melegy.redscreenofdeath:red-screen-of-death:0.1.2'
|
||||||
|
|
||||||
|
implementation 'net.lingala.zip4j:zip4j:2.7.0'
|
||||||
|
implementation 'org.apache.commons:commons-io:1.3.2'
|
||||||
|
|
||||||
|
|
||||||
/**** Builds and flavors ****/
|
/**** Builds and flavors ****/
|
||||||
// debugImplementation because LeakCanary should only run in debug builds.
|
// debugImplementation because LeakCanary should only run in debug builds.
|
||||||
|
@ -0,0 +1,191 @@
|
|||||||
|
package ml.docilealligator.infinityforreddit.asynctasks;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
|
|
||||||
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
|
|
||||||
|
import net.lingala.zip4j.ZipFile;
|
||||||
|
import net.lingala.zip4j.model.ZipParameters;
|
||||||
|
import net.lingala.zip4j.model.enums.EncryptionMethod;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import ml.docilealligator.infinityforreddit.BuildConfig;
|
||||||
|
import ml.docilealligator.infinityforreddit.R;
|
||||||
|
import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils;
|
||||||
|
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
|
||||||
|
|
||||||
|
public class BackupSettings {
|
||||||
|
public static void backupSettings(Context context, Executor executor, Handler handler,
|
||||||
|
ContentResolver contentResolver, Uri destinationDirUri,
|
||||||
|
SharedPreferences defaultSharedPreferences,
|
||||||
|
SharedPreferences lightThemeSharedPreferences,
|
||||||
|
SharedPreferences darkThemeSharedPreferences,
|
||||||
|
SharedPreferences amoledThemeSharedPreferences,
|
||||||
|
SharedPreferences sortTypeSharedPreferences,
|
||||||
|
SharedPreferences postLayoutSharedPreferences,
|
||||||
|
SharedPreferences postFeedScrolledPositionSharedPreferences,
|
||||||
|
SharedPreferences mainActivityTabsSharedPreferences,
|
||||||
|
SharedPreferences nsfwAndSpoilerSharedPreferencs,
|
||||||
|
SharedPreferences bottomAppBarSharedPreferences,
|
||||||
|
SharedPreferences postHistorySharedPreferences,
|
||||||
|
BackupSettingsListener backupSettingsListener) {
|
||||||
|
executor.execute(() -> {
|
||||||
|
boolean res = saveSharedPreferencesToFile(context, defaultSharedPreferences,
|
||||||
|
SharedPreferencesUtils.DEFAULT_PREFERENCES_FILE);
|
||||||
|
boolean res1 = saveSharedPreferencesToFile(context, lightThemeSharedPreferences,
|
||||||
|
CustomThemeSharedPreferencesUtils.LIGHT_THEME_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res2 = saveSharedPreferencesToFile(context, darkThemeSharedPreferences,
|
||||||
|
CustomThemeSharedPreferencesUtils.DARK_THEME_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res3 = saveSharedPreferencesToFile(context, amoledThemeSharedPreferences,
|
||||||
|
CustomThemeSharedPreferencesUtils.AMOLED_THEME_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res4 = saveSharedPreferencesToFile(context, sortTypeSharedPreferences,
|
||||||
|
SharedPreferencesUtils.SORT_TYPE_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res5 = saveSharedPreferencesToFile(context, postLayoutSharedPreferences,
|
||||||
|
SharedPreferencesUtils.POST_LAYOUT_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res6 = saveSharedPreferencesToFile(context, postFeedScrolledPositionSharedPreferences,
|
||||||
|
SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res7 = saveSharedPreferencesToFile(context, mainActivityTabsSharedPreferences,
|
||||||
|
SharedPreferencesUtils.MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res8 = saveSharedPreferencesToFile(context, nsfwAndSpoilerSharedPreferencs,
|
||||||
|
SharedPreferencesUtils.NSFW_AND_SPOILER_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res9 = saveSharedPreferencesToFile(context, bottomAppBarSharedPreferences,
|
||||||
|
SharedPreferencesUtils.BOTTOM_APP_BAR_SHARED_PREFERENCES_FILE);
|
||||||
|
boolean res10 = saveSharedPreferencesToFile(context, postHistorySharedPreferences,
|
||||||
|
SharedPreferencesUtils.POST_HISTORY_SHARED_PREFERENCES_FILE);
|
||||||
|
|
||||||
|
boolean zipRes = zipAndMoveToDestinationDir(context, contentResolver, destinationDirUri);
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileUtils.deleteDirectory(new File(context.getExternalCacheDir() + "/Backup/"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.post(() -> {
|
||||||
|
boolean finalResult = res && res1 && res2 && res3 && res4 && res5 && res6 && res7 && res8 && res9 && res10 && zipRes;
|
||||||
|
if (finalResult) {
|
||||||
|
backupSettingsListener.success();
|
||||||
|
} else {
|
||||||
|
if (!zipRes) {
|
||||||
|
backupSettingsListener.failed(context.getText(R.string.create_zip_in_destination_directory_failed).toString());
|
||||||
|
} else {
|
||||||
|
backupSettingsListener.failed(context.getText(R.string.backup_some_settings_failed).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean saveSharedPreferencesToFile(Context context, SharedPreferences sharedPreferences,
|
||||||
|
String fileName) {
|
||||||
|
|
||||||
|
boolean result = false;
|
||||||
|
ObjectOutputStream output = null;
|
||||||
|
String backupDir = context.getExternalCacheDir() + "/Backup/" + BuildConfig.VERSION_NAME;
|
||||||
|
if (!new File(backupDir).exists()) {
|
||||||
|
new File(backupDir).mkdirs();
|
||||||
|
} else {
|
||||||
|
File backupDirFile = new File(backupDir);
|
||||||
|
backupDirFile.delete();
|
||||||
|
backupDirFile.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
output = new ObjectOutputStream(new FileOutputStream(new File(backupDir + "/" + fileName + ".txt")));
|
||||||
|
output.writeObject(sharedPreferences.getAll());
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (output != null) {
|
||||||
|
output.flush();
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean zipAndMoveToDestinationDir(Context context, ContentResolver contentResolver, Uri destinationDirUri) {
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
boolean result = false;
|
||||||
|
try {
|
||||||
|
String time = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(System.currentTimeMillis()));
|
||||||
|
String fileName = "Infinity_For_Reddit_Settings_Backup_v" + BuildConfig.VERSION_NAME + "-" + time + ".zip";
|
||||||
|
String filePath = context.getExternalCacheDir() + "/Backup/" + fileName;
|
||||||
|
ZipFile zip = new ZipFile(filePath, "123321".toCharArray());
|
||||||
|
ZipParameters zipParameters = new ZipParameters();
|
||||||
|
zipParameters.setEncryptFiles(true);
|
||||||
|
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
|
||||||
|
zip.addFolder(new File(context.getExternalCacheDir() + "/Backup/" + BuildConfig.VERSION_NAME + "/"), zipParameters);
|
||||||
|
|
||||||
|
DocumentFile dir = DocumentFile.fromTreeUri(context, destinationDirUri);
|
||||||
|
if (dir == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DocumentFile checkForDuplicate = dir.findFile(fileName);
|
||||||
|
if (checkForDuplicate != null) {
|
||||||
|
checkForDuplicate.delete();
|
||||||
|
}
|
||||||
|
DocumentFile destinationFile = dir.createFile("application/zip", fileName);
|
||||||
|
if (destinationFile == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream = contentResolver.openOutputStream(destinationFile.getUri());
|
||||||
|
if (outputStream == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] fileReader = new byte[1024];
|
||||||
|
|
||||||
|
FileInputStream inputStream = new FileInputStream(filePath);
|
||||||
|
while (true) {
|
||||||
|
int read = inputStream.read(fileReader);
|
||||||
|
|
||||||
|
if (read == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream.write(fileReader, 0, read);
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (outputStream != null) {
|
||||||
|
try {
|
||||||
|
outputStream.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface BackupSettingsListener {
|
||||||
|
void success();
|
||||||
|
void failed(String errorMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -2,12 +2,15 @@ package ml.docilealligator.infinityforreddit.settings;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@ -25,6 +28,7 @@ import javax.inject.Named;
|
|||||||
import ml.docilealligator.infinityforreddit.Infinity;
|
import ml.docilealligator.infinityforreddit.Infinity;
|
||||||
import ml.docilealligator.infinityforreddit.R;
|
import ml.docilealligator.infinityforreddit.R;
|
||||||
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
|
import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase;
|
||||||
|
import ml.docilealligator.infinityforreddit.asynctasks.BackupSettings;
|
||||||
import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllPostLayouts;
|
import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllPostLayouts;
|
||||||
import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllReadPosts;
|
import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllReadPosts;
|
||||||
import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllSortTypes;
|
import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllSortTypes;
|
||||||
@ -34,11 +38,15 @@ import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllUsers;
|
|||||||
import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent;
|
import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent;
|
||||||
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
|
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
|
||||||
|
|
||||||
|
import static android.app.Activity.RESULT_OK;
|
||||||
|
import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
*/
|
*/
|
||||||
public class AdvancedPreferenceFragment extends PreferenceFragmentCompat {
|
public class AdvancedPreferenceFragment extends PreferenceFragmentCompat {
|
||||||
|
|
||||||
|
private static final int SELECT_BACKUP_SETTINGS_DIRECTORY_REQUEST_CODE = 1;
|
||||||
@Inject
|
@Inject
|
||||||
RedditDataRoomDatabase mRedditDataRoomDatabase;
|
RedditDataRoomDatabase mRedditDataRoomDatabase;
|
||||||
@Inject
|
@Inject
|
||||||
@ -69,6 +77,12 @@ public class AdvancedPreferenceFragment extends PreferenceFragmentCompat {
|
|||||||
@Named("nsfw_and_spoiler")
|
@Named("nsfw_and_spoiler")
|
||||||
SharedPreferences nsfwAndBlurringSharedPreferences;
|
SharedPreferences nsfwAndBlurringSharedPreferences;
|
||||||
@Inject
|
@Inject
|
||||||
|
@Named("bottom_app_bar")
|
||||||
|
SharedPreferences bottomAppBarSharedPreferences;
|
||||||
|
@Inject
|
||||||
|
@Named("post_history")
|
||||||
|
SharedPreferences postHistorySharedPreferences;
|
||||||
|
@Inject
|
||||||
Executor executor;
|
Executor executor;
|
||||||
private Activity activity;
|
private Activity activity;
|
||||||
|
|
||||||
@ -87,6 +101,8 @@ public class AdvancedPreferenceFragment extends PreferenceFragmentCompat {
|
|||||||
Preference deleteReadPostsPreference = findPreference(SharedPreferencesUtils.DELETE_READ_POSTS_IN_DATABASE);
|
Preference deleteReadPostsPreference = findPreference(SharedPreferencesUtils.DELETE_READ_POSTS_IN_DATABASE);
|
||||||
Preference deleteAllLegacySettingsPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_LEGACY_SETTINGS);
|
Preference deleteAllLegacySettingsPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_LEGACY_SETTINGS);
|
||||||
Preference resetAllSettingsPreference = findPreference(SharedPreferencesUtils.RESET_ALL_SETTINGS);
|
Preference resetAllSettingsPreference = findPreference(SharedPreferencesUtils.RESET_ALL_SETTINGS);
|
||||||
|
Preference backupSettingsPreference = findPreference(SharedPreferencesUtils.BACKUP_SETTINGS);
|
||||||
|
Preference restoreSettingsPreference = findPreference(SharedPreferencesUtils.RESTORE_SETTINGS);
|
||||||
|
|
||||||
if (deleteSubredditsPreference != null) {
|
if (deleteSubredditsPreference != null) {
|
||||||
deleteSubredditsPreference.setOnPreferenceClickListener(preference -> {
|
deleteSubredditsPreference.setOnPreferenceClickListener(preference -> {
|
||||||
@ -252,6 +268,67 @@ public class AdvancedPreferenceFragment extends PreferenceFragmentCompat {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (backupSettingsPreference != null) {
|
||||||
|
backupSettingsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
Intent intent = new Intent(ACTION_OPEN_DOCUMENT_TREE);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||||
|
startActivityForResult(intent, SELECT_BACKUP_SETTINGS_DIRECTORY_REQUEST_CODE);
|
||||||
|
|
||||||
|
/*BackupSettings.backupSettings(activity, executor, new Handler(), activity.getContentResolver(), null,
|
||||||
|
mSharedPreferences, lightThemeSharedPreferences, darkThemeSharedPreferences,
|
||||||
|
amoledThemeSharedPreferences, mSortTypeSharedPreferences, mPostLayoutSharedPreferences,
|
||||||
|
postFeedScrolledPositionSharedPreferences, mainActivityTabsSharedPreferences,
|
||||||
|
nsfwAndBlurringSharedPreferences, bottomAppBarSharedPreferences, postHistorySharedPreferences,
|
||||||
|
new BackupSettings.BackupSettingsListener() {
|
||||||
|
@Override
|
||||||
|
public void success() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restoreSettingsPreference != null) {
|
||||||
|
restoreSettingsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||||
|
if (requestCode == SELECT_BACKUP_SETTINGS_DIRECTORY_REQUEST_CODE && resultCode == RESULT_OK) {
|
||||||
|
Uri uri = data.getData();
|
||||||
|
BackupSettings.backupSettings(activity, executor, new Handler(), activity.getContentResolver(), uri,
|
||||||
|
mSharedPreferences, lightThemeSharedPreferences, darkThemeSharedPreferences,
|
||||||
|
amoledThemeSharedPreferences, mSortTypeSharedPreferences, mPostLayoutSharedPreferences,
|
||||||
|
postFeedScrolledPositionSharedPreferences, mainActivityTabsSharedPreferences,
|
||||||
|
nsfwAndBlurringSharedPreferences, bottomAppBarSharedPreferences, postHistorySharedPreferences,
|
||||||
|
new BackupSettings.BackupSettingsListener() {
|
||||||
|
@Override
|
||||||
|
public void success() {
|
||||||
|
Toast.makeText(activity, R.string.backup_settings_success, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(String errorMessage) {
|
||||||
|
Toast.makeText(activity, errorMessage, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -169,7 +169,10 @@ public class SharedPreferencesUtils {
|
|||||||
public static final String HIDE_SUBREDDIT_AND_USER_PREFIX = "hide_subreddit_and_user_prefix";
|
public static final String HIDE_SUBREDDIT_AND_USER_PREFIX = "hide_subreddit_and_user_prefix";
|
||||||
public static final String HIDE_THE_NUMBER_OF_VOTES = "hide_the_number_of_votes";
|
public static final String HIDE_THE_NUMBER_OF_VOTES = "hide_the_number_of_votes";
|
||||||
public static final String HIDE_THE_NUMBER_OF_COMMENTS = "hide_the_number_of_comments";
|
public static final String HIDE_THE_NUMBER_OF_COMMENTS = "hide_the_number_of_comments";
|
||||||
|
public static final String BACKUP_SETTINGS = "backup_settings";
|
||||||
|
public static final String RESTORE_SETTINGS = "restore_settings";
|
||||||
|
|
||||||
|
public static final String DEFAULT_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit_preferences";
|
||||||
public static final String MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.main_page_tabs";
|
public static final String MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.main_page_tabs";
|
||||||
public static final String MAIN_PAGE_TAB_COUNT = "_main_page_tab_count";
|
public static final String MAIN_PAGE_TAB_COUNT = "_main_page_tab_count";
|
||||||
public static final String MAIN_PAGE_SHOW_TAB_NAMES = "_main_page_show_tab_names";
|
public static final String MAIN_PAGE_SHOW_TAB_NAMES = "_main_page_show_tab_names";
|
||||||
|
@ -541,6 +541,8 @@
|
|||||||
<string name="settings_hide_the_number_of_votes">Hide the Number of Votes</string>
|
<string name="settings_hide_the_number_of_votes">Hide the Number of Votes</string>
|
||||||
<string name="settings_hide_the_number_of_comments">Hide the Number of Comments</string>
|
<string name="settings_hide_the_number_of_comments">Hide the Number of Comments</string>
|
||||||
<string name="settings_show_avatar_on_the_right_in_the_navigation_drawer">Show Avatar on the Left in the Navigation Drawer</string>
|
<string name="settings_show_avatar_on_the_right_in_the_navigation_drawer">Show Avatar on the Left in the Navigation Drawer</string>
|
||||||
|
<string name="settings_backup_settings_title">Backup Settings</string>
|
||||||
|
<string name="settings_restore_settings_title">Restore Settings</string>
|
||||||
|
|
||||||
<string name="no_link_available">Cannot get the link</string>
|
<string name="no_link_available">Cannot get the link</string>
|
||||||
|
|
||||||
@ -1037,4 +1039,8 @@
|
|||||||
|
|
||||||
<string name="anonymous_front_page_no_subscriptions">Start by joining a subreddit!</string>
|
<string name="anonymous_front_page_no_subscriptions">Start by joining a subreddit!</string>
|
||||||
|
|
||||||
|
<string name="backup_settings_success">Successfully exported settings to the destination directory</string>
|
||||||
|
<string name="create_zip_in_destination_directory_failed">Could not create backup zip in the destination directory</string>
|
||||||
|
<string name="backup_some_settings_failed">Could not backup some settings but others were successfully exported to the destination directory</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -38,6 +38,14 @@
|
|||||||
app:key="reset_all_settings"
|
app:key="reset_all_settings"
|
||||||
app:title="@string/settings_reset_all_settings_title" />
|
app:title="@string/settings_reset_all_settings_title" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
app:key="backup_settings"
|
||||||
|
app:title="@string/settings_backup_settings_title" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
app:key="restore_settings"
|
||||||
|
app:title="@string/settings_restore_settings_title" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:icon="@drawable/ic_info_preference_24dp"
|
android:icon="@drawable/ic_info_preference_24dp"
|
||||||
app:summary="@string/settings_advanced_settings_summary"
|
app:summary="@string/settings_advanced_settings_summary"
|
||||||
|
Loading…
Reference in New Issue
Block a user