summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/event/PlaybackPositionEvent.java19
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/event/ProgressEvent.java36
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java69
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java87
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java119
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java34
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java6
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java5
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/Optional.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/QueueSorter.java5
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java50
-rw-r--r--core/src/main/res/drawable/ic_warning_red.xml5
-rw-r--r--core/src/main/res/values/strings.xml2
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java13
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java4
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java31
21 files changed, 286 insertions, 214 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/PlaybackPositionEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/PlaybackPositionEvent.java
new file mode 100644
index 000000000..3327d8a02
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/event/PlaybackPositionEvent.java
@@ -0,0 +1,19 @@
+package de.danoeh.antennapod.core.event;
+
+public class PlaybackPositionEvent {
+ private final int position;
+ private final int duration;
+
+ public PlaybackPositionEvent(int position, int duration) {
+ this.position = position;
+ this.duration = duration;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public int getDuration() {
+ return duration;
+ }
+}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/event/ProgressEvent.java b/core/src/main/java/de/danoeh/antennapod/core/event/ProgressEvent.java
deleted file mode 100644
index 3769d6bb1..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/event/ProgressEvent.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package de.danoeh.antennapod.core.event;
-
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-public class ProgressEvent {
-
- public enum Action {
- START, END
- }
-
- public final Action action;
- public final String message;
-
- private ProgressEvent(Action action, String message) {
- this.action = action;
- this.message = message;
- }
-
- public static ProgressEvent start(String message) {
- return new ProgressEvent(Action.START, message);
- }
-
- public static ProgressEvent end() {
- return new ProgressEvent(Action.END, null);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
- .append("action", action)
- .append("message", message)
- .toString();
- }
-
-}
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 3495164a6..744e9b924 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
@@ -218,6 +218,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, ImageR
return itemIdentifier;
} else if (title != null && !title.isEmpty()) {
return title;
+ } else if (hasMedia() && media.getDownload_url() != null) {
+ return media.getDownload_url();
} else {
return link;
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java b/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java
index bb34e2c0f..3dd87cc0b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/glide/ApOkHttpUrlLoader.java
@@ -92,11 +92,9 @@ class ApOkHttpUrlLoader implements ModelLoader<String, InputStream> {
@Nullable
@Override
public LoadData<InputStream> buildLoadData(@NonNull String model, int width, int height, @NonNull Options options) {
- Log.d(TAG, "buildLoadData() called with: " + "model = [" + model + "], width = ["
- + width + "], height = [" + height + "]");
- if(TextUtils.isEmpty(model)) {
+ if (TextUtils.isEmpty(model)) {
return null;
- } else if(model.startsWith("/")) {
+ } else if (model.startsWith("/")) {
return new LoadData<>(new ObjectKey(model), new AudioCoverFetcher(model));
} else {
GlideUrl url = new GlideUrl(model);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
index a4cc22d8b..f2c0c8fe3 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java
@@ -4,7 +4,12 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import android.util.Log;
import de.danoeh.antennapod.core.feed.EventDistributor;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.feed.MediaType;
+import de.danoeh.antennapod.core.service.playback.PlayerStatus;
+import de.danoeh.antennapod.core.util.playback.Playable;
/**
* Provides access to preferences set by the playback service. A private
@@ -19,35 +24,35 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
* Contains the feed id of the currently playing item if it is a FeedMedia
* object.
*/
- public static final String PREF_CURRENTLY_PLAYING_FEED_ID = "de.danoeh.antennapod.preferences.lastPlayedFeedId";
+ private static final String PREF_CURRENTLY_PLAYING_FEED_ID = "de.danoeh.antennapod.preferences.lastPlayedFeedId";
/**
* Contains the id of the currently playing FeedMedia object or
* NO_MEDIA_PLAYING if the currently playing media is no FeedMedia object.
*/
- public static final String PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID = "de.danoeh.antennapod.preferences.lastPlayedFeedMediaId";
+ private static final String PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID = "de.danoeh.antennapod.preferences.lastPlayedFeedMediaId";
/**
* Type of the media object that is currently being played. This preference
* is set to NO_MEDIA_PLAYING after playback has been completed and is set
* as soon as the 'play' button is pressed.
*/
- public static final String PREF_CURRENTLY_PLAYING_MEDIA = "de.danoeh.antennapod.preferences.currentlyPlayingMedia";
+ private static final String PREF_CURRENTLY_PLAYING_MEDIA = "de.danoeh.antennapod.preferences.currentlyPlayingMedia";
/**
* True if last played media was streamed.
*/
- public static final String PREF_CURRENT_EPISODE_IS_STREAM = "de.danoeh.antennapod.preferences.lastIsStream";
+ private static final String PREF_CURRENT_EPISODE_IS_STREAM = "de.danoeh.antennapod.preferences.lastIsStream";
/**
* True if last played media was a video.
*/
- public static final String PREF_CURRENT_EPISODE_IS_VIDEO = "de.danoeh.antennapod.preferences.lastIsVideo";
+ private static final String PREF_CURRENT_EPISODE_IS_VIDEO = "de.danoeh.antennapod.preferences.lastIsVideo";
/**
* The current player status as int.
*/
- public static final String PREF_CURRENT_PLAYER_STATUS = "de.danoeh.antennapod.preferences.currentPlayerStatus";
+ private static final String PREF_CURRENT_PLAYER_STATUS = "de.danoeh.antennapod.preferences.currentPlayerStatus";
/**
* Value of PREF_CURRENTLY_PLAYING_MEDIA if no media is playing.
@@ -87,10 +92,6 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
}
}
- public static long getLastPlayedFeedId() {
- return prefs.getLong(PREF_CURRENTLY_PLAYING_FEED_ID, -1);
- }
-
public static long getCurrentlyPlayingMedia() {
return prefs.getLong(PREF_CURRENTLY_PLAYING_MEDIA, NO_MEDIA_PLAYING);
}
@@ -119,4 +120,52 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference
editor.putInt(PREF_CURRENT_PLAYER_STATUS, PLAYER_STATUS_OTHER);
editor.apply();
}
+
+ public static void writeMediaPlaying(Playable playable, PlayerStatus playerStatus, boolean stream) {
+ Log.d(TAG, "Writing playback preferences");
+ SharedPreferences.Editor editor = prefs.edit();
+
+ if (playable == null) {
+ writeNoMediaPlaying();
+ } else {
+ editor.putLong(PREF_CURRENTLY_PLAYING_MEDIA, playable.getPlayableType());
+ editor.putBoolean(PREF_CURRENT_EPISODE_IS_STREAM, stream);
+ editor.putBoolean(PREF_CURRENT_EPISODE_IS_VIDEO, playable.getMediaType() == MediaType.VIDEO);
+ if (playable instanceof FeedMedia) {
+ FeedMedia fMedia = (FeedMedia) playable;
+ editor.putLong(PREF_CURRENTLY_PLAYING_FEED_ID, fMedia.getItem().getFeed().getId());
+ editor.putLong(PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID, fMedia.getId());
+ } else {
+ editor.putLong(PREF_CURRENTLY_PLAYING_FEED_ID, NO_MEDIA_PLAYING);
+ editor.putLong(PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID, NO_MEDIA_PLAYING);
+ }
+ playable.writeToPreferences(editor);
+ }
+ editor.putInt(PREF_CURRENT_PLAYER_STATUS, getCurrentPlayerStatusAsInt(playerStatus));
+
+ editor.apply();
+ }
+
+ public static void writePlayerStatus(PlayerStatus playerStatus) {
+ Log.d(TAG, "Writing player status playback preferences");
+
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putInt(PREF_CURRENT_PLAYER_STATUS, getCurrentPlayerStatusAsInt(playerStatus));
+ editor.apply();
+ }
+
+ private static int getCurrentPlayerStatusAsInt(PlayerStatus playerStatus) {
+ int playerStatusAsInt;
+ switch (playerStatus) {
+ case PLAYING:
+ playerStatusAsInt = PLAYER_STATUS_PLAYING;
+ break;
+ case PAUSED:
+ playerStatusAsInt = PLAYER_STATUS_PAUSED;
+ break;
+ default:
+ playerStatusAsInt = PLAYER_STATUS_OTHER;
+ }
+ return playerStatusAsInt;
+ }
}
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 0f346893e..b429740bf 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
@@ -13,6 +13,8 @@ import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
@@ -190,10 +192,8 @@ public class DownloadService extends Service {
handleFailedDownload(status, downloader.getDownloadRequest());
if (type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
- long id = status.getFeedfileId();
- FeedMedia media = DBReader.getFeedMedia(id);
- FeedItem item;
- if (media == null || (item = media.getItem()) == null) {
+ FeedItem item = getFeedItemFromId(status.getFeedfileId());
+ if (item == null) {
return;
}
boolean httpNotFound = status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR
@@ -213,9 +213,8 @@ public class DownloadService extends Service {
// if FeedMedia download has been canceled, fake FeedItem update
// so that lists reload that it
if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
- FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId());
- FeedItem item;
- if (media == null || (item = media.getItem()) == null) {
+ FeedItem item = getFeedItemFromId(status.getFeedfileId());
+ if (item == null) {
return;
}
EventBus.getDefault().post(FeedItemEvent.updated(item));
@@ -386,6 +385,12 @@ public class DownloadService extends Service {
Downloader d = getDownloader(url);
if (d != null) {
d.cancel();
+ DownloadRequester.getInstance().removeDownload(d.getDownloadRequest());
+
+ FeedItem item = getFeedItemFromId(d.getDownloadRequest().getFeedfileId());
+ if (item != null) {
+ EventBus.getDefault().post(FeedItemEvent.updated(item));
+ }
} else {
Log.e(TAG, "Could not cancel download with url " + url);
}
@@ -430,12 +435,40 @@ public class DownloadService extends Service {
queryDownloads();
}
- private Downloader getDownloader(DownloadRequest request) {
- if (!URLUtil.isHttpUrl(request.getSource()) && !URLUtil.isHttpsUrl(request.getSource())) {
- Log.e(TAG, "Could not find appropriate downloader for " + request.getSource());
- return null;
+ @VisibleForTesting
+ public interface DownloaderFactory {
+ @Nullable
+ Downloader create(@NonNull DownloadRequest request);
+ }
+
+ private static class DefaultDownloaderFactory implements DownloaderFactory {
+ @Nullable
+ @Override
+ public Downloader create(@NonNull DownloadRequest request) {
+ if (!URLUtil.isHttpUrl(request.getSource()) && !URLUtil.isHttpsUrl(request.getSource())) {
+ Log.e(TAG, "Could not find appropriate downloader for " + request.getSource());
+ return null;
+ }
+ return new HttpDownloader(request);
}
- return new HttpDownloader(request);
+ }
+
+ private static DownloaderFactory downloaderFactory = new DefaultDownloaderFactory();
+
+ @VisibleForTesting
+ public static DownloaderFactory getDownloaderFactory() {
+ return downloaderFactory;
+ }
+
+ // public scope rather than package private,
+ // because androidTest put classes in the non-standard de.test.antennapod hierarchy
+ @VisibleForTesting
+ public static void setDownloaderFactory(DownloaderFactory downloaderFactory) {
+ DownloadService.downloaderFactory = downloaderFactory;
+ }
+
+ private Downloader getDownloader(@NonNull DownloadRequest request) {
+ return downloaderFactory.create(request);
}
/**
@@ -578,6 +611,16 @@ public class DownloadService extends Service {
syncExecutor.execute(new FailedDownloadHandler(status, request));
}
+ @Nullable
+ private FeedItem getFeedItemFromId(long id) {
+ FeedMedia media = DBReader.getFeedMedia(id);
+ if (media != null) {
+ return media.getItem();
+ } else {
+ return null;
+ }
+ }
+
/**
* Takes a single Feed, parses the corresponding file and refreshes
* information in the manager
@@ -654,6 +697,7 @@ public class DownloadService extends Service {
Log.e(TAG, "FeedSyncThread was interrupted");
} catch (ExecutionException e) {
Log.e(TAG, "ExecutionException in FeedSyncThread: " + e.getMessage());
+ e.printStackTrace();
}
}
@@ -688,6 +732,7 @@ public class DownloadService extends Service {
Log.e(TAG, "FeedSyncThread was interrupted");
} catch (ExecutionException e) {
Log.e(TAG, "ExecutionException in FeedSyncThread: " + e.getMessage());
+ e.printStackTrace();
}
}
@@ -983,14 +1028,17 @@ public class DownloadService extends Service {
final FeedItem item = media.getItem();
try {
+ DBWriter.setFeedMedia(media).get();
+
// we've received the media, we don't want to autodownload it again
if (item != null) {
item.setAutoDownload(false);
+ // setFeedItem() signals (via EventBus) that the item has been updated,
+ // so we do it after the enclosing media has been updated above,
+ // to ensure subscribers will get the updated FeedMedia as well
DBWriter.setFeedItem(item).get();
}
- DBWriter.setFeedMedia(media).get();
-
if (item != null && UserPreferences.enqueueDownloadedEpisodes() &&
!DBTasks.isInQueue(DownloadService.this, item.getId())) {
DBWriter.addQueueItem(DownloadService.this, item).get();
@@ -1058,7 +1106,13 @@ public class DownloadService extends Service {
private final Runnable postDownloaderTask = new Runnable() {
@Override
public void run() {
- List<Downloader> list = Collections.unmodifiableList(downloads);
+ List<Downloader> runningDownloads = new ArrayList<>();
+ for (Downloader downloader : downloads) {
+ if (!downloader.cancelled) {
+ runningDownloads.add(downloader);
+ }
+ }
+ List<Downloader> list = Collections.unmodifiableList(runningDownloads);
EventBus.getDefault().postSticky(DownloadEvent.refresh(list));
postHandler.postDelayed(postDownloaderTask, 1500);
}
@@ -1076,6 +1130,9 @@ public class DownloadService extends Service {
private static String compileNotificationString(List<Downloader> downloads) {
List<String> lines = new ArrayList<>(downloads.size());
for (Downloader downloader : downloads) {
+ if (downloader.cancelled) {
+ continue;
+ }
StringBuilder line = new StringBuilder("• ");
DownloadRequest request = downloader.getDownloadRequest();
switch (request.getFeedfileType()) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
index c3b412012..556aad573 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
@@ -63,6 +64,7 @@ public class ExoPlayerWrapper implements IPlayer {
loadControl.setBufferDurationsMs(30000, 120000,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
+ loadControl.setBackBuffer(UserPreferences.getRewindSecs() * 1000 + 500, true);
SimpleExoPlayer p = ExoPlayerFactory.newSimpleInstance(mContext, new DefaultRenderersFactory(mContext),
new DefaultTrackSelector(), loadControl.createDefaultLoadControl());
p.setSeekParameters(SeekParameters.PREVIOUS_SYNC);
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 9164f561f..f8f095ea8 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
@@ -584,7 +584,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
}
playerLock.unlock();
- Log.d(TAG, "getPosition() -> " + retVal);
return retVal;
}
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 a3535616e..e58d5cb31 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
@@ -12,7 +12,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
@@ -45,10 +44,12 @@ import com.bumptech.glide.request.target.Target;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
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.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.ServiceEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed;
@@ -66,7 +67,6 @@ import de.danoeh.antennapod.core.storage.DBReader;
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.IntentUtils;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.QueueAccess;
@@ -74,6 +74,9 @@ import de.danoeh.antennapod.core.util.gui.NotificationUtils;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
import org.greenrobot.eventbus.EventBus;
/**
@@ -212,6 +215,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
private PlaybackServiceTaskManager taskManager;
private PlaybackServiceFlavorHelper flavorHelper;
private PlaybackServiceStateManager stateManager;
+ private Disposable positionEventTimer;
/**
* Used for Lollipop notifications, Android Wear, and Android Auto.
@@ -331,8 +335,8 @@ public class PlaybackService extends MediaBrowserServiceCompat {
isRunning = false;
currentMediaType = MediaType.UNKNOWN;
- PreferenceManager.getDefaultSharedPreferences(this)
- .unregisterOnSharedPreferenceChangeListener(prefListener);
+ cancelPositionObserver();
+ PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(prefListener);
if (mediaSession != null) {
mediaSession.release();
}
@@ -566,7 +570,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (status == PlayerStatus.PLAYING) {
- mediaPlayer.pause(!UserPreferences.isPersistNotify(), true);
+ mediaPlayer.pause(!UserPreferences.isPersistNotify(), false);
} else if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
mediaPlayer.resume();
} else if (status == PlayerStatus.PREPARING) {
@@ -590,7 +594,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
return true;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (status == PlayerStatus.PLAYING) {
- mediaPlayer.pause(!UserPreferences.isPersistNotify(), true);
+ mediaPlayer.pause(!UserPreferences.isPersistNotify(), false);
}
return true;
@@ -717,7 +721,8 @@ public class PlaybackService extends MediaBrowserServiceCompat {
updateMediaSession(newInfo.playerStatus);
switch (newInfo.playerStatus) {
case INITIALIZED:
- writePlaybackPreferences();
+ PlaybackPreferences.writeMediaPlaying(mediaPlayer.getPSMPInfo().playable,
+ mediaPlayer.getPSMPInfo().playerStatus, mediaPlayer.isStreaming());
break;
case PREPARED:
@@ -734,7 +739,8 @@ public class PlaybackService extends MediaBrowserServiceCompat {
// remove notification on pause
stateManager.stopForeground(true);
}
- writePlayerStatusPlaybackPreferences();
+ cancelPositionObserver();
+ PlaybackPreferences.writePlayerStatus(mediaPlayer.getPlayerStatus());
break;
case STOPPED:
@@ -743,8 +749,9 @@ public class PlaybackService extends MediaBrowserServiceCompat {
break;
case PLAYING:
- writePlayerStatusPlaybackPreferences();
+ PlaybackPreferences.writePlayerStatus(mediaPlayer.getPlayerStatus());
setupNotification(newInfo);
+ setupPositionUpdater();
stateManager.validStartCommandWasReceived();
// set sleep timer if auto-enabled
if (newInfo.oldPlayerStatus != null && newInfo.oldPlayerStatus != PlayerStatus.SEEKING &&
@@ -1023,82 +1030,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
EventBus.getDefault().post(new MessageEvent(getString(R.string.sleep_timer_disabled_label)));
}
- private int getCurrentPlayerStatusAsInt(PlayerStatus playerStatus) {
- int playerStatusAsInt;
- switch (playerStatus) {
- case PLAYING:
- playerStatusAsInt = PlaybackPreferences.PLAYER_STATUS_PLAYING;
- break;
- case PAUSED:
- playerStatusAsInt = PlaybackPreferences.PLAYER_STATUS_PAUSED;
- break;
- default:
- playerStatusAsInt = PlaybackPreferences.PLAYER_STATUS_OTHER;
- }
- return playerStatusAsInt;
- }
-
- private void writePlaybackPreferences() {
- Log.d(TAG, "Writing playback preferences");
-
- SharedPreferences.Editor editor = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext()).edit();
- PlaybackServiceMediaPlayer.PSMPInfo info = mediaPlayer.getPSMPInfo();
- MediaType mediaType = mediaPlayer.getCurrentMediaType();
- boolean stream = mediaPlayer.isStreaming();
- int playerStatus = getCurrentPlayerStatusAsInt(info.playerStatus);
-
- if (info.playable != null) {
- editor.putLong(PlaybackPreferences.PREF_CURRENTLY_PLAYING_MEDIA,
- info.playable.getPlayableType());
- editor.putBoolean(
- PlaybackPreferences.PREF_CURRENT_EPISODE_IS_STREAM,
- stream);
- editor.putBoolean(
- PlaybackPreferences.PREF_CURRENT_EPISODE_IS_VIDEO,
- mediaType == MediaType.VIDEO);
- if (info.playable instanceof FeedMedia) {
- FeedMedia fMedia = (FeedMedia) info.playable;
- editor.putLong(
- PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID,
- fMedia.getItem().getFeed().getId());
- editor.putLong(
- PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID,
- fMedia.getId());
- } else {
- editor.putLong(
- PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID,
- PlaybackPreferences.NO_MEDIA_PLAYING);
- editor.putLong(
- PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID,
- PlaybackPreferences.NO_MEDIA_PLAYING);
- }
- info.playable.writeToPreferences(editor);
- } else {
- editor.putLong(PlaybackPreferences.PREF_CURRENTLY_PLAYING_MEDIA,
- PlaybackPreferences.NO_MEDIA_PLAYING);
- editor.putLong(PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID,
- PlaybackPreferences.NO_MEDIA_PLAYING);
- editor.putLong(
- PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID,
- PlaybackPreferences.NO_MEDIA_PLAYING);
- }
- editor.putInt(
- PlaybackPreferences.PREF_CURRENT_PLAYER_STATUS, playerStatus);
-
- editor.apply();
- }
-
- private void writePlayerStatusPlaybackPreferences() {
- Log.d(TAG, "Writing player status playback preferences");
-
- SharedPreferences.Editor editor = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext()).edit();
- int playerStatus = getCurrentPlayerStatusAsInt(mediaPlayer.getPlayerStatus());
- editor.putInt(PlaybackPreferences.PREF_CURRENT_PLAYER_STATUS, playerStatus);
- editor.apply();
- }
-
private void sendNotificationBroadcast(int type, int code) {
Intent intent = new Intent(ACTION_PLAYER_NOTIFICATION);
intent.putExtra(EXTRA_NOTIFICATION_TYPE, type);
@@ -1653,6 +1584,24 @@ public class PlaybackService extends MediaBrowserServiceCompat {
return mediaPlayer.getVideoSize();
}
+ private void setupPositionUpdater() {
+ if (positionEventTimer != null) {
+ positionEventTimer.dispose();
+ }
+
+ Log.d(TAG, "Setting up position observer");
+ positionEventTimer = Observable.interval(1, TimeUnit.SECONDS)
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(aLong ->
+ EventBus.getDefault().post(new PlaybackPositionEvent(getCurrentPosition(), getDuration())));
+ }
+
+ private void cancelPositionObserver() {
+ if (positionEventTimer != null) {
+ positionEventTimer.dispose();
+ }
+ }
+
private final MediaSessionCompat.Callback sessionCallback = new MediaSessionCompat.Callback() {
private static final String TAG = "MediaSessionCompat";
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
index 68839023e..1a13f9e9f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java
@@ -7,6 +7,9 @@ import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.util.Log;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -14,13 +17,12 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.playback.Playable;
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@@ -102,6 +104,34 @@ public class PlaybackServiceTaskManager {
}
}
+ @Subscribe
+ public void onEvent(FeedItemEvent event) {
+ // Use case: when an item in the queue has been downloaded,
+ // listening to the event to ensure the downloaded item will be used.
+ Log.d(TAG, "onEvent(FeedItemEvent " + event + ")");
+
+ for (FeedItem item : event.items) {
+ if (isItemInQueue(item.getId())) {
+ Log.d(TAG, "onEvent(FeedItemEvent) - some item (" + item.getId() + ") in the queue has been updated (usually downloaded). Refresh the queue.");
+ cancelQueueLoader();
+ loadQueue();
+ return;
+ }
+ }
+ }
+
+ private boolean isItemInQueue(long itemId) {
+ List<FeedItem> queue = getQueueIfLoaded();
+ if (queue != null) {
+ for (FeedItem item : queue) {
+ if (item.getId() == itemId) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Returns the queue if it is already loaded or null if it hasn't been loaded yet.
* In order to wait until the queue has been loaded, use getQueue()
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 4c15f5f00..46fa4b99c 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.SharedPreferences;
import android.database.Cursor;
import android.os.Looper;
+import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
@@ -440,10 +441,9 @@ public final class DBTasks {
/**
* Get a FeedItem by its identifying value.
*/
- private static FeedItem searchFeedItemByIdentifyingValue(Feed feed,
- String identifier) {
+ private static FeedItem searchFeedItemByIdentifyingValue(Feed feed, String identifier) {
for (FeedItem item : feed.getItems()) {
- if (item.getIdentifyingValue().equals(identifier)) {
+ if (TextUtils.equals(item.getIdentifyingValue(), identifier)) {
return item;
}
}
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 a3271bcf9..a1732e08f 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
@@ -28,8 +28,6 @@ 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.FeedItem;
@@ -38,7 +36,6 @@ import de.danoeh.antennapod.core.feed.FeedPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.util.LongIntMap;
-import org.greenrobot.eventbus.EventBus;
// TODO Remove media column from feeditem table
@@ -1478,11 +1475,9 @@ public class PodDBAdapter {
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
final int newVersion) {
- EventBus.getDefault().post(ProgressEvent.start(context.getString(R.string.progress_upgrading_database)));
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
+ newVersion + ".");
DBUpgrader.upgrade(db, oldVersion, newVersion);
- EventBus.getDefault().post(ProgressEvent.end());
}
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java b/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java
index 0fe11ec53..37f12c01c 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/Optional.java
@@ -77,7 +77,7 @@ public final class Optional<T> {
* @param <T> Type of the non-existent value
* @return an empty {@code Optional}
*/
- public static<T> Optional<T> empty() {
+ public static <T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/QueueSorter.java b/core/src/main/java/de/danoeh/antennapod/core/util/QueueSorter.java
index 37172d042..0c21ca393 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/QueueSorter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/QueueSorter.java
@@ -164,7 +164,7 @@ public class QueueSorter {
Collections.sort(feedItems, itemComparator);
if (spread == 0) {
spread = feedItems.size();
- } else if (feedItems.size() % spread != 0){
+ } else if (spread % feedItems.size() != 0){
spread *= feedItems.size();
}
}
@@ -180,6 +180,9 @@ public class QueueSorter {
Map<Long, List<FeedItem>> spreadItems = new HashMap<>();
for (List<FeedItem> feedItems : feeds) {
long thisSpread = spread / feedItems.size();
+ if (thisSpread == 0) {
+ thisSpread = 1;
+ }
// Starting from 0 ensures we front-load, so the queue starts with one episode from
// each feed in the queue
long itemSpread = 0;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java
index d22d08e09..a3f747e09 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java
@@ -72,7 +72,7 @@ public class ChapterReader extends ID3Reader {
String decodedLink = URLDecoder.decode(link.toString(), "UTF-8");
currentChapter.setLink(decodedLink);
Log.d(TAG, "Found link: " + currentChapter.getLink());
- } catch (IllegalArgumentException _iae) {
+ } catch (IllegalArgumentException iae) {
Log.w(TAG, "Bad URL found in ID3 data");
}
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 ac5418dd0..1456ebd8d 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
@@ -21,11 +21,10 @@ import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
-import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.ServiceEvent;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -69,9 +68,6 @@ public class PlaybackController {
private final ScheduledThreadPoolExecutor schedExecutor;
private static final int SCHED_EX_POOLSIZE = 1;
- private MediaPositionObserver positionObserver;
- private ScheduledFuture<?> positionObserverFuture;
-
private boolean mediaInfoLoaded = false;
private boolean released = false;
private boolean initialized = false;
@@ -177,7 +173,6 @@ public class PlaybackController {
} catch (IllegalArgumentException e) {
// ignore
}
- cancelPositionObserver();
schedExecutor.shutdownNow();
media = null;
released = true;
@@ -254,29 +249,6 @@ public class PlaybackController {
.getIntent());
}
-
-
- private void setupPositionObserver() {
- if (positionObserverFuture == null ||
- positionObserverFuture.isCancelled() ||
- positionObserverFuture.isDone()) {
-
- Log.d(TAG, "Setting up position observer");
- positionObserver = new MediaPositionObserver();
- positionObserverFuture = schedExecutor.scheduleWithFixedDelay(
- positionObserver, MediaPositionObserver.WAITING_INTERVALL,
- MediaPositionObserver.WAITING_INTERVALL,
- TimeUnit.MILLISECONDS);
- }
- }
-
- private void cancelPositionObserver() {
- if (positionObserverFuture != null) {
- boolean result = positionObserverFuture.cancel(true);
- Log.d(TAG, "PositionObserver cancelled. Result: " + result);
- }
- }
-
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if(service instanceof PlaybackService.LocalBinder) {
@@ -337,7 +309,6 @@ public class PlaybackController {
onBufferUpdate(progress);
break;
case PlaybackService.NOTIFICATION_TYPE_RELOAD:
- cancelPositionObserver();
mediaInfoLoaded = false;
queryService();
onReloadNotification(intent.getIntExtra(
@@ -447,7 +418,6 @@ public class PlaybackController {
case PAUSED:
clearStatusMsg();
checkMediaInfoLoaded();
- cancelPositionObserver();
onPositionObserverUpdate();
updatePlayButtonAppearance(playResource, playText);
if (!PlaybackService.isCasting() &&
@@ -463,7 +433,6 @@ public class PlaybackController {
onAwaitingVideoSurface();
setScreenOn(true);
}
- setupPositionObserver();
updatePlayButtonAppearance(pauseResource, pauseText);
break;
case PREPARING:
@@ -581,7 +550,6 @@ public class PlaybackController {
*/
public void onSeekBarStartTrackingTouch(SeekBar seekBar) {
// interrupt position Observer, restart later
- cancelPositionObserver();
}
/**
@@ -590,7 +558,6 @@ public class PlaybackController {
public void onSeekBarStopTrackingTouch(SeekBar seekBar, float prog) {
if (playbackService != null && media != null) {
playbackService.seekTo((int) (prog * media.getDuration()));
- setupPositionObserver();
}
}
@@ -836,19 +803,4 @@ public class PlaybackController {
}
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
-
- /**
- * Refreshes the current position of the media file that is playing.
- */
- public class MediaPositionObserver implements Runnable {
-
- static final int WAITING_INTERVALL = 1000;
-
- @Override
- public void run() {
- if (playbackService != null && playbackService.getStatus() == PlayerStatus.PLAYING) {
- activity.runOnUiThread(PlaybackController.this::onPositionObserverUpdate);
- }
- }
- }
}
diff --git a/core/src/main/res/drawable/ic_warning_red.xml b/core/src/main/res/drawable/ic_warning_red.xml
new file mode 100644
index 000000000..475a41bbb
--- /dev/null
+++ b/core/src/main/res/drawable/ic_warning_red.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#FF0000"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FF000000" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
+</vector>
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index c7bd2d2a2..adf938d75 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -394,6 +394,8 @@
<string name="pref_automatic_download_sum">Configure the automatic download of episodes.</string>
<string name="pref_autodl_wifi_filter_title">Enable Wi-Fi filter</string>
<string name="pref_autodl_wifi_filter_sum">Allow automatic download only for selected Wi-Fi networks.</string>
+ <string name="autodl_wifi_filter_permission_title">Permission required</string>
+ <string name="autodl_wifi_filter_permission_message">Location permission is required for Wi-Fi filter. Tap to grant the permission.</string>
<string name="pref_automatic_download_on_battery_title">Download when not charging</string>
<string name="pref_automatic_download_on_battery_sum">Allow automatic download when the battery is not charging</string>
<string name="pref_parallel_downloads_title">Parallel Downloads</string>
diff --git a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
index 244fb0254..800222ada 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/ClientConfig.java
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.core;
import android.content.Context;
+import android.util.Log;
import de.danoeh.antennapod.core.cast.CastManager;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
@@ -15,6 +16,8 @@ import de.danoeh.antennapod.core.util.exception.RxJavaErrorHandlerSetup;
* Apps using the core module of AntennaPod should register implementations of all interfaces here.
*/
public class ClientConfig {
+ private static final String TAG = "ClientConfig";
+
private ClientConfig(){}
/**
@@ -44,7 +47,15 @@ public class ClientConfig {
UserPreferences.init(context);
PlaybackPreferences.init(context);
NetworkUtils.init(context);
- CastManager.init(context);
+ // Don't initialize Cast-related logic unless it is enabled, to avoid the unnecessary
+ // Google Play Service usage.
+ // Down side: when the user decides to enable casting, AntennaPod needs to be restarted
+ // for it to take effect.
+ if (UserPreferences.isCastEnabled()) {
+ CastManager.init(context);
+ } else {
+ Log.v(TAG, "Cast is disabled. All Cast-related initialization will be skipped.");
+ }
SleepTimerPreferences.init(context);
RxJavaErrorHandlerSetup.setupRxJavaErrorHandler();
initialized = true;
diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java
index 5198a76bd..414a7840c 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastManager.java
@@ -163,6 +163,10 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
return INSTANCE;
}
+ public static boolean isInitialized() {
+ return INSTANCE != null;
+ }
+
/**
* Returns the active {@link RemoteMediaPlayer} instance. Since there are a number of media
* control APIs that this library do not provide a wrapper for, client applications can call
diff --git a/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java b/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java
index 7ab1be380..79c71f164 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceFlavorHelper.java
@@ -56,11 +56,18 @@ public class PlaybackServiceFlavorHelper {
PlaybackServiceFlavorHelper(Context context, PlaybackService.FlavorHelperCallback callback) {
this.callback = callback;
+ if (!CastManager.isInitialized()) {
+ return;
+ }
mediaRouter = MediaRouter.getInstance(context.getApplicationContext());
setCastConsumer(context);
}
void initializeMediaPlayer(Context context) {
+ if (!CastManager.isInitialized()) {
+ callback.setMediaPlayer(new LocalPSMP(context, callback.getMediaPlayerCallback()));
+ return;
+ }
castManager = CastManager.getInstance();
castManager.addCastConsumer(castConsumer);
boolean isCasting = castManager.isConnected();
@@ -77,10 +84,16 @@ public class PlaybackServiceFlavorHelper {
}
void removeCastConsumer() {
+ if (!CastManager.isInitialized()) {
+ return;
+ }
castManager.removeCastConsumer(castConsumer);
}
boolean castDisconnect(boolean castDisconnect) {
+ if (!CastManager.isInitialized()) {
+ return false;
+ }
if (castDisconnect) {
castManager.disconnect();
}
@@ -88,6 +101,9 @@ public class PlaybackServiceFlavorHelper {
}
boolean onMediaPlayerInfo(Context context, int code, @StringRes int resourceId) {
+ if (!CastManager.isInitialized()) {
+ return false;
+ }
switch (code) {
case RemotePSMP.CAST_ERROR:
callback.sendNotificationBroadcast(PlaybackService.NOTIFICATION_TYPE_SHOW_TOAST, resourceId);
@@ -218,6 +234,9 @@ public class PlaybackServiceFlavorHelper {
}
void registerWifiBroadcastReceiver() {
+ if (!CastManager.isInitialized()) {
+ return;
+ }
if (wifiBroadcastReceiver != null) {
return;
}
@@ -243,6 +262,9 @@ public class PlaybackServiceFlavorHelper {
}
void unregisterWifiBroadcastReceiver() {
+ if (!CastManager.isInitialized()) {
+ return;
+ }
if (wifiBroadcastReceiver != null) {
callback.unregisterReceiver(wifiBroadcastReceiver);
wifiBroadcastReceiver = null;
@@ -250,6 +272,9 @@ public class PlaybackServiceFlavorHelper {
}
boolean onSharedPreference(String key) {
+ if (!CastManager.isInitialized()) {
+ return false;
+ }
if (UserPreferences.PREF_CAST_ENABLED.equals(key)) {
if (!UserPreferences.isCastEnabled()) {
if (castManager.isConnecting() || castManager.isConnected()) {
@@ -263,6 +288,9 @@ public class PlaybackServiceFlavorHelper {
}
void sessionStateAddActionForWear(PlaybackStateCompat.Builder sessionState, String actionName, CharSequence name, int icon) {
+ if (!CastManager.isInitialized()) {
+ return;
+ }
PlaybackStateCompat.CustomAction.Builder actionBuilder =
new PlaybackStateCompat.CustomAction.Builder(actionName, name, icon);
Bundle actionExtras = new Bundle();
@@ -273,6 +301,9 @@ public class PlaybackServiceFlavorHelper {
}
void mediaSessionSetExtraForWear(MediaSessionCompat mediaSession) {
+ if (!CastManager.isInitialized()) {
+ return;
+ }
Bundle sessionExtras = new Bundle();
sessionExtras.putBoolean(MediaControlConstants.EXTRA_RESERVE_SLOT_SKIP_TO_PREVIOUS, true);
sessionExtras.putBoolean(MediaControlConstants.EXTRA_RESERVE_SLOT_SKIP_TO_NEXT, true);