summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2020-10-25 17:58:57 +0100
committerByteHamster <info@bytehamster.com>2020-10-25 17:58:57 +0100
commit361db64a07feb66e5632b8d60b14337b2e3497b0 (patch)
treee8aeb83771efcf565802ea371e28650ccdd0184a
parentb9c63ca992b02015fcd88c1966f805064b0068cb (diff)
downloadAntennaPod-361db64a07feb66e5632b8d60b14337b2e3497b0.zip
Allow to re-connect SAF document tree
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java67
-rw-r--r--app/src/main/res/menu/feedinfo.xml14
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java5
-rw-r--r--core/src/main/res/values/strings.xml2
4 files changed, 80 insertions, 8 deletions
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 ae03b5032..67d531173 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
@@ -1,16 +1,21 @@
package de.danoeh.antennapod.fragment;
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.LightingColorFilter;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
+import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.util.Log;
@@ -36,6 +41,7 @@ import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LangUtils;
@@ -43,12 +49,17 @@ import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.view.ToolbarIconTintManager;
+import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.MaybeOnSubscribe;
+import io.reactivex.Observable;
+import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
+import java.util.Collections;
+
/**
* Displays information about a feed.
*/
@@ -56,6 +67,7 @@ public class FeedInfoFragment extends Fragment {
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 Feed feed;
private Disposable disposable;
@@ -237,6 +249,7 @@ public class FeedInfoFragment extends Fragment {
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
+ menu.findItem(R.id.reconnect_local_folder).setVisible(feed != null && feed.isLocalFeed());
menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null
&& IntentUtils.isCallable(getContext(), new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
@@ -256,6 +269,60 @@ public class FeedInfoFragment extends Fragment {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getContext(), e.getMessage());
}
+
+ if (item.getItemId() == R.id.reconnect_local_folder) {
+ AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
+ 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);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "No activity found. Should never happen...");
+ }
+ });
+ alert.setNegativeButton(android.R.string.cancel, null);
+ alert.show();
+ return true;
+ }
+
return handled || super.onOptionsItemSelected(item);
}
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode != Activity.RESULT_OK || data == null) {
+ return;
+ }
+ Uri uri = data.getData();
+
+ if (requestCode == REQUEST_CODE_ADD_LOCAL_FOLDER) {
+ reconnectLocalFolder(uri);
+ }
+ }
+
+ private void reconnectLocalFolder(Uri uri) {
+ if (Build.VERSION.SDK_INT < 21 || feed == null) {
+ return;
+ }
+
+ Completable.fromAction(() -> {
+ getActivity().getContentResolver()
+ .takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ DocumentFile documentFile = DocumentFile.fromTreeUri(getContext(), uri);
+ if (documentFile == null) {
+ throw new IllegalArgumentException("Unable to retrieve document tree");
+ }
+ feed.setDownload_url(Feed.PREFIX_LOCAL_FOLDER + uri.toString());
+ DBTasks.updateFeed(getContext(), feed, true);
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ () -> ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(R.string.add_local_folder_success, Snackbar.LENGTH_SHORT),
+ error -> ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(error.getLocalizedMessage(), Snackbar.LENGTH_LONG));
+ }
}
diff --git a/app/src/main/res/menu/feedinfo.xml b/app/src/main/res/menu/feedinfo.xml
index f20d679a5..b1daf1f36 100644
--- a/app/src/main/res/menu/feedinfo.xml
+++ b/app/src/main/res/menu/feedinfo.xml
@@ -6,17 +6,19 @@
android:icon="?attr/location_web_site"
custom:showAsAction="ifRoom|collapseActionView"
android:title="@string/visit_website_label"
- android:visible="true">
- </item>
+ android:visible="true"/>
<item
android:id="@+id/share_link_item"
custom:showAsAction="collapseActionView"
- android:title="@string/share_website_url_label">
- </item>
+ android:title="@string/share_website_url_label"/>
<item
android:id="@+id/share_download_url_item"
custom:showAsAction="collapseActionView"
- android:title="@string/share_feed_url_label">
- </item>
+ android:title="@string/share_feed_url_label"/>
+ <item
+ android:id="@+id/reconnect_local_folder"
+ custom:showAsAction="collapseActionView"
+ android:title="@string/reconnect_local_folder"
+ android:visible="false" />
</menu>
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
index 7ebb8633b..2791be08c 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java
@@ -32,11 +32,12 @@ public class LocalFeedUpdater {
String uriString = feed.getDownload_url().replace(Feed.PREFIX_LOCAL_FOLDER, "");
DocumentFile documentFolder = DocumentFile.fromTreeUri(context, Uri.parse(uriString));
if (documentFolder == null) {
- reportError(feed, "Unable to retrieve document tree");
+ reportError(feed, "Unable to retrieve document tree."
+ + "Try re-connecting the folder on the podcast info page.");
return;
}
if (!documentFolder.exists() || !documentFolder.canRead()) {
- reportError(feed, "Cannot read local directory");
+ reportError(feed, "Cannot read local directory. Try re-connecting the folder on the podcast info page.");
return;
}
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 8cb369961..30f64b35f 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -741,6 +741,8 @@
<string name="search_powered_by">Results by %1$s</string>
<string name="add_local_folder">Add local folder</string>
<string name="add_local_folder_success">Adding local folder succeeded</string>
+ <string name="reconnect_local_folder">Re-connect local folder</string>
+ <string name="reconnect_local_folder_warning">In case of permission denials, you can use this to re-connect to the exact same folder. Do not select another folder.</string>
<string name="local_feed_description">This virtual podcast was created by adding a folder to AntennaPod.</string>
<string name="filter">Filter</string>