diff options
author | ByteHamster <info@bytehamster.com> | 2022-04-02 11:59:41 +0200 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2022-04-02 12:03:44 +0200 |
commit | 4a91d6f5dea2c050b3713c8fc899d11ce9272dd6 (patch) | |
tree | bc371f7b6d7852b3fbc41a7f22a94b8486c32d33 /core | |
parent | 310eccc4ce0d90d95c7f34439ffcc3b29b007c42 (diff) | |
parent | 832b51de7def1f63780c285991733522e6fbd333 (diff) | |
download | AntennaPod-4a91d6f5dea2c050b3713c8fc899d11ce9272dd6.zip |
Merge branch 'master' into develop
Diffstat (limited to 'core')
14 files changed, 83 insertions, 62 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java b/core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java index d5181b2b7..cfa35ea29 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java @@ -35,4 +35,22 @@ public class MenuItemUtils { public interface UpdateRefreshMenuItemChecker { boolean isRefreshing(); } + + /** + * When pressing a context menu item, Android calls onContextItemSelected + * for ALL fragments in arbitrary order, not just for the fragment that the + * context menu was created from. This assigns the listener to every menu item, + * so that the correct fragment is always called first and can consume the click. + * <p /> + * Note that Android still calls the onContextItemSelected methods of all fragments + * when the passed listener returns false. + */ + public static void setOnClickListeners(Menu menu, MenuItem.OnMenuItemClickListener listener) { + for (int i = 0; i < menu.size(); i++) { + if (menu.getItem(i).getSubMenu() != null) { + setOnClickListeners(menu.getItem(i).getSubMenu(), listener); + } + menu.getItem(i).setOnMenuItemClickListener(listener); + } + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java index f6caa9016..081b7d5f0 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java @@ -9,6 +9,7 @@ import android.util.Log; import android.view.KeyEvent; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.app.NotificationCompat; import androidx.preference.PreferenceManager; @@ -866,51 +867,39 @@ public class UserPreferences { * * @param type The name of the folder inside the data folder. May be null * when accessing the root of the data folder. - * @return The data folder that has been requested or null if the folder - * could not be created. + * @return The data folder that has been requested or null if the folder could not be created. */ - public static File getDataFolder(String type) { - String strDir = prefs.getString(PREF_DATA_FOLDER, null); - if (strDir == null) { - Log.d(TAG, "Using default data folder"); - return context.getExternalFilesDir(type); - } else { - File dataDir = new File(strDir); - if (!dataDir.exists()) { - if (!dataDir.mkdir()) { - Log.w(TAG, "Could not create data folder"); - return null; - } - } + public static File getDataFolder(@Nullable String type) { + File dataFolder = getTypeDir(prefs.getString(PREF_DATA_FOLDER, null), type); + if (dataFolder == null || !dataFolder.canWrite()) { + Log.d(TAG, "User data folder not writable or not set. Trying default."); + dataFolder = context.getExternalFilesDir(type); + } + if (dataFolder == null || !dataFolder.canWrite()) { + Log.d(TAG, "Default data folder not available or not writable. Falling back to internal memory."); + dataFolder = getTypeDir(context.getFilesDir().getAbsolutePath(), type); + } + return dataFolder; + } - if (type == null) { - return dataDir; - } else { - // handle path separators - String[] dirs = type.split("/"); - for (int i = 0; i < dirs.length; i++) { - if (dirs.length > 0) { - if (i < dirs.length - 1) { - dataDir = getDataFolder(dirs[i]); - if (dataDir == null) { - return null; - } - } - type = dirs[i]; - } - } - File typeDir = new File(dataDir, type); - if (!typeDir.exists()) { - if (dataDir.canWrite()) { - if (!typeDir.mkdir()) { - Log.e(TAG, "Could not create data folder named " + type); - return null; - } - } - } - return typeDir; + @Nullable + private static File getTypeDir(@Nullable String baseDirPath, @Nullable String type) { + if (baseDirPath == null) { + return null; + } + File baseDir = new File(baseDirPath); + File typeDir = type == null ? baseDir : new File(baseDir, type); + if (!typeDir.exists()) { + if (!baseDir.canWrite()) { + Log.e(TAG, "Base dir is not writable " + baseDir.getAbsolutePath()); + return null; + } + if (!typeDir.mkdirs()) { + Log.e(TAG, "Could not create type dir " + typeDir.getAbsolutePath()); + return null; } } + return typeDir; } public static void setDataFolder(String dir) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java index 789cde714..fc708ef6a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java @@ -290,8 +290,9 @@ public class DownloadRequest implements Parcelable { this.feedfileType = feed.getTypeAsInt(); } - public void setInitiatedByUser(boolean initiatedByUser) { + public Builder withInitiatedByUser(boolean initiatedByUser) { this.initiatedByUser = initiatedByUser; + return this; } public void setForce(boolean force) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index 4869b3faa..1cd456072 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -508,7 +508,7 @@ public class DownloadService extends Service { for (Feed feed : feeds) { if (feed.getPreferences().getKeepUpdated()) { DownloadRequest.Builder builder = DownloadRequestCreator.create(feed); - builder.setInitiatedByUser(initiatedByUser); + builder.withInitiatedByUser(initiatedByUser); addNewRequest(builder.build()); } } @@ -554,7 +554,7 @@ public class DownloadService extends Service { * * @param status the download that is going to be saved */ - private void saveDownloadStatus(DownloadStatus status) { + private void saveDownloadStatus(@NonNull DownloadStatus status) { reportQueue.add(status); DBWriter.addDownloadStatus(status); } @@ -664,7 +664,6 @@ public class DownloadService extends Service { if (notificationUpdater != null) { notificationUpdater.run(); } - downloadEnqueueExecutor.shutdown(); // Do not accept new downloads cancelNotificationUpdater(); ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE); stopSelf(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java index 22981dcda..dc5893b23 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedParserTask.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.download.handler; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.NonNull; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedPreferences; @@ -18,6 +19,7 @@ import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import java.io.File; import java.io.IOException; +import java.util.Date; import java.util.concurrent.Callable; public class FeedParserTask implements Callable<FeedHandlerResult> { @@ -28,6 +30,10 @@ public class FeedParserTask implements Callable<FeedHandlerResult> { public FeedParserTask(DownloadRequest request) { this.request = request; + downloadStatus = new DownloadStatus( + 0, request.getTitle(), 0, request.getFeedfileType(), false, + false, true, DownloadError.ERROR_REQUEST_ERROR, new Date(), + "Unknown error: Status not set", request.isInitiatedByUser()); } @Override @@ -112,6 +118,7 @@ public class FeedParserTask implements Callable<FeedHandlerResult> { } } + @NonNull public DownloadStatus getDownloadStatus() { return downloadStatus; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java index 042a903d3..5e97c233f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/FeedSyncTask.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.download.handler; import android.content.Context; +import androidx.annotation.NonNull; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.model.download.DownloadStatus; @@ -11,19 +12,17 @@ import de.danoeh.antennapod.parser.feed.FeedHandlerResult; public class FeedSyncTask { private final DownloadRequest request; private final Context context; - private DownloadStatus downloadStatus; private Feed savedFeed; + private final FeedParserTask task; public FeedSyncTask(Context context, DownloadRequest request) { this.request = request; this.context = context; + this.task = new FeedParserTask(request); } public boolean run() { - FeedParserTask task = new FeedParserTask(request); FeedHandlerResult result = task.call(); - downloadStatus = task.getDownloadStatus(); - if (!task.isSuccessful()) { return false; } @@ -39,8 +38,9 @@ public class FeedSyncTask { return true; } + @NonNull public DownloadStatus getDownloadStatus() { - return downloadStatus; + return task.getDownloadStatus(); } public Feed getSavedFeed() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java index 4aa76f453..b30f44eec 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java @@ -29,20 +29,18 @@ import de.danoeh.antennapod.net.sync.model.EpisodeAction; public class MediaDownloadedHandler implements Runnable { private static final String TAG = "MediaDownloadedHandler"; private final DownloadRequest request; - private final DownloadStatus status; private final Context context; private DownloadStatus updatedStatus; public MediaDownloadedHandler(@NonNull Context context, @NonNull DownloadStatus status, @NonNull DownloadRequest request) { - this.status = status; this.request = request; this.context = context; + this.updatedStatus = status; } @Override public void run() { - updatedStatus = status; FeedMedia media = DBReader.getFeedMedia(request.getFeedfileId()); if (media == null) { Log.e(TAG, "Could not find downloaded media object in database"); @@ -111,6 +109,7 @@ public class MediaDownloadedHandler implements Runnable { } } + @NonNull public DownloadStatus getUpdatedStatus() { return updatedStatus; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java index f2afa6fd1..52638ca77 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java @@ -96,7 +96,7 @@ public class AutomaticDownloadAlgorithm { List<DownloadRequest> requests = new ArrayList<>(); for (FeedItem episode : itemsToDownload) { DownloadRequest.Builder request = DownloadRequestCreator.create(episode.getMedia()); - request.setInitiatedByUser(false); + request.withInitiatedByUser(false); requests.add(request.build()); } DownloadService.download(context, false, requests.toArray(new DownloadRequest[0])); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java index 64cf446aa..528ded708 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java @@ -103,7 +103,10 @@ public final class DBReader { try (Cursor cursor = adapter.getFeedCursorDownloadUrls()) { List<String> result = new ArrayList<>(cursor.getCount()); while (cursor.moveToNext()) { - result.add(cursor.getString(1)); + String url = cursor.getString(1); + if (url != null && !url.startsWith(Feed.PREFIX_LOCAL_FOLDER)) { + result.add(url); + } } return result; } finally { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java index e5310c4ff..6ec27c01e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java @@ -162,7 +162,7 @@ public final class DBTasks { private static void forceRefreshFeed(Context context, Feed feed, boolean loadAllPages, boolean initiatedByUser) { DownloadRequest.Builder builder = DownloadRequestCreator.create(feed); - builder.setInitiatedByUser(initiatedByUser); + builder.withInitiatedByUser(initiatedByUser); builder.setForce(true); builder.loadAllPages(loadAllPages); DownloadService.download(context, false, builder.build()); diff --git a/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java b/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java index 6d6d7bb41..0640f7577 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/sync/SyncService.java @@ -145,6 +145,10 @@ public class SyncService extends Worker { Log.d(TAG, "Downloaded subscription changes: " + subscriptionChanges); for (String downloadUrl : subscriptionChanges.getAdded()) { + if (!downloadUrl.startsWith("http")) { // Also matches https + Log.d(TAG, "Skipping url: " + downloadUrl); + continue; + } if (!URLChecker.containsUrl(localSubscriptions, downloadUrl) && !queuedRemovedFeeds.contains(downloadUrl)) { Feed feed = new Feed(downloadUrl, null); DownloadRequest.Builder builder = DownloadRequestCreator.create(feed); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java b/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java index dbad1f63e..674082a13 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java @@ -123,7 +123,7 @@ public class AutoUpdateManager { Log.d(TAG, "Run auto update immediately in background."); if (!NetworkUtils.networkAvailable()) { Log.d(TAG, "Ignoring: No network connection."); - } else if (NetworkUtils.isEpisodeDownloadAllowed()) { + } else if (NetworkUtils.isFeedRefreshAllowed()) { startRefreshAllFeeds(context); } else { confirmMobileAllFeedsRefresh(context); @@ -134,8 +134,12 @@ public class AutoUpdateManager { AlertDialog.Builder builder = new AlertDialog.Builder(context) .setTitle(R.string.feed_refresh_title) .setMessage(R.string.confirm_mobile_feed_refresh_dialog_message) - .setPositiveButton(R.string.yes, + .setPositiveButton(R.string.confirm_mobile_streaming_button_once, (dialog, which) -> startRefreshAllFeeds(context)) + .setNeutralButton(R.string.confirm_mobile_streaming_button_always, (dialog, which) -> { + UserPreferences.setAllowMobileFeedRefresh(true); + startRefreshAllFeeds(context); + }) .setNegativeButton(R.string.no, null); builder.show(); } diff --git a/core/src/main/res/values-v23/styles.xml b/core/src/main/res/values-v23/styles.xml index dde8e41ae..33c64ad4a 100644 --- a/core/src/main/res/values-v23/styles.xml +++ b/core/src/main/res/values-v23/styles.xml @@ -4,7 +4,7 @@ <item name="android:windowContentTransitions">true</item> <item name="android:statusBarColor">@color/background_light</item> <item name="android:windowLightStatusBar">true</item> - <item name="android:navigationBarColor">@color/background_light</item> + <item name="android:navigationBarColor">@color/grey600</item> </style> <style name="Theme.AntennaPod.Dark" parent="Theme.Base.AntennaPod.Dark"> diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index 8c15d35c0..2fa76eae5 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -109,7 +109,6 @@ <style name="Theme.AntennaPod.Light.Translucent" parent="Theme.AntennaPod.Light.NoTitle"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> - <item name="android:background">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> <item name="android:backgroundDimEnabled">true</item> <item name="android:windowAnimationStyle">@style/AnimationFade</item> @@ -120,7 +119,6 @@ <style name="Theme.AntennaPod.Dark.Translucent" parent="Theme.AntennaPod.Dark.NoTitle"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> - <item name="android:background">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> <item name="android:backgroundDimEnabled">true</item> <item name="android:windowAnimationStyle">@style/AnimationFade</item> @@ -131,7 +129,6 @@ <style name="Theme.AntennaPod.TrueBlack.Translucent" parent="Theme.AntennaPod.TrueBlack"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> - <item name="android:background">@android:color/transparent</item> <item name="android:windowContentOverlay">@null</item> <item name="android:backgroundDimEnabled">true</item> <item name="android:windowAnimationStyle">@style/AnimationFade</item> |