aboutsummaryrefslogtreecommitdiff
path: root/ime/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'ime/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java')
-rw-r--r--ime/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java167
1 files changed, 129 insertions, 38 deletions
diff --git a/ime/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java b/ime/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java
index 265d4d9a5..7a40a1e6d 100644
--- a/ime/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java
+++ b/ime/app/src/main/java/com/anysoftkeyboard/ui/settings/MainFragment.java
@@ -1,8 +1,11 @@
package com.anysoftkeyboard.ui.settings;
import android.Manifest;
+import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
@@ -28,13 +31,17 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import android.widget.Toast;
import com.anysoftkeyboard.PermissionsRequestCodes;
import com.anysoftkeyboard.base.utils.Logger;
import com.anysoftkeyboard.keyboards.AnyKeyboard;
import com.anysoftkeyboard.keyboards.Keyboard;
import com.anysoftkeyboard.keyboards.views.DemoAnyKeyboardView;
import com.anysoftkeyboard.prefs.GlobalPrefsBackup;
+import com.anysoftkeyboard.prefs.backup.PrefsXmlStorage;
import com.anysoftkeyboard.rx.RxSchedulers;
+import com.anysoftkeyboard.ui.FileExplorerCreate;
+import com.anysoftkeyboard.ui.FileExplorerRestore;
import com.anysoftkeyboard.ui.settings.setup.SetUpKeyboardWizardFragment;
import com.anysoftkeyboard.ui.settings.setup.SetupSupport;
import com.anysoftkeyboard.ui.tutorials.ChangeLogFragment;
@@ -47,6 +54,9 @@ import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.disposables.Disposables;
import io.reactivex.functions.Function;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.List;
import net.evendanan.chauffeur.lib.FragmentChauffeurActivity;
@@ -63,12 +73,21 @@ public class MainFragment extends Fragment {
static final int DIALOG_SAVE_FAILED = 11;
static final int DIALOG_LOAD_SUCCESS = 20;
static final int DIALOG_LOAD_FAILED = 21;
+ static int successDialog;
+ static int failedDialog;
+ public static List<GlobalPrefsBackup.ProviderDetails> supportedProviders;
+ public static Boolean[] checked;
+ static Function<
+ Pair<List<GlobalPrefsBackup.ProviderDetails>, Boolean[]>,
+ ObservableSource<GlobalPrefsBackup.ProviderDetails>>
+ action;
private final boolean mTestingBuild;
private AnimationDrawable mNotConfiguredAnimation = null;
@NonNull private Disposable mPaletteDisposable = Disposables.empty();
private DemoAnyKeyboardView mDemoAnyKeyboardView;
+ public int modeBackupRestore;
private GeneralDialogController mDialogController;
@NonNull private CompositeDisposable mDisposable = new CompositeDisposable();
@@ -350,16 +369,15 @@ public class MainFragment extends Fragment {
private void onBackupRestoreDialogRequired(AlertDialog.Builder builder, int optionId) {
final int actionString;
- final Function<
- Pair<List<GlobalPrefsBackup.ProviderDetails>, Boolean[]>,
- ObservableSource<GlobalPrefsBackup.ProviderDetails>>
- action;
- final int successDialog;
- final int failedDialog;
+ final int choosePathString = R.string.word_editor_action_choose_path;
+
+ final String actionCustomPath;
+ modeBackupRestore = optionId;
switch (optionId) {
case R.id.backup_prefs:
action = GlobalPrefsBackup::backup;
actionString = R.string.word_editor_action_backup_words;
+ actionCustomPath = Intent.ACTION_CREATE_DOCUMENT;
builder.setTitle(R.string.pick_prefs_providers_to_backup);
successDialog = DIALOG_SAVE_SUCCESS;
failedDialog = DIALOG_SAVE_FAILED;
@@ -367,6 +385,7 @@ public class MainFragment extends Fragment {
case R.id.restore_prefs:
action = GlobalPrefsBackup::restore;
actionString = R.string.word_editor_action_restore_words;
+ actionCustomPath = Intent.ACTION_GET_CONTENT;
builder.setTitle(R.string.pick_prefs_providers_to_restore);
successDialog = DIALOG_LOAD_SUCCESS;
failedDialog = DIALOG_LOAD_FAILED;
@@ -376,11 +395,10 @@ public class MainFragment extends Fragment {
"The option-id " + optionId + " is not supported here.");
}
- final List<GlobalPrefsBackup.ProviderDetails> supportedProviders =
- GlobalPrefsBackup.getAllPrefsProviders(getContext());
+ supportedProviders = GlobalPrefsBackup.getAllPrefsProviders(getContext());
final CharSequence[] providersTitles = new CharSequence[supportedProviders.size()];
final boolean[] initialChecked = new boolean[supportedProviders.size()];
- final Boolean[] checked = new Boolean[supportedProviders.size()];
+ checked = new Boolean[supportedProviders.size()];
for (int providerIndex = 0; providerIndex < supportedProviders.size(); providerIndex++) {
// starting with everything checked
@@ -399,38 +417,111 @@ public class MainFragment extends Fragment {
mDisposable.dispose();
mDisposable = new CompositeDisposable();
- mDisposable.add(
- RxProgressDialog.create(
- new Pair<>(supportedProviders, checked),
- getActivity(),
- getText(R.string.take_a_while_progress_message),
- R.layout.progress_window)
- .subscribeOn(RxSchedulers.background())
- .flatMap(action)
- .observeOn(RxSchedulers.mainThread())
- .subscribe(
- providerDetails ->
- Logger.i(
- "MainFragment",
- "Finished backing up %s",
- providerDetails.provider.providerId()),
- e -> {
- Logger.w(
- "MainFragment",
- e,
- "Failed to do operation due to %s",
- e.getMessage());
- mDialogController.showDialog(
- failedDialog, e.getMessage());
- },
- () ->
- mDialogController.showDialog(
- successDialog,
- GlobalPrefsBackup.getBackupFile()
- .getAbsolutePath())));
+ mDisposable.add(launchBackupRestore(0, null));
+ });
+ builder.setNeutralButton(
+ choosePathString,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ Intent dataToFileChooser = new Intent();
+ dataToFileChooser.setType("text/xml");
+ dataToFileChooser.setAction(actionCustomPath);
+ dataToFileChooser.putExtra("checked", checked);
+ try {
+ startActivityForResult(dataToFileChooser, 1);
+ } catch (ActivityNotFoundException e) {
+ Logger.e(TAG, "Could not launch the custom path activity");
+ Toast.makeText(
+ getActivity().getApplicationContext(),
+ R.string.toast_error_custom_path_backup,
+ Toast.LENGTH_LONG)
+ .show();
+ }
+
+ } else {
+ Intent intent = null;
+ if (optionId == R.id.backup_prefs) {
+ intent = new Intent(getContext(), FileExplorerCreate.class);
+ } else if (optionId == R.id.restore_prefs) {
+ intent = new Intent(getContext(), FileExplorerRestore.class);
+ }
+ startActivity(intent);
+ }
+ }
});
}
+ private Disposable launchBackupRestore(int custom, Uri customUri) {
+ File filePath;
+ if (custom == 1) filePath = new File(customUri.getPath());
+ else filePath = GlobalPrefsBackup.getBackupFile();
+
+ return RxProgressDialog.create(
+ new Pair<>(supportedProviders, checked),
+ getActivity(),
+ getText(R.string.take_a_while_progress_message),
+ R.layout.progress_window)
+ .subscribeOn(RxSchedulers.background())
+ .flatMap(action)
+ .observeOn(RxSchedulers.mainThread())
+ .subscribe(
+ providerDetails ->
+ Logger.i(
+ "MainFragment",
+ "Finished backing up %s",
+ providerDetails.provider.providerId()),
+ e -> {
+ Logger.w(
+ "MainFragment",
+ e,
+ "Failed to do operation due to %s",
+ e.getMessage());
+ mDialogController.showDialog(failedDialog, e.getMessage());
+ },
+ () -> mDialogController.showDialog(successDialog, filePath));
+ }
+
+ public static void launchRestoreCustomFileData(InputStream inputStream) {
+ PrefsXmlStorage.prefsXmlStorageCustomPath(inputStream);
+ }
+
+ public static void launchBackupCustomFileData(OutputStream outputStream) {
+ PrefsXmlStorage.prefsXmlBackupCustomPath(outputStream);
+ }
+
+ // This function is if launched when selecting neutral button of the main Fragment
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if (requestCode == 1
+ && resultCode == Activity.RESULT_OK
+ && data != null
+ && data.getDataString() != null) {
+
+ ContentResolver resolver = getContext().getContentResolver();
+ Logger.d(TAG, "Resolver " + resolver.getType(data.getData()));
+ try {
+ // Actually, it is not a good idea to convert URI into filepath.
+ // For more informations, see:
+ // https://commonsware.com/blog/2016/03/15/how-consume-content-uri.html
+ if (modeBackupRestore == R.id.restore_prefs) {
+ Logger.d(TAG, "Launching Restore at uri " + data.getData());
+ launchRestoreCustomFileData(resolver.openInputStream(data.getData()));
+ } else if (modeBackupRestore == R.id.backup_prefs) {
+ Logger.d(TAG, "Launching Backup at uri " + data.getData());
+ launchBackupCustomFileData(resolver.openOutputStream(data.getData()));
+ }
+ launchBackupRestore(1, data.getData());
+ } catch (Exception e) {
+ e.printStackTrace();
+ Logger.d(TAG, "Error when getting inputStream on onActivityResult");
+ }
+ }
+ }
+
private static class StoragePermissionRequest
extends PermissionsRequest.PermissionsRequestBase {