From 0a22e9fc3848a006247d1460c49e66e0c0e08a7c Mon Sep 17 00:00:00 2001 From: Taco Date: Fri, 24 Sep 2021 04:18:54 -0400 Subject: [PATCH] Update AndroidX Fragment to 1.3.6 (#5201) --- app/build.gradle | 1 + .../activity/OpmlImportActivity.java | 41 +++-- .../antennapod/fragment/AddFeedFragment.java | 59 ++++--- .../fragment/ExternalPlayerFragment.java | 6 +- .../antennapod/fragment/FeedInfoFragment.java | 33 ++-- .../antennapod/fragment/ItemFragment.java | 5 - .../fragment/SubscriptionFragment.java | 4 +- .../ImportExportPreferencesFragment.java | 158 +++++++++++------- build.gradle | 1 + core/build.gradle | 1 + 10 files changed, 182 insertions(+), 127 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 08e569987..5c721e88d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -122,6 +122,7 @@ dependencies { implementation "androidx.appcompat:appcompat:$appcompatVersion" implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0' implementation "androidx.core:core:$coreVersion" + implementation "androidx.fragment:fragment:$fragmentVersion" implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation "androidx.media:media:$mediaVersion" implementation "androidx.preference:preference:$preferenceVersion" diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java index a6810715c..3d0c9d113 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java @@ -1,5 +1,6 @@ package de.danoeh.antennapod.activity; +import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; @@ -15,7 +16,9 @@ import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; -import androidx.annotation.NonNull; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts.RequestPermission; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; @@ -35,7 +38,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.input.BOMInputStream; -import org.apache.commons.lang3.ArrayUtils; import java.io.InputStream; import java.io.InputStreamReader; @@ -48,7 +50,6 @@ import java.util.List; * */ public class OpmlImportActivity extends AppCompatActivity { private static final String TAG = "OpmlImportBaseActivity"; - private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 5; @Nullable private Uri uri; OpmlSelectionBinding viewBinding; private ArrayAdapter listAdapter; @@ -198,27 +199,23 @@ public class OpmlImportActivity extends AppCompatActivity { } private void requestPermission() { - String[] permissions = { android.Manifest.permission.READ_EXTERNAL_STORAGE }; - ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_READ_EXTERNAL_STORAGE); + requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE); } - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, - @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if (requestCode != PERMISSION_REQUEST_READ_EXTERNAL_STORAGE) { - return; - } - if (grantResults.length > 0 && ArrayUtils.contains(grantResults, PackageManager.PERMISSION_GRANTED)) { - startImport(); - } else { - new AlertDialog.Builder(this) - .setMessage(R.string.opml_import_ask_read_permission) - .setPositiveButton(android.R.string.ok, (dialog, which) -> requestPermission()) - .setNegativeButton(R.string.cancel_label, (dialog, which) -> finish()) - .show(); - } - } + private final ActivityResultLauncher requestPermissionLauncher = + registerForActivityResult(new RequestPermission(), isGranted -> { + if (isGranted) { + startImport(); + } else { + new AlertDialog.Builder(this) + .setMessage(R.string.opml_import_ask_read_permission) + .setPositiveButton(android.R.string.ok, (dialog, which) -> + requestPermission()) + .setNegativeButton(R.string.cancel_label, (dialog, which) -> + finish()) + .show(); + } + }); /** Starts the import process. */ private void startImport() { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java index 64e7f161e..deac31335 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -1,6 +1,5 @@ package de.danoeh.antennapod.fragment; -import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ClipboardManager; import android.content.Context; @@ -13,8 +12,12 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.activity.result.contract.ActivityResultContracts.GetContent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.documentfile.provider.DocumentFile; @@ -48,14 +51,17 @@ import java.util.Collections; public class AddFeedFragment extends Fragment { public static final String TAG = "AddFeedFragment"; - private static final int REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH = 1; - private static final int REQUEST_CODE_ADD_LOCAL_FOLDER = 2; private static final String KEY_UP_ARROW = "up_arrow"; private AddfeedBinding viewBinding; private MainActivity activity; private boolean displayUpArrow; + private final ActivityResultLauncher chooseOpmlImportPathLauncher = + registerForActivityResult(new GetContent(), this::chooseOpmlImportPathResult); + private final ActivityResultLauncher addLocalFolderLauncher = + registerForActivityResult(new AddLocalFolder(), this::addLocalFolderResult); + @Override @Nullable public View onCreateView(@NonNull LayoutInflater inflater, @@ -91,10 +97,7 @@ public class AddFeedFragment extends Fragment { viewBinding.opmlImportButton.setOnClickListener(v -> { try { - Intent intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT); - intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE); - intentGetContentAction.setType("*/*"); - startActivityForResult(intentGetContentAction, REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH); + chooseOpmlImportPathLauncher.launch("*/*"); } catch (ActivityNotFoundException e) { e.printStackTrace(); ((MainActivity) getActivity()) @@ -107,9 +110,7 @@ public class AddFeedFragment extends Fragment { return; } try { - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivityForResult(intent, REQUEST_CODE_ADD_LOCAL_FOLDER); + addLocalFolderLauncher.launch(null); } catch (ActivityNotFoundException e) { e.printStackTrace(); ((MainActivity) getActivity()) @@ -171,22 +172,23 @@ public class AddFeedFragment extends Fragment { setRetainInstance(true); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode != Activity.RESULT_OK || data == null) { + private void chooseOpmlImportPathResult(final Uri uri) { + if (uri == null) { return; } - Uri uri = data.getData(); + final Intent intent = new Intent(getContext(), OpmlImportActivity.class); + intent.setData(uri); + startActivity(intent); + } - if (requestCode == REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH) { - Intent intent = new Intent(getContext(), OpmlImportActivity.class); - intent.setData(uri); - startActivity(intent); - } else if (requestCode == REQUEST_CODE_ADD_LOCAL_FOLDER) { - Observable.fromCallable(() -> addLocalFolder(uri)) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( + private void addLocalFolderResult(final Uri uri) { + if (uri == null) { + return; + } + Observable.fromCallable(() -> addLocalFolder(uri)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( feed -> { Fragment fragment = FeedItemlistFragment.newInstance(feed.getId()); ((MainActivity) getActivity()).loadChildFragment(fragment); @@ -195,7 +197,6 @@ public class AddFeedFragment extends Fragment { ((MainActivity) getActivity()) .showSnackbarAbovePlayer(error.getLocalizedMessage(), Snackbar.LENGTH_LONG); }); - } } private Feed addLocalFolder(Uri uri) throws DownloadRequestException { @@ -219,4 +220,14 @@ public class AddFeedFragment extends Fragment { DBTasks.forceRefreshFeed(getContext(), fromDatabase, true); return fromDatabase; } + + private static class AddLocalFolder extends ActivityResultContracts.OpenDocumentTree { + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @NonNull + @Override + public Intent createIntent(@NonNull final Context context, @Nullable final Uri input) { + return super.createIntent(context, input) + .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index 8e070738c..4e6ba692b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -9,6 +9,8 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; + +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; @@ -77,8 +79,8 @@ public class ExternalPlayerFragment extends Fragment { } @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); butPlay.setOnClickListener(v -> { if (controller == null) { return; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java index da7e7e633..5acc6e364 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java @@ -1,6 +1,5 @@ package de.danoeh.antennapod.fragment; -import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ClipData; import android.content.Context; @@ -10,8 +9,12 @@ import android.graphics.LightingColorFilter; import android.net.Uri; import android.os.Build; import android.os.Bundle; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.AppCompatDrawableManager; import androidx.appcompat.widget.Toolbar; @@ -74,7 +77,8 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId"; private static final String TAG = "FeedInfoActivity"; - private static final int REQUEST_CODE_ADD_LOCAL_FOLDER = 2; + private final ActivityResultLauncher addLocalFolderLauncher = + registerForActivityResult(new AddLocalFolder(), this::addLocalFolderResult); private Feed feed; private Disposable disposable; @@ -351,9 +355,7 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic alert.setMessage(R.string.reconnect_local_folder_warning); alert.setPositiveButton(android.R.string.ok, (dialog, which) -> { try { - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivityForResult(intent, REQUEST_CODE_ADD_LOCAL_FOLDER); + addLocalFolderLauncher.launch(null); } catch (ActivityNotFoundException e) { Log.e(TAG, "No activity found. Should never happen..."); } @@ -366,16 +368,11 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic return handled; } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode != Activity.RESULT_OK || data == null) { + private void addLocalFolderResult(final Uri uri) { + if (uri == null) { return; } - Uri uri = data.getData(); - - if (requestCode == REQUEST_CODE_ADD_LOCAL_FOLDER) { - reconnectLocalFolder(uri); - } + reconnectLocalFolder(uri); } private void reconnectLocalFolder(Uri uri) { @@ -401,4 +398,14 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic error -> ((MainActivity) getActivity()) .showSnackbarAbovePlayer(error.getLocalizedMessage(), Snackbar.LENGTH_LONG)); } + + private static class AddLocalFolder extends ActivityResultContracts.OpenDocumentTree { + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @NonNull + @Override + public Intent createIntent(@NonNull final Context context, @Nullable final Uri input) { + return super.createIntent(context, input) + .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index 31c6da8cd..d4c243676 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -229,11 +229,6 @@ public class ItemFragment extends Fragment { load(); } - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - } - @Override public void onStart() { super.onStart(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index b720f1167..90ed2a8bd 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -249,8 +249,8 @@ public class SubscriptionFragment extends Fragment } @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onViewCreated(@NonNull View v, Bundle savedInstanceState) { + super.onViewCreated(v, savedInstanceState); subscriptionAdapter = new SubscriptionsRecyclerAdapter((MainActivity) getActivity()); subscriptionAdapter.setOnSelectModeListener(this); subscriptionRecycler.setAdapter(subscriptionAdapter); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java index f6aa45e93..4727983b5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java @@ -12,6 +12,13 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.util.Log; + +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.activity.result.contract.ActivityResultContracts.GetContent; +import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; +import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.core.content.FileProvider; import androidx.preference.PreferenceFragmentCompat; @@ -54,13 +61,19 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { private static final String DEFAULT_HTML_OUTPUT_NAME = "antennapod-feeds-%s.html"; private static final String CONTENT_TYPE_HTML = "text/html"; private static final String DEFAULT_FAVORITES_OUTPUT_NAME = "antennapod-favorites-%s.html"; - private static final int REQUEST_CODE_CHOOSE_OPML_EXPORT_PATH = 1; - private static final int REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH = 2; - private static final int REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH = 3; - private static final int REQUEST_CODE_RESTORE_DATABASE = 4; - private static final int REQUEST_CODE_BACKUP_DATABASE = 5; - private static final int REQUEST_CODE_CHOOSE_FAVORITES_EXPORT_PATH = 6; private static final String DATABASE_EXPORT_FILENAME = "AntennaPodBackup-%s.db"; + private final ActivityResultLauncher chooseOpmlExportPathLauncher = + registerForActivityResult(new StartActivityForResult(), this::chooseOpmlExportPathResult); + private final ActivityResultLauncher chooseHtmlExportPathLauncher = + registerForActivityResult(new StartActivityForResult(), this::chooseHtmlExportPathResult); + private final ActivityResultLauncher chooseFavoritesExportPathLauncher = + registerForActivityResult(new StartActivityForResult(), this::chooseFavoritesExportPathResult); + private final ActivityResultLauncher restoreDatabaseLauncher = + registerForActivityResult(new StartActivityForResult(), this::restoreDatabaseResult); + private final ActivityResultLauncher backupDatabaseLauncher = + registerForActivityResult(new BackupDatabase(), this::backupDatabaseResult); + private final ActivityResultLauncher chooseOpmlImportPathLauncher = + registerForActivityResult(new GetContent(), this::chooseOpmlImportPathResult); private Disposable disposable; private ProgressDialog progressDialog; @@ -95,23 +108,20 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { findPreference(PREF_OPML_EXPORT).setOnPreferenceClickListener( preference -> { openExportPathPicker(CONTENT_TYPE_OPML, dateStampFilename(DEFAULT_OPML_OUTPUT_NAME), - REQUEST_CODE_CHOOSE_OPML_EXPORT_PATH, new OpmlWriter()); + chooseOpmlExportPathLauncher, new OpmlWriter()); return true; } ); findPreference(PREF_HTML_EXPORT).setOnPreferenceClickListener( preference -> { openExportPathPicker(CONTENT_TYPE_HTML, dateStampFilename(DEFAULT_HTML_OUTPUT_NAME), - REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH, new HtmlWriter()); + chooseHtmlExportPathLauncher, new HtmlWriter()); return true; }); findPreference(PREF_OPML_IMPORT).setOnPreferenceClickListener( preference -> { try { - Intent intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT); - intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE); - intentGetContentAction.setType("*/*"); - startActivityForResult(intentGetContentAction, REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH); + chooseOpmlImportPathLauncher.launch("*/*"); } catch (ActivityNotFoundException e) { Log.e(TAG, "No activity found. Should never happen..."); } @@ -130,7 +140,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { findPreference(PREF_FAVORITE_EXPORT).setOnPreferenceClickListener( preference -> { openExportPathPicker(CONTENT_TYPE_HTML, dateStampFilename(DEFAULT_FAVORITES_OUTPUT_NAME), - REQUEST_CODE_CHOOSE_FAVORITES_EXPORT_PATH, new FavoritesWriter()); + chooseFavoritesExportPathLauncher, new FavoritesWriter()); return true; }); } @@ -160,12 +170,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { private void exportDatabase() { if (Build.VERSION.SDK_INT >= 19) { - Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT) - .addCategory(Intent.CATEGORY_OPENABLE) - .setType("application/x-sqlite3") - .putExtra(Intent.EXTRA_TITLE, dateStampFilename(DATABASE_EXPORT_FILENAME)); - - startActivityForResult(intent, REQUEST_CODE_BACKUP_DATABASE); + backupDatabaseLauncher.launch(dateStampFilename(DATABASE_EXPORT_FILENAME)); } else { File sd = Environment.getExternalStorageDirectory(); File backupDB = new File(sd, dateStampFilename(DATABASE_EXPORT_FILENAME)); @@ -193,12 +198,12 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { if (Build.VERSION.SDK_INT >= 19) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.setType("*/*"); - startActivityForResult(intent, REQUEST_CODE_RESTORE_DATABASE); + restoreDatabaseLauncher.launch(intent); } else { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); - startActivityForResult(Intent.createChooser(intent, - getString(R.string.import_select_file)), REQUEST_CODE_RESTORE_DATABASE); + restoreDatabaseLauncher.launch(Intent.createChooser(intent, + getString(R.string.import_select_file))); } } ); @@ -249,46 +254,71 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { alert.show(); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode != Activity.RESULT_OK || data == null) { + private void chooseOpmlExportPathResult(final ActivityResult result) { + if (result.getResultCode() != Activity.RESULT_OK || result.getData() == null) { return; } - Uri uri = data.getData(); - - if (requestCode == REQUEST_CODE_CHOOSE_OPML_EXPORT_PATH) { - exportWithWriter(new OpmlWriter(), uri); - } else if (requestCode == REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH) { - exportWithWriter(new HtmlWriter(), uri); - } else if (requestCode == REQUEST_CODE_CHOOSE_FAVORITES_EXPORT_PATH) { - exportWithWriter(new FavoritesWriter(), uri); - } else if (requestCode == REQUEST_CODE_RESTORE_DATABASE) { - progressDialog.show(); - disposable = Completable.fromAction(() -> DatabaseExporter.importBackup(uri, getContext())) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(() -> { - showDatabaseImportSuccessDialog(); - UserPreferences.unsetUsageCountingDate(); - progressDialog.dismiss(); - }, this::showExportErrorDialog); - } else if (requestCode == REQUEST_CODE_BACKUP_DATABASE) { - progressDialog.show(); - disposable = Completable.fromAction(() -> DatabaseExporter.exportToDocument(uri, getContext())) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(() -> { - Snackbar.make(getView(), R.string.export_success_title, Snackbar.LENGTH_LONG).show(); - progressDialog.dismiss(); - }, this::showExportErrorDialog); - } else if (requestCode == REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH) { - Intent intent = new Intent(getContext(), OpmlImportActivity.class); - intent.setData(uri); - startActivity(intent); - } + final Uri uri = result.getData().getData(); + exportWithWriter(new OpmlWriter(), uri); } - private void openExportPathPicker(String contentType, String title, int requestCode, ExportWriter writer) { + private void chooseHtmlExportPathResult(final ActivityResult result) { + if (result.getResultCode() != Activity.RESULT_OK || result.getData() == null) { + return; + } + final Uri uri = result.getData().getData(); + exportWithWriter(new HtmlWriter(), uri); + } + + private void chooseFavoritesExportPathResult(final ActivityResult result) { + if (result.getResultCode() != Activity.RESULT_OK || result.getData() == null) { + return; + } + final Uri uri = result.getData().getData(); + exportWithWriter(new FavoritesWriter(), uri); + } + + private void restoreDatabaseResult(final ActivityResult result) { + if (result.getResultCode() != Activity.RESULT_OK || result.getData() == null) { + return; + } + final Uri uri = result.getData().getData(); + progressDialog.show(); + disposable = Completable.fromAction(() -> DatabaseExporter.importBackup(uri, getContext())) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(() -> { + showDatabaseImportSuccessDialog(); + UserPreferences.unsetUsageCountingDate(); + progressDialog.dismiss(); + }, this::showExportErrorDialog); + } + + private void backupDatabaseResult(final Uri uri) { + if (uri == null) { + return; + } + progressDialog.show(); + disposable = Completable.fromAction(() -> DatabaseExporter.exportToDocument(uri, getContext())) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(() -> { + Snackbar.make(getView(), R.string.export_success_title, Snackbar.LENGTH_LONG).show(); + progressDialog.dismiss(); + }, this::showExportErrorDialog); + } + + private void chooseOpmlImportPathResult(final Uri uri) { + if (uri == null) { + return; + } + final Intent intent = new Intent(getContext(), OpmlImportActivity.class); + intent.setData(uri); + startActivity(intent); + } + + private void openExportPathPicker(String contentType, String title, + final ActivityResultLauncher result, ExportWriter writer) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) { Intent intentPickAction = new Intent(Intent.ACTION_CREATE_DOCUMENT) .addCategory(Intent.CATEGORY_OPENABLE) @@ -298,7 +328,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { // Creates an implicit intent to launch a file manager which lets // the user choose a specific directory to export to. try { - startActivityForResult(intentPickAction, requestCode); + result.launch(intentPickAction); return; } catch (ActivityNotFoundException e) { Log.e(TAG, "No activity found. Should never happen..."); @@ -309,4 +339,14 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { // fallback to the legacy export process exportWithWriter(writer, null); } + + private static class BackupDatabase extends ActivityResultContracts.CreateDocument { + @NonNull + @Override + public Intent createIntent(@NonNull final Context context, @NonNull final String input) { + return super.createIntent(context, input) + .addCategory(Intent.CATEGORY_OPENABLE) + .setType("application/x-sqlite3"); + } + } } diff --git a/build.gradle b/build.gradle index 7271a4650..2debd6ebf 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,7 @@ project.ext { annotationVersion = "1.2.0" appcompatVersion = "1.3.1" coreVersion = "1.5.0" + fragmentVersion = "1.3.6" mediaVersion = "1.1.0" preferenceVersion = "1.1.1" workManagerVersion = "2.3.4" diff --git a/core/build.gradle b/core/build.gradle index 953a85a97..59e2973ae 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -34,6 +34,7 @@ dependencies { implementation "androidx.appcompat:appcompat:$appcompatVersion" implementation "androidx.core:core:$coreVersion" implementation 'androidx.documentfile:documentfile:1.0.1' + implementation "androidx.fragment:fragment:$fragmentVersion" implementation "androidx.media:media:$mediaVersion" implementation "androidx.preference:preference:$preferenceVersion" implementation "androidx.work:work-runtime:$workManagerVersion"