diff options
Diffstat (limited to 'core')
18 files changed, 171 insertions, 140 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/main/java/de/danoeh/antennapod/core/ClientConfig.java index 9dab98939..360c8c9e2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/ClientConfig.java +++ b/core/src/main/java/de/danoeh/antennapod/core/ClientConfig.java @@ -11,6 +11,4 @@ public class ClientConfig { public static String USER_AGENT; public static ApplicationCallbacks applicationCallbacks; - - public static DownloadServiceCallbacks downloadServiceCallbacks; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java b/core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java deleted file mode 100644 index 53ed63c2d..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/DownloadServiceCallbacks.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.danoeh.antennapod.core; - -import android.app.PendingIntent; -import android.content.Context; - -import de.danoeh.antennapod.net.download.serviceinterface.DownloadRequest; - -/** - * Callbacks for the DownloadService of the core module. - */ -public interface DownloadServiceCallbacks { - - /** - * Returns a PendingIntent for a notification the main notification of the DownloadService. - * <p/> - * The PendingIntent takes the users to a screen where they can observe all currently running - * downloads. - * - * @return A non-null PendingIntent for the notification. - */ - PendingIntent getNotificationContentIntent(Context context); - - /** - * Returns a PendingIntent for a notification that tells the user to enter a username - * or a password for a requested download. - * <p/> - * The PendingIntent takes users to an Activity that lets the user enter their username - * and password to retry the download. - * - * @return A non-null PendingIntent for the notification. - */ - PendingIntent getAuthentificationNotificationContentIntent(Context context, DownloadRequest request); - - /** - * Returns a PendingIntent for notification that notifies the user about the completion of downloads - * along with information about failed and successful downloads. - * <p/> - * The PendingIntent takes users to an activity where they can look at all successful and failed downloads. - * - * @return A non-null PendingIntent for the notification - */ - PendingIntent getReportNotificationContentIntent(Context context); - - /** - * Returns a PendingIntent for notification that notifies the user about the episodes that have been automatically - * downloaded. - * <p/> - * The PendingIntent takes users to an activity where they can look at their episode queue. - * - * @return A non-null PendingIntent for the notification - */ - PendingIntent getAutoDownloadReportNotificationContentIntent(Context context); -} - diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java index b7e4934f5..afe814fcb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/ThemeSwitcher.java @@ -59,12 +59,15 @@ public abstract class ThemeSwitcher { if (theme == UserPreferences.ThemePreference.SYSTEM) { int nightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; if (nightMode == Configuration.UI_MODE_NIGHT_YES) { - return UserPreferences.ThemePreference.DARK; + theme = UserPreferences.ThemePreference.DARK; } else { - return UserPreferences.ThemePreference.LIGHT; + theme = UserPreferences.ThemePreference.LIGHT; } } + if (theme == UserPreferences.ThemePreference.DARK && UserPreferences.getIsBlackTheme()) { + theme = UserPreferences.ThemePreference.BLACK; + } return theme; } } 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 30745a60d..0e55e9a36 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 @@ -14,6 +14,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import androidx.core.app.NotificationManagerCompat; import androidx.core.app.ServiceCompat; import de.danoeh.antennapod.core.R; @@ -82,6 +83,7 @@ public class DownloadService extends Service { private final ExecutorService downloadEnqueueExecutor; private final List<DownloadStatus> reportQueue = new ArrayList<>(); + private final List<DownloadRequest> failedRequestsForReport = new ArrayList<>(); private DownloadServiceNotification notificationManager; private final NewEpisodesNotification newEpisodesNotification; private NotificationUpdater notificationUpdater; @@ -176,11 +178,15 @@ public class DownloadService extends Service { if (intent != null && intent.hasExtra(EXTRA_REQUESTS)) { Notification notification = notificationManager.updateNotifications(downloads); startForeground(R.id.notification_downloading, notification); + NotificationManagerCompat.from(this).cancel(R.id.notification_download_report); + NotificationManagerCompat.from(this).cancel(R.id.notification_auto_download_report); setupNotificationUpdaterIfNecessary(); downloadEnqueueExecutor.execute(() -> onDownloadQueued(intent)); } else if (intent != null && intent.getBooleanExtra(EXTRA_REFRESH_ALL, false)) { Notification notification = notificationManager.updateNotifications(downloads); startForeground(R.id.notification_downloading, notification); + NotificationManagerCompat.from(this).cancel(R.id.notification_download_report); + NotificationManagerCompat.from(this).cancel(R.id.notification_auto_download_report); setupNotificationUpdaterIfNecessary(); downloadEnqueueExecutor.execute(() -> enqueueAll(intent)); } else if (downloads.size() == 0) { @@ -198,8 +204,9 @@ public class DownloadService extends Service { boolean showAutoDownloadReport = UserPreferences.showAutoDownloadReport(); if (UserPreferences.showDownloadReport() || showAutoDownloadReport) { - notificationManager.updateReport(reportQueue, showAutoDownloadReport); + notificationManager.updateReport(reportQueue, showAutoDownloadReport, failedRequestsForReport); reportQueue.clear(); + failedRequestsForReport.clear(); } unregisterReceiver(cancelDownloadReceiver); @@ -273,8 +280,8 @@ public class DownloadService extends Service { if (type == Feed.FEEDFILETYPE_FEED) { Log.d(TAG, "Handling completed Feed Download"); - FeedSyncTask task = new FeedSyncTask(DownloadService.this, request); - boolean success = task.run(); + FeedSyncTask feedSyncTask = new FeedSyncTask(DownloadService.this, request); + boolean success = feedSyncTask.run(); if (success) { if (request.getFeedfileId() == 0) { @@ -283,24 +290,26 @@ public class DownloadService extends Service { // we create a 'successful' download log if the feed's last refresh failed List<DownloadStatus> log = DBReader.getFeedDownloadLog(request.getFeedfileId()); if (log.size() > 0 && !log.get(0).isSuccessful()) { - saveDownloadStatus(task.getDownloadStatus()); + saveDownloadStatus(feedSyncTask.getDownloadStatus(), downloader.getDownloadRequest()); } if (!request.isInitiatedByUser()) { // Was stored in the database before and not initiated manually - newEpisodesNotification.showIfNeeded(DownloadService.this, task.getSavedFeed()); + newEpisodesNotification.showIfNeeded(DownloadService.this, feedSyncTask.getSavedFeed()); } if (downloader.permanentRedirectUrl != null) { DBWriter.updateFeedDownloadURL(request.getSource(), downloader.permanentRedirectUrl); + } else if (feedSyncTask.getRedirectUrl() != null) { + DBWriter.updateFeedDownloadURL(request.getSource(), feedSyncTask.getRedirectUrl()); } } else { DBWriter.setFeedLastUpdateFailed(request.getFeedfileId(), true); - saveDownloadStatus(task.getDownloadStatus()); + saveDownloadStatus(feedSyncTask.getDownloadStatus(), downloader.getDownloadRequest()); } } else if (type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { Log.d(TAG, "Handling completed FeedMedia Download"); MediaDownloadedHandler handler = new MediaDownloadedHandler(DownloadService.this, status, request); handler.run(); - saveDownloadStatus(handler.getUpdatedStatus()); + saveDownloadStatus(handler.getUpdatedStatus(), downloader.getDownloadRequest()); } } @@ -319,7 +328,7 @@ public class DownloadService extends Service { DownloadServiceInterface.get().download(this, false, downloader.getDownloadRequest()); } else { Log.e(TAG, "Download failed"); - saveDownloadStatus(status); + saveDownloadStatus(status, downloader.getDownloadRequest()); new FailedDownloadHandler(downloader.getDownloadRequest()).run(); if (type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { @@ -459,6 +468,9 @@ public class DownloadService extends Service { if (feed.getPreferences().getKeepUpdated()) { DownloadRequest.Builder builder = DownloadRequestCreator.create(feed); builder.withInitiatedByUser(initiatedByUser); + if (feed.hasLastUpdateFailed()) { + builder.setForce(true); + } addNewRequest(builder.build()); } } @@ -507,8 +519,11 @@ public class DownloadService extends Service { * * @param status the download that is going to be saved */ - private void saveDownloadStatus(@NonNull DownloadStatus status) { + private void saveDownloadStatus(@NonNull DownloadStatus status, @NonNull DownloadRequest request) { reportQueue.add(status); + if (!status.isSuccessful() && !status.isCancelled()) { + failedRequestsForReport.add(request); + } DBWriter.addDownloadStatus(status); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java index 384a6070e..7b7e52e0e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java @@ -16,6 +16,13 @@ public class DownloadServiceInterfaceImpl extends DownloadServiceInterface { private static final String TAG = "DownloadServiceInterface"; public void download(Context context, boolean cleanupMedia, DownloadRequest... requests) { + Intent intent = makeDownloadIntent(context, cleanupMedia, requests); + if (intent != null) { + ContextCompat.startForegroundService(context, intent); + } + } + + public Intent makeDownloadIntent(Context context, boolean cleanupMedia, DownloadRequest... requests) { ArrayList<DownloadRequest> requestsToSend = new ArrayList<>(); for (DownloadRequest request : requests) { if (!isDownloadingFile(request.getSource())) { @@ -23,7 +30,7 @@ public class DownloadServiceInterfaceImpl extends DownloadServiceInterface { } } if (requestsToSend.isEmpty()) { - return; + return null; } else if (requestsToSend.size() > 100) { if (BuildConfig.DEBUG) { throw new IllegalArgumentException("Android silently drops intent payloads that are too large"); @@ -38,7 +45,7 @@ public class DownloadServiceInterfaceImpl extends DownloadServiceInterface { if (cleanupMedia) { launchIntent.putExtra(DownloadService.EXTRA_CLEANUP_MEDIA, true); } - ContextCompat.startForegroundService(context, launchIntent); + return launchIntent; } public void refreshAllFeeds(Context context, boolean initiatedByUser) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java index fd24a716e..6ba8348d6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java @@ -4,9 +4,10 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; +import android.os.Build; import android.util.Log; import androidx.core.app.NotificationCompat; -import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.util.DownloadErrorLabel; import de.danoeh.antennapod.model.download.DownloadStatus; @@ -14,6 +15,9 @@ import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.core.util.gui.NotificationUtils; import de.danoeh.antennapod.net.download.serviceinterface.DownloadRequest; +import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface; +import de.danoeh.antennapod.ui.appstartintent.DownloadAuthenticationActivityStarter; +import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter; import java.util.List; @@ -34,7 +38,7 @@ public class DownloadServiceNotification { .setWhen(0) .setOnlyAlertOnce(true) .setShowWhen(false) - .setContentIntent(ClientConfig.downloadServiceCallbacks.getNotificationContentIntent(context)) + .setContentIntent(getNotificationContentIntent(context)) .setSmallIcon(R.drawable.ic_notification_sync); notificationCompatBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); @@ -150,7 +154,8 @@ public class DownloadServiceNotification { * user about the number of completed downloads. A report will only be * created if there is at least one failed download excluding images */ - public void updateReport(List<DownloadStatus> reportQueue, boolean showAutoDownloadReport) { + public void updateReport(List<DownloadStatus> reportQueue, boolean showAutoDownloadReport, + List<DownloadRequest> failedRequests) { // check if report should be created boolean createReport = false; int failedDownloads = 0; @@ -170,48 +175,68 @@ public class DownloadServiceNotification { } } - if (createReport) { - Log.d(TAG, "Creating report"); - - // create notification object - String channelId; - int titleId; - int iconId; - int id; - String content; - PendingIntent intent; - if (failedDownloads == 0) { - // We are generating an auto-download report - channelId = NotificationUtils.CHANNEL_ID_AUTO_DOWNLOAD; - titleId = R.string.auto_download_report_title; - iconId = R.drawable.ic_notification_new; - intent = ClientConfig.downloadServiceCallbacks.getAutoDownloadReportNotificationContentIntent(context); - id = R.id.notification_auto_download_report; - content = createAutoDownloadNotificationContent(reportQueue); - } else { - channelId = NotificationUtils.CHANNEL_ID_DOWNLOAD_ERROR; - titleId = R.string.download_report_title; - iconId = R.drawable.ic_notification_sync_error; - intent = ClientConfig.downloadServiceCallbacks.getReportNotificationContentIntent(context); - id = R.id.notification_download_report; - content = createFailedDownloadNotificationContent(reportQueue); - } - - NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId); - builder.setTicker(context.getString(titleId)) - .setContentTitle(context.getString(titleId)) - .setContentText(content) - .setStyle(new NotificationCompat.BigTextStyle().bigText(content)) - .setSmallIcon(iconId) - .setContentIntent(intent) - .setAutoCancel(true); - builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); - NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - nm.notify(id, builder.build()); - Log.d(TAG, "Download report notification was posted"); - } else { + if (!createReport) { Log.d(TAG, "No report is created"); + return; + } + Log.d(TAG, "Creating report"); + if (failedDownloads == 0) { + createAutoDownloadReportNotification(reportQueue); + } else { + createDownloadFailedNotification(reportQueue, failedRequests); + } + Log.d(TAG, "Download report notification was posted"); + } + + private void createAutoDownloadReportNotification(List<DownloadStatus> reportQueue) { + PendingIntent intent = getAutoDownloadReportNotificationContentIntent(context); + String content = createAutoDownloadNotificationContent(reportQueue); + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, + NotificationUtils.CHANNEL_ID_AUTO_DOWNLOAD); + builder.setTicker(context.getString(R.string.auto_download_report_title)) + .setContentTitle(context.getString(R.string.auto_download_report_title)) + .setContentText(content) + .setStyle(new NotificationCompat.BigTextStyle().bigText(content)) + .setSmallIcon(R.drawable.ic_notification_new) + .setContentIntent(intent) + .setAutoCancel(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); + NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + nm.notify(R.id.notification_auto_download_report, builder.build()); + } + + private void createDownloadFailedNotification(List<DownloadStatus> reportQueue, + List<DownloadRequest> failedRequests) { + Intent retryIntent = DownloadServiceInterface.get().makeDownloadIntent(context, + false, failedRequests.toArray(new DownloadRequest[0])); + PendingIntent retryPendingIntent = null; + if (retryIntent != null && Build.VERSION.SDK_INT >= 26) { + retryPendingIntent = PendingIntent.getForegroundService(context, R.id.pending_intent_download_service_retry, + retryIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } else if (retryIntent != null) { + retryPendingIntent = PendingIntent.getService(context, + R.id.pending_intent_download_service_retry, retryIntent, + PendingIntent.FLAG_UPDATE_CURRENT + | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); + } + PendingIntent intent = getReportNotificationContentIntent(context); + String content = createFailedDownloadNotificationContent(reportQueue); + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, + NotificationUtils.CHANNEL_ID_DOWNLOAD_ERROR); + builder.setTicker(context.getString(R.string.download_report_title)) + .setContentTitle(context.getString(R.string.download_report_title)) + .setContentText(content) + .setStyle(new NotificationCompat.BigTextStyle().bigText(content)) + .setSmallIcon(R.drawable.ic_notification_sync_error) + .setContentIntent(intent) + .setAutoCancel(true); + if (retryPendingIntent != null) { + builder.addAction(new NotificationCompat.Action( + R.drawable.ic_notification_sync, context.getString(R.string.retry_label), retryPendingIntent)); } + builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); + NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + nm.notify(R.id.notification_download_report, builder.build()); } public void postAuthenticationNotification(final DownloadRequest downloadRequest) { @@ -226,9 +251,32 @@ public class DownloadServiceNotification { + ": " + resourceTitle)) .setSmallIcon(R.drawable.ic_notification_key) .setAutoCancel(true) - .setContentIntent(ClientConfig.downloadServiceCallbacks.getAuthentificationNotificationContentIntent(context, downloadRequest)); + .setContentIntent(new DownloadAuthenticationActivityStarter( + context, downloadRequest.getFeedfileId(), downloadRequest).getPendingIntent()); builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(downloadRequest.getSource().hashCode(), builder.build()); } + + public PendingIntent getReportNotificationContentIntent(Context context) { + Intent intent = new MainActivityStarter(context) + .withFragmentLoaded("DownloadsFragment") + .withFragmentArgs("show_logs", true) + .getIntent(); + return PendingIntent.getActivity(context, R.id.pending_intent_download_service_report, intent, + PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); + } + + public PendingIntent getAutoDownloadReportNotificationContentIntent(Context context) { + Intent intent = new MainActivityStarter(context).withFragmentLoaded("QueueFragment").getIntent(); + return PendingIntent.getActivity(context, R.id.pending_intent_download_service_autodownload_report, intent, + PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); + } + + public PendingIntent getNotificationContentIntent(Context context) { + Intent intent = new MainActivityStarter(context).withFragmentLoaded("DownloadsFragment").getIntent(); + return PendingIntent.getActivity(context, + R.id.pending_intent_download_service_notification, intent, + PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); + } } 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 07670bff3..e3010fe24 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 @@ -14,6 +14,7 @@ public class FeedSyncTask { private final Context context; private Feed savedFeed; private final FeedParserTask task; + private FeedHandlerResult feedHandlerResult; public FeedSyncTask(Context context, DownloadRequest request) { this.request = request; @@ -22,15 +23,15 @@ public class FeedSyncTask { } public boolean run() { - FeedHandlerResult result = task.call(); + feedHandlerResult = task.call(); if (!task.isSuccessful()) { return false; } - savedFeed = DBTasks.updateFeed(context, result.feed, false); + savedFeed = DBTasks.updateFeed(context, feedHandlerResult.feed, false); // If loadAllPages=true, check if another page is available and queue it for download final boolean loadAllPages = request.getArguments().getBoolean(DownloadRequest.REQUEST_ARG_LOAD_ALL_PAGES); - final Feed feed = result.feed; + final Feed feed = feedHandlerResult.feed; if (loadAllPages && feed.getNextPageLink() != null) { feed.setId(savedFeed.getId()); DBTasks.loadNextPageOfFeed(context, feed, true); @@ -46,4 +47,8 @@ public class FeedSyncTask { public Feed getSavedFeed() { return savedFeed; } + + public String getRedirectUrl() { + return feedHandlerResult.redirectUrl; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 434aa77e7..176a78f0f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -399,7 +399,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { mediaItems.add(createBrowsableMediaItem(R.string.queue_label, R.drawable.ic_playlist_play_black, DBReader.getQueue().size())); mediaItems.add(createBrowsableMediaItem(R.string.downloads_label, R.drawable.ic_download_black, - DBReader.getDownloadedItems().size())); + DBReader.getDownloadedItems(UserPreferences.getDownloadsSortedOrder()).size())); mediaItems.add(createBrowsableMediaItem(R.string.episodes_label, R.drawable.ic_feed_black, DBReader.getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.UNPLAYED)))); List<Feed> feeds = DBReader.getFeedList(); @@ -413,7 +413,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (parentId.equals(getResources().getString(R.string.queue_label))) { feedItems = DBReader.getQueue(); } else if (parentId.equals(getResources().getString(R.string.downloads_label))) { - feedItems = DBReader.getDownloadedItems(); + feedItems = DBReader.getDownloadedItems(UserPreferences.getDownloadsSortedOrder()); } else if (parentId.equals(getResources().getString(R.string.episodes_label))) { feedItems = DBReader.getRecentlyPublishedEpisodes(0, MAX_ANDROID_AUTO_EPISODES_PER_FEED, diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java index 3111d01bc..3d69dbdbc 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java @@ -294,6 +294,7 @@ public class PlaybackServiceTaskManager { public void run() { Log.d(TAG, "Starting"); long lastTick = System.currentTimeMillis(); + EventBus.getDefault().post(SleepTimerUpdatedEvent.updated(timeLeft)); while (timeLeft > 0) { try { Thread.sleep(UPDATE_INTERVAL); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java index 2be330a3e..30c50b576 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/APCleanupAlgorithm.java @@ -15,6 +15,7 @@ import java.util.concurrent.ExecutionException; import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; +import de.danoeh.antennapod.model.feed.SortOrder; /** * Implementation of the EpisodeCleanupAlgorithm interface used by AntennaPod. @@ -88,7 +89,7 @@ public class APCleanupAlgorithm extends EpisodeCleanupAlgorithm { @NonNull private List<FeedItem> getCandidates() { List<FeedItem> candidates = new ArrayList<>(); - List<FeedItem> downloadedItems = DBReader.getDownloadedItems(); + List<FeedItem> downloadedItems = DBReader.getDownloadedItems(SortOrder.DATE_NEW_OLD); Date mostRecentDateForDeletion = calcMostRecentDateForDeletion(new Date()); for (FeedItem item : downloadedItems) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/APQueueCleanupAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/APQueueCleanupAlgorithm.java index 9fce34a44..3241f37ef 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/APQueueCleanupAlgorithm.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/APQueueCleanupAlgorithm.java @@ -12,6 +12,7 @@ import java.util.Locale; import java.util.concurrent.ExecutionException; import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.model.feed.SortOrder; /** * A cleanup algorithm that removes any item that isn't in the queue and isn't a favorite @@ -75,7 +76,7 @@ public class APQueueCleanupAlgorithm extends EpisodeCleanupAlgorithm { @NonNull private List<FeedItem> getCandidates() { List<FeedItem> candidates = new ArrayList<>(); - List<FeedItem> downloadedItems = DBReader.getDownloadedItems(); + List<FeedItem> downloadedItems = DBReader.getDownloadedItems(SortOrder.DATE_NEW_OLD); for (FeedItem item : downloadedItems) { if (item.hasMedia() && item.getMedia().isDownloaded() 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 55acb8b92..4641e366c 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 @@ -20,6 +20,7 @@ import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedItemFilter; import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.model.feed.FeedPreferences; +import de.danoeh.antennapod.model.feed.SortOrder; import de.danoeh.antennapod.model.feed.SubscriptionsFilter; import de.danoeh.antennapod.storage.preferences.UserPreferences; import de.danoeh.antennapod.model.download.DownloadStatus; @@ -280,15 +281,19 @@ public final class DBReader { * @return A list of FeedItems whose episdoe has been downloaded. */ @NonNull - public static List<FeedItem> getDownloadedItems() { + public static List<FeedItem> getDownloadedItems(@Nullable SortOrder sortOrder) { Log.d(TAG, "getDownloadedItems() called"); + // Set a default sort order + if (sortOrder == null) { + sortOrder = SortOrder.DATE_NEW_OLD; + } + PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); - try (Cursor cursor = adapter.getDownloadedItemsCursor()) { + try (Cursor cursor = adapter.getDownloadedItemsCursor(sortOrder)) { List<FeedItem> items = extractItemlistFromCursor(adapter, cursor); loadAdditionalFeedItemListData(items); - Collections.sort(items, new FeedItemPubdateComparator()); return items; } finally { adapter.close(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/ExceptFavoriteCleanupAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/ExceptFavoriteCleanupAlgorithm.java index 5d092da6d..448cffeb9 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/ExceptFavoriteCleanupAlgorithm.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/ExceptFavoriteCleanupAlgorithm.java @@ -13,6 +13,7 @@ import java.util.Locale; import java.util.concurrent.ExecutionException; import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.model.feed.SortOrder; import de.danoeh.antennapod.storage.preferences.UserPreferences; /** @@ -74,7 +75,7 @@ public class ExceptFavoriteCleanupAlgorithm extends EpisodeCleanupAlgorithm { @NonNull private List<FeedItem> getCandidates() { List<FeedItem> candidates = new ArrayList<>(); - List<FeedItem> downloadedItems = DBReader.getDownloadedItems(); + List<FeedItem> downloadedItems = DBReader.getDownloadedItems(SortOrder.DATE_NEW_OLD); for (FeedItem item : downloadedItems) { if (item.hasMedia() && item.getMedia().isDownloaded() diff --git a/core/src/main/res/drawable/bg_pill_translucent.xml b/core/src/main/res/drawable/bg_pill_translucent.xml new file mode 100644 index 000000000..b25a9ac82 --- /dev/null +++ b/core/src/main/res/drawable/bg_pill_translucent.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> + <solid android:color="#D2404040" /> + <corners android:radius="18dp" /> +</shape> diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index b08541771..090d5e2e4 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -135,20 +135,6 @@ <item>-2</item> </string-array> - <string-array name="theme_options"> - <item>@string/pref_theme_title_use_system</item> - <item>@string/pref_theme_title_light</item> - <item>@string/pref_theme_title_dark</item> - <item>@string/pref_theme_title_trueblack</item> - </string-array> - - <string-array name="theme_values"> - <item>system</item> - <item>0</item> - <item>1</item> - <item>2</item> - </string-array> - <string-array name="nav_drawer_titles"> <item>@string/home_label</item> <item>@string/queue_label</item> diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml index 19a7c0fde..553da121a 100644 --- a/core/src/main/res/values/colors.xml +++ b/core/src/main/res/values/colors.xml @@ -9,7 +9,7 @@ <color name="black">#000000</color> <color name="image_readability_tint">#80000000</color> <color name="feed_image_bg">#50000000</color> - <color name="feed_text_bg">#ccbfbfbf</color> + <color name="feed_text_bg">#55333333</color> <!-- Theme colors --> <color name="background_light">#FFFFFF</color> diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index 1cdb1c0c2..45f13931e 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -284,4 +284,13 @@ <item name="android:clickable">true</item> </style> + <style name="TextPill"> + <item name="android:background">@drawable/bg_pill_translucent</item> + <item name="android:layout_margin">8dp</item> + <item name="android:textColor">@color/white</item> + <item name="android:textAlignment">center</item> + <item name="android:paddingStart">8dp</item> + <item name="android:paddingEnd">8dp</item> + </style> + </resources> diff --git a/core/src/test/java/de/danoeh/antennapod/core/storage/DbReaderTest.java b/core/src/test/java/de/danoeh/antennapod/core/storage/DbReaderTest.java index 93f158b66..c44c6ae43 100644 --- a/core/src/test/java/de/danoeh/antennapod/core/storage/DbReaderTest.java +++ b/core/src/test/java/de/danoeh/antennapod/core/storage/DbReaderTest.java @@ -237,7 +237,7 @@ public class DbReaderTest { public void testGetDownloadedItems() { final int numItems = 10; List<FeedItem> downloaded = saveDownloadedItems(numItems); - List<FeedItem> downloadedSaved = DBReader.getDownloadedItems(); + List<FeedItem> downloadedSaved = DBReader.getDownloadedItems(null); assertNotNull(downloadedSaved); assertEquals(downloaded.size(), downloadedSaved.size()); for (FeedItem item : downloadedSaved) { |