diff options
Diffstat (limited to 'app/src/main')
4 files changed, 229 insertions, 44 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/BackupSettings.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/BackupSettings.java index a6fc1508..e4f18e22 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/BackupSettings.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/BackupSettings.java @@ -95,17 +95,18 @@ public class BackupSettings { 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(); - } + ObjectOutputStream output = null; try { + String backupDir = context.getExternalCacheDir() + "/Backup/" + BuildConfig.VERSION_NAME; + if (!new File(backupDir).exists()) { + new File(backupDir).mkdirs(); + } else { + File backupDirFile = new File(backupDir); + FileUtils.deleteDirectory(backupDirFile); + backupDirFile.mkdirs(); + } + output = new ObjectOutputStream(new FileOutputStream(new File(backupDir + "/" + fileName + ".txt"))); output.writeObject(sharedPreferences.getAll()); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/RestoreSettings.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/RestoreSettings.java new file mode 100644 index 00000000..3b85ef9a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/RestoreSettings.java @@ -0,0 +1,171 @@ +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 net.lingala.zip4j.ZipFile; + +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.InputStream; +import java.io.ObjectInputStream; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; + +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class RestoreSettings { + public static void restoreSettings(Context context, Executor executor, Handler handler, + ContentResolver contentResolver, Uri zipFileUri, + SharedPreferences defaultSharedPreferences, + SharedPreferences lightThemeSharedPreferences, + SharedPreferences darkThemeSharedPreferences, + SharedPreferences amoledThemeSharedPreferences, + SharedPreferences sortTypeSharedPreferences, + SharedPreferences postLayoutSharedPreferences, + SharedPreferences postFeedScrolledPositionSharedPreferences, + SharedPreferences mainActivityTabsSharedPreferences, + SharedPreferences nsfwAndSpoilerSharedPreferencs, + SharedPreferences bottomAppBarSharedPreferences, + SharedPreferences postHistorySharedPreferences, + RestoreSettingsListener restoreSettingsListener) { + executor.execute(() -> { + try { + InputStream zipFileInputStream = contentResolver.openInputStream(zipFileUri); + if (zipFileInputStream == null) { + handler.post(() -> restoreSettingsListener.failed(context.getString(R.string.restore_settings_failed_cannot_get_file))); + return; + } + + String cachePath = context.getExternalCacheDir() + "/Restore/"; + if (new File(cachePath).exists()) { + FileUtils.deleteDirectory(new File(cachePath)); + } + new File(cachePath).mkdir(); + FileOutputStream zipCacheOutputStream = new FileOutputStream(new File(cachePath + "restore.zip")); + + byte[] fileReader = new byte[1024]; + + while (true) { + int read = zipFileInputStream.read(fileReader); + + if (read == -1) { + break; + } + + zipCacheOutputStream.write(fileReader, 0, read); + } + + new ZipFile(cachePath + "restore.zip", "123321".toCharArray()).extractAll(cachePath); + new File(cachePath + "restore.zip").delete(); + File[] files = new File(cachePath).listFiles(); + if (files == null || files.length <= 0) { + handler.post(() -> restoreSettingsListener.failed(context.getString(R.string.restore_settings_failed_file_corrupted))); + } else { + File restoreFilesDir = files[0]; + File[] restoreFiles = restoreFilesDir.listFiles(); + boolean result = true; + if (restoreFiles != null) { + for (File f : restoreFiles) { + if (f.getName().startsWith(SharedPreferencesUtils.DEFAULT_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(defaultSharedPreferences, f.toString()); + } else if (f.getName().startsWith(CustomThemeSharedPreferencesUtils.LIGHT_THEME_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(lightThemeSharedPreferences, f.toString()); + } else if (f.getName().startsWith(CustomThemeSharedPreferencesUtils.DARK_THEME_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(darkThemeSharedPreferences, f.toString()); + } else if (f.getName().startsWith(CustomThemeSharedPreferencesUtils.AMOLED_THEME_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(amoledThemeSharedPreferences, f.toString()); + } else if (f.getName().startsWith(SharedPreferencesUtils.SORT_TYPE_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(sortTypeSharedPreferences, f.toString()); + } else if (f.getName().startsWith(SharedPreferencesUtils.POST_LAYOUT_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(postLayoutSharedPreferences, f.toString()); + } else if (f.getName().startsWith(SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(postFeedScrolledPositionSharedPreferences, f.toString()); + } else if (f.getName().startsWith(SharedPreferencesUtils.MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(mainActivityTabsSharedPreferences, f.toString()); + } else if (f.getName().startsWith(SharedPreferencesUtils.NSFW_AND_SPOILER_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(nsfwAndSpoilerSharedPreferencs, f.toString()); + } else if (f.getName().startsWith(SharedPreferencesUtils.BOTTOM_APP_BAR_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(bottomAppBarSharedPreferences, f.toString()); + } else if (f.getName().startsWith(SharedPreferencesUtils.POST_HISTORY_SHARED_PREFERENCES_FILE)) { + result = result & importSharedPreferencsFromFile(postHistorySharedPreferences, f.toString()); + } + } + } else { + handler.post(() -> restoreSettingsListener.failed(context.getString(R.string.restore_settings_failed_file_corrupted))); + } + + FileUtils.deleteDirectory(new File(cachePath)); + + if (result) { + handler.post(restoreSettingsListener::success); + } else { + handler.post(() -> restoreSettingsListener.failed(context.getString(R.string.restore_settings_partially_failed))); + } + } + } catch (IOException e) { + e.printStackTrace(); + + handler.post(() -> restoreSettingsListener.failed(context.getString(R.string.restore_settings_partially_failed))); + } + }); + } + + private static boolean importSharedPreferencsFromFile(SharedPreferences sharedPreferences, String uriString) { + boolean result = false; + ObjectInputStream input = null; + + try { + input = new ObjectInputStream(new FileInputStream(new File(uriString))); + Object object = input.readObject(); + if (object instanceof Map) { + Map<String, Object> map = (Map<String, Object>) object; + Set<Map.Entry<String, Object>> entrySet = map.entrySet(); + SharedPreferences.Editor editor = sharedPreferences.edit(); + for (Map.Entry<String, Object> e : entrySet) { + if (e.getValue() instanceof String) { + editor.putString(e.getKey(), (String) e.getValue()); + } else if (e.getValue() instanceof Integer) { + editor.putInt(e.getKey(), (Integer) e.getValue()); + } else if (e.getValue() instanceof Float) { + editor.putFloat(e.getKey(), (Float) e.getValue()); + } else if (e.getValue() instanceof Boolean) { + editor.putBoolean(e.getKey(), (Boolean) e.getValue()); + } else if (e.getValue() instanceof Long) { + editor.putLong(e.getKey(), (Long) e.getValue()); + } + } + + editor.apply(); + + result = true; + } + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } finally { + try { + if (input != null) { + input.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return result; + } + + public interface RestoreSettingsListener { + void success(); + void failed(String errorMessage); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java index 0708edd7..899b2394 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java @@ -35,6 +35,7 @@ import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllSortTypes; import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllSubreddits; import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllThemes; import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllUsers; +import ml.docilealligator.infinityforreddit.asynctasks.RestoreSettings; import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -47,6 +48,7 @@ import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE; public class AdvancedPreferenceFragment extends PreferenceFragmentCompat { private static final int SELECT_BACKUP_SETTINGS_DIRECTORY_REQUEST_CODE = 1; + private static final int SELECT_RESTORE_SETTINGS_DIRECTORY_REQUEST_CODE = 2; @Inject RedditDataRoomDatabase mRedditDataRoomDatabase; @Inject @@ -276,23 +278,6 @@ public class AdvancedPreferenceFragment extends PreferenceFragmentCompat { 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; } }); @@ -302,6 +287,10 @@ public class AdvancedPreferenceFragment extends PreferenceFragmentCompat { restoreSettingsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { + Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT); + chooseFile.setType("application/zip"); + chooseFile = Intent.createChooser(chooseFile, "Choose a file"); + startActivityForResult(chooseFile, SELECT_RESTORE_SETTINGS_DIRECTORY_REQUEST_CODE); return true; } }); @@ -310,24 +299,44 @@ public class AdvancedPreferenceFragment extends PreferenceFragmentCompat { @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(); - } - }); + if (resultCode == RESULT_OK) { + if (requestCode == SELECT_BACKUP_SETTINGS_DIRECTORY_REQUEST_CODE) { + 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(); + } + }); + } else if (requestCode == SELECT_RESTORE_SETTINGS_DIRECTORY_REQUEST_CODE) { + Uri uri = data.getData(); + RestoreSettings.restoreSettings(activity, executor, new Handler(), activity.getContentResolver(), uri, + mSharedPreferences, lightThemeSharedPreferences, darkThemeSharedPreferences, + amoledThemeSharedPreferences, mSortTypeSharedPreferences, mPostLayoutSharedPreferences, + postFeedScrolledPositionSharedPreferences, mainActivityTabsSharedPreferences, + nsfwAndBlurringSharedPreferences, bottomAppBarSharedPreferences, postHistorySharedPreferences, + new RestoreSettings.RestoreSettingsListener() { + @Override + public void success() { + Toast.makeText(activity, R.string.restore_settings_success, Toast.LENGTH_LONG).show(); + } + + @Override + public void failed(String errorMessage) { + Toast.makeText(activity, errorMessage, Toast.LENGTH_LONG).show(); + } + }); + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 795a6a0a..d243b437 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1042,5 +1042,9 @@ <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> + <string name="restore_settings_success">Successfully restored settings. Restart the app to see the changes.</string> + <string name="restore_settings_partially_failed">Some settings may not be restored successfully. Restart the app to see the changes.</string> + <string name="restore_settings_failed_file_corrupted">Cannot restore settings. The file may be corrupted.</string> + <string name="restore_settings_failed_cannot_get_file">Cannot access the file</string> </resources> |