From 05f923ebe256b71636e2369d48450a52ab87f944 Mon Sep 17 00:00:00 2001 From: alifeflow Date: Sun, 25 Mar 2018 16:00:42 +0900 Subject: [Ture Black] True Black Theme for AMOLED Add true black themese Modified code that fails to support three themes --- .../java/de/danoeh/antennapod/core/preferences/UserPreferences.java | 4 ++++ core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java | 2 ++ 2 files changed, 6 insertions(+) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 743ee135d..cbcdf727f 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 @@ -167,6 +167,8 @@ public class UserPreferences { int theme = getTheme(); if (theme == R.style.Theme_AntennaPod_Dark) { return R.style.Theme_AntennaPod_Dark_NoTitle; + }else if (theme == R.style.Theme_AntennaPod_TrueBlack){ + return R.style.Theme_AntennaPod_TrueBlack_NoTitle; } else { return R.style.Theme_AntennaPod_Light_NoTitle; } @@ -603,6 +605,8 @@ public class UserPreferences { return R.style.Theme_AntennaPod_Light; case 1: return R.style.Theme_AntennaPod_Dark; + case 2: + return R.style.Theme_AntennaPod_TrueBlack; default: return R.style.Theme_AntennaPod_Light; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java index f67367643..184c3ee54 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java @@ -12,6 +12,8 @@ public class ThemeUtils { int theme = UserPreferences.getTheme(); if (theme == R.style.Theme_AntennaPod_Dark) { return R.color.selection_background_color_dark; + }else if (theme == R.style.Theme_AntennaPod_TrueBlack){ + return R.color.selection_background_color_trueblack; } else if (theme == R.style.Theme_AntennaPod_Light) { return R.color.selection_background_color_light; } else { -- cgit v1.2.3 From deb2cea72f0f50d5ad2e3248bc8adc65ac896275 Mon Sep 17 00:00:00 2001 From: alifeflow Date: Sat, 14 Apr 2018 14:09:19 +0900 Subject: [True Black] Cleaning up Code Remove unused imports and redundant values Coding style adjustment --- .../java/de/danoeh/antennapod/core/preferences/UserPreferences.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 cbcdf727f..6aaed1b3d 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 @@ -167,7 +167,7 @@ public class UserPreferences { int theme = getTheme(); if (theme == R.style.Theme_AntennaPod_Dark) { return R.style.Theme_AntennaPod_Dark_NoTitle; - }else if (theme == R.style.Theme_AntennaPod_TrueBlack){ + } else if (theme == R.style.Theme_AntennaPod_TrueBlack) { return R.style.Theme_AntennaPod_TrueBlack_NoTitle; } else { return R.style.Theme_AntennaPod_Light_NoTitle; -- cgit v1.2.3 From d652bd21842e851802b7a842856726048d7f2498 Mon Sep 17 00:00:00 2001 From: Spencer Visick Date: Thu, 19 Apr 2018 21:39:21 -0700 Subject: Fix Bluetooth Forward Skip Button for Android 8 It appears that Oreo has changed the behavior for Bluetooth KeyEvents. Starting with Android 8.0, KeyEvent.getSource() returns 0 (unknown source). This change explicitly sets when a key press is sent from a notification, or lockscreen event. Otherwise we use the customer-defined skip behavior. --- .../antennapod/core/service/playback/PlaybackService.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 ab25f0a5f..dd7e84857 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 @@ -447,8 +447,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (keycode != -1) { Log.d(TAG, "Received media button event"); - handleKeycode(keycode, intent.getIntExtra(MediaButtonReceiver.EXTRA_SOURCE, - InputDeviceCompat.SOURCE_CLASS_NONE)); + handleKeycode(keycode, true); } else if (!flavorHelper.castDisconnect(castDisconnect) && playable != null) { started = true; boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM, @@ -472,7 +471,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { * Handles media button events * return: keycode was handled */ - private boolean handleKeycode(int keycode, int source) { + private boolean handleKeycode(int keycode, boolean notificationButton) { Log.d(TAG, "Handling keycode: " + keycode); final PlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo(); final PlayerStatus status = info.playerStatus; @@ -505,7 +504,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { return true; case KeyEvent.KEYCODE_MEDIA_NEXT: - if (source == InputDevice.SOURCE_CLASS_NONE || + if (notificationButton || UserPreferences.shouldHardwareButtonSkip()) { // assume the skip command comes from a notification or the lockscreen // a >| skip button should actually skip @@ -1756,11 +1755,11 @@ public class PlaybackService extends MediaBrowserServiceCompat { public boolean onMediaButtonEvent(final Intent mediaButton) { Log.d(TAG, "onMediaButtonEvent(" + mediaButton + ")"); if (mediaButton != null) { - KeyEvent keyEvent = (KeyEvent) mediaButton.getExtras().get(Intent.EXTRA_KEY_EVENT); + KeyEvent keyEvent = (KeyEvent) mediaButton.getParcelableExtra(Intent.EXTRA_KEY_EVENT); if (keyEvent != null && keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getRepeatCount() == 0) { - return handleKeycode(keyEvent.getKeyCode(), keyEvent.getSource()); + return handleKeycode(keyEvent.getKeyCode(), false); } } return false; -- cgit v1.2.3 From 4bba6b30a1b5e82b93edc27742ec35362b08d1c7 Mon Sep 17 00:00:00 2001 From: orionlee Date: Mon, 30 Apr 2018 14:59:45 -0700 Subject: Issue #2579: Provide share Link in episode playback screen even when the episode has no link - Use podcast link as the fallback. Also bug fix share link with position: to include epsiode and podcast title. --- .../de/danoeh/antennapod/core/util/ShareUtils.java | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java index 898f7bedb..149cdcbc6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java @@ -50,11 +50,30 @@ public class ShareUtils { return item.getFeed().getTitle() + ": " + item.getTitle(); } + /** + * Get the link for the feed item for the purpose of Share. It fallbacks to + * use the feed's link if the named feed item has no link. + */ + private static String getItemShareLink(FeedItem item) { + String link = item.getLink(); + if (link == null) { + Feed feed = item.getFeed(); + if (feed != null) { + link = feed.getLink(); + } + } + return link; + } + + public static boolean hasLinkToShare(FeedItem item) { + return ( item != null && getItemShareLink(item) != null ); + } + public static void shareFeedItemLink(Context context, FeedItem item, boolean withPosition) { - String text = getItemShareText(item) + " " + item.getLink(); + String text = getItemShareText(item) + " " + getItemShareLink(item); if(withPosition) { int pos = item.getMedia().getPosition(); - text = item.getLink() + " [" + Converter.getDurationStringLong(pos) + "]"; + text += " [" + Converter.getDurationStringLong(pos) + "]"; } shareLink(context, text); } -- cgit v1.2.3 From 345fcc17d0416f8db61a2506aa88c25b53718ebb Mon Sep 17 00:00:00 2001 From: orionlee Date: Mon, 30 Apr 2018 15:44:19 -0700 Subject: FeedItem Visit Website tweak: use feed website as a fallback, analogous to how share FeedItem link work. Applicable to both feed playback screen and feed information screen. --- .../de/danoeh/antennapod/core/util/FeedItemUtil.java | 15 +++++++++++++++ .../de/danoeh/antennapod/core/util/ShareUtils.java | 19 ++----------------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java index 892e5ff38..129c1923e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.util; import java.util.List; +import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; public class FeedItemUtil { @@ -75,4 +76,18 @@ public class FeedItemUtil { return false; } + /** + * Get the link for the feed item for the purpose of Share. It fallbacks to + * use the feed's link if the named feed item has no link. + */ + public static String getLinkWithFallback(FeedItem item) { + String link = item.getLink(); + if (link == null) { + Feed feed = item.getFeed(); + if (feed != null) { + link = feed.getLink(); + } + } + return link; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java index 149cdcbc6..0fbca2437 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java @@ -50,27 +50,12 @@ public class ShareUtils { return item.getFeed().getTitle() + ": " + item.getTitle(); } - /** - * Get the link for the feed item for the purpose of Share. It fallbacks to - * use the feed's link if the named feed item has no link. - */ - private static String getItemShareLink(FeedItem item) { - String link = item.getLink(); - if (link == null) { - Feed feed = item.getFeed(); - if (feed != null) { - link = feed.getLink(); - } - } - return link; - } - public static boolean hasLinkToShare(FeedItem item) { - return ( item != null && getItemShareLink(item) != null ); + return ( item != null && FeedItemUtil.getLinkWithFallback(item) != null ); } public static void shareFeedItemLink(Context context, FeedItem item, boolean withPosition) { - String text = getItemShareText(item) + " " + getItemShareLink(item); + String text = getItemShareText(item) + " " + FeedItemUtil.getLinkWithFallback(item); if(withPosition) { int pos = item.getMedia().getPosition(); text += " [" + Converter.getDurationStringLong(pos) + "]"; -- cgit v1.2.3 From ab0f4131850695537c22258633aecb4aca0aece5 Mon Sep 17 00:00:00 2001 From: orionlee Date: Mon, 30 Apr 2018 15:49:18 -0700 Subject: Make FeedItemUtil.getLinkWithFallback(item) tolerates null item. --- .../java/de/danoeh/antennapod/core/util/FeedItemUtil.java | 15 +++++++++------ .../java/de/danoeh/antennapod/core/util/ShareUtils.java | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java index 129c1923e..516c57d55 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java @@ -81,13 +81,16 @@ public class FeedItemUtil { * use the feed's link if the named feed item has no link. */ public static String getLinkWithFallback(FeedItem item) { - String link = item.getLink(); - if (link == null) { - Feed feed = item.getFeed(); - if (feed != null) { - link = feed.getLink(); + String link = null; + if (item != null) { + link = item.getLink(); + if (link == null) { + Feed feed = item.getFeed(); + if (feed != null) { + link = feed.getLink(); + } } - } + } // else null item, can only return null return link; } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java index 0fbca2437..5ae00460e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java @@ -51,7 +51,7 @@ public class ShareUtils { } public static boolean hasLinkToShare(FeedItem item) { - return ( item != null && FeedItemUtil.getLinkWithFallback(item) != null ); + return FeedItemUtil.getLinkWithFallback(item) != null; } public static void shareFeedItemLink(Context context, FeedItem item, boolean withPosition) { -- cgit v1.2.3 From 4c7531d277bf4b2a733031b9b1d3a7e9c1ad0241 Mon Sep 17 00:00:00 2001 From: orionlee Date: Wed, 2 May 2018 13:53:56 -0700 Subject: Flatten nested ifs, per @ByteHamster feedback --- .../de/danoeh/antennapod/core/util/FeedItemUtil.java | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java index 516c57d55..76a6549ae 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemUtil.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.core.util; import java.util.List; -import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; public class FeedItemUtil { @@ -81,16 +80,13 @@ public class FeedItemUtil { * use the feed's link if the named feed item has no link. */ public static String getLinkWithFallback(FeedItem item) { - String link = null; - if (item != null) { - link = item.getLink(); - if (link == null) { - Feed feed = item.getFeed(); - if (feed != null) { - link = feed.getLink(); - } - } - } // else null item, can only return null - return link; + if (item == null) { + return null; + } else if (item.getLink() != null) { + return item.getLink(); + } else if (item.getFeed() != null) { + return item.getFeed().getLink(); + } + return null; } } -- cgit v1.2.3 From 1d0459b126d7d219a0d10ec4d8c8b2fbd48fd8fa Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Tue, 9 Jan 2018 19:08:23 +0100 Subject: Updated build tools --- .../de/danoeh/antennapod/core/service/playback/PlaybackService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 67a2cdad2..3479c3368 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 @@ -31,7 +31,7 @@ import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.view.InputDeviceCompat; -import android.support.v7.app.NotificationCompat; +import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -1293,7 +1293,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { PendingIntent stopButtonPendingIntent = getPendingIntentForMediaAction( KeyEvent.KEYCODE_MEDIA_STOP, numActions); - notificationBuilder.setStyle(new android.support.v7.app.NotificationCompat.MediaStyle() + notificationBuilder.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle() .setMediaSession(mediaSession.getSessionToken()) .setShowActionsInCompactView(compactActionList.toArray()) .setShowCancelButton(true) -- cgit v1.2.3 From 7ad176ce299bb2abfa3698ce64ffc69b16cfdc8b Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 10 Jan 2018 21:50:29 +0100 Subject: Added notification categories Android treats IMPORTANCE_DEFAULT as IMPORTANCE_HIGH https://issuetracker.google.com/issues/65108694 --- .../core/asynctask/FlattrClickWorker.java | 5 +- .../core/service/GpodnetSyncService.java | 3 +- .../core/service/download/DownloadService.java | 7 +-- .../core/service/playback/PlaybackService.java | 5 +- .../antennapod/core/util/NotificationUtils.java | 62 ++++++++++++++++++++++ 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java index 5bd65f4e9..627e601bd 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java @@ -10,6 +10,7 @@ import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; +import de.danoeh.antennapod.core.util.NotificationUtils; import org.shredzone.flattr4j.exception.FlattrException; import java.util.LinkedList; @@ -175,7 +176,7 @@ public class FlattrClickWorker extends AsyncTask Date: Sun, 22 Apr 2018 22:21:46 +0200 Subject: Start PlaybackService lazily to allow using ForegroundService --- .../danoeh/antennapod/core/event/ServiceEvent.java | 13 +++ .../core/receiver/MediaButtonReceiver.java | 3 +- .../core/service/GpodnetSyncService.java | 21 ++++- .../core/service/download/DownloadService.java | 3 +- .../core/service/playback/PlaybackService.java | 73 ++++++++++++----- .../de/danoeh/antennapod/core/storage/DBTasks.java | 12 +-- .../antennapod/core/storage/DownloadRequester.java | 3 +- .../antennapod/core/util/NotificationUtils.java | 10 +++ .../core/util/playback/PlaybackController.java | 92 +++++++++++++++------- 9 files changed, 167 insertions(+), 63 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/event/ServiceEvent.java (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/ServiceEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/ServiceEvent.java new file mode 100644 index 000000000..b3241a8b6 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/event/ServiceEvent.java @@ -0,0 +1,13 @@ +package de.danoeh.antennapod.core.event; + +public class ServiceEvent { + public enum Action { + SERVICE_STARTED + } + + public final Action action; + + public ServiceEvent(Action action) { + this.action = action; + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java index 9b4b91151..b191dbf8b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/MediaButtonReceiver.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.receiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.support.v4.content.ContextCompat; import android.util.Log; import android.view.KeyEvent; @@ -29,7 +30,7 @@ public class MediaButtonReceiver extends BroadcastReceiver { Intent serviceIntent = new Intent(context, PlaybackService.class); serviceIntent.putExtra(EXTRA_KEYCODE, event.getKeyCode()); serviceIntent.putExtra(EXTRA_SOURCE, event.getSource()); - context.startService(serviceIntent); + ContextCompat.startForegroundService(context, serviceIntent); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java index d022dbf02..48398e0c5 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java @@ -8,6 +8,7 @@ import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.support.v4.app.NotificationCompat; +import android.support.v4.content.ContextCompat; import android.support.v4.util.ArrayMap; import android.util.Log; import android.util.Pair; @@ -58,6 +59,18 @@ public class GpodnetSyncService extends Service { private boolean syncSubscriptions = false; private boolean syncActions = false; + private static final int NOTIFICATION_ID = 2; + + @Override + public void onCreate() { + super.onCreate(); + startForeground(NOTIFICATION_ID, + new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_GPODNET) + .setSmallIcon(R.drawable.stat_notify_sync) + .setContentTitle(getString(R.string.gpodnet_main_label)) + .setContentText(getString(R.string.synchronizing)) + .build()); + } @Override public int onStartCommand(Intent intent, int flags, int startId) { @@ -110,6 +123,7 @@ public class GpodnetSyncService extends Service { private synchronized void sync() { if (!GpodnetPreferences.loggedIn() || !NetworkUtils.networkAvailable()) { + stopForeground(true); stopSelf(); return; } @@ -126,6 +140,7 @@ public class GpodnetSyncService extends Service { } syncActions = false; } + stopForeground(true); stopSelf(); } @@ -394,7 +409,7 @@ public class GpodnetSyncService extends Service { if (GpodnetPreferences.loggedIn()) { Intent intent = new Intent(context, GpodnetSyncService.class); intent.putExtra(ARG_ACTION, ACTION_SYNC); - context.startService(intent); + ContextCompat.startForegroundService(context, intent); } } @@ -402,7 +417,7 @@ public class GpodnetSyncService extends Service { if (GpodnetPreferences.loggedIn()) { Intent intent = new Intent(context, GpodnetSyncService.class); intent.putExtra(ARG_ACTION, ACTION_SYNC_SUBSCRIPTIONS); - context.startService(intent); + ContextCompat.startForegroundService(context, intent); } } @@ -410,7 +425,7 @@ public class GpodnetSyncService extends Service { if (GpodnetPreferences.loggedIn()) { Intent intent = new Intent(context, GpodnetSyncService.class); intent.putExtra(ARG_ACTION, ACTION_SYNC_ACTIONS); - context.startService(intent); + ContextCompat.startForegroundService(context, intent); } } } 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 24be93415..34cabf564 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 @@ -296,6 +296,7 @@ public class DownloadService extends Service { setupNotificationBuilders(); requester = DownloadRequester.getInstance(); + startForeground(NOTIFICATION_ID, updateNotifications()); } @Override @@ -353,7 +354,7 @@ public class DownloadService extends Service { /** * Updates the contents of the service's notifications. Should be called - * before setupNotificationBuilders. + * after setupNotificationBuilders. */ private Notification updateNotifications() { if (notificationCompatBuilder == null) { 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 03beec06a..0ec135923 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 @@ -24,6 +24,7 @@ import android.os.Vibrator; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.StringRes; +import android.support.v4.content.ContextCompat; import android.support.v4.media.MediaBrowserCompat; import android.support.v4.media.MediaBrowserServiceCompat; import android.support.v4.media.MediaDescriptionCompat; @@ -49,6 +50,7 @@ import java.util.List; import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.MessageEvent; +import de.danoeh.antennapod.core.event.ServiceEvent; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; @@ -314,6 +316,34 @@ public class PlaybackService extends MediaBrowserServiceCompat { flavorHelper.initializeMediaPlayer(PlaybackService.this); mediaSession.setActive(true); + + NotificationCompat.Builder notificationBuilder = createBasicNotification(); + startForeground(NOTIFICATION_ID, notificationBuilder.build()); + EventBus.getDefault().post(new ServiceEvent(ServiceEvent.Action.SERVICE_STARTED)); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia(); + Playable lastPlayable = Playable.PlayableUtils.createInstanceFromPreferences( + getApplicationContext(), (int) currentlyPlayingMedia, prefs); + setupNotification(lastPlayable); + } + + private NotificationCompat.Builder createBasicNotification() { + final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext()); + + final PendingIntent pIntent = PendingIntent.getActivity(this, 0, + PlaybackService.getPlayerActivityIntent(this), + PendingIntent.FLAG_UPDATE_CURRENT); + + return new NotificationCompat.Builder( + this, NotificationUtils.CHANNEL_ID_PLAYING) + .setContentTitle(getString(R.string.app_name)) + .setContentText("Service is running") // Just in case the notification is not updated (should not occur) + .setOngoing(false) + .setContentIntent(pIntent) + .setWhen(0) // we don't need the time + .setSmallIcon(smallIcon) + .setPriority(NotificationCompat.PRIORITY_MIN); } @Override @@ -568,8 +598,10 @@ public class PlaybackService extends MediaBrowserServiceCompat { } public void notifyVideoSurfaceAbandoned() { - stopForeground(!UserPreferences.isPersistNotify()); + mediaPlayer.pause(true, false); mediaPlayer.resetVideoSurface(); + setupNotification(getPlayable()); + stopForeground(!UserPreferences.isPersistNotify()); } private final PlaybackServiceTaskManager.PSTMCallback taskManagerCallback = new PlaybackServiceTaskManager.PSTMCallback() { @@ -763,6 +795,15 @@ public class PlaybackService extends MediaBrowserServiceCompat { } }; + public static void startService(final Context context, final Playable media, boolean startWhenPrepared, boolean shouldStream) { + Intent launchIntent = new Intent(context, PlaybackService.class); + launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); + launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, startWhenPrepared); + launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream); + launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true); + ContextCompat.startForegroundService(context, launchIntent); + } + private Playable getNextInQueue(final Playable currentMedia) { if (!(currentMedia instanceof FeedMedia)) { Log.d(TAG, "getNextInQueue(), but playable not an instance of FeedMedia, so not proceeding"); @@ -1172,10 +1213,10 @@ public class PlaybackService extends MediaBrowserServiceCompat { * Prepares notification and starts the service in the foreground. */ private void setupNotification(final PlaybackServiceMediaPlayer.PSMPInfo info) { - final PendingIntent pIntent = PendingIntent.getActivity(this, 0, - PlaybackService.getPlayerActivityIntent(this), - PendingIntent.FLAG_UPDATE_CURRENT); + setupNotification(info.playable); + } + private synchronized void setupNotification(final Playable playable) { if (notificationSetupThread != null) { notificationSetupThread.interrupt(); } @@ -1185,12 +1226,12 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void run() { Log.d(TAG, "Starting background work"); - if (info.playable != null) { + if (playable != null) { int iconSize = getResources().getDimensionPixelSize( android.R.dimen.notification_large_icon_width); try { icon = Glide.with(PlaybackService.this) - .load(info.playable.getImageLocation()) + .load(playable.getImageLocation()) .asBitmap() .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) .centerCrop() @@ -1209,24 +1250,18 @@ public class PlaybackService extends MediaBrowserServiceCompat { return; } PlayerStatus playerStatus = mediaPlayer.getPlayerStatus(); - final int smallIcon = ClientConfig.playbackServiceCallbacks.getNotificationIconResource(getApplicationContext()); - if (!Thread.currentThread().isInterrupted() && started && info.playable != null) { - String contentText = info.playable.getEpisodeTitle(); - String contentTitle = info.playable.getFeedTitle(); + if (!Thread.currentThread().isInterrupted() && started && playable != null) { + String contentText = playable.getEpisodeTitle(); + String contentTitle = playable.getFeedTitle(); Notification notification; // Builder is v7, even if some not overwritten methods return its parent's v4 interface - NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( - PlaybackService.this, NotificationUtils.CHANNEL_ID_PLAYING) - .setContentTitle(contentTitle) + NotificationCompat.Builder notificationBuilder = createBasicNotification(); + notificationBuilder.setContentTitle(contentTitle) .setContentText(contentText) - .setOngoing(false) - .setContentIntent(pIntent) - .setLargeIcon(icon) - .setSmallIcon(smallIcon) - .setWhen(0) // we don't need the time - .setPriority(UserPreferences.getNotifyPriority()); // set notification priority + .setPriority(UserPreferences.getNotifyPriority()) + .setLargeIcon(icon); // set notification priority IntList compactActionList = new IntList(); int numActions = 0; // we start and 0 and then increment by 1 for each call to addAction 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 573954412..74f69406f 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 @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; +import android.support.v4.content.ContextCompat; import android.util.Log; import java.util.ArrayList; @@ -123,16 +124,7 @@ public final class DBTasks { media); } } - // Start playback Service - Intent launchIntent = new Intent(context, PlaybackService.class); - launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); - launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, - startWhenPrepared); - launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, - shouldStream); - launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, - true); - context.startService(launchIntent); + PlaybackService.startService(context, media, startWhenPrepared, shouldStream); if (showPlayer) { // Launch media player context.startActivity(PlaybackService.getPlayerActivityIntent( diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index a8fd79fda..df618e252 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; +import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.util.Log; import android.webkit.URLUtil; @@ -81,7 +82,7 @@ public class DownloadRequester { Intent launchIntent = new Intent(context, DownloadService.class); launchIntent.putExtra(DownloadService.EXTRA_REQUEST, request); - context.startService(launchIntent); + ContextCompat.startForegroundService(context, launchIntent); return true; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java index f3824294f..e81b03d77 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java @@ -13,6 +13,7 @@ public class NotificationUtils { public static final String CHANNEL_ID_DOWNLOADING = "downloading"; public static final String CHANNEL_ID_PLAYING = "playing"; public static final String CHANNEL_ID_ERROR = "error"; + public static final String CHANNEL_ID_GPODNET = "gpodnet"; public static void createChannels(Context context) { if (android.os.Build.VERSION.SDK_INT < 26) { @@ -25,6 +26,7 @@ public class NotificationUtils { mNotificationManager.createNotificationChannel(createChannelDownloading(context)); mNotificationManager.createNotificationChannel(createChannelPlaying(context)); mNotificationManager.createNotificationChannel(createChannelError(context)); + mNotificationManager.createNotificationChannel(createChannelGpodnet(context)); } } @@ -59,4 +61,12 @@ public class NotificationUtils { mChannel.setDescription(c.getString(R.string.notification_channel_error_description)); return mChannel; } + + @RequiresApi(api = Build.VERSION_CODES.O) + private static NotificationChannel createChannelGpodnet(Context c) { + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_GPODNET, + c.getString(R.string.notification_channel_gpodnet), NotificationManager.IMPORTANCE_MIN); + mChannel.setDescription(c.getString(R.string.notification_channel_gpodnet_description)); + return mChannel; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index a160b4f0a..79772f015 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -14,6 +14,7 @@ import android.os.Build; import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -59,7 +60,7 @@ public abstract class PlaybackController { private PlaybackService playbackService; private Playable media; - private PlayerStatus status; + private PlayerStatus status = PlayerStatus.STOPPED; private final ScheduledThreadPoolExecutor schedExecutor; private static final int SCHED_EX_POOLSIZE = 1; @@ -69,6 +70,7 @@ public abstract class PlaybackController { private boolean mediaInfoLoaded = false; private boolean released = false; + private boolean initialized = false; private Subscription serviceBinder; @@ -92,10 +94,14 @@ public abstract class PlaybackController { } /** - * Creates a new connection to the playbackService. Should be called in the - * activity's onResume() method. + * Creates a new connection to the playbackService. */ - public void init() { + public synchronized void init() { + if (initialized) { + return; + } + initialized = true; + activity.registerReceiver(statusUpdate, new IntentFilter( PlaybackService.ACTION_PLAYER_STATUS_CHANGED)); @@ -167,7 +173,7 @@ public abstract class PlaybackController { */ private void bindToService() { Log.d(TAG, "Trying to connect to service"); - if(serviceBinder != null) { + if (serviceBinder != null) { serviceBinder.unsubscribe(); } serviceBinder = Observable.fromCallable(this::getPlayLastPlayedMediaIntent) @@ -178,7 +184,7 @@ public abstract class PlaybackController { if (!PlaybackService.started) { if (intent != null) { Log.d(TAG, "Calling start service"); - activity.startService(intent); + ContextCompat.startForegroundService(activity, intent); bound = activity.bindService(intent, mConnection, 0); } else { status = PlayerStatus.STOPPED; @@ -194,32 +200,37 @@ public abstract class PlaybackController { }, error -> Log.e(TAG, Log.getStackTraceString(error))); } + private Playable getMediaFromPreferences() { + long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia(); + if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( + activity.getApplicationContext()); + return PlayableUtils.createInstanceFromPreferences(activity, + (int) currentlyPlayingMedia, prefs); + } + return null; + } + /** * Returns an intent that starts the PlaybackService and plays the last * played media or null if no last played media could be found. */ private Intent getPlayLastPlayedMediaIntent() { Log.d(TAG, "Trying to restore last played media"); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( - activity.getApplicationContext()); - long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia(); - if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) { - Playable media = PlayableUtils.createInstanceFromPreferences(activity, - (int) currentlyPlayingMedia, prefs); - if (media != null) { - Intent serviceIntent = new Intent(activity, PlaybackService.class); - serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); - serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false); - serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true); - boolean fileExists = media.localFileAvailable(); - boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); - if (!fileExists && !lastIsStream && media instanceof FeedMedia) { - DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media); - } - serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, - lastIsStream || !fileExists); - return serviceIntent; + Playable media = getMediaFromPreferences(); + if (media != null) { + Intent serviceIntent = new Intent(activity, PlaybackService.class); + serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); + serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false); + serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true); + boolean fileExists = media.localFileAvailable(); + boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); + if (!fileExists && !lastIsStream && media instanceof FeedMedia) { + DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media); } + serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, + lastIsStream || !fileExists); + return serviceIntent; } Log.d(TAG, "No last played media found"); return null; @@ -511,7 +522,7 @@ public abstract class PlaybackController { "PlaybackService has no media object. Trying to restore last played media."); Intent serviceIntent = getPlayLastPlayedMediaIntent(); if (serviceIntent != null) { - activity.startService(serviceIntent); + ContextCompat.startForegroundService(activity, serviceIntent); } } */ @@ -576,6 +587,7 @@ public abstract class PlaybackController { public void playPause() { if (playbackService == null) { + PlaybackService.startService(activity, media, true, false); Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!"); return; } @@ -609,6 +621,8 @@ public abstract class PlaybackController { public int getPosition() { if (playbackService != null) { return playbackService.getCurrentPosition(); + } else if (media != null) { + return media.getPosition(); } else { return PlaybackService.INVALID_TIME; } @@ -617,12 +631,17 @@ public abstract class PlaybackController { public int getDuration() { if (playbackService != null) { return playbackService.getDuration(); + } else if (media != null) { + return media.getDuration(); } else { return PlaybackService.INVALID_TIME; } } public Playable getMedia() { + if (media == null) { + media = getMediaFromPreferences(); + } return media; } @@ -714,8 +733,13 @@ public abstract class PlaybackController { } public boolean isPlayingVideoLocally() { - return playbackService != null && PlaybackService.getCurrentMediaType() == MediaType.VIDEO - && !PlaybackService.isCasting(); + if (PlaybackService.isCasting()) { + return false; + } else if (playbackService != null) { + return PlaybackService.getCurrentMediaType() == MediaType.VIDEO; + } else { + return getMedia() != null && getMedia().getMediaType() == MediaType.VIDEO; + } } public Pair getVideoSize() { @@ -755,6 +779,18 @@ public abstract class PlaybackController { } } + public void resumeServiceNotRunning() { + if (getMedia().getMediaType() == MediaType.AUDIO) { + TypedArray res = activity.obtainStyledAttributes(new int[]{ + de.danoeh.antennapod.core.R.attr.av_play_big}); + getPlayButton().setImageResource( + res.getResourceId(0, de.danoeh.antennapod.core.R.drawable.ic_play_arrow_grey600_36dp)); + res.recycle(); + } else { + getPlayButton().setImageResource(R.drawable.ic_av_play_circle_outline_80dp); + } + } + /** * Refreshes the current position of the media file that is playing. */ -- cgit v1.2.3 From 2190101cf949d58057e0f0e2ca24dbe81d201426 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Thu, 3 May 2018 18:47:57 +0200 Subject: Added JobScheduler for feed updates --- .../core/preferences/UserPreferences.java | 70 ++++++++++++++++++---- .../core/service/FeedUpdateJobService.java | 30 ++++++++++ 2 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java (limited to 'core/src/main/java/de/danoeh/antennapod') 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 a93012d59..17362c721 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 @@ -2,17 +2,23 @@ package de.danoeh.antennapod.core.preferences; import android.app.AlarmManager; import android.app.PendingIntent; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.Build; import android.os.SystemClock; import android.preference.PreferenceManager; import android.support.annotation.IntRange; import android.support.annotation.NonNull; +import android.support.annotation.RequiresApi; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; +import de.danoeh.antennapod.core.service.FeedUpdateJobService; import org.json.JSONArray; import org.json.JSONException; @@ -103,6 +109,10 @@ public class UserPreferences { private static final String PREF_DATA_FOLDER = "prefDataFolder"; public static final String PREF_IMAGE_CACHE_SIZE = "prefImageCacheSize"; + // JobScheduler + private static final int JOB_ID_FEED_UPDATE = 42; + private static final float JOB_SCHEDULER_TIME_VARIATION = 1.5f; + // Mediaplayer private static final String PREF_PLAYBACK_SPEED = "prefPlaybackSpeed"; private static final String PREF_FAST_FORWARD_SECS = "prefFastForwardSecs"; @@ -797,18 +807,31 @@ public class UserPreferences { */ private static void restartUpdateIntervalAlarm(long triggerAtMillis, long intervalMillis) { Log.d(TAG, "Restarting update alarm."); + + if (intervalMillis <= 0) { + Log.d(TAG, "Automatic update was deactivated"); + return; + } + + if (Build.VERSION.SDK_INT >= 23) { + JobInfo.Builder builder = getFeedUpdateJobBuilder(); + builder.setOverrideDeadline((long) (triggerAtMillis * JOB_SCHEDULER_TIME_VARIATION)); + JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); + if (jobScheduler != null) { + jobScheduler.schedule(builder.build()); + Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); + } + return; + } + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, FeedUpdateReceiver.class); PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmManager.cancel(updateIntent); - if (intervalMillis > 0) { - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + triggerAtMillis, - updateIntent); - Log.d(TAG, "Changed alarm to new interval " + TimeUnit.MILLISECONDS.toHours(intervalMillis) + " h"); - } else { - Log.d(TAG, "Automatic update was deactivated"); - } + alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + triggerAtMillis, + updateIntent); + Log.d(TAG, "Changed alarm to new interval " + TimeUnit.MILLISECONDS.toHours(intervalMillis) + " h"); } /** @@ -816,10 +839,6 @@ public class UserPreferences { */ private static void restartUpdateTimeOfDayAlarm(int hoursOfDay, int minute) { Log.d(TAG, "Restarting update alarm."); - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, - new Intent(context, FeedUpdateReceiver.class), 0); - alarmManager.cancel(updateIntent); Calendar now = Calendar.getInstance(); Calendar alarm = (Calendar)now.clone(); @@ -828,6 +847,24 @@ public class UserPreferences { if (alarm.before(now) || alarm.equals(now)) { alarm.add(Calendar.DATE, 1); } + + if (Build.VERSION.SDK_INT >= 23) { + JobInfo.Builder builder = getFeedUpdateJobBuilder(); + long triggerAtMillis = alarm.getTimeInMillis() - now.getTimeInMillis(); + builder.setOverrideDeadline((long) (triggerAtMillis * JOB_SCHEDULER_TIME_VARIATION)); + JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); + if (jobScheduler != null) { + jobScheduler.schedule(builder.build()); + Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); + } + return; + } + + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, + new Intent(context, FeedUpdateReceiver.class), 0); + alarmManager.cancel(updateIntent); + Log.d(TAG, "Alarm set for: " + alarm.toString() + " : " + alarm.getTimeInMillis()); alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(), @@ -835,6 +872,15 @@ public class UserPreferences { Log.d(TAG, "Changed alarm to new time of day " + hoursOfDay + ":" + minute); } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static JobInfo.Builder getFeedUpdateJobBuilder() { + ComponentName serviceComponent = new ComponentName(context, FeedUpdateJobService.class); + JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_FEED_UPDATE, serviceComponent); + builder.setMinimumLatency(15 * 60 * 1000); + builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); + return builder; + } + /** * Reads episode cache size as it is saved in the episode_cache_size_values array. */ diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java new file mode 100644 index 000000000..d9a7e31cc --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java @@ -0,0 +1,30 @@ +package de.danoeh.antennapod.core.service; + +import android.app.job.JobParameters; +import android.app.job.JobService; +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.util.Log; +import de.danoeh.antennapod.core.ClientConfig; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.storage.DBTasks; + +@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) +public class FeedUpdateJobService extends JobService { + private static final String TAG = "FeedUpdateJobService"; + + @Override + public boolean onStartJob(JobParameters params) { + Log.d(TAG, "Job started"); + ClientConfig.initialize(getApplicationContext()); + DBTasks.refreshAllFeeds(getApplicationContext(), null); + UserPreferences.restartUpdateAlarm(false); + return true; + } + + @Override + public boolean onStopJob(JobParameters params) { + return true; + } + +} -- cgit v1.2.3 From ffdfefc35d194aee0890e1640ad394f743bf030f Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Thu, 3 May 2018 19:36:40 +0200 Subject: Fixed fresh install crash --- .../de/danoeh/antennapod/core/util/playback/PlaybackController.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 79772f015..36253d075 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -780,6 +780,9 @@ public abstract class PlaybackController { } public void resumeServiceNotRunning() { + if (getMedia() == null) { + return; + } if (getMedia().getMediaType() == MediaType.AUDIO) { TypedArray res = activity.obtainStyledAttributes(new int[]{ de.danoeh.antennapod.core.R.attr.av_play_big}); -- cgit v1.2.3 From 9f0d187efdba753e110dbc32ed9ba58c2fe4ce66 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 4 May 2018 13:57:52 +0200 Subject: Fix empty contentEncoded This code duplication was forgotten in #2607 --- .../main/java/de/danoeh/antennapod/core/feed/FeedMedia.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java index 2d551e1b2..a22422596 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java @@ -554,15 +554,9 @@ public class FeedMedia extends FeedFile implements Playable { public Callable loadShownotes() { return () -> { if (item == null) { - item = DBReader.getFeedItem( - itemID); + item = DBReader.getFeedItem(itemID); } - if (item.getContentEncoded() == null || item.getDescription() == null) { - DBReader.loadExtraInformationOfFeedItem( - item); - - } - return (item.getContentEncoded() != null) ? item.getContentEncoded() : item.getDescription(); + return item.loadShownotes().call(); }; } -- cgit v1.2.3 From f66e19845c123160ba6174c2dec337070a6d9b22 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 4 May 2018 14:36:32 +0200 Subject: Review changes --- .../core/preferences/UserPreferences.java | 23 +++++++++++++--------- .../core/service/playback/PlaybackService.java | 6 ++++++ .../core/util/playback/PlaybackController.java | 12 +++++++++-- 3 files changed, 30 insertions(+), 11 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 17362c721..d2ef5d2a6 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 @@ -111,7 +111,6 @@ public class UserPreferences { // JobScheduler private static final int JOB_ID_FEED_UPDATE = 42; - private static final float JOB_SCHEDULER_TIME_VARIATION = 1.5f; // Mediaplayer private static final String PREF_PLAYBACK_SPEED = "prefPlaybackSpeed"; @@ -813,13 +812,19 @@ public class UserPreferences { return; } - if (Build.VERSION.SDK_INT >= 23) { - JobInfo.Builder builder = getFeedUpdateJobBuilder(); - builder.setOverrideDeadline((long) (triggerAtMillis * JOB_SCHEDULER_TIME_VARIATION)); + if (Build.VERSION.SDK_INT >= 24) { JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); if (jobScheduler != null) { - jobScheduler.schedule(builder.build()); - Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); + JobInfo oldJob = jobScheduler.getPendingJob(JOB_ID_FEED_UPDATE); + if (oldJob == null || oldJob.getIntervalMillis() != intervalMillis) { + JobInfo.Builder builder = getFeedUpdateJobBuilder(); + builder.setPeriodic(intervalMillis); + jobScheduler.cancel(JOB_ID_FEED_UPDATE); + jobScheduler.schedule(builder.build()); + Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); + } else { + Log.d(TAG, "JobScheduler was already set at interval " + intervalMillis + ", ignoring."); + } } return; } @@ -848,12 +853,13 @@ public class UserPreferences { alarm.add(Calendar.DATE, 1); } - if (Build.VERSION.SDK_INT >= 23) { + if (Build.VERSION.SDK_INT >= 24) { JobInfo.Builder builder = getFeedUpdateJobBuilder(); long triggerAtMillis = alarm.getTimeInMillis() - now.getTimeInMillis(); - builder.setOverrideDeadline((long) (triggerAtMillis * JOB_SCHEDULER_TIME_VARIATION)); + builder.setMinimumLatency(triggerAtMillis); JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); if (jobScheduler != null) { + jobScheduler.cancel(JOB_ID_FEED_UPDATE); jobScheduler.schedule(builder.build()); Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); } @@ -876,7 +882,6 @@ public class UserPreferences { private static JobInfo.Builder getFeedUpdateJobBuilder() { ComponentName serviceComponent = new ComponentName(context, FeedUpdateJobService.class); JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_FEED_UPDATE, serviceComponent); - builder.setMinimumLatency(15 * 60 * 1000); builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); return builder; } 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 0ec135923..5801ee3d5 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 @@ -795,6 +795,12 @@ public class PlaybackService extends MediaBrowserServiceCompat { } }; + public static void startIfNotRunning(final Context context, final Playable media, boolean startWhenPrepared, boolean shouldStream) { + if (!isRunning) { + startService(context, media, startWhenPrepared, shouldStream); + } + } + public static void startService(final Context context, final Playable media, boolean startWhenPrepared, boolean shouldStream) { Intent launchIntent = new Intent(context, PlaybackService.class); launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 36253d075..0b874be1f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -96,7 +96,15 @@ public abstract class PlaybackController { /** * Creates a new connection to the playbackService. */ - public synchronized void init() { + public void init() { + if (PlaybackService.isRunning) { + initServiceRunning(); + } else { + initServiceNotRunning(); + } + } + + private synchronized void initServiceRunning() { if (initialized) { return; } @@ -779,7 +787,7 @@ public abstract class PlaybackController { } } - public void resumeServiceNotRunning() { + private void initServiceNotRunning() { if (getMedia() == null) { return; } -- cgit v1.2.3 From a97b524a05ad40335822b9cb492692b2386d89de Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 4 May 2018 22:23:15 +0200 Subject: Review changes #2 --- .../core/preferences/UserPreferences.java | 17 ++++++++++++----- .../core/receiver/FeedUpdateReceiver.java | 9 ++------- .../core/service/FeedUpdateJobService.java | 4 ++-- .../de/danoeh/antennapod/core/storage/DBTasks.java | 1 + .../antennapod/core/util/FeedUpdateUtils.java | 21 +++++++++++++++++++++ 5 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java (limited to 'core/src/main/java/de/danoeh/antennapod') 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 d2ef5d2a6..6012e5b49 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 @@ -807,11 +807,6 @@ public class UserPreferences { private static void restartUpdateIntervalAlarm(long triggerAtMillis, long intervalMillis) { Log.d(TAG, "Restarting update alarm."); - if (intervalMillis <= 0) { - Log.d(TAG, "Automatic update was deactivated"); - return; - } - if (Build.VERSION.SDK_INT >= 24) { JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); if (jobScheduler != null) { @@ -820,6 +815,12 @@ public class UserPreferences { JobInfo.Builder builder = getFeedUpdateJobBuilder(); builder.setPeriodic(intervalMillis); jobScheduler.cancel(JOB_ID_FEED_UPDATE); + + if (intervalMillis <= 0) { + Log.d(TAG, "Automatic update was deactivated"); + return; + } + jobScheduler.schedule(builder.build()); Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); } else { @@ -833,6 +834,12 @@ public class UserPreferences { Intent intent = new Intent(context, FeedUpdateReceiver.class); PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmManager.cancel(updateIntent); + + if (intervalMillis <= 0) { + Log.d(TAG, "Automatic update was deactivated"); + return; + } + alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + triggerAtMillis, updateIntent); diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java index 9bbeb7c88..f1a316954 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java @@ -7,8 +7,7 @@ import android.util.Log; import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.DBTasks; -import de.danoeh.antennapod.core.util.NetworkUtils; +import de.danoeh.antennapod.core.util.FeedUpdateUtils; /** * Refreshes all feeds when it receives an intent @@ -21,11 +20,7 @@ public class FeedUpdateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received intent"); ClientConfig.initialize(context); - if (NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()) { - DBTasks.refreshAllFeeds(context, null); - } else { - Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); - } + FeedUpdateUtils.startAutoUpdate(context); UserPreferences.restartUpdateAlarm(false); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java index d9a7e31cc..2d418218d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java @@ -7,7 +7,7 @@ import android.support.annotation.RequiresApi; import android.util.Log; import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.DBTasks; +import de.danoeh.antennapod.core.util.FeedUpdateUtils; @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public class FeedUpdateJobService extends JobService { @@ -17,7 +17,7 @@ public class FeedUpdateJobService extends JobService { public boolean onStartJob(JobParameters params) { Log.d(TAG, "Job started"); ClientConfig.initialize(getApplicationContext()); - DBTasks.refreshAllFeeds(getApplicationContext(), null); + FeedUpdateUtils.startAutoUpdate(getApplicationContext()); UserPreferences.restartUpdateAlarm(false); return true; } 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 74f69406f..b6a203cb8 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 @@ -124,6 +124,7 @@ public final class DBTasks { media); } } + // Needs to be called even if the service is already running to deliver the new media intent PlaybackService.startService(context, media, startWhenPrepared, shouldStream); if (showPlayer) { // Launch media player diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java new file mode 100644 index 000000000..4d2dde88c --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java @@ -0,0 +1,21 @@ +package de.danoeh.antennapod.core.util; + +import android.content.Context; +import android.util.Log; +import de.danoeh.antennapod.core.storage.DBTasks; + +public class FeedUpdateUtils { + private static final String TAG = "FeedUpdateUtils"; + + private FeedUpdateUtils() { + + } + + public static void startAutoUpdate(Context context) { + if (NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()) { + DBTasks.refreshAllFeeds(context, null); + } else { + Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); + } + } +} -- cgit v1.2.3 From eeb032e9382535e544eb16ea74ae9733302483df Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 4 May 2018 22:41:53 +0200 Subject: Notify system when job is done --- .../core/receiver/FeedUpdateReceiver.java | 2 +- .../core/service/FeedUpdateJobService.java | 9 +++- .../de/danoeh/antennapod/core/storage/DBTasks.java | 56 ++++++++++++---------- .../antennapod/core/util/FeedUpdateUtils.java | 8 +++- 4 files changed, 45 insertions(+), 30 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java index f1a316954..67f6d9348 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java @@ -20,7 +20,7 @@ public class FeedUpdateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received intent"); ClientConfig.initialize(context); - FeedUpdateUtils.startAutoUpdate(context); + FeedUpdateUtils.startAutoUpdate(context, false); UserPreferences.restartUpdateAlarm(false); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java index 2d418218d..3fc3551ee 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java @@ -17,8 +17,13 @@ public class FeedUpdateJobService extends JobService { public boolean onStartJob(JobParameters params) { Log.d(TAG, "Job started"); ClientConfig.initialize(getApplicationContext()); - FeedUpdateUtils.startAutoUpdate(getApplicationContext()); - UserPreferences.restartUpdateAlarm(false); + + new Thread(() -> { + FeedUpdateUtils.startAutoUpdate(getApplicationContext(), true); + UserPreferences.restartUpdateAlarm(false); + jobFinished(params, false); // needsReschedule = false + }).start(); + return true; } 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 b6a203cb8..b1937985f 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 @@ -151,36 +151,42 @@ public final class DBTasks { * @param context Might be used for accessing the database * @param feeds List of Feeds that should be refreshed. */ - public static void refreshAllFeeds(final Context context, - final List feeds) { + public static void refreshAllFeeds(final Context context, final List feeds) { + new Thread(() -> refreshAllFeedsSynchronously(context, feeds)).start(); + } + + /** + * Refreshes a given list of Feeds in the current Thread. This method might ignore subsequent calls if it is still + * enqueuing Feeds for download from a previous call. MUST NOT be executed from main thread. + * + * @param context Might be used for accessing the database + * @param feeds List of Feeds that should be refreshed. + */ + public static void refreshAllFeedsSynchronously(final Context context, final List feeds) { if (isRefreshing.compareAndSet(false, true)) { - new Thread() { - public void run() { - if (feeds != null) { - refreshFeeds(context, feeds); - } else { - refreshFeeds(context, DBReader.getFeedList()); - } - isRefreshing.set(false); + if (feeds != null) { + refreshFeeds(context, feeds); + } else { + refreshFeeds(context, DBReader.getFeedList()); + } + isRefreshing.set(false); - SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); - prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); + prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); - if (FlattrUtils.hasToken()) { - Log.d(TAG, "Flattring all pending things."); - new FlattrClickWorker(context).executeAsync(); // flattr pending things + if (FlattrUtils.hasToken()) { + Log.d(TAG, "Flattring all pending things."); + new FlattrClickWorker(context).executeAsync(); // flattr pending things - Log.d(TAG, "Fetching flattr status."); - new FlattrStatusFetcher(context).start(); + Log.d(TAG, "Fetching flattr status."); + new FlattrStatusFetcher(context).start(); - } - if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { - GpodnetSyncService.sendSyncIntent(context); - } - Log.d(TAG, "refreshAllFeeds autodownload"); - autodownloadUndownloadedItems(context); - } - }.start(); + } + if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { + GpodnetSyncService.sendSyncIntent(context); + } + Log.d(TAG, "refreshAllFeeds autodownload"); + autodownloadUndownloadedItems(context); } else { Log.d(TAG, "Ignoring request to refresh all feeds: Refresh lock is locked"); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java index 4d2dde88c..a57ab2ce6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java @@ -11,9 +11,13 @@ public class FeedUpdateUtils { } - public static void startAutoUpdate(Context context) { + public static void startAutoUpdate(Context context, boolean synchronously) { if (NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()) { - DBTasks.refreshAllFeeds(context, null); + if (synchronously) { + DBTasks.refreshAllFeedsSynchronously(context, null); + } else { + DBTasks.refreshAllFeeds(context, null); + } } else { Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); } -- cgit v1.2.3 From ca3d6b9a3deed4479160edbe823644513b7550a5 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 4 May 2018 22:47:53 +0200 Subject: Persist job through reboot --- .../main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java | 1 + 1 file changed, 1 insertion(+) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 6012e5b49..07a62b743 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 @@ -890,6 +890,7 @@ public class UserPreferences { ComponentName serviceComponent = new ComponentName(context, FeedUpdateJobService.class); JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_FEED_UPDATE, serviceComponent); builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); + builder.setPersisted(true); return builder; } -- cgit v1.2.3 From 0b54d97a0a9a2caeb51c85a68749df9afe0dbdb3 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 5 May 2018 13:39:57 +0200 Subject: Switched widget to JobIntentService --- .../core/service/playback/PlaybackService.java | 24 ++++------------------ .../antennapod/core/util/playback/Playable.java | 18 ++++++++++++++++ .../core/util/playback/PlaybackController.java | 15 ++------------ 3 files changed, 24 insertions(+), 33 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 5801ee3d5..a34ce4943 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 @@ -77,8 +77,6 @@ import de.greenrobot.event.EventBus; * Controls the MediaPlayer that plays a FeedMedia-file */ public class PlaybackService extends MediaBrowserServiceCompat { - public static final String FORCE_WIDGET_UPDATE = "de.danoeh.antennapod.FORCE_WIDGET_UPDATE"; - public static final String STOP_WIDGET_UPDATE = "de.danoeh.antennapod.STOP_WIDGET_UPDATE"; /** * Logging tag */ @@ -321,11 +319,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { startForeground(NOTIFICATION_ID, notificationBuilder.build()); EventBus.getDefault().post(new ServiceEvent(ServiceEvent.Action.SERVICE_STARTED)); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia(); - Playable lastPlayable = Playable.PlayableUtils.createInstanceFromPreferences( - getApplicationContext(), (int) currentlyPlayingMedia, prefs); - setupNotification(lastPlayable); + + setupNotification(Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext())); } private NotificationCompat.Builder createBasicNotification() { @@ -635,7 +630,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void onWidgetUpdaterTick() { - updateWidget(); + //PlayerWidgetJobService.updateWidget(getBaseContext()); // TODO: Not accessible from core module } @Override @@ -697,7 +692,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { Intent statusUpdate = new Intent(ACTION_PLAYER_STATUS_CHANGED); // statusUpdate.putExtra(EXTRA_NEW_PLAYER_STATUS, newInfo.playerStatus.ordinal()); sendBroadcast(statusUpdate); - updateWidget(); + //PlayerWidgetJobService.updateWidget(getBaseContext()); // TODO: Not accessible from core module bluetoothNotifyChange(newInfo, AVRCP_ACTION_PLAYER_STATUS_CHANGED); bluetoothNotifyChange(newInfo, AVRCP_ACTION_META_CHANGED); } @@ -855,7 +850,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (!isCasting) { stopForeground(true); } - stopWidgetUpdater(); } if (mediaType == null) { sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_END, 0); @@ -1402,16 +1396,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { } } - private void stopWidgetUpdater() { - taskManager.cancelWidgetUpdater(); - sendBroadcast(new Intent(STOP_WIDGET_UPDATE)); - } - - private void updateWidget() { - PlaybackService.this.sendBroadcast(new Intent( - FORCE_WIDGET_UPDATE)); - } - public boolean sleepTimerActive() { return taskManager.isSleepTimerActive(); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java index 279c56338..bb9896f25 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.core.util.playback; import android.content.Context; import android.content.SharedPreferences; import android.os.Parcelable; +import android.preference.PreferenceManager; import android.util.Log; import java.util.List; @@ -11,6 +12,7 @@ import de.danoeh.antennapod.core.asynctask.ImageResource; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.MediaType; +import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.ShownotesProvider; @@ -175,6 +177,22 @@ public interface Playable extends Parcelable, class PlayableUtils { private static final String TAG = "PlayableUtils"; + /** + * Restores a playable object from a sharedPreferences file. This method might load data from the database, + * depending on the type of playable that was restored. + * + * @return The restored Playable object + */ + public static Playable createInstanceFromPreferences(Context context) { + long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia(); + if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); + return PlayableUtils.createInstanceFromPreferences(context, + (int) currentlyPlayingMedia, prefs); + } + return null; + } + /** * Restores a playable object from a sharedPreferences file. This method might load data from the database, * depending on the type of playable that was restored. diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 0b874be1f..d1d6b5c63 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -208,24 +208,13 @@ public abstract class PlaybackController { }, error -> Log.e(TAG, Log.getStackTraceString(error))); } - private Playable getMediaFromPreferences() { - long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia(); - if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( - activity.getApplicationContext()); - return PlayableUtils.createInstanceFromPreferences(activity, - (int) currentlyPlayingMedia, prefs); - } - return null; - } - /** * Returns an intent that starts the PlaybackService and plays the last * played media or null if no last played media could be found. */ private Intent getPlayLastPlayedMediaIntent() { Log.d(TAG, "Trying to restore last played media"); - Playable media = getMediaFromPreferences(); + Playable media = PlayableUtils.createInstanceFromPreferences(activity); if (media != null) { Intent serviceIntent = new Intent(activity, PlaybackService.class); serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); @@ -648,7 +637,7 @@ public abstract class PlaybackController { public Playable getMedia() { if (media == null) { - media = getMediaFromPreferences(); + media = PlayableUtils.createInstanceFromPreferences(activity); } return media; } -- cgit v1.2.3 From 7107819a6aa61c6f171e43fe582133302d5f260b Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 5 May 2018 14:04:12 +0200 Subject: Moved widget from app to core --- .../antennapod/core/receiver/PlayerWidget.java | 56 +++++++ .../core/service/PlayerWidgetJobService.java | 179 +++++++++++++++++++++ .../core/service/playback/PlaybackService.java | 5 +- 3 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java create mode 100644 core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java new file mode 100644 index 000000000..edc2ea3e0 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/PlayerWidget.java @@ -0,0 +1,56 @@ +package de.danoeh.antennapod.core.receiver; + +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.util.Log; +import de.danoeh.antennapod.core.service.PlayerWidgetJobService; + +import java.util.Arrays; + + +public class PlayerWidget extends AppWidgetProvider { + private static final String TAG = "PlayerWidget"; + private static final String PREFS_NAME = "PlayerWidgetPrefs"; + private static final String KEY_ENABLED = "WidgetEnabled"; + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "onReceive"); + super.onReceive(context, intent); + PlayerWidgetJobService.updateWidget(context); + } + + @Override + public void onEnabled(Context context) { + super.onEnabled(context); + Log.d(TAG, "Widget enabled"); + setEnabled(context, true); + PlayerWidgetJobService.updateWidget(context); + } + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + appWidgetManager + "], appWidgetIds = [" + Arrays.toString(appWidgetIds) + "]"); + PlayerWidgetJobService.updateWidget(context); + } + + @Override + public void onDisabled(Context context) { + super.onDisabled(context); + Log.d(TAG, "Widget disabled"); + setEnabled(context, false); + } + + public static boolean isEnabled(Context context) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getBoolean(KEY_ENABLED, false); + } + + private void setEnabled(Context context, boolean enabled) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + prefs.edit().putBoolean(KEY_ENABLED, enabled).apply(); + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java new file mode 100644 index 000000000..49f3058ef --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java @@ -0,0 +1,179 @@ +package de.danoeh.antennapod.core.service; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Build; +import android.os.IBinder; +import android.support.annotation.NonNull; +import android.support.v4.app.JobIntentService; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.RemoteViews; +import de.danoeh.antennapod.core.R; +import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; +import de.danoeh.antennapod.core.service.playback.PlaybackService; +import de.danoeh.antennapod.core.service.playback.PlayerStatus; +import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.playback.Playable; +import de.danoeh.antennapod.core.receiver.PlayerWidget; + +/** + * Updates the state of the player widget + */ +public class PlayerWidgetJobService extends JobIntentService { + private static final String TAG = "PlayerWidgetJobService"; + + private PlaybackService playbackService; + private final Object waitForService = new Object(); + + public PlayerWidgetJobService() { + } + + public static void updateWidget(Context context) { + enqueueWork(context, PlayerWidgetJobService.class, 0, new Intent(context, PlayerWidgetJobService.class)); + } + + @Override + protected void onHandleWork(@NonNull Intent intent) { + if (!PlayerWidget.isEnabled(getApplicationContext())) { + return; + } + + if (PlaybackService.isRunning && playbackService == null) { + synchronized (waitForService) { + bindService(new Intent(this, PlaybackService.class), mConnection, 0); + while (playbackService == null) { + try { + waitForService.wait(); + } catch (InterruptedException e) { + return; + } + } + } + } + + updateViews(); + + if (playbackService != null) { + try { + unbindService(mConnection); + } catch (IllegalArgumentException e) { + Log.w(TAG, "IllegalArgumentException when trying to unbind service"); + } + } + } + + private void updateViews() { + + ComponentName playerWidget = new ComponentName(this, PlayerWidget.class); + AppWidgetManager manager = AppWidgetManager.getInstance(this); + RemoteViews views = new RemoteViews(getPackageName(), R.layout.player_widget); + PendingIntent startMediaplayer = PendingIntent.getActivity(this, 0, + PlaybackService.getPlayerActivityIntent(this), 0); + + final PendingIntent startAppPending = PendingIntent.getActivity(this, 0, + PlaybackService.getPlayerActivityIntent(this), + PendingIntent.FLAG_UPDATE_CURRENT); + + boolean nothingPlaying = false; + Playable media; + PlayerStatus status; + if (playbackService != null) { + media = playbackService.getPlayable(); + status = playbackService.getStatus(); + } else { + media = Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext()); + status = PlayerStatus.STOPPED; + } + + if (media != null) { + views.setOnClickPendingIntent(R.id.layout_left, startMediaplayer); + + views.setTextViewText(R.id.txtvTitle, media.getEpisodeTitle()); + + String progressString; + if (playbackService != null) { + progressString = getProgressString(playbackService.getCurrentPosition(), playbackService.getDuration()); + } else { + progressString = getProgressString(media.getPosition(), media.getDuration()); + } + + if (progressString != null) { + views.setViewVisibility(R.id.txtvProgress, View.VISIBLE); + views.setTextViewText(R.id.txtvProgress, progressString); + } + + if (status == PlayerStatus.PLAYING) { + views.setImageViewResource(R.id.butPlay, R.drawable.ic_pause_white_24dp); + if (Build.VERSION.SDK_INT >= 15) { + views.setContentDescription(R.id.butPlay, getString(R.string.pause_label)); + } + } else { + views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp); + if (Build.VERSION.SDK_INT >= 15) { + views.setContentDescription(R.id.butPlay, getString(R.string.play_label)); + } + } + views.setOnClickPendingIntent(R.id.butPlay, createMediaButtonIntent()); + } else { + nothingPlaying = true; + } + + if (nothingPlaying) { + // start the app if they click anything + views.setOnClickPendingIntent(R.id.layout_left, startAppPending); + views.setOnClickPendingIntent(R.id.butPlay, startAppPending); + views.setViewVisibility(R.id.txtvProgress, View.INVISIBLE); + views.setTextViewText(R.id.txtvTitle, + this.getString(R.string.no_media_playing_label)); + views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp); + } + + manager.updateAppWidget(playerWidget, views); + } + + /** + * Creates an intent which fakes a mediabutton press + */ + private PendingIntent createMediaButtonIntent() { + KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE); + Intent startingIntent = new Intent(getBaseContext(), MediaButtonReceiver.class); + startingIntent.setAction(MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER); + startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); + + return PendingIntent.getBroadcast(this, 0, startingIntent, 0); + } + + private String getProgressString(int position, int duration) { + if (position > 0 && duration > 0) { + return Converter.getDurationStringLong(position) + " / " + + Converter.getDurationStringLong(duration); + } else { + return null; + } + } + + private final ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + Log.d(TAG, "Connection to service established"); + if (service instanceof PlaybackService.LocalBinder) { + synchronized (waitForService) { + playbackService = ((PlaybackService.LocalBinder) service).getService(); + waitForService.notifyAll(); + } + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + playbackService = null; + Log.d(TAG, "Disconnected from service"); + } + + }; +} 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 a34ce4943..9643b9cd3 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 @@ -62,6 +62,7 @@ import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; +import de.danoeh.antennapod.core.service.PlayerWidgetJobService; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; @@ -630,7 +631,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void onWidgetUpdaterTick() { - //PlayerWidgetJobService.updateWidget(getBaseContext()); // TODO: Not accessible from core module + PlayerWidgetJobService.updateWidget(getBaseContext()); } @Override @@ -692,7 +693,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { Intent statusUpdate = new Intent(ACTION_PLAYER_STATUS_CHANGED); // statusUpdate.putExtra(EXTRA_NEW_PLAYER_STATUS, newInfo.playerStatus.ordinal()); sendBroadcast(statusUpdate); - //PlayerWidgetJobService.updateWidget(getBaseContext()); // TODO: Not accessible from core module + PlayerWidgetJobService.updateWidget(getBaseContext()); bluetoothNotifyChange(newInfo, AVRCP_ACTION_PLAYER_STATUS_CHANGED); bluetoothNotifyChange(newInfo, AVRCP_ACTION_META_CHANGED); } -- cgit v1.2.3 From 7a768e9809dafc7e6f5944e26ebf2f1cb0e786aa Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 5 May 2018 14:32:04 +0200 Subject: Fixed widget if service is not running --- .../antennapod/core/service/playback/PlaybackService.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 9643b9cd3..dc67c0758 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 @@ -515,6 +515,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { } else if (status == PlayerStatus.INITIALIZED) { mediaPlayer.setStartWhenPrepared(true); mediaPlayer.prepare(); + } else if (mediaPlayer.getPlayable() == null) { + startPlayingFromPreferences(); } return true; case KeyEvent.KEYCODE_MEDIA_PLAY: @@ -523,6 +525,8 @@ public class PlaybackService extends MediaBrowserServiceCompat { } else if (status == PlayerStatus.INITIALIZED) { mediaPlayer.setStartWhenPrepared(true); mediaPlayer.prepare(); + } else if (mediaPlayer.getPlayable() == null) { + startPlayingFromPreferences(); } return true; case KeyEvent.KEYCODE_MEDIA_PAUSE: @@ -576,6 +580,15 @@ public class PlaybackService extends MediaBrowserServiceCompat { return false; } + private void startPlayingFromPreferences() { + Playable playable = Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext()); + if (playable != null) { + mediaPlayer.playMediaObject(playable, false, true, true); + started = true; + PlaybackService.this.updateMediaSessionMetadata(playable); + } + } + /** * Called by a mediaplayer Activity as soon as it has prepared its * mediaplayer. -- cgit v1.2.3 From a270d4fc031caba89909fcd710849a6ba18f326b Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 5 May 2018 15:10:08 +0200 Subject: Migrated Gpodnet to JobIntentService, so it does not need notification --- .../core/service/GpodnetSyncService.java | 116 ++++----------------- 1 file changed, 23 insertions(+), 93 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java index 48398e0c5..8a18d93b9 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java @@ -3,10 +3,10 @@ package de.danoeh.antennapod.core.service; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; -import android.app.Service; import android.content.Context; import android.content.Intent; -import android.os.IBinder; +import android.support.annotation.NonNull; +import android.support.v4.app.JobIntentService; import android.support.v4.app.NotificationCompat; import android.support.v4.content.ContextCompat; import android.support.v4.util.ArrayMap; @@ -16,6 +16,7 @@ import android.util.Pair; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.R; @@ -44,7 +45,7 @@ import de.danoeh.antennapod.core.util.NotificationUtils; * Synchronizes local subscriptions with gpodder.net service. The service should be started with ACTION_SYNC as an action argument. * This class also provides static methods for starting the GpodnetSyncService. */ -public class GpodnetSyncService extends Service { +public class GpodnetSyncService extends JobIntentService { private static final String TAG = "GpodnetSyncService"; private static final long WAIT_INTERVAL = 5000L; @@ -55,26 +56,19 @@ public class GpodnetSyncService extends Service { private static final String ACTION_SYNC_SUBSCRIPTIONS = "de.danoeh.antennapod.intent.action.sync_subscriptions"; private static final String ACTION_SYNC_ACTIONS = "de.danoeh.antennapod.intent.action.sync_ACTIONS"; - private GpodnetService service; + private static final AtomicInteger syncActionCount = new AtomicInteger(0); + private GpodnetService service; private boolean syncSubscriptions = false; private boolean syncActions = false; - private static final int NOTIFICATION_ID = 2; - @Override - public void onCreate() { - super.onCreate(); - startForeground(NOTIFICATION_ID, - new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_GPODNET) - .setSmallIcon(R.drawable.stat_notify_sync) - .setContentTitle(getString(R.string.gpodnet_main_label)) - .setContentText(getString(R.string.synchronizing)) - .build()); + public static void enqueueWork(Context context, Intent intent) { + enqueueWork(context, GpodnetSyncService.class, 0, intent); } @Override - public int onStartCommand(Intent intent, int flags, int startId) { - final String action = (intent != null) ? intent.getStringExtra(ARG_ACTION) : null; + protected void onHandleWork(@NonNull Intent intent) { + final String action = intent.getStringExtra(ARG_ACTION); if (action != null) { switch(action) { case ACTION_SYNC: @@ -92,24 +86,20 @@ public class GpodnetSyncService extends Service { } if(syncSubscriptions || syncActions) { Log.d(TAG, String.format("Waiting %d milliseconds before uploading changes", WAIT_INTERVAL)); - syncWaiterThread.restart(); + int syncActionId = syncActionCount.incrementAndGet(); + try { + Thread.sleep(WAIT_INTERVAL); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (syncActionId == syncActionCount.get()) { + // onHandleWork was not called again in the meantime + sync(); + } } } else { Log.e(TAG, "Received invalid intent: action argument is null"); } - return START_STICKY; - } - - @Override - public void onDestroy() { - super.onDestroy(); - Log.d(TAG, "onDestroy"); - syncWaiterThread.interrupt(); - } - - @Override - public IBinder onBind(Intent intent) { - return null; } private synchronized GpodnetService tryLogin() throws GpodnetServiceException { @@ -140,8 +130,6 @@ public class GpodnetSyncService extends Service { } syncActions = false; } - stopForeground(true); - stopSelf(); } private synchronized void syncSubscriptionChanges() { @@ -347,69 +335,11 @@ public class GpodnetSyncService extends Service { nm.notify(id, notification); } - private final WaiterThread syncWaiterThread = new WaiterThread(WAIT_INTERVAL) { - @Override - public void onWaitCompleted() { - sync(); - } - }; - - private abstract class WaiterThread { - private final long waitInterval; - private Thread thread; - - private WaiterThread(long waitInterval) { - this.waitInterval = waitInterval; - reinit(); - } - - public abstract void onWaitCompleted(); - - public void exec() { - if (!thread.isAlive()) { - thread.start(); - } - } - - private void reinit() { - if (thread != null && thread.isAlive()) { - Log.d(TAG, "Interrupting waiter thread"); - thread.interrupt(); - } - thread = new Thread() { - @Override - public void run() { - try { - Thread.sleep(waitInterval); - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (!isInterrupted()) { - synchronized (this) { - onWaitCompleted(); - } - } - } - }; - } - - public void restart() { - reinit(); - exec(); - } - - public void interrupt() { - if (thread != null && thread.isAlive()) { - thread.interrupt(); - } - } - } - public static void sendSyncIntent(Context context) { if (GpodnetPreferences.loggedIn()) { Intent intent = new Intent(context, GpodnetSyncService.class); intent.putExtra(ARG_ACTION, ACTION_SYNC); - ContextCompat.startForegroundService(context, intent); + enqueueWork(context, intent); } } @@ -417,7 +347,7 @@ public class GpodnetSyncService extends Service { if (GpodnetPreferences.loggedIn()) { Intent intent = new Intent(context, GpodnetSyncService.class); intent.putExtra(ARG_ACTION, ACTION_SYNC_SUBSCRIPTIONS); - ContextCompat.startForegroundService(context, intent); + enqueueWork(context, intent); } } @@ -425,7 +355,7 @@ public class GpodnetSyncService extends Service { if (GpodnetPreferences.loggedIn()) { Intent intent = new Intent(context, GpodnetSyncService.class); intent.putExtra(ARG_ACTION, ACTION_SYNC_ACTIONS); - ContextCompat.startForegroundService(context, intent); + enqueueWork(context, intent); } } } -- cgit v1.2.3 From 304696d59e985ddd396685f9be22256f2c3f9aec Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 5 May 2018 18:23:29 +0200 Subject: Stop playback service when item of deleted feed is played Closes #2425 --- .../java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java | 3 +++ core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java | 3 +++ 2 files changed, 6 insertions(+) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java index af735aefd..0e64f484f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java @@ -609,6 +609,9 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { public void shutdown() { executor.shutdown(); if (mediaPlayer != null) { + try { + mediaPlayer.stop(); + } catch (Exception ignore) { } mediaPlayer.release(); } releaseWifiLockIfNecessary(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index 49de7ffe7..8cdf82e15 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -188,6 +188,9 @@ public class DBWriter { if(queue.remove(item)) { removed.add(item); } + if (item.getState() == FeedItem.State.PLAYING && PlaybackService.isRunning) { + context.stopService(new Intent(context, PlaybackService.class)); + } if (item.getMedia() != null && item.getMedia().isDownloaded()) { File mediaFile = new File(item.getMedia() -- cgit v1.2.3 From 61f8000352d80eef4687a66e0d6174637469adc2 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 6 May 2018 18:52:16 +0200 Subject: Using callback instead of sync/async methods --- .../core/receiver/FeedUpdateReceiver.java | 2 +- .../core/service/FeedUpdateJobService.java | 5 +- .../de/danoeh/antennapod/core/storage/DBTasks.java | 64 ++++++++++------------ .../antennapod/core/util/FeedUpdateUtils.java | 8 +-- 4 files changed, 35 insertions(+), 44 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java index 67f6d9348..05e12f6df 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java +++ b/core/src/main/java/de/danoeh/antennapod/core/receiver/FeedUpdateReceiver.java @@ -20,7 +20,7 @@ public class FeedUpdateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Log.d(TAG, "Received intent"); ClientConfig.initialize(context); - FeedUpdateUtils.startAutoUpdate(context, false); + FeedUpdateUtils.startAutoUpdate(context, null); UserPreferences.restartUpdateAlarm(false); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java index 3fc3551ee..55a8d6b86 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateJobService.java @@ -18,11 +18,10 @@ public class FeedUpdateJobService extends JobService { Log.d(TAG, "Job started"); ClientConfig.initialize(getApplicationContext()); - new Thread(() -> { - FeedUpdateUtils.startAutoUpdate(getApplicationContext(), true); + FeedUpdateUtils.startAutoUpdate(getApplicationContext(), () -> { UserPreferences.restartUpdateAlarm(false); jobFinished(params, false); // needsReschedule = false - }).start(); + }); return true; } 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 b1937985f..d1713ff99 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 @@ -148,45 +148,41 @@ public final class DBTasks { * Refreshes a given list of Feeds in a separate Thread. This method might ignore subsequent calls if it is still * enqueuing Feeds for download from a previous call * - * @param context Might be used for accessing the database - * @param feeds List of Feeds that should be refreshed. + * @param context Might be used for accessing the database + * @param feeds List of Feeds that should be refreshed. + * @param callback Called after everything was added enqueued for download */ - public static void refreshAllFeeds(final Context context, final List feeds) { - new Thread(() -> refreshAllFeedsSynchronously(context, feeds)).start(); - } - - /** - * Refreshes a given list of Feeds in the current Thread. This method might ignore subsequent calls if it is still - * enqueuing Feeds for download from a previous call. MUST NOT be executed from main thread. - * - * @param context Might be used for accessing the database - * @param feeds List of Feeds that should be refreshed. - */ - public static void refreshAllFeedsSynchronously(final Context context, final List feeds) { + public static void refreshAllFeeds(final Context context, final List feeds, Runnable callback) { if (isRefreshing.compareAndSet(false, true)) { - if (feeds != null) { - refreshFeeds(context, feeds); - } else { - refreshFeeds(context, DBReader.getFeedList()); - } - isRefreshing.set(false); + new Thread(() -> { + if (feeds != null) { + refreshFeeds(context, feeds); + } else { + refreshFeeds(context, DBReader.getFeedList()); + } + isRefreshing.set(false); - SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); - prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); + prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); - if (FlattrUtils.hasToken()) { - Log.d(TAG, "Flattring all pending things."); - new FlattrClickWorker(context).executeAsync(); // flattr pending things + if (FlattrUtils.hasToken()) { + Log.d(TAG, "Flattring all pending things."); + new FlattrClickWorker(context).executeAsync(); // flattr pending things - Log.d(TAG, "Fetching flattr status."); - new FlattrStatusFetcher(context).start(); + Log.d(TAG, "Fetching flattr status."); + new FlattrStatusFetcher(context).start(); - } - if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { - GpodnetSyncService.sendSyncIntent(context); - } - Log.d(TAG, "refreshAllFeeds autodownload"); - autodownloadUndownloadedItems(context); + } + if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { + GpodnetSyncService.sendSyncIntent(context); + } + Log.d(TAG, "refreshAllFeeds autodownload"); + autodownloadUndownloadedItems(context); + + if (callback != null) { + callback.run(); + } + }).start(); } else { Log.d(TAG, "Ignoring request to refresh all feeds: Refresh lock is locked"); } @@ -344,7 +340,7 @@ public final class DBTasks { Log.d(TAG, "last refresh: " + Converter.getDurationStringLocalized(context, System.currentTimeMillis() - lastRefresh) + " ago"); if(lastRefresh <= System.currentTimeMillis() - interval) { - DBTasks.refreshAllFeeds(context, null); + DBTasks.refreshAllFeeds(context, null, null); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java index a57ab2ce6..24e0da9ed 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedUpdateUtils.java @@ -11,13 +11,9 @@ public class FeedUpdateUtils { } - public static void startAutoUpdate(Context context, boolean synchronously) { + public static void startAutoUpdate(Context context, Runnable callback) { if (NetworkUtils.networkAvailable() && NetworkUtils.isDownloadAllowed()) { - if (synchronously) { - DBTasks.refreshAllFeedsSynchronously(context, null); - } else { - DBTasks.refreshAllFeeds(context, null); - } + DBTasks.refreshAllFeeds(context, null, callback); } else { Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); } -- cgit v1.2.3 From 22f791e05f58b03bfa84ca206cbc113ec002ef82 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 6 May 2018 19:07:25 +0200 Subject: Moved auto update handling to new class --- .../core/preferences/UserPreferences.java | 100 +++--------------- .../core/util/download/AutoUpdateManager.java | 113 +++++++++++++++++++++ 2 files changed, 127 insertions(+), 86 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java (limited to 'core/src/main/java/de/danoeh/antennapod') 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 07a62b743..48efdc84c 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 @@ -1,24 +1,22 @@ package de.danoeh.antennapod.core.preferences; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; -import android.os.SystemClock; import android.preference.PreferenceManager; import android.support.annotation.IntRange; import android.support.annotation.NonNull; -import android.support.annotation.RequiresApi; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; - -import de.danoeh.antennapod.core.service.FeedUpdateJobService; +import de.danoeh.antennapod.core.R; +import de.danoeh.antennapod.core.service.download.ProxyConfig; +import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; +import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm; +import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm; +import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; +import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.download.AutoUpdateManager; import org.json.JSONArray; import org.json.JSONException; @@ -31,15 +29,6 @@ import java.util.Calendar; import java.util.List; import java.util.concurrent.TimeUnit; -import de.danoeh.antennapod.core.R; -import de.danoeh.antennapod.core.receiver.FeedUpdateReceiver; -import de.danoeh.antennapod.core.service.download.ProxyConfig; -import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; -import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm; -import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm; -import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; -import de.danoeh.antennapod.core.util.Converter; - /** * Provides access to preferences set by the user in the settings screen. A * private instance of this class must first be instantiated via @@ -109,9 +98,6 @@ public class UserPreferences { private static final String PREF_DATA_FOLDER = "prefDataFolder"; public static final String PREF_IMAGE_CACHE_SIZE = "prefImageCacheSize"; - // JobScheduler - private static final int JOB_ID_FEED_UPDATE = 42; - // Mediaplayer private static final String PREF_PLAYBACK_SPEED = "prefPlaybackSpeed"; private static final String PREF_FAST_FORWARD_SECS = "prefFastForwardSecs"; @@ -808,42 +794,10 @@ public class UserPreferences { Log.d(TAG, "Restarting update alarm."); if (Build.VERSION.SDK_INT >= 24) { - JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - if (jobScheduler != null) { - JobInfo oldJob = jobScheduler.getPendingJob(JOB_ID_FEED_UPDATE); - if (oldJob == null || oldJob.getIntervalMillis() != intervalMillis) { - JobInfo.Builder builder = getFeedUpdateJobBuilder(); - builder.setPeriodic(intervalMillis); - jobScheduler.cancel(JOB_ID_FEED_UPDATE); - - if (intervalMillis <= 0) { - Log.d(TAG, "Automatic update was deactivated"); - return; - } - - jobScheduler.schedule(builder.build()); - Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); - } else { - Log.d(TAG, "JobScheduler was already set at interval " + intervalMillis + ", ignoring."); - } - } - return; - } - - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - Intent intent = new Intent(context, FeedUpdateReceiver.class); - PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, intent, 0); - alarmManager.cancel(updateIntent); - - if (intervalMillis <= 0) { - Log.d(TAG, "Automatic update was deactivated"); - return; + AutoUpdateManager.restartJobServiceInterval(context, intervalMillis); + } else { + AutoUpdateManager.restartAlarmManagerInterval(context, triggerAtMillis, intervalMillis); } - - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + triggerAtMillis, - updateIntent); - Log.d(TAG, "Changed alarm to new interval " + TimeUnit.MILLISECONDS.toHours(intervalMillis) + " h"); } /** @@ -861,37 +815,11 @@ public class UserPreferences { } if (Build.VERSION.SDK_INT >= 24) { - JobInfo.Builder builder = getFeedUpdateJobBuilder(); long triggerAtMillis = alarm.getTimeInMillis() - now.getTimeInMillis(); - builder.setMinimumLatency(triggerAtMillis); - JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - if (jobScheduler != null) { - jobScheduler.cancel(JOB_ID_FEED_UPDATE); - jobScheduler.schedule(builder.build()); - Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); - } - return; + AutoUpdateManager.restartJobServiceTriggerAt(context, triggerAtMillis); + } else { + AutoUpdateManager.restartAlarmManagerTimeOfDay(context, alarm); } - - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, - new Intent(context, FeedUpdateReceiver.class), 0); - alarmManager.cancel(updateIntent); - - Log.d(TAG, "Alarm set for: " + alarm.toString() + " : " + alarm.getTimeInMillis()); - alarmManager.set(AlarmManager.RTC_WAKEUP, - alarm.getTimeInMillis(), - updateIntent); - Log.d(TAG, "Changed alarm to new time of day " + hoursOfDay + ":" + minute); - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - private static JobInfo.Builder getFeedUpdateJobBuilder() { - ComponentName serviceComponent = new ComponentName(context, FeedUpdateJobService.class); - JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_FEED_UPDATE, serviceComponent); - builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); - builder.setPersisted(true); - return builder; } /** 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 new file mode 100644 index 000000000..ec9fcae4e --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/download/AutoUpdateManager.java @@ -0,0 +1,113 @@ +package de.danoeh.antennapod.core.util.download; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.app.job.JobInfo; +import android.app.job.JobScheduler; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.SystemClock; +import android.support.annotation.RequiresApi; +import android.util.Log; +import de.danoeh.antennapod.core.receiver.FeedUpdateReceiver; +import de.danoeh.antennapod.core.service.FeedUpdateJobService; + +import java.util.Calendar; +import java.util.concurrent.TimeUnit; + +public class AutoUpdateManager { + private static final int JOB_ID_FEED_UPDATE = 42; + private static final String TAG = "AutoUpdateManager"; + + private AutoUpdateManager() { + + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static JobInfo.Builder getFeedUpdateJobBuilder(Context context) { + ComponentName serviceComponent = new ComponentName(context, FeedUpdateJobService.class); + JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_FEED_UPDATE, serviceComponent); + builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); + builder.setPersisted(true); + return builder; + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public static void restartJobServiceInterval(Context context, long intervalMillis) { + JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); + if (jobScheduler != null) { + JobInfo oldJob = jobScheduler.getPendingJob(JOB_ID_FEED_UPDATE); + if (oldJob == null || oldJob.getIntervalMillis() != intervalMillis) { + JobInfo.Builder builder = getFeedUpdateJobBuilder(context); + builder.setPeriodic(intervalMillis); + jobScheduler.cancel(JOB_ID_FEED_UPDATE); + + if (intervalMillis <= 0) { + Log.d(TAG, "Automatic update was deactivated"); + return; + } + + jobScheduler.schedule(builder.build()); + Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); + } else { + Log.d(TAG, "JobScheduler was already set at interval " + intervalMillis + ", ignoring."); + } + } + } + + public static void restartAlarmManagerInterval(Context context, long triggerAtMillis, long intervalMillis) { + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + + if (alarmManager == null) { + Log.d(TAG, "AlarmManager was null"); + return; + } + + Intent intent = new Intent(context, FeedUpdateReceiver.class); + PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, intent, 0); + alarmManager.cancel(updateIntent); + + if (intervalMillis <= 0) { + Log.d(TAG, "Automatic update was deactivated"); + return; + } + + alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + triggerAtMillis, + updateIntent); + Log.d(TAG, "Changed alarm to new interval " + TimeUnit.MILLISECONDS.toHours(intervalMillis) + " h"); + } + + @RequiresApi(api = Build.VERSION_CODES.N) + public static void restartJobServiceTriggerAt(Context context, long triggerAtMillis) { + JobInfo.Builder builder = getFeedUpdateJobBuilder(context); + builder.setMinimumLatency(triggerAtMillis); + JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); + if (jobScheduler != null) { + jobScheduler.cancel(JOB_ID_FEED_UPDATE); + jobScheduler.schedule(builder.build()); + Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); + } + } + + public static void restartAlarmManagerTimeOfDay(Context context, Calendar alarm) { + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, + new Intent(context, FeedUpdateReceiver.class), 0); + + if (alarmManager == null) { + Log.d(TAG, "AlarmManager was null"); + return; + } + + alarmManager.cancel(updateIntent); + + Log.d(TAG, "Alarm set for: " + alarm.toString() + " : " + alarm.getTimeInMillis()); + alarmManager.set(AlarmManager.RTC_WAKEUP, + alarm.getTimeInMillis(), + updateIntent); + Log.d(TAG, "Changed alarm to new time of day " + alarm.get(Calendar.HOUR_OF_DAY) + ":" + alarm.get(Calendar.MINUTE)); + } +} -- cgit v1.2.3 From cb70aeb3cfe1cdf81937ee98c79cee324024048a Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 6 May 2018 19:15:40 +0200 Subject: Code style improvements --- .../core/service/PlayerWidgetJobService.java | 3 -- .../de/danoeh/antennapod/core/storage/DBTasks.java | 62 +++++++++++----------- .../antennapod/core/util/playback/Playable.java | 2 + .../core/util/playback/PlaybackController.java | 34 ++++++------ 4 files changed, 52 insertions(+), 49 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java index 49f3058ef..2fd790ac7 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java @@ -31,9 +31,6 @@ public class PlayerWidgetJobService extends JobIntentService { private PlaybackService playbackService; private final Object waitForService = new Object(); - public PlayerWidgetJobService() { - } - public static void updateWidget(Context context) { enqueueWork(context, PlayerWidgetJobService.class, 0, new Intent(context, PlayerWidgetJobService.class)); } 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 d1713ff99..02098e9ed 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 @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.util.Log; @@ -150,42 +151,43 @@ public final class DBTasks { * * @param context Might be used for accessing the database * @param feeds List of Feeds that should be refreshed. - * @param callback Called after everything was added enqueued for download + * @param callback Called after everything was added enqueued for download. Might be null. */ - public static void refreshAllFeeds(final Context context, final List feeds, Runnable callback) { - if (isRefreshing.compareAndSet(false, true)) { - new Thread(() -> { - if (feeds != null) { - refreshFeeds(context, feeds); - } else { - refreshFeeds(context, DBReader.getFeedList()); - } - isRefreshing.set(false); + public static void refreshAllFeeds(final Context context, final List feeds, @Nullable Runnable callback) { + if (!isRefreshing.compareAndSet(false, true)) { + Log.d(TAG, "Ignoring request to refresh all feeds: Refresh lock is locked"); + return; + } - SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); - prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); + new Thread(() -> { + if (feeds != null) { + refreshFeeds(context, feeds); + } else { + refreshFeeds(context, DBReader.getFeedList()); + } + isRefreshing.set(false); - if (FlattrUtils.hasToken()) { - Log.d(TAG, "Flattring all pending things."); - new FlattrClickWorker(context).executeAsync(); // flattr pending things + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); + prefs.edit().putLong(PREF_LAST_REFRESH, System.currentTimeMillis()).apply(); - Log.d(TAG, "Fetching flattr status."); - new FlattrStatusFetcher(context).start(); + if (FlattrUtils.hasToken()) { + Log.d(TAG, "Flattring all pending things."); + new FlattrClickWorker(context).executeAsync(); // flattr pending things - } - if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { - GpodnetSyncService.sendSyncIntent(context); - } - Log.d(TAG, "refreshAllFeeds autodownload"); - autodownloadUndownloadedItems(context); + Log.d(TAG, "Fetching flattr status."); + new FlattrStatusFetcher(context).start(); - if (callback != null) { - callback.run(); - } - }).start(); - } else { - Log.d(TAG, "Ignoring request to refresh all feeds: Refresh lock is locked"); - } + } + if (ClientConfig.gpodnetCallbacks.gpodnetEnabled()) { + GpodnetSyncService.sendSyncIntent(context); + } + Log.d(TAG, "refreshAllFeeds autodownload"); + autodownloadUndownloadedItems(context); + + if (callback != null) { + callback.run(); + } + }).start(); } /** diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java index bb9896f25..ff7f5b79d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Parcelable; import android.preference.PreferenceManager; +import android.support.annotation.Nullable; import android.util.Log; import java.util.List; @@ -183,6 +184,7 @@ public interface Playable extends Parcelable, * * @return The restored Playable object */ + @Nullable public static Playable createInstanceFromPreferences(Context context) { long currentlyPlayingMedia = PlaybackPreferences.getCurrentlyPlayingMedia(); if (currentlyPlayingMedia != PlaybackPreferences.NO_MEDIA_PLAYING) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index d1d6b5c63..7c930a8e2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -14,6 +14,7 @@ import android.os.Build; import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.util.Log; @@ -212,25 +213,26 @@ public abstract class PlaybackController { * Returns an intent that starts the PlaybackService and plays the last * played media or null if no last played media could be found. */ - private Intent getPlayLastPlayedMediaIntent() { + @Nullable private Intent getPlayLastPlayedMediaIntent() { Log.d(TAG, "Trying to restore last played media"); Playable media = PlayableUtils.createInstanceFromPreferences(activity); - if (media != null) { - Intent serviceIntent = new Intent(activity, PlaybackService.class); - serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); - serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false); - serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true); - boolean fileExists = media.localFileAvailable(); - boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); - if (!fileExists && !lastIsStream && media instanceof FeedMedia) { - DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media); - } - serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, - lastIsStream || !fileExists); - return serviceIntent; + if (media == null) { + Log.d(TAG, "No last played media found"); + return null; } - Log.d(TAG, "No last played media found"); - return null; + + Intent serviceIntent = new Intent(activity, PlaybackService.class); + serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); + serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false); + serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true); + boolean fileExists = media.localFileAvailable(); + boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); + if (!fileExists && !lastIsStream && media instanceof FeedMedia) { + DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media); + } + serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, + lastIsStream || !fileExists); + return serviceIntent; } -- cgit v1.2.3 From 4411b0ffaa34aede5c42ad3cbc401b63db40a371 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 6 May 2018 19:21:02 +0200 Subject: Fix possible missing sync calls --- .../de/danoeh/antennapod/core/service/GpodnetSyncService.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java index 8a18d93b9..94fadae02 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java @@ -56,13 +56,13 @@ public class GpodnetSyncService extends JobIntentService { private static final String ACTION_SYNC_SUBSCRIPTIONS = "de.danoeh.antennapod.intent.action.sync_subscriptions"; private static final String ACTION_SYNC_ACTIONS = "de.danoeh.antennapod.intent.action.sync_ACTIONS"; - private static final AtomicInteger syncActionCount = new AtomicInteger(0); - private GpodnetService service; - private boolean syncSubscriptions = false; - private boolean syncActions = false; - public static void enqueueWork(Context context, Intent intent) { + private static final AtomicInteger syncActionCount = new AtomicInteger(0); + private static boolean syncSubscriptions = false; + private static boolean syncActions = false; + + private static void enqueueWork(Context context, Intent intent) { enqueueWork(context, GpodnetSyncService.class, 0, intent); } -- cgit v1.2.3 From f6082f58088d79a8b46556fc68c7bbbf30008c82 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sun, 6 May 2018 19:44:07 +0200 Subject: Using builder to call PlaybackService --- .../core/service/playback/PlaybackService.java | 15 ----- .../de/danoeh/antennapod/core/storage/DBTasks.java | 10 ++- .../core/util/playback/PlaybackController.java | 17 ++--- .../core/util/playback/PlaybackServiceStarter.java | 76 ++++++++++++++++++++++ 4 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java (limited to 'core/src/main/java/de/danoeh/antennapod') 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 dc67c0758..c1d3b6f1f 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 @@ -804,21 +804,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { } }; - public static void startIfNotRunning(final Context context, final Playable media, boolean startWhenPrepared, boolean shouldStream) { - if (!isRunning) { - startService(context, media, startWhenPrepared, shouldStream); - } - } - - public static void startService(final Context context, final Playable media, boolean startWhenPrepared, boolean shouldStream) { - Intent launchIntent = new Intent(context, PlaybackService.class); - launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); - launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, startWhenPrepared); - launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream); - launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true); - ContextCompat.startForegroundService(context, launchIntent); - } - private Playable getNextInQueue(final Playable currentMedia) { if (!(currentMedia instanceof FeedMedia)) { Log.d(TAG, "getNextInQueue(), but playable not an instance of FeedMedia, so not proceeding"); 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 02098e9ed..22a7b64fe 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 @@ -40,6 +40,7 @@ import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator; import de.danoeh.antennapod.core.util.exception.MediaFileNotFoundException; import de.danoeh.antennapod.core.util.flattr.FlattrUtils; +import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; import static android.content.Context.MODE_PRIVATE; @@ -125,8 +126,13 @@ public final class DBTasks { media); } } - // Needs to be called even if the service is already running to deliver the new media intent - PlaybackService.startService(context, media, startWhenPrepared, shouldStream); + + new PlaybackServiceStarter(context, media) + .callEvenIfRunning(true) + .startWhenPrepared(startWhenPrepared) + .shouldStream(shouldStream) + .start(); + if (showPlayer) { // Launch media player context.startActivity(PlaybackService.getPlayerActivityIntent( diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 7c930a8e2..a3f02d5cc 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -221,18 +221,16 @@ public abstract class PlaybackController { return null; } - Intent serviceIntent = new Intent(activity, PlaybackService.class); - serviceIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); - serviceIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, false); - serviceIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, true); boolean fileExists = media.localFileAvailable(); boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); if (!fileExists && !lastIsStream && media instanceof FeedMedia) { DBTasks.notifyMissingFeedMediaFile(activity, (FeedMedia) media); } - serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, - lastIsStream || !fileExists); - return serviceIntent; + + return new PlaybackServiceStarter(activity, media) + .startWhenPrepared(false) + .shouldStream(lastIsStream || !fileExists) + .getIntent(); } @@ -586,7 +584,10 @@ public abstract class PlaybackController { public void playPause() { if (playbackService == null) { - PlaybackService.startService(activity, media, true, false); + new PlaybackServiceStarter(activity, media) + .startWhenPrepared(true) + .streamIfLastWasStream() + .start(); Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!"); return; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java new file mode 100644 index 000000000..3ba553d12 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java @@ -0,0 +1,76 @@ +package de.danoeh.antennapod.core.util.playback; + +import android.content.Context; +import android.content.Intent; +import android.media.MediaPlayer; +import android.support.v4.content.ContextCompat; +import de.danoeh.antennapod.core.preferences.PlaybackPreferences; +import de.danoeh.antennapod.core.service.playback.PlaybackService; + +public class PlaybackServiceStarter { + private final Context context; + private final Playable media; + private boolean startWhenPrepared = false; + private boolean shouldStream = false; + private boolean callEvenIfRunning = false; + private boolean prepareImmediately = true; + + public PlaybackServiceStarter(Context context, Playable media) { + this.context = context; + this.media = media; + } + + /** + * Default value: false + */ + public PlaybackServiceStarter shouldStream(boolean shouldStream) { + this.shouldStream = shouldStream; + return this; + } + + public PlaybackServiceStarter streamIfLastWasStream() { + boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); + return shouldStream(lastIsStream); + } + + /** + * Default value: false + */ + public PlaybackServiceStarter startWhenPrepared(boolean startWhenPrepared) { + this.startWhenPrepared = startWhenPrepared; + return this; + } + + /** + * Default value: false + */ + public PlaybackServiceStarter callEvenIfRunning(boolean callEvenIfRunning) { + this.callEvenIfRunning = callEvenIfRunning; + return this; + } + + /** + * Default value: true + */ + public PlaybackServiceStarter prepareImmediately(boolean prepareImmediately) { + this.prepareImmediately = prepareImmediately; + return this; + } + + public Intent getIntent() { + Intent launchIntent = new Intent(context, PlaybackService.class); + launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); + launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, startWhenPrepared); + launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream); + launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, prepareImmediately); + + return launchIntent; + } + + public void start() { + if (PlaybackService.isRunning && !callEvenIfRunning) { + return; + } + ContextCompat.startForegroundService(context, getIntent()); + } +} -- cgit v1.2.3 From eb0ef1e2014c8e1b8f7ff76359bd476cc52fd7b5 Mon Sep 17 00:00:00 2001 From: orionlee Date: Fri, 18 May 2018 13:42:39 -0700 Subject: core tests: Make DownloadServiceTest be a unit test (the portion of DownloadService tested is all in-memory logic). --- .../de/danoeh/antennapod/core/service/download/DownloadService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 a62c9d8bf..ae103ee18 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 @@ -7,8 +7,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.media.MediaMetadataRetriever; import android.os.Binder; import android.os.Build; @@ -1107,7 +1105,7 @@ public class DownloadService extends Service { * that every image reference is unique. */ @VisibleForTesting - public static void removeDuplicateImages(Feed feed) { + static void removeDuplicateImages(Feed feed) { Set known = new HashSet<>(); for (FeedItem item : feed.getItems()) { String url = item.hasItemImage() ? item.getImage().getDownload_url() : null; -- cgit v1.2.3 From 6bda6405b8102a1111e6d0521584fedf8ebc3a07 Mon Sep 17 00:00:00 2001 From: brad Date: Sun, 20 May 2018 23:01:14 -0700 Subject: avoid unused context parameter --- .../antennapod/core/storage/DownloadRequester.java | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index a8fd79fda..1f429d189 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -176,8 +176,8 @@ public class DownloadRequester { args.putInt(REQUEST_ARG_PAGE_NR, feed.getPageNr()); args.putBoolean(REQUEST_ARG_LOAD_ALL_PAGES, loadAllPages); - download(context, feed, null, new File(getFeedfilePath(context), - getFeedfileName(feed)), true, username, password, lastModified, true, args); + download(context, feed, null, new File(getFeedfilePath(), getFeedfileName(feed)), + true, username, password, lastModified, true, args); } } @@ -203,8 +203,7 @@ public class DownloadRequester { if (feedmedia.getFile_url() != null) { dest = new File(feedmedia.getFile_url()); } else { - dest = new File(getMediafilePath(context, feedmedia), - getMediafilename(feedmedia)); + dest = new File(getMediafilePath(feedmedia), getMediafilename(feedmedia)); } download(context, feedmedia, feed, dest, false, username, password, null, false, null); @@ -305,10 +304,8 @@ public class DownloadRequester { return downloads.size(); } - private synchronized String getFeedfilePath(Context context) - throws DownloadRequestException { - return getExternalFilesDirOrThrowException(context, FEED_DOWNLOADPATH) - .toString() + "/"; + private synchronized String getFeedfilePath() throws DownloadRequestException { + return getExternalFilesDirOrThrowException(FEED_DOWNLOADPATH).toString() + "/"; } private synchronized String getFeedfileName(Feed feed) { @@ -319,10 +316,8 @@ public class DownloadRequester { return "feed-" + FileNameGenerator.generateFileName(filename); } - private synchronized String getMediafilePath(Context context, FeedMedia media) - throws DownloadRequestException { + private synchronized String getMediafilePath(FeedMedia media) throws DownloadRequestException { File externalStorage = getExternalFilesDirOrThrowException( - context, MEDIA_DOWNLOADPATH + FileNameGenerator.generateFileName(media.getItem() .getFeed().getTitle()) + "/" @@ -330,8 +325,7 @@ public class DownloadRequester { return externalStorage.toString(); } - private File getExternalFilesDirOrThrowException(Context context, - String type) throws DownloadRequestException { + private File getExternalFilesDirOrThrowException(String type) throws DownloadRequestException { File result = UserPreferences.getDataFolder(type); if (result == null) { throw new DownloadRequestException( -- cgit v1.2.3 From 3edbbe8c5356f00cd12824b5819ec9b42a347eca Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 26 May 2018 23:13:16 +0200 Subject: Moved notification utils to other package --- .../core/asynctask/FlattrClickWorker.java | 2 +- .../core/service/GpodnetSyncService.java | 3 +- .../core/service/download/DownloadService.java | 4 +- .../core/service/playback/PlaybackService.java | 5 +- .../antennapod/core/util/NotificationUtils.java | 72 ---------------------- .../core/util/gui/NotificationUtils.java | 72 ++++++++++++++++++++++ 6 files changed, 76 insertions(+), 82 deletions(-) delete mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java create mode 100644 core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java index 627e601bd..f4c99011a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/asynctask/FlattrClickWorker.java @@ -10,7 +10,7 @@ import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; -import de.danoeh.antennapod.core.util.NotificationUtils; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; import org.shredzone.flattr4j.exception.FlattrException; import java.util.LinkedList; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java index 94fadae02..de040603d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java @@ -8,7 +8,6 @@ import android.content.Intent; import android.support.annotation.NonNull; import android.support.v4.app.JobIntentService; import android.support.v4.app.NotificationCompat; -import android.support.v4.content.ContextCompat; import android.support.v4.util.ArrayMap; import android.util.Log; import android.util.Pair; @@ -39,7 +38,7 @@ import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.NetworkUtils; -import de.danoeh.antennapod.core.util.NotificationUtils; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; /** * Synchronizes local subscriptions with gpodder.net service. The service should be started with ACTION_SYNC as an action argument. 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 34cabf564..e3b8a505b 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 @@ -7,8 +7,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.media.MediaMetadataRetriever; import android.os.Binder; import android.os.Build; @@ -22,7 +20,7 @@ import android.util.Log; import android.util.Pair; import android.webkit.URLUtil; -import de.danoeh.antennapod.core.util.NotificationUtils; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; import org.apache.commons.io.FileUtils; import org.xml.sax.SAXException; 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 c1d23c626..be6cb346d 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 @@ -24,19 +24,16 @@ import android.os.Vibrator; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.StringRes; -import android.support.v4.content.ContextCompat; import android.support.v4.media.MediaBrowserCompat; import android.support.v4.media.MediaBrowserServiceCompat; import android.support.v4.media.MediaDescriptionCompat; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; -import android.support.v4.view.InputDeviceCompat; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import android.view.InputDevice; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.widget.Toast; @@ -68,7 +65,7 @@ import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.FeedSearcher; import de.danoeh.antennapod.core.util.IntList; -import de.danoeh.antennapod.core.util.NotificationUtils; +import de.danoeh.antennapod.core.util.gui.NotificationUtils; import de.danoeh.antennapod.core.util.QueueAccess; import de.danoeh.antennapod.core.util.playback.ExternalMedia; import de.danoeh.antennapod.core.util.playback.Playable; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java deleted file mode 100644 index e81b03d77..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/NotificationUtils.java +++ /dev/null @@ -1,72 +0,0 @@ -package de.danoeh.antennapod.core.util; - - -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.content.Context; -import android.os.Build; -import android.support.annotation.RequiresApi; -import de.danoeh.antennapod.core.R; - -public class NotificationUtils { - public static final String CHANNEL_ID_USER_ACTION = "user_action"; - public static final String CHANNEL_ID_DOWNLOADING = "downloading"; - public static final String CHANNEL_ID_PLAYING = "playing"; - public static final String CHANNEL_ID_ERROR = "error"; - public static final String CHANNEL_ID_GPODNET = "gpodnet"; - - public static void createChannels(Context context) { - if (android.os.Build.VERSION.SDK_INT < 26) { - return; - } - NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - - if (mNotificationManager != null) { - mNotificationManager.createNotificationChannel(createChannelUserAction(context)); - mNotificationManager.createNotificationChannel(createChannelDownloading(context)); - mNotificationManager.createNotificationChannel(createChannelPlaying(context)); - mNotificationManager.createNotificationChannel(createChannelError(context)); - mNotificationManager.createNotificationChannel(createChannelGpodnet(context)); - } - } - - @RequiresApi(api = Build.VERSION_CODES.O) - private static NotificationChannel createChannelUserAction(Context c) { - NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_USER_ACTION, - c.getString(R.string.notification_channel_user_action), NotificationManager.IMPORTANCE_HIGH); - mChannel.setDescription(c.getString(R.string.notification_channel_user_action_description)); - return mChannel; - } - - @RequiresApi(api = Build.VERSION_CODES.O) - private static NotificationChannel createChannelDownloading(Context c) { - NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_DOWNLOADING, - c.getString(R.string.notification_channel_downloading), NotificationManager.IMPORTANCE_LOW); - mChannel.setDescription(c.getString(R.string.notification_channel_downloading_description)); - return mChannel; - } - - @RequiresApi(api = Build.VERSION_CODES.O) - private static NotificationChannel createChannelPlaying(Context c) { - NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_PLAYING, - c.getString(R.string.notification_channel_playing), NotificationManager.IMPORTANCE_LOW); - mChannel.setDescription(c.getString(R.string.notification_channel_playing_description)); - return mChannel; - } - - @RequiresApi(api = Build.VERSION_CODES.O) - private static NotificationChannel createChannelError(Context c) { - NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_ERROR, - c.getString(R.string.notification_channel_error), NotificationManager.IMPORTANCE_HIGH); - mChannel.setDescription(c.getString(R.string.notification_channel_error_description)); - return mChannel; - } - - @RequiresApi(api = Build.VERSION_CODES.O) - private static NotificationChannel createChannelGpodnet(Context c) { - NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_GPODNET, - c.getString(R.string.notification_channel_gpodnet), NotificationManager.IMPORTANCE_MIN); - mChannel.setDescription(c.getString(R.string.notification_channel_gpodnet_description)); - return mChannel; - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java new file mode 100644 index 000000000..39e4d8335 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java @@ -0,0 +1,72 @@ +package de.danoeh.antennapod.core.util.gui; + + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Build; +import android.support.annotation.RequiresApi; +import de.danoeh.antennapod.core.R; + +public class NotificationUtils { + public static final String CHANNEL_ID_USER_ACTION = "user_action"; + public static final String CHANNEL_ID_DOWNLOADING = "downloading"; + public static final String CHANNEL_ID_PLAYING = "playing"; + public static final String CHANNEL_ID_ERROR = "error"; + public static final String CHANNEL_ID_GPODNET = "gpodnet"; + + public static void createChannels(Context context) { + if (android.os.Build.VERSION.SDK_INT < 26) { + return; + } + NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + if (mNotificationManager != null) { + mNotificationManager.createNotificationChannel(createChannelUserAction(context)); + mNotificationManager.createNotificationChannel(createChannelDownloading(context)); + mNotificationManager.createNotificationChannel(createChannelPlaying(context)); + mNotificationManager.createNotificationChannel(createChannelError(context)); + mNotificationManager.createNotificationChannel(createChannelGpodnet(context)); + } + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private static NotificationChannel createChannelUserAction(Context c) { + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_USER_ACTION, + c.getString(R.string.notification_channel_user_action), NotificationManager.IMPORTANCE_HIGH); + mChannel.setDescription(c.getString(R.string.notification_channel_user_action_description)); + return mChannel; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private static NotificationChannel createChannelDownloading(Context c) { + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_DOWNLOADING, + c.getString(R.string.notification_channel_downloading), NotificationManager.IMPORTANCE_LOW); + mChannel.setDescription(c.getString(R.string.notification_channel_downloading_description)); + return mChannel; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private static NotificationChannel createChannelPlaying(Context c) { + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_PLAYING, + c.getString(R.string.notification_channel_playing), NotificationManager.IMPORTANCE_LOW); + mChannel.setDescription(c.getString(R.string.notification_channel_playing_description)); + return mChannel; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private static NotificationChannel createChannelError(Context c) { + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_ERROR, + c.getString(R.string.notification_channel_error), NotificationManager.IMPORTANCE_HIGH); + mChannel.setDescription(c.getString(R.string.notification_channel_error_description)); + return mChannel; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private static NotificationChannel createChannelGpodnet(Context c) { + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_GPODNET, + c.getString(R.string.notification_channel_gpodnet), NotificationManager.IMPORTANCE_MIN); + mChannel.setDescription(c.getString(R.string.notification_channel_gpodnet_description)); + return mChannel; + } +} -- cgit v1.2.3 From badc8398049314451a7c2f51a632e323786d6c7b Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 26 May 2018 23:14:07 +0200 Subject: Gpodder sync does not need a notification anymore --- .../de/danoeh/antennapod/core/util/gui/NotificationUtils.java | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java index 39e4d8335..1c42364ea 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/gui/NotificationUtils.java @@ -13,7 +13,6 @@ public class NotificationUtils { public static final String CHANNEL_ID_DOWNLOADING = "downloading"; public static final String CHANNEL_ID_PLAYING = "playing"; public static final String CHANNEL_ID_ERROR = "error"; - public static final String CHANNEL_ID_GPODNET = "gpodnet"; public static void createChannels(Context context) { if (android.os.Build.VERSION.SDK_INT < 26) { @@ -26,7 +25,6 @@ public class NotificationUtils { mNotificationManager.createNotificationChannel(createChannelDownloading(context)); mNotificationManager.createNotificationChannel(createChannelPlaying(context)); mNotificationManager.createNotificationChannel(createChannelError(context)); - mNotificationManager.createNotificationChannel(createChannelGpodnet(context)); } } @@ -61,12 +59,4 @@ public class NotificationUtils { mChannel.setDescription(c.getString(R.string.notification_channel_error_description)); return mChannel; } - - @RequiresApi(api = Build.VERSION_CODES.O) - private static NotificationChannel createChannelGpodnet(Context c) { - NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID_GPODNET, - c.getString(R.string.notification_channel_gpodnet), NotificationManager.IMPORTANCE_MIN); - mChannel.setDescription(c.getString(R.string.notification_channel_gpodnet_description)); - return mChannel; - } } -- cgit v1.2.3 From 9ce48bd86bc5f32f197f2f5b0d3a78596b9c15fe Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 26 May 2018 23:20:47 +0200 Subject: Added a refreshAllFeeds method without callback --- .../java/de/danoeh/antennapod/core/storage/DBTasks.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 22a7b64fe..da500fd3e 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 @@ -151,6 +151,17 @@ public final class DBTasks { private static final AtomicBoolean isRefreshing = new AtomicBoolean(false); + /** + * Refreshes a given list of Feeds in a separate Thread. This method might ignore subsequent calls if it is still + * enqueuing Feeds for download from a previous call + * + * @param context Might be used for accessing the database + * @param feeds List of Feeds that should be refreshed. + */ + public static void refreshAllFeeds(final Context context, final List feeds) { + refreshAllFeeds(context, feeds, null); + } + /** * Refreshes a given list of Feeds in a separate Thread. This method might ignore subsequent calls if it is still * enqueuing Feeds for download from a previous call @@ -348,7 +359,7 @@ public final class DBTasks { Log.d(TAG, "last refresh: " + Converter.getDurationStringLocalized(context, System.currentTimeMillis() - lastRefresh) + " ago"); if(lastRefresh <= System.currentTimeMillis() - interval) { - DBTasks.refreshAllFeeds(context, null, null); + DBTasks.refreshAllFeeds(context, null); } } -- cgit v1.2.3 From b3e02e215cadafa3d76120f92a022d5f714bcd7e Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 26 May 2018 23:25:18 +0200 Subject: Simplified AutoUpdateManager --- .../core/util/download/AutoUpdateManager.java | 61 ++++++++++++---------- 1 file changed, 34 insertions(+), 27 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 ec9fcae4e..83fe8f137 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 @@ -37,24 +37,28 @@ public class AutoUpdateManager { @RequiresApi(api = Build.VERSION_CODES.N) public static void restartJobServiceInterval(Context context, long intervalMillis) { JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - if (jobScheduler != null) { - JobInfo oldJob = jobScheduler.getPendingJob(JOB_ID_FEED_UPDATE); - if (oldJob == null || oldJob.getIntervalMillis() != intervalMillis) { - JobInfo.Builder builder = getFeedUpdateJobBuilder(context); - builder.setPeriodic(intervalMillis); - jobScheduler.cancel(JOB_ID_FEED_UPDATE); - - if (intervalMillis <= 0) { - Log.d(TAG, "Automatic update was deactivated"); - return; - } - - jobScheduler.schedule(builder.build()); - Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); - } else { - Log.d(TAG, "JobScheduler was already set at interval " + intervalMillis + ", ignoring."); - } + if (jobScheduler == null) { + Log.d(TAG, "JobScheduler was null."); + return; + } + + JobInfo oldJob = jobScheduler.getPendingJob(JOB_ID_FEED_UPDATE); + if (oldJob != null && oldJob.getIntervalMillis() == intervalMillis) { + Log.d(TAG, "JobScheduler was already set at interval " + intervalMillis + ", ignoring."); + return; + } + + JobInfo.Builder builder = getFeedUpdateJobBuilder(context); + builder.setPeriodic(intervalMillis); + jobScheduler.cancel(JOB_ID_FEED_UPDATE); + + if (intervalMillis <= 0) { + Log.d(TAG, "Automatic update was deactivated"); + return; } + + jobScheduler.schedule(builder.build()); + Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); } public static void restartAlarmManagerInterval(Context context, long triggerAtMillis, long intervalMillis) { @@ -65,8 +69,8 @@ public class AutoUpdateManager { return; } - Intent intent = new Intent(context, FeedUpdateReceiver.class); - PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, intent, 0); + PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, + new Intent(context, FeedUpdateReceiver.class), 0); alarmManager.cancel(updateIntent); if (intervalMillis <= 0) { @@ -82,26 +86,29 @@ public class AutoUpdateManager { @RequiresApi(api = Build.VERSION_CODES.N) public static void restartJobServiceTriggerAt(Context context, long triggerAtMillis) { - JobInfo.Builder builder = getFeedUpdateJobBuilder(context); - builder.setMinimumLatency(triggerAtMillis); JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); - if (jobScheduler != null) { - jobScheduler.cancel(JOB_ID_FEED_UPDATE); - jobScheduler.schedule(builder.build()); - Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); + if (jobScheduler == null) { + Log.d(TAG, "JobScheduler was null."); + return; } + + JobInfo.Builder builder = getFeedUpdateJobBuilder(context); + builder.setMinimumLatency(triggerAtMillis); + jobScheduler.cancel(JOB_ID_FEED_UPDATE); + jobScheduler.schedule(builder.build()); + Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); } public static void restartAlarmManagerTimeOfDay(Context context, Calendar alarm) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, - new Intent(context, FeedUpdateReceiver.class), 0); if (alarmManager == null) { Log.d(TAG, "AlarmManager was null"); return; } + PendingIntent updateIntent = PendingIntent.getBroadcast(context, 0, + new Intent(context, FeedUpdateReceiver.class), 0); alarmManager.cancel(updateIntent); Log.d(TAG, "Alarm set for: " + alarm.toString() + " : " + alarm.getTimeInMillis()); -- cgit v1.2.3 From 443f6315fa2935c413dcfdf2c6cbc96a7a330f84 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 26 May 2018 23:30:06 +0200 Subject: Moved methods into AutoUpdateManager --- .../core/preferences/UserPreferences.java | 41 +-------------------- .../core/util/download/AutoUpdateManager.java | 43 ++++++++++++++++++++-- 2 files changed, 41 insertions(+), 43 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 48efdc84c..44b2fa2b2 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 @@ -2,7 +2,6 @@ package de.danoeh.antennapod.core.preferences; import android.content.Context; import android.content.SharedPreferences; -import android.os.Build; import android.preference.PreferenceManager; import android.support.annotation.IntRange; import android.support.annotation.NonNull; @@ -25,7 +24,6 @@ import java.io.IOException; import java.net.Proxy; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; import java.util.List; import java.util.concurrent.TimeUnit; @@ -776,49 +774,14 @@ public class UserPreferences { int[] timeOfDay = getUpdateTimeOfDay(); Log.d(TAG, "timeOfDay: " + Arrays.toString(timeOfDay)); if (timeOfDay.length == 2) { - restartUpdateTimeOfDayAlarm(timeOfDay[0], timeOfDay[1]); + AutoUpdateManager.restartUpdateTimeOfDayAlarm(context, timeOfDay[0], timeOfDay[1]); } else { long milliseconds = getUpdateInterval(); long startTrigger = milliseconds; if (now) { startTrigger = TimeUnit.SECONDS.toMillis(10); } - restartUpdateIntervalAlarm(startTrigger, milliseconds); - } - } - - /** - * Sets the interval in which the feeds are refreshed automatically - */ - private static void restartUpdateIntervalAlarm(long triggerAtMillis, long intervalMillis) { - Log.d(TAG, "Restarting update alarm."); - - if (Build.VERSION.SDK_INT >= 24) { - AutoUpdateManager.restartJobServiceInterval(context, intervalMillis); - } else { - AutoUpdateManager.restartAlarmManagerInterval(context, triggerAtMillis, intervalMillis); - } - } - - /** - * Sets time of day the feeds are refreshed automatically - */ - private static void restartUpdateTimeOfDayAlarm(int hoursOfDay, int minute) { - Log.d(TAG, "Restarting update alarm."); - - Calendar now = Calendar.getInstance(); - Calendar alarm = (Calendar)now.clone(); - alarm.set(Calendar.HOUR_OF_DAY, hoursOfDay); - alarm.set(Calendar.MINUTE, minute); - if (alarm.before(now) || alarm.equals(now)) { - alarm.add(Calendar.DATE, 1); - } - - if (Build.VERSION.SDK_INT >= 24) { - long triggerAtMillis = alarm.getTimeInMillis() - now.getTimeInMillis(); - AutoUpdateManager.restartJobServiceTriggerAt(context, triggerAtMillis); - } else { - AutoUpdateManager.restartAlarmManagerTimeOfDay(context, alarm); + AutoUpdateManager.restartUpdateIntervalAlarm(context, startTrigger, milliseconds); } } 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 83fe8f137..ad723c685 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 @@ -25,6 +25,41 @@ public class AutoUpdateManager { } + /** + * Sets the interval in which the feeds are refreshed automatically + */ + public static void restartUpdateIntervalAlarm(Context context, long triggerAtMillis, long intervalMillis) { + Log.d(TAG, "Restarting update alarm."); + + if (Build.VERSION.SDK_INT >= 24) { + restartJobServiceInterval(context, intervalMillis); + } else { + restartAlarmManagerInterval(context, triggerAtMillis, intervalMillis); + } + } + + /** + * Sets time of day the feeds are refreshed automatically + */ + public static void restartUpdateTimeOfDayAlarm(Context context, int hoursOfDay, int minute) { + Log.d(TAG, "Restarting update alarm."); + + Calendar now = Calendar.getInstance(); + Calendar alarm = (Calendar)now.clone(); + alarm.set(Calendar.HOUR_OF_DAY, hoursOfDay); + alarm.set(Calendar.MINUTE, minute); + if (alarm.before(now) || alarm.equals(now)) { + alarm.add(Calendar.DATE, 1); + } + + if (Build.VERSION.SDK_INT >= 24) { + long triggerAtMillis = alarm.getTimeInMillis() - now.getTimeInMillis(); + restartJobServiceTriggerAt(context, triggerAtMillis); + } else { + restartAlarmManagerTimeOfDay(context, alarm); + } + } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private static JobInfo.Builder getFeedUpdateJobBuilder(Context context) { ComponentName serviceComponent = new ComponentName(context, FeedUpdateJobService.class); @@ -35,7 +70,7 @@ public class AutoUpdateManager { } @RequiresApi(api = Build.VERSION_CODES.N) - public static void restartJobServiceInterval(Context context, long intervalMillis) { + private static void restartJobServiceInterval(Context context, long intervalMillis) { JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); if (jobScheduler == null) { Log.d(TAG, "JobScheduler was null."); @@ -61,7 +96,7 @@ public class AutoUpdateManager { Log.d(TAG, "JobScheduler was set at interval " + intervalMillis); } - public static void restartAlarmManagerInterval(Context context, long triggerAtMillis, long intervalMillis) { + private static void restartAlarmManagerInterval(Context context, long triggerAtMillis, long intervalMillis) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); if (alarmManager == null) { @@ -85,7 +120,7 @@ public class AutoUpdateManager { } @RequiresApi(api = Build.VERSION_CODES.N) - public static void restartJobServiceTriggerAt(Context context, long triggerAtMillis) { + private static void restartJobServiceTriggerAt(Context context, long triggerAtMillis) { JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); if (jobScheduler == null) { Log.d(TAG, "JobScheduler was null."); @@ -99,7 +134,7 @@ public class AutoUpdateManager { Log.d(TAG, "JobScheduler was set for " + triggerAtMillis); } - public static void restartAlarmManagerTimeOfDay(Context context, Calendar alarm) { + private static void restartAlarmManagerTimeOfDay(Context context, Calendar alarm) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); if (alarmManager == null) { -- cgit v1.2.3 From ba2233430e96f31de10aa82468529bfd781a742a Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Tue, 5 Jun 2018 23:52:19 +0200 Subject: Removed FeedImage --- .../de/danoeh/antennapod/core/UpdateManager.java | 24 ------ .../java/de/danoeh/antennapod/core/feed/Feed.java | 32 ++++---- .../de/danoeh/antennapod/core/feed/FeedImage.java | 92 ---------------------- .../de/danoeh/antennapod/core/feed/FeedItem.java | 44 +++-------- .../core/service/download/DownloadService.java | 29 +------ .../core/service/download/HttpDownloader.java | 10 +-- .../danoeh/antennapod/core/storage/DBReader.java | 79 +------------------ .../danoeh/antennapod/core/storage/DBWriter.java | 37 --------- .../antennapod/core/storage/PodDBAdapter.java | 76 +----------------- .../core/syndication/namespace/NSITunes.java | 16 +--- .../core/syndication/namespace/NSMedia.java | 18 +---- .../core/syndication/namespace/NSRSS20.java | 22 +----- .../core/syndication/namespace/atom/NSAtom.java | 7 +- 13 files changed, 47 insertions(+), 439 deletions(-) delete mode 100644 core/src/main/java/de/danoeh/antennapod/core/feed/FeedImage.java (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java b/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java index 96e3a77be..7f0fc4b2b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/UpdateManager.java @@ -14,7 +14,6 @@ import java.io.File; import java.util.List; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; @@ -64,29 +63,6 @@ class UpdateManager { } private static void onUpgrade(final int oldVersionCode, final int newVersionCode) { - if(oldVersionCode < 1030099) { - // delete the now obsolete image cache - // from now on, Glide will handle caching images - new Thread() { - public void run() { - List feeds = DBReader.getFeedList(); - for (Feed podcast : feeds) { - List episodes = DBReader.getFeedItemList(podcast); - for (FeedItem episode : episodes) { - FeedImage image = episode.getImage(); - if (image != null && image.isDownloaded() && image.getFile_url() != null) { - File imageFile = new File(image.getFile_url()); - if (imageFile.exists()) { - imageFile.delete(); - } - image.setFile_url(null); // calls setDownloaded(false) - DBWriter.setFeedImage(image); - } - } - } - } - }.start(); - } if(oldVersionCode < 1050004) { if(MediaPlayer.isPrestoLibraryInstalled(context) && Build.VERSION.SDK_INT >= 16) { UserPreferences.enableSonic(true); diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java index 78df74ee7..4f0659a64 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java @@ -44,7 +44,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { * Name of the author */ private String author; - private FeedImage image; + private String imageUrl; private List items; /** @@ -96,7 +96,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { * This constructor is used for restoring a feed from the database. */ public Feed(long id, String lastUpdate, String title, String customTitle, String link, String description, String paymentLink, - String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl, + String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl, String downloadUrl, boolean downloaded, FlattrStatus status, boolean paged, String nextPageLink, String filter, boolean lastUpdateFailed) { super(fileUrl, downloadUrl, downloaded); @@ -111,7 +111,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { this.language = language; this.type = type; this.feedIdentifier = feedIdentifier; - this.image = image; + this.imageUrl = imageUrl; this.flattrStatus = status; this.paged = paged; this.nextPageLink = nextPageLink; @@ -128,9 +128,9 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { * This constructor is used for test purposes and uses a default flattr status object. */ public Feed(long id, String lastUpdate, String title, String link, String description, String paymentLink, - String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl, + String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl, String downloadUrl, boolean downloaded) { - this(id, lastUpdate, title, null, link, description, paymentLink, author, language, type, feedIdentifier, image, + this(id, lastUpdate, title, null, link, description, paymentLink, author, language, type, feedIdentifier, imageUrl, fileUrl, downloadUrl, downloaded, new FlattrStatus(), false, null, null, false); } @@ -266,8 +266,8 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { public void updateFromOther(Feed other) { // don't update feed's download_url, we do that manually if redirected // see AntennapodHttpClient - if (other.image != null) { - this.image = other.image; + if (other.imageUrl != null) { + this.imageUrl = other.imageUrl; } if (other.feedTitle != null) { feedTitle = other.feedTitle; @@ -305,8 +305,8 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { if (super.compareWithOther(other)) { return true; } - if (other.image != null) { - if (image == null || !TextUtils.equals(image.download_url, other.image.download_url)) { + if (other.imageUrl != null) { + if (imageUrl == null || !TextUtils.equals(imageUrl, other.imageUrl)) { return true; } } @@ -411,12 +411,12 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { this.description = description; } - public FeedImage getImage() { - return image; + public String getImageUrl() { + return imageUrl; } - public void setImage(FeedImage image) { - this.image = image; + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; } public List getItems() { @@ -505,11 +505,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { @Override public String getImageLocation() { - if (image != null) { - return image.getImageLocation(); - } else { - return null; - } + return imageUrl; } public int getPageNr() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedImage.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedImage.java deleted file mode 100644 index 45bd2ad31..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedImage.java +++ /dev/null @@ -1,92 +0,0 @@ -package de.danoeh.antennapod.core.feed; - -import android.database.Cursor; - -import java.io.File; - -import de.danoeh.antennapod.core.asynctask.ImageResource; -import de.danoeh.antennapod.core.storage.PodDBAdapter; - - -public class FeedImage extends FeedFile implements ImageResource { - public static final int FEEDFILETYPE_FEEDIMAGE = 1; - - private String title; - private FeedComponent owner; - - public FeedImage(FeedComponent owner, String download_url, String title) { - super(null, download_url, false); - this.download_url = download_url; - this.title = title; - this.owner = owner; - } - - public FeedImage(long id, String title, String file_url, - String download_url, boolean downloaded) { - super(file_url, download_url, downloaded); - this.id = id; - this.title = title; - } - - public FeedImage() { - super(); - } - - public static FeedImage fromCursor(Cursor cursor) { - int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID); - int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE); - int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL); - int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL); - int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED); - - return new FeedImage( - cursor.getLong(indexId), - cursor.getString(indexTitle), - cursor.getString(indexFileUrl), - cursor.getString(indexDownloadUrl), - cursor.getInt(indexDownloaded) > 0 - ); - } - - - @Override - public String getHumanReadableIdentifier() { - if (owner != null && owner.getHumanReadableIdentifier() != null) { - return owner.getHumanReadableIdentifier(); - } else { - return download_url; - } - } - - @Override - public int getTypeAsInt() { - return FEEDFILETYPE_FEEDIMAGE; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public FeedComponent getOwner() { - return owner; - } - - public void setOwner(FeedComponent owner) { - this.owner = owner; - } - - @Override - public String getImageLocation() { - if (file_url != null && downloaded) { - return new File(file_url).getAbsolutePath(); - } else if(download_url != null) { - return download_url; - } else { - return null; - } - } -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java index 87298d4c3..d6a6996fe 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java @@ -4,6 +4,7 @@ import android.database.Cursor; import android.support.annotation.Nullable; import android.text.TextUtils; +import de.danoeh.antennapod.core.asynctask.ImageResource; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -14,7 +15,6 @@ import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; -import de.danoeh.antennapod.core.asynctask.ImageResource; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.util.ShownotesProvider; @@ -75,7 +75,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr * in the database. The 'hasChapters' attribute should be used to check if this item has any chapters. * */ private List chapters; - private FeedImage image; + private String imageUrl; /* * 0: auto download disabled @@ -100,7 +100,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr * This constructor is used by DBReader. * */ public FeedItem(long id, String title, String link, Date pubDate, String paymentLink, long feedId, - FlattrStatus flattrStatus, boolean hasChapters, FeedImage image, int state, + FlattrStatus flattrStatus, boolean hasChapters, String imageUrl, int state, String itemIdentifier, long autoDownload) { this.id = id; this.title = title; @@ -110,7 +110,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr this.feedId = feedId; this.flattrStatus = flattrStatus; this.hasChapters = hasChapters; - this.image = image; + this.imageUrl = imageUrl; this.state = state; this.itemIdentifier = itemIdentifier; this.autoDownload = autoDownload; @@ -177,8 +177,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr public void updateFromOther(FeedItem other) { super.updateFromOther(other); - if (other.image != null) { - this.image = other.image; + if (other.imageUrl != null) { + this.imageUrl = other.imageUrl; } if (other.title != null) { title = other.title; @@ -212,9 +212,6 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr chapters = other.chapters; } } - if (image == null) { - image = other.image; - } } /** @@ -389,8 +386,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr public String getImageLocation() { if(media != null && media.hasEmbeddedPicture()) { return media.getImageLocation(); - } else if (image != null) { - return image.getImageLocation(); + } else if (imageUrl != null) { + return imageUrl; } else if (feed != null) { return feed.getImageLocation(); } else { @@ -426,29 +423,12 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr * Returns the image of this item or the image of the feed if this item does * not have its own image. */ - public FeedImage getImage() { - return (hasItemImage()) ? image : feed.getImage(); - } - - public void setImage(FeedImage image) { - this.image = image; - if (image != null) { - image.setOwner(this); - } - } - - /** - * Returns true if this FeedItem has its own image, false otherwise. - */ - public boolean hasItemImage() { - return image != null; + public String getImageUrl() { + return (imageUrl != null) ? imageUrl : feed.getImageUrl(); } - /** - * Returns true if this FeedItem has its own image and the image has been downloaded. - */ - public boolean hasItemImageDownloaded() { - return image != null && image.isDownloaded(); + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; } @Override 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 9c2266622..bfca04d60 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 @@ -55,7 +55,6 @@ import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -489,9 +488,7 @@ public class DownloadService extends Service { if (status.isSuccessful()) { successfulDownloads++; } else if (!status.isCancelled()) { - if (status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE) { - createReport = true; - } + createReport = true; failedDownloads++; } } @@ -688,10 +685,6 @@ public class DownloadService extends Service { Log.d(TAG, "Bundling " + results.size() + " feeds"); - for (Pair result : results) { - removeDuplicateImages(result.second.feed); // duplicate images have to removed because the DownloadRequester does not accept two downloads with the same download URL yet. - } - // Save information of feed in DB if (dbUpdateFuture != null) { try { @@ -1101,26 +1094,6 @@ public class DownloadService extends Service { } } - /** - * Checks if the FeedItems of this feed have images that point to the same URL. If two FeedItems - * have an image that points to the same URL, the reference of the second item is removed, so - * that every image reference is unique. - */ - @VisibleForTesting - static void removeDuplicateImages(Feed feed) { - Set known = new HashSet<>(); - for (FeedItem item : feed.getItems()) { - String url = item.hasItemImage() ? item.getImage().getDownload_url() : null; - if (url != null) { - if (known.contains(url)) { - item.setImage(null); - } else { - known.add(url); - } - } - } - } - private static String compileNotificationString(List downloads) { List lines = new ArrayList<>(downloads.size()); for (Downloader downloader : downloads) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java index 7ab0931d6..8cce02155 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java @@ -20,7 +20,6 @@ import java.util.Date; import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.R; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.util.DateUtils; import de.danoeh.antennapod.core.util.DownloadError; @@ -50,13 +49,8 @@ public class HttpDownloader extends Downloader { if (request.isDeleteOnFailure() && fileExists) { Log.w(TAG, "File already exists"); - if (request.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE) { - onFail(DownloadError.ERROR_FILE_EXISTS, null); - return; - } else { - onSuccess(); - return; - } + onSuccess(); + return; } OkHttpClient.Builder httpClientBuilder = AntennapodHttpClient.newBuilder(); 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 fa87cc216..b090f30a1 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 @@ -13,7 +13,6 @@ import java.util.Map; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -213,13 +212,8 @@ public final class DBReader { result.add(item); itemIds.add(item.getId()); } while (cursor.moveToNext()); - Map images = getFeedImages(adapter, imageIds.toArray()); Map medias = getFeedMedia(adapter, itemIds); - for (int i = 0; i < result.size(); i++) { - FeedItem item = result.get(i); - long imageId = imageIds.get(i); - FeedImage image = images.get(imageId); - item.setImage(image); + for (FeedItem item : result) { FeedMedia media = medias.get(item.getId()); item.setMedia(media); if (media != null) { @@ -254,24 +248,9 @@ public final class DBReader { } private static Feed extractFeedFromCursorRow(PodDBAdapter adapter, Cursor cursor) { - final FeedImage image; - int indexImage = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE); - long imageId = cursor.getLong(indexImage); - if (imageId != 0) { - image = getFeedImage(adapter, imageId); - } else { - image = null; - } - Feed feed = Feed.fromCursor(cursor); - if (image != null) { - feed.setImage(image); - image.setOwner(feed); - } - FeedPreferences preferences = FeedPreferences.fromCursor(cursor); feed.setPreferences(preferences); - return feed; } @@ -838,62 +817,6 @@ public final class DBReader { } } - /** - * Searches the DB for a FeedImage of the given id. - * - * @param imageId The id of the object - * @return The found object - */ - public static FeedImage getFeedImage(final long imageId) { - Log.d(TAG, "getFeedImage() called with: " + "imageId = [" + imageId + "]"); - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - try { - return getFeedImage(adapter, imageId); - } finally { - adapter.close(); - } - } - - /** - * Searches the DB for a FeedImage of the given id. - * - * @param imageId The id of the object - * @return The found object - */ - private static FeedImage getFeedImage(PodDBAdapter adapter, final long imageId) { - return getFeedImages(adapter, imageId).get(imageId); - } - - /** - * Searches the DB for a FeedImage of the given id. - * - * @param imageIds The ids of the images - * @return Map that associates the id of an image with the image itself - */ - private static Map getFeedImages(PodDBAdapter adapter, final long... imageIds) { - String[] ids = new String[imageIds.length]; - for (int i = 0, len = imageIds.length; i < len; i++) { - ids[i] = String.valueOf(imageIds[i]); - } - Cursor cursor = adapter.getImageCursor(ids); - int imageCount = cursor.getCount(); - if (imageCount == 0) { - cursor.close(); - return Collections.emptyMap(); - } - Map result = new ArrayMap<>(imageCount); - try { - while (cursor.moveToNext()) { - FeedImage image = FeedImage.fromCursor(cursor); - result.put(image.getId(), image); - } - } finally { - cursor.close(); - } - return result; - } - /** * Searches the DB for a FeedMedia of the given id. * diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index 8cdf82e15..1f4fad4ba 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -32,7 +32,6 @@ import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedEvent; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -166,17 +165,6 @@ public class DBWriter { editor.commit(); } - // delete image file - if (feed.getImage() != null) { - if (feed.getImage().isDownloaded() - && feed.getImage().getFile_url() != null) { - File imageFile = new File(feed.getImage() - .getFile_url()); - imageFile.delete(); - } else if (requester.isDownloadingFile(feed.getImage())) { - requester.cancelDownload(context, feed.getImage()); - } - } // delete stored media files and mark them as read List queue = DBReader.getQueue(); List removed = new ArrayList<>(); @@ -200,16 +188,6 @@ public class DBWriter { && requester.isDownloadingFile(item.getMedia())) { requester.cancelDownload(context, item.getMedia()); } - - if (item.hasItemImage()) { - FeedImage image = item.getImage(); - if (image.isDownloaded() && image.getFile_url() != null) { - File imgFile = new File(image.getFile_url()); - imgFile.delete(); - } else if (requester.isDownloadingFile(image)) { - requester.cancelDownload(context, item.getImage()); - } - } } PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); @@ -785,21 +763,6 @@ public class DBWriter { }); } - /** - * Saves a FeedImage object in the database. This method will save all attributes of the FeedImage object. The - * contents of FeedComponent-attributes (e.g. the FeedImages's 'feed'-attribute) will not be saved. - * - * @param image The FeedImage object. - */ - public static Future setFeedImage(final FeedImage image) { - return dbExec.submit(() -> { - PodDBAdapter adapter = PodDBAdapter.getInstance(); - adapter.open(); - adapter.setImage(image); - adapter.close(); - }); - } - /** * Updates download URL of a feed */ diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index e82252310..bfce27ced 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -27,7 +27,6 @@ import de.danoeh.antennapod.core.event.ProgressEvent; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedComponent; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -74,6 +73,7 @@ public class PodDBAdapter { public static final String KEY_SIZE = "filesize"; public static final String KEY_MIME_TYPE = "mime_type"; public static final String KEY_IMAGE = "image"; + public static final String KEY_IMAGE_URL = "image_url"; public static final String KEY_FEED = "feed"; private static final String KEY_MEDIA = "media"; public static final String KEY_DOWNLOADED = "downloaded"; @@ -388,12 +388,7 @@ public class PodDBAdapter { values.put(KEY_PAYMENT_LINK, feed.getPaymentLink()); values.put(KEY_AUTHOR, feed.getAuthor()); values.put(KEY_LANGUAGE, feed.getLanguage()); - if (feed.getImage() != null) { - if (feed.getImage().getId() == 0) { - setImage(feed.getImage()); - } - values.put(KEY_IMAGE, feed.getImage().getId()); - } + //TODO values.put(KEY_IMAGE_URL, feed.getImageUrl()); values.put(KEY_FILE_URL, feed.getFile_url()); values.put(KEY_DOWNLOAD_URL, feed.getDownload_url()); @@ -450,54 +445,7 @@ public class PodDBAdapter { } /** - * Inserts or updates an image entry - * - * @return the id of the entry - */ - public long setImage(FeedImage image) { - boolean startedTransaction = false; - - try { - if (!db.inTransaction()) { - db.beginTransactionNonExclusive(); - startedTransaction = true; - } - - ContentValues values = new ContentValues(); - values.put(KEY_TITLE, image.getTitle()); - values.put(KEY_DOWNLOAD_URL, image.getDownload_url()); - values.put(KEY_DOWNLOADED, image.isDownloaded()); - values.put(KEY_FILE_URL, image.getFile_url()); - if (image.getId() == 0) { - image.setId(db.insert(TABLE_NAME_FEED_IMAGES, null, values)); - } else { - db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID + "=?", - new String[]{String.valueOf(image.getId())}); - } - - final FeedComponent owner = image.getOwner(); - if (owner != null && owner.getId() != 0) { - values.clear(); - values.put(KEY_IMAGE, image.getId()); - if (owner instanceof Feed) { - db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(image.getOwner().getId())}); - } - } - if (startedTransaction) { - db.setTransactionSuccessful(); - } - } catch (SQLException e) { - Log.e(TAG, Log.getStackTraceString(e)); - } finally { - if (startedTransaction) { - db.endTransaction(); - } - } - return image.getId(); - } - - /** - * Inserts or updates an image entry + * Inserts or updates a media entry * * @return the id of the entry */ @@ -759,12 +707,7 @@ public class PodDBAdapter { values.put(KEY_ITEM_IDENTIFIER, item.getItemIdentifier()); values.put(KEY_FLATTR_STATUS, item.getFlattrStatus().toLong()); values.put(KEY_AUTO_DOWNLOAD, item.getAutoDownload()); - if (item.hasItemImage()) { - if (item.getImage().getId() == 0) { - setImage(item.getImage()); - } - values.put(KEY_IMAGE, item.getImage().getId()); - } + values.put(KEY_IMAGE_URL, item.getImageUrl()); if (item.getId() == 0) { item.setId(db.insert(TABLE_NAME_FEED_ITEMS, null, values)); @@ -993,11 +936,6 @@ public class PodDBAdapter { new String[]{String.valueOf(item.getId())}); } - private void removeFeedImage(FeedImage image) { - db.delete(TABLE_NAME_FEED_IMAGES, KEY_ID + "=?", - new String[]{String.valueOf(image.getId())}); - } - /** * Remove a FeedItem and its FeedMedia entry. */ @@ -1008,9 +946,6 @@ public class PodDBAdapter { if (item.hasChapters() || item.getChapters() != null) { removeChaptersOfItem(item); } - if (item.hasItemImage()) { - removeFeedImage(item.getImage()); - } db.delete(TABLE_NAME_FEED_ITEMS, KEY_ID + "=?", new String[]{String.valueOf(item.getId())}); } @@ -1021,9 +956,6 @@ public class PodDBAdapter { public void removeFeed(Feed feed) { try { db.beginTransactionNonExclusive(); - if (feed.getImage() != null) { - removeFeedImage(feed.getImage()); - } if (feed.getItems() != null) { for (FeedItem item : feed.getItems()) { removeFeedItem(item); diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java index 670e99fce..18af0800f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java @@ -7,7 +7,6 @@ import org.xml.sax.Attributes; import java.util.concurrent.TimeUnit; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.syndication.handler.HandlerState; public class NSITunes extends Namespace { @@ -16,7 +15,6 @@ public class NSITunes extends Namespace { public static final String NSURI = "http://www.itunes.com/dtds/podcast-1.0.dtd"; private static final String IMAGE = "image"; - private static final String IMAGE_TITLE = "image"; private static final String IMAGE_HREF = "href"; private static final String AUTHOR = "author"; @@ -29,21 +27,15 @@ public class NSITunes extends Namespace { public SyndElement handleElementStart(String localName, HandlerState state, Attributes attributes) { if (IMAGE.equals(localName)) { - FeedImage image = new FeedImage(); - image.setTitle(IMAGE_TITLE); - image.setDownload_url(attributes.getValue(IMAGE_HREF)); + String url = attributes.getValue(IMAGE_HREF); if (state.getCurrentItem() != null) { - // this is an items image - image.setTitle(state.getCurrentItem().getTitle() + IMAGE_TITLE); - image.setOwner(state.getCurrentItem()); - state.getCurrentItem().setImage(image); + state.getCurrentItem().setImageUrl(url); } else { // this is the feed image // prefer to all other images - if (!TextUtils.isEmpty(image.getDownload_url())) { - image.setOwner(state.getFeed()); - state.getFeed().setImage(image); + if (!TextUtils.isEmpty(url)) { + state.getFeed().setImageUrl(url); } } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java index f2cfc2e57..638383223 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSMedia.java @@ -7,7 +7,6 @@ import org.xml.sax.Attributes; import java.util.concurrent.TimeUnit; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.syndication.handler.HandlerState; import de.danoeh.antennapod.core.syndication.namespace.atom.AtomText; @@ -94,25 +93,16 @@ public class NSMedia extends Namespace { } state.getCurrentItem().setMedia(media); } else if (state.getCurrentItem() != null && url != null && validTypeImage) { - FeedImage image = new FeedImage(); - image.setDownload_url(url); - image.setOwner(state.getCurrentItem()); - - state.getCurrentItem().setImage(image); + state.getCurrentItem().setImageUrl(url); } } else if (IMAGE.equals(localName)) { String url = attributes.getValue(IMAGE_URL); if (url != null) { - FeedImage image = new FeedImage(); - image.setDownload_url(url); - if (state.getCurrentItem() != null) { - image.setOwner(state.getCurrentItem()); - state.getCurrentItem().setImage(image); + state.getCurrentItem().setImageUrl(url); } else { - if (state.getFeed().getImage() == null) { - image.setOwner(state.getFeed()); - state.getFeed().setImage(image); + if (state.getFeed().getImageUrl() == null) { + state.getFeed().setImageUrl(url); } } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java index 3d752df76..a1100a976 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSRSS20.java @@ -6,7 +6,6 @@ import android.util.Log; import org.xml.sax.Attributes; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.syndication.handler.HandlerState; @@ -77,17 +76,6 @@ public class NSRSS20 extends Namespace { state.getCurrentItem().setMedia(media); } - } else if (IMAGE.equals(localName)) { - if (state.getTagstack().size() >= 1) { - String parent = state.getTagstack().peek().getName(); - if (CHANNEL.equals(parent)) { - Feed feed = state.getFeed(); - if(feed != null && feed.getImage() == null) { - feed.setImage(new FeedImage()); - feed.getImage().setOwner(state.getFeed()); - } - } - } } return new SyndElement(localName, this); } @@ -134,11 +122,6 @@ public class NSRSS20 extends Namespace { state.getCurrentItem().setTitle(title); } else if (CHANNEL.equals(second) && state.getFeed() != null) { state.getFeed().setTitle(title); - } else if (IMAGE.equals(second) && CHANNEL.equals(third)) { - if(state.getFeed() != null && state.getFeed().getImage() != null && - state.getFeed().getImage().getTitle() == null) { - state.getFeed().getImage().setTitle(title); - } } } else if (LINK.equals(top)) { if (CHANNEL.equals(second) && state.getFeed() != null) { @@ -150,9 +133,8 @@ public class NSRSS20 extends Namespace { state.getCurrentItem().setPubDate(DateUtils.parse(content)); } else if (URL.equals(top) && IMAGE.equals(second) && CHANNEL.equals(third)) { // prefer itunes:image - if(state.getFeed() != null && state.getFeed().getImage() != null && - state.getFeed().getImage().getDownload_url() == null) { - state.getFeed().getImage().setDownload_url(content); + if (state.getFeed() != null) { + state.getFeed().setImageUrl(content); } } else if (DESCR.equals(localName)) { if (CHANNEL.equals(second) && state.getFeed() != null) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java index 1fe388d9d..aab1b1a5b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/atom/NSAtom.java @@ -5,7 +5,6 @@ import android.util.Log; import org.xml.sax.Attributes; -import de.danoeh.antennapod.core.feed.FeedImage; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.syndication.handler.HandlerState; @@ -210,10 +209,10 @@ public class NSAtom extends Namespace { state.getCurrentItem().setPubDate(DateUtils.parse(content)); } else if (PUBLISHED.equals(top) && ENTRY.equals(second) && state.getCurrentItem() != null) { state.getCurrentItem().setPubDate(DateUtils.parse(content)); - } else if (IMAGE_LOGO.equals(top) && state.getFeed() != null && state.getFeed().getImage() == null) { - state.getFeed().setImage(new FeedImage(state.getFeed(), content, null)); + } else if (IMAGE_LOGO.equals(top) && state.getFeed() != null && state.getFeed().getImageUrl() == null) { + state.getFeed().setImageUrl(content); } else if (IMAGE_ICON.equals(top) && state.getFeed() != null) { - state.getFeed().setImage(new FeedImage(state.getFeed(), content, null)); + state.getFeed().setImageUrl(content); } else if (AUTHOR_NAME.equals(top) && AUTHOR.equals(second) && state.getFeed() != null && state.getCurrentItem() == null) { String currentName = state.getFeed().getAuthor(); -- cgit v1.2.3 From abb13dc447f3ab4663507cd23a5bca0a39263874 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 6 Jun 2018 00:07:21 +0200 Subject: Database scheme update --- .../antennapod/core/storage/PodDBAdapter.java | 30 +++++++++------------- 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index bfce27ced..4b86536d8 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -133,7 +133,7 @@ public class PodDBAdapter { + KEY_DOWNLOADED + " INTEGER," + KEY_LINK + " TEXT," + KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT," + KEY_LASTUPDATE + " TEXT," + KEY_LANGUAGE + " TEXT," + KEY_AUTHOR - + " TEXT," + KEY_IMAGE + " INTEGER," + KEY_TYPE + " TEXT," + + " TEXT," + KEY_IMAGE_URL + " TEXT," + KEY_TYPE + " TEXT," + KEY_FEED_IDENTIFIER + " TEXT," + KEY_AUTO_DOWNLOAD + " INTEGER DEFAULT 1," + KEY_FLATTR_STATUS + " INTEGER," + KEY_USERNAME + " TEXT," @@ -155,14 +155,9 @@ public class PodDBAdapter { + KEY_MEDIA + " INTEGER," + KEY_FEED + " INTEGER," + KEY_HAS_CHAPTERS + " INTEGER," + KEY_ITEM_IDENTIFIER + " TEXT," + KEY_FLATTR_STATUS + " INTEGER," - + KEY_IMAGE + " INTEGER," + + KEY_IMAGE_URL + " TEXT," + KEY_AUTO_DOWNLOAD + " INTEGER)"; - private static final String CREATE_TABLE_FEED_IMAGES = "CREATE TABLE " - + TABLE_NAME_FEED_IMAGES + " (" + TABLE_PRIMARY_KEY + KEY_TITLE - + " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT," - + KEY_DOWNLOADED + " INTEGER)"; - private static final String CREATE_TABLE_FEED_MEDIA = "CREATE TABLE " + TABLE_NAME_FEED_MEDIA + " (" + TABLE_PRIMARY_KEY + KEY_DURATION + " INTEGER," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL @@ -195,10 +190,6 @@ public class PodDBAdapter { + TABLE_NAME_FEED_ITEMS + "_" + KEY_FEED + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_FEED + ")"; - private static final String CREATE_INDEX_FEEDITEMS_IMAGE = "CREATE INDEX " - + TABLE_NAME_FEED_ITEMS + "_" + KEY_IMAGE + " ON " + TABLE_NAME_FEED_ITEMS + " (" - + KEY_IMAGE + ")"; - private static final String CREATE_INDEX_FEEDITEMS_PUBDATE = "CREATE INDEX IF NOT EXISTS " + TABLE_NAME_FEED_ITEMS + "_" + KEY_PUBDATE + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_PUBDATE + ")"; @@ -240,7 +231,7 @@ public class PodDBAdapter { TABLE_NAME_FEEDS + "." + KEY_LASTUPDATE, TABLE_NAME_FEEDS + "." + KEY_LANGUAGE, TABLE_NAME_FEEDS + "." + KEY_AUTHOR, - TABLE_NAME_FEEDS + "." + KEY_IMAGE, + TABLE_NAME_FEEDS + "." + KEY_IMAGE_URL, TABLE_NAME_FEEDS + "." + KEY_TYPE, TABLE_NAME_FEEDS + "." + KEY_FEED_IDENTIFIER, TABLE_NAME_FEEDS + "." + KEY_AUTO_DOWNLOAD, @@ -273,7 +264,7 @@ public class PodDBAdapter { TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS, TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER, TABLE_NAME_FEED_ITEMS + "." + KEY_FLATTR_STATUS, - TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE, + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL, TABLE_NAME_FEED_ITEMS + "." + KEY_AUTO_DOWNLOAD }; @@ -283,7 +274,6 @@ public class PodDBAdapter { private static final String[] ALL_TABLES = { TABLE_NAME_FEEDS, TABLE_NAME_FEED_ITEMS, - TABLE_NAME_FEED_IMAGES, TABLE_NAME_FEED_MEDIA, TABLE_NAME_DOWNLOAD_LOG, TABLE_NAME_QUEUE, @@ -1604,7 +1594,7 @@ public class PodDBAdapter { */ private static class PodDBHelper extends SQLiteOpenHelper { - private static final int VERSION = 1060200; + private static final int VERSION = 1060596; private final Context context; @@ -1625,7 +1615,6 @@ public class PodDBAdapter { public void onCreate(final SQLiteDatabase db) { db.execSQL(CREATE_TABLE_FEEDS); db.execSQL(CREATE_TABLE_FEED_ITEMS); - db.execSQL(CREATE_TABLE_FEED_IMAGES); db.execSQL(CREATE_TABLE_FEED_MEDIA); db.execSQL(CREATE_TABLE_DOWNLOAD_LOG); db.execSQL(CREATE_TABLE_QUEUE); @@ -1633,7 +1622,6 @@ public class PodDBAdapter { db.execSQL(CREATE_TABLE_FAVORITES); db.execSQL(CREATE_INDEX_FEEDITEMS_FEED); - db.execSQL(CREATE_INDEX_FEEDITEMS_IMAGE); db.execSQL(CREATE_INDEX_FEEDITEMS_PUBDATE); db.execSQL(CREATE_INDEX_FEEDITEMS_READ); db.execSQL(CREATE_INDEX_FEEDMEDIA_FEEDITEM); @@ -1770,7 +1758,6 @@ public class PodDBAdapter { // create indexes db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED); - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE); db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM); db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM); db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM); @@ -1904,6 +1891,13 @@ public class PodDBAdapter { db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " + PodDBAdapter.KEY_CUSTOM_TITLE + " TEXT"); } + if (oldVersion < 1060596) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT"); + db.execSQL("DROP TABLE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES); + } EventBus.getDefault().post(ProgressEvent.end()); } -- cgit v1.2.3 From eba0817ee047272d8d8a8ef7f5392638bae40741 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 6 Jun 2018 00:08:22 +0200 Subject: Prevent crash --- core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java | 5 ----- 1 file changed, 5 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') 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 b090f30a1..5eb5145e8 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 @@ -200,14 +200,9 @@ public final class DBReader { private static List extractItemlistFromCursor(PodDBAdapter adapter, Cursor cursor) { List result = new ArrayList<>(cursor.getCount()); - LongList imageIds = new LongList(cursor.getCount()); LongList itemIds = new LongList(cursor.getCount()); if (cursor.moveToFirst()) { do { - int indexImage = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE); - long imageId = cursor.getLong(indexImage); - imageIds.add(imageId); - FeedItem item = FeedItem.fromCursor(cursor); result.add(item); itemIds.add(item.getId()); -- cgit v1.2.3 From fa4807617598a83619b49a85c5c0eeb915a9526b Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 6 Jun 2018 00:15:19 +0200 Subject: Write feed url to database --- core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java | 3 ++- core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java | 4 +++- .../src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java index 4f0659a64..3395653f3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java @@ -191,6 +191,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { int indexNextPageLink = cursor.getColumnIndex(PodDBAdapter.KEY_NEXT_PAGE_LINK); int indexHide = cursor.getColumnIndex(PodDBAdapter.KEY_HIDE); int indexLastUpdateFailed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_UPDATE_FAILED); + int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL); Feed feed = new Feed( cursor.getLong(indexId), @@ -204,7 +205,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource { cursor.getString(indexLanguage), cursor.getString(indexType), cursor.getString(indexFeedIdentifier), - null, + cursor.getString(indexImageUrl), cursor.getString(indexFileUrl), cursor.getString(indexDownloadUrl), cursor.getInt(indexDownloaded) > 0, diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java index d6a6996fe..b0a87c885 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java @@ -158,6 +158,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr int indexRead = cursor.getColumnIndex(PodDBAdapter.KEY_READ); int indexItemIdentifier = cursor.getColumnIndex(PodDBAdapter.KEY_ITEM_IDENTIFIER); int indexAutoDownload = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DOWNLOAD); + int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL); long id = cursor.getInt(indexId); String title = cursor.getString(indexTitle); @@ -170,9 +171,10 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr int state = cursor.getInt(indexRead); String itemIdentifier = cursor.getString(indexItemIdentifier); long autoDownload = cursor.getLong(indexAutoDownload); + String imageUrl = cursor.getString(indexImageUrl); return new FeedItem(id, title, link, pubDate, paymentLink, feedId, flattrStatus, - hasChapters, null, state, itemIdentifier, autoDownload); + hasChapters, imageUrl, state, itemIdentifier, autoDownload); } public void updateFromOther(FeedItem other) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 4b86536d8..ffd44e73a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -378,7 +378,7 @@ public class PodDBAdapter { values.put(KEY_PAYMENT_LINK, feed.getPaymentLink()); values.put(KEY_AUTHOR, feed.getAuthor()); values.put(KEY_LANGUAGE, feed.getLanguage()); - //TODO values.put(KEY_IMAGE_URL, feed.getImageUrl()); + values.put(KEY_IMAGE_URL, feed.getImageUrl()); values.put(KEY_FILE_URL, feed.getFile_url()); values.put(KEY_DOWNLOAD_URL, feed.getDownload_url()); -- cgit v1.2.3 From 9b738ca5d47c7e47b691e900381eea27cf2ba34d Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 6 Jun 2018 14:52:50 +0200 Subject: Fixed feed item display --- .../antennapod/core/storage/PodDBAdapter.java | 29 ++++++++-------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index ffd44e73a..7289a3352 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -14,19 +14,10 @@ import android.database.sqlite.SQLiteOpenHelper; import android.media.MediaMetadataRetriever; import android.text.TextUtils; import android.util.Log; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Set; - import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.event.ProgressEvent; import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedComponent; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; @@ -37,6 +28,13 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus; import de.greenrobot.event.EventBus; import org.apache.commons.io.FileUtils; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + // TODO Remove media column from feeditem table /** @@ -1285,17 +1283,10 @@ public class PodDBAdapter { public Cursor getImageAuthenticationCursor(final String imageUrl) { String downloadUrl = DatabaseUtils.sqlEscapeString(imageUrl); final String query = "" - + "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_IMAGES + + "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + TABLE_NAME_FEEDS - + " ON " + TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" + TABLE_NAME_FEEDS + "." + KEY_IMAGE - + " WHERE " + TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "=" + downloadUrl - + " UNION SELECT " + KEY_USERNAME + "," + KEY_PASSWORD - + " FROM " + TABLE_NAME_FEED_IMAGES - + " INNER JOIN " + TABLE_NAME_FEED_ITEMS - + " ON " + TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE - + " INNER JOIN " + TABLE_NAME_FEEDS - + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID - + " WHERE " + TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "=" + downloadUrl; + + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + " = " + TABLE_NAME_FEEDS + "." + KEY_ID + + " WHERE " + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL + "=" + downloadUrl; return db.rawQuery(query, null); } -- cgit v1.2.3 From e15451177bf7fd5770d965e7210f59981d467a58 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 6 Jun 2018 15:17:39 +0200 Subject: Moved database upgrades to their own class --- .../danoeh/antennapod/core/storage/DBUpgrader.java | 273 +++++++++++++++++++ .../antennapod/core/storage/PodDBAdapter.java | 292 ++------------------- 2 files changed, 291 insertions(+), 274 deletions(-) create mode 100644 core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java new file mode 100644 index 000000000..f2451b66c --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java @@ -0,0 +1,273 @@ +package de.danoeh.antennapod.core.storage; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.media.MediaMetadataRetriever; +import android.util.Log; +import de.danoeh.antennapod.core.feed.FeedItem; + +class DBUpgrader { + /** + * Upgrades the given database to a new schema version + */ + static void upgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { + if (oldVersion <= 1) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " + + PodDBAdapter.KEY_TYPE + " TEXT"); + } + if (oldVersion <= 2) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS + + " ADD COLUMN " + PodDBAdapter.KEY_LINK + " TEXT"); + } + if (oldVersion <= 3) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_ITEM_IDENTIFIER + " TEXT"); + } + if (oldVersion <= 4) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " + + PodDBAdapter.KEY_FEED_IDENTIFIER + " TEXT"); + } + if (oldVersion <= 5) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG + + " ADD COLUMN " + PodDBAdapter.KEY_REASON_DETAILED + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG + + " ADD COLUMN " + PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE + " TEXT"); + } + if (oldVersion <= 6) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS + + " ADD COLUMN " + PodDBAdapter.KEY_CHAPTER_TYPE + " INTEGER"); + } + if (oldVersion <= 7) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE + + " INTEGER"); + } + if (oldVersion <= 8) { + final int KEY_ID_POSITION = 0; + final int KEY_MEDIA_POSITION = 1; + + // Add feeditem column to feedmedia table + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_FEEDITEM + + " INTEGER"); + Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS, + new String[]{PodDBAdapter.KEY_ID, PodDBAdapter.KEY_MEDIA}, "? > 0", + new String[]{PodDBAdapter.KEY_MEDIA}, null, null, null); + if (feeditemCursor.moveToFirst()) { + db.beginTransaction(); + ContentValues contentValues = new ContentValues(); + do { + long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION); + contentValues.put(PodDBAdapter.KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION)); + db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, PodDBAdapter.KEY_ID + "=?", new String[]{String.valueOf(mediaId)}); + contentValues.clear(); + } while (feeditemCursor.moveToNext()); + db.setTransactionSuccessful(); + db.endTransaction(); + } + feeditemCursor.close(); + } + if (oldVersion <= 9) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + + " INTEGER DEFAULT 1"); + } + if (oldVersion <= 10) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS + + " INTEGER"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS + + " INTEGER"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_PLAYED_DURATION + + " INTEGER"); + } + if (oldVersion <= 11) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_USERNAME + + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_PASSWORD + + " TEXT"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE + + " INTEGER"); + } + if (oldVersion <= 12) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_IS_PAGED + " INTEGER DEFAULT 0"); + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_NEXT_PAGE_LINK + " TEXT"); + } + if (oldVersion <= 13) { + // remove duplicate rows in "Chapters" table that were created because of a bug. + db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " + + "(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)", + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, + PodDBAdapter.KEY_ID, + PodDBAdapter.KEY_ID, + PodDBAdapter.KEY_ID, + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, + PodDBAdapter.KEY_TITLE, + PodDBAdapter.KEY_START, + PodDBAdapter.KEY_FEEDITEM, + PodDBAdapter.KEY_LINK, + PodDBAdapter.KEY_CHAPTER_TYPE)); + } + if (oldVersion <= 14) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " SET " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " = " + + "(SELECT " + PodDBAdapter.KEY_AUTO_DOWNLOAD + + " FROM " + PodDBAdapter.TABLE_NAME_FEEDS + + " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID + + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")"); + + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT"); + + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0"); + + // create indexes + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED); + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE); + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM); + db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM); + db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM); + } + if (oldVersion <= 15) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0" + + " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=0"); + Cursor c = db.rawQuery("SELECT " + PodDBAdapter.KEY_FILE_URL + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=1 " + + " AND " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=-1", null); + if (c.moveToFirst()) { + MediaMetadataRetriever mmr = new MediaMetadataRetriever(); + do { + String fileUrl = c.getString(0); + try { + mmr.setDataSource(fileUrl); + byte[] image = mmr.getEmbeddedPicture(); + if (image != null) { + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=1" + + " WHERE " + PodDBAdapter.KEY_FILE_URL + "='" + fileUrl + "'"); + } else { + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0" + + " WHERE " + PodDBAdapter.KEY_FILE_URL + "='" + fileUrl + "'"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } while (c.moveToNext()); + } + c.close(); + } + if (oldVersion <= 16) { + String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON " + + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "=" + + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_FEEDITEM + + " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON " + + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "=" + + PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_FEEDITEM + + " WHERE " + + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_READ + " = 0 AND " // unplayed + + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_DOWNLOADED + " = 0 AND " // undownloaded + + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_POSITION + " = 0 AND " // not partially played + + PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_ID + " IS NULL"; // not in queue + String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + + " SET " + PodDBAdapter.KEY_READ + "=" + FeedItem.NEW + + " WHERE " + PodDBAdapter.KEY_ID + " IN (" + selectNew + ")"; + Log.d("Migration", "SQL: " + sql); + db.execSQL(sql); + } + if (oldVersion <= 17) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0"); + } + if (oldVersion < 1030005) { + db.execSQL("UPDATE FeedItems SET auto_download=0 WHERE " + + "(read=1 OR id IN (SELECT feeditem FROM FeedMedia WHERE position>0 OR downloaded=1)) " + + "AND id NOT IN (SELECT feeditem FROM Queue)"); + } + if (oldVersion < 1040001) { + db.execSQL(PodDBAdapter.CREATE_TABLE_FAVORITES); + } + if (oldVersion < 1040002) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + + " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYED_TIME + " INTEGER DEFAULT 0"); + } + if (oldVersion < 1040013) { + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE); + db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ); + } + if (oldVersion < 1050003) { + // Migrates feed list filter data + + db.beginTransaction(); + + // Change to intermediate values to avoid overwriting in the following find/replace + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'unplayed', 'noplay')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'not_queued', 'noqueue')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'not_downloaded', 'nodl')"); + + // Replace played, queued, and downloaded with their opposites + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'played', 'unplayed')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'queued', 'not_queued')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'downloaded', 'not_downloaded')"); + + // Now replace intermediates for unplayed, not queued, etc. with their opposites + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'noplay', 'played')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'noqueue', 'queued')"); + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'nodl', 'downloaded')"); + + // Paused doesn't have an opposite, so unplayed is the next best option + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" + + "SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'paused', 'unplayed')"); + + db.setTransactionSuccessful(); + db.endTransaction(); + + // and now get ready for autodownload filters + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_INCLUDE_FILTER + " TEXT DEFAULT ''"); + + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_EXCLUDE_FILTER + " TEXT DEFAULT ''"); + + // and now auto refresh + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_KEEP_UPDATED + " INTEGER DEFAULT 1"); + } + if (oldVersion < 1050004) { + // prevent old timestamps to be misinterpreted as ETags + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + + " SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL"); + } + if (oldVersion < 1060200) { + db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + + " ADD COLUMN " + PodDBAdapter.KEY_CUSTOM_TITLE + " TEXT"); + } + } + +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index e82252310..db1e63aee 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -75,7 +75,7 @@ public class PodDBAdapter { public static final String KEY_MIME_TYPE = "mime_type"; public static final String KEY_IMAGE = "image"; public static final String KEY_FEED = "feed"; - private static final String KEY_MEDIA = "media"; + public static final String KEY_MEDIA = "media"; public static final String KEY_DOWNLOADED = "downloaded"; public static final String KEY_LASTUPDATE = "last_update"; public static final String KEY_FEEDFILE = "feedfile"; @@ -114,14 +114,14 @@ public class PodDBAdapter { public static final String KEY_EXCLUDE_FILTER = "exclude_filter"; // Table names - private static final String TABLE_NAME_FEEDS = "Feeds"; - private static final String TABLE_NAME_FEED_ITEMS = "FeedItems"; - private static final String TABLE_NAME_FEED_IMAGES = "FeedImages"; - private static final String TABLE_NAME_FEED_MEDIA = "FeedMedia"; - private static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog"; - private static final String TABLE_NAME_QUEUE = "Queue"; - private static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters"; - private static final String TABLE_NAME_FAVORITES = "Favorites"; + static final String TABLE_NAME_FEEDS = "Feeds"; + static final String TABLE_NAME_FEED_ITEMS = "FeedItems"; + static final String TABLE_NAME_FEED_IMAGES = "FeedImages"; + static final String TABLE_NAME_FEED_MEDIA = "FeedMedia"; + static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog"; + static final String TABLE_NAME_QUEUE = "Queue"; + static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters"; + static final String TABLE_NAME_FAVORITES = "Favorites"; // SQL Statements for creating new tables private static final String TABLE_PRIMARY_KEY = KEY_ID @@ -191,36 +191,36 @@ public class PodDBAdapter { + KEY_LINK + " TEXT," + KEY_CHAPTER_TYPE + " INTEGER)"; // SQL Statements for creating indexes - private static final String CREATE_INDEX_FEEDITEMS_FEED = "CREATE INDEX " + static final String CREATE_INDEX_FEEDITEMS_FEED = "CREATE INDEX " + TABLE_NAME_FEED_ITEMS + "_" + KEY_FEED + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_FEED + ")"; - private static final String CREATE_INDEX_FEEDITEMS_IMAGE = "CREATE INDEX " + static final String CREATE_INDEX_FEEDITEMS_IMAGE = "CREATE INDEX " + TABLE_NAME_FEED_ITEMS + "_" + KEY_IMAGE + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_IMAGE + ")"; - private static final String CREATE_INDEX_FEEDITEMS_PUBDATE = "CREATE INDEX IF NOT EXISTS " + static final String CREATE_INDEX_FEEDITEMS_PUBDATE = "CREATE INDEX IF NOT EXISTS " + TABLE_NAME_FEED_ITEMS + "_" + KEY_PUBDATE + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_PUBDATE + ")"; - private static final String CREATE_INDEX_FEEDITEMS_READ = "CREATE INDEX IF NOT EXISTS " + static final String CREATE_INDEX_FEEDITEMS_READ = "CREATE INDEX IF NOT EXISTS " + TABLE_NAME_FEED_ITEMS + "_" + KEY_READ + " ON " + TABLE_NAME_FEED_ITEMS + " (" + KEY_READ + ")"; - private static final String CREATE_INDEX_QUEUE_FEEDITEM = "CREATE INDEX " + static final String CREATE_INDEX_QUEUE_FEEDITEM = "CREATE INDEX " + TABLE_NAME_QUEUE + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_QUEUE + " (" + KEY_FEEDITEM + ")"; - private static final String CREATE_INDEX_FEEDMEDIA_FEEDITEM = "CREATE INDEX " + static final String CREATE_INDEX_FEEDMEDIA_FEEDITEM = "CREATE INDEX " + TABLE_NAME_FEED_MEDIA + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_FEED_MEDIA + " (" + KEY_FEEDITEM + ")"; - private static final String CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM = "CREATE INDEX " + static final String CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM = "CREATE INDEX " + TABLE_NAME_SIMPLECHAPTERS + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_SIMPLECHAPTERS + " (" + KEY_FEEDITEM + ")"; - private static final String CREATE_TABLE_FAVORITES = "CREATE TABLE " + static final String CREATE_TABLE_FAVORITES = "CREATE TABLE " + TABLE_NAME_FAVORITES + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_FEEDITEM + " INTEGER," + KEY_FEED + " INTEGER)"; @@ -1716,263 +1716,7 @@ public class PodDBAdapter { EventBus.getDefault().post(ProgressEvent.start(context.getString(R.string.progress_upgrading_database))); Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion + "."); - if (oldVersion <= 1) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " - + KEY_TYPE + " TEXT"); - } - if (oldVersion <= 2) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS - + " ADD COLUMN " + KEY_LINK + " TEXT"); - } - if (oldVersion <= 3) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_ITEM_IDENTIFIER + " TEXT"); - } - if (oldVersion <= 4) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN " - + KEY_FEED_IDENTIFIER + " TEXT"); - } - if (oldVersion <= 5) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG - + " ADD COLUMN " + KEY_REASON_DETAILED + " TEXT"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG - + " ADD COLUMN " + KEY_DOWNLOADSTATUS_TITLE + " TEXT"); - } - if (oldVersion <= 6) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS - + " ADD COLUMN " + KEY_CHAPTER_TYPE + " INTEGER"); - } - if (oldVersion <= 7) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_PLAYBACK_COMPLETION_DATE - + " INTEGER"); - } - if (oldVersion <= 8) { - final int KEY_ID_POSITION = 0; - final int KEY_MEDIA_POSITION = 1; - - // Add feeditem column to feedmedia table - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_FEEDITEM - + " INTEGER"); - Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS, - new String[]{KEY_ID, KEY_MEDIA}, "? > 0", - new String[]{KEY_MEDIA}, null, null, null); - if (feeditemCursor.moveToFirst()) { - db.beginTransaction(); - ContentValues contentValues = new ContentValues(); - do { - long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION); - contentValues.put(KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION)); - db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, KEY_ID + "=?", new String[]{String.valueOf(mediaId)}); - contentValues.clear(); - } while (feeditemCursor.moveToNext()); - db.setTransactionSuccessful(); - db.endTransaction(); - } - feeditemCursor.close(); - } - if (oldVersion <= 9) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_AUTO_DOWNLOAD - + " INTEGER DEFAULT 1"); - } - if (oldVersion <= 10) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_FLATTR_STATUS - + " INTEGER"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_FLATTR_STATUS - + " INTEGER"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_PLAYED_DURATION - + " INTEGER"); - } - if (oldVersion <= 11) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_USERNAME - + " TEXT"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_PASSWORD - + " TEXT"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_IMAGE - + " INTEGER"); - } - if (oldVersion <= 12) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_IS_PAGED + " INTEGER DEFAULT 0"); - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_NEXT_PAGE_LINK + " TEXT"); - } - if (oldVersion <= 13) { - // remove duplicate rows in "Chapters" table that were created because of a bug. - db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " + - "(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)", - PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, - KEY_ID, - KEY_ID, - KEY_ID, - PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS, - KEY_TITLE, - KEY_START, - KEY_FEEDITEM, - KEY_LINK, - KEY_CHAPTER_TYPE)); - } - if (oldVersion <= 14) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " ADD COLUMN " + KEY_AUTO_DOWNLOAD + " INTEGER"); - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " SET " + KEY_AUTO_DOWNLOAD + " = " - + "(SELECT " + KEY_AUTO_DOWNLOAD - + " FROM " + PodDBAdapter.TABLE_NAME_FEEDS - + " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + KEY_ID - + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + ")"); - - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_HIDE + " TEXT"); - - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0"); - - // create indexes - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED); - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE); - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM); - db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM); - db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM); - } - if (oldVersion <= 15) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1"); - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0" - + " WHERE " + KEY_DOWNLOADED + "=0"); - Cursor c = db.rawQuery("SELECT " + KEY_FILE_URL - + " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " WHERE " + KEY_DOWNLOADED + "=1 " - + " AND " + KEY_HAS_EMBEDDED_PICTURE + "=-1", null); - if (c.moveToFirst()) { - MediaMetadataRetriever mmr = new MediaMetadataRetriever(); - do { - String fileUrl = c.getString(0); - try { - mmr.setDataSource(fileUrl); - byte[] image = mmr.getEmbeddedPicture(); - if (image != null) { - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " SET " + KEY_HAS_EMBEDDED_PICTURE + "=1" - + " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'"); - } else { - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0" - + " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'"); - } - } catch (Exception e) { - e.printStackTrace(); - } - } while (c.moveToNext()); - } - c.close(); - } - if (oldVersion <= 16) { - String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID - + " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON " - + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" - + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM - + " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON " - + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" - + PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_FEEDITEM - + " WHERE " - + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_READ + " = 0 AND " // unplayed - + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + " = 0 AND " // undownloaded - + PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_POSITION + " = 0 AND " // not partially played - + PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_ID + " IS NULL"; // not in queue - String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS - + " SET " + KEY_READ + "=" + FeedItem.NEW - + " WHERE " + KEY_ID + " IN (" + selectNew + ")"; - Log.d("Migration", "SQL: " + sql); - db.execSQL(sql); - } - if (oldVersion <= 17) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0"); - } - if (oldVersion < 1030005) { - db.execSQL("UPDATE FeedItems SET auto_download=0 WHERE " + - "(read=1 OR id IN (SELECT feeditem FROM FeedMedia WHERE position>0 OR downloaded=1)) " + - "AND id NOT IN (SELECT feeditem FROM Queue)"); - } - if (oldVersion < 1040001) { - db.execSQL(CREATE_TABLE_FAVORITES); - } - if (oldVersion < 1040002) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA - + " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYED_TIME + " INTEGER DEFAULT 0"); - } - if (oldVersion < 1040013) { - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE); - db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ); - } - if (oldVersion < 1050003) { - // Migrates feed list filter data - - db.beginTransaction(); - - // Change to intermediate values to avoid overwriting in the following find/replace - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'unplayed', 'noplay')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'not_queued', 'noqueue')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'not_downloaded', 'nodl')"); - - // Replace played, queued, and downloaded with their opposites - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'played', 'unplayed')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'queued', 'not_queued')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'downloaded', 'not_downloaded')"); - - // Now replace intermediates for unplayed, not queued, etc. with their opposites - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'noplay', 'played')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'noqueue', 'queued')"); - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'nodl', 'downloaded')"); - - // Paused doesn't have an opposite, so unplayed is the next best option - db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" + - "SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'paused', 'unplayed')"); - - db.setTransactionSuccessful(); - db.endTransaction(); - - // and now get ready for autodownload filters - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_INCLUDE_FILTER + " TEXT DEFAULT ''"); - - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_EXCLUDE_FILTER + " TEXT DEFAULT ''"); - - // and now auto refresh - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_KEEP_UPDATED + " INTEGER DEFAULT 1"); - } - if (oldVersion < 1050004) { - // prevent old timestamps to be misinterpreted as ETags - db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS - + " SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL"); - } - if (oldVersion < 1060200) { - db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS - + " ADD COLUMN " + PodDBAdapter.KEY_CUSTOM_TITLE + " TEXT"); - } - + DBUpgrader.upgrade(db, oldVersion, newVersion); EventBus.getDefault().post(ProgressEvent.end()); } } -- cgit v1.2.3 From bb716ce9eadb0b63b0b3dfea269898ef928a6ff0 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 6 Jun 2018 16:32:41 +0200 Subject: Moved playing background into attr --- .../java/de/danoeh/antennapod/core/util/ThemeUtils.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java index 184c3ee54..03d0f10ff 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ThemeUtils.java @@ -1,7 +1,12 @@ package de.danoeh.antennapod.core.util; +import android.content.Context; +import android.support.annotation.AttrRes; +import android.support.annotation.ColorInt; +import android.support.annotation.ColorRes; import android.util.Log; +import android.util.TypedValue; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -12,7 +17,7 @@ public class ThemeUtils { int theme = UserPreferences.getTheme(); if (theme == R.style.Theme_AntennaPod_Dark) { return R.color.selection_background_color_dark; - }else if (theme == R.style.Theme_AntennaPod_TrueBlack){ + } else if (theme == R.style.Theme_AntennaPod_TrueBlack){ return R.color.selection_background_color_trueblack; } else if (theme == R.style.Theme_AntennaPod_Light) { return R.color.selection_background_color_light; @@ -22,4 +27,10 @@ public class ThemeUtils { return R.color.selection_background_color_light; } } + + public static @ColorInt int getColorFromAttr(Context context, @AttrRes int attr) { + TypedValue typedValue = new TypedValue(); + context.getTheme().resolveAttribute(attr, typedValue, true); + return typedValue.data; + } } -- cgit v1.2.3 From 0ece32ab0e65b7c946a9ebfa729ef047d66ff989 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 6 Jun 2018 18:01:23 +0200 Subject: Move old image url to new column --- .../java/de/danoeh/antennapod/core/storage/DBUpgrader.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java index 95dfcca1b..29ed5f7f9 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java @@ -272,6 +272,19 @@ class DBUpgrader { + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT"); db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT"); + + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + " SET " + PodDBAdapter.KEY_IMAGE_URL + " = (" + + " SELECT " + PodDBAdapter.KEY_DOWNLOAD_URL + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + + " WHERE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + "." + PodDBAdapter.KEY_ID + + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_IMAGE + ")"); + + db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + " SET " + PodDBAdapter.KEY_IMAGE_URL + " = (" + + " SELECT " + PodDBAdapter.KEY_DOWNLOAD_URL + + " FROM " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + + " WHERE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + "." + PodDBAdapter.KEY_ID + + " = " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_IMAGE + ")"); + db.execSQL("DROP TABLE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES); } } -- cgit v1.2.3 From e282250c089efb29ed7de96c5e4071be737a0af8 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 8 Jun 2018 00:15:43 +0200 Subject: Fixed image url of Feed --- .../src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'core/src/main/java/de/danoeh/antennapod') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 9ad74ecf3..591015dff 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -1285,7 +1285,9 @@ public class PodDBAdapter { + "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_ITEMS + " INNER JOIN " + TABLE_NAME_FEEDS + " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + " = " + TABLE_NAME_FEEDS + "." + KEY_ID - + " WHERE " + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL + "=" + downloadUrl; + + " WHERE " + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL + "=" + downloadUrl + + " UNION SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEEDS + + " WHERE " + TABLE_NAME_FEEDS + "." + KEY_IMAGE_URL + "=" + downloadUrl; return db.rawQuery(query, null); } -- cgit v1.2.3