summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2020-10-25 19:33:21 +0100
committerByteHamster <info@bytehamster.com>2020-10-25 19:33:21 +0100
commit679e4829997d886a07fe3361fd9d917db16061d2 (patch)
treea6de6275fa337e69651e370135e750bbadf901a1 /core/src
parentcaaf2c72db2220c84ce24b60853c5fe6a5874b18 (diff)
parent71b6c57773d1af6e6df967bba968e08cb0268335 (diff)
downloadAntennaPod-679e4829997d886a07fe3361fd9d917db16061d2.zip
Merge branch 'develop' into add-local-feeds
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/ChapterMerger.java55
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java32
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java20
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java45
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java81
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java13
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java57
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/RemoteMedia.java2
-rw-r--r--core/src/main/res/values/strings.xml4
11 files changed, 205 insertions, 108 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/ChapterMerger.java b/core/src/main/java/de/danoeh/antennapod/core/feed/ChapterMerger.java
new file mode 100644
index 000000000..f33fa7511
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/ChapterMerger.java
@@ -0,0 +1,55 @@
+package de.danoeh.antennapod.core.feed;
+
+import android.text.TextUtils;
+import android.util.Log;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+public class ChapterMerger {
+ private static final String TAG = "ChapterMerger";
+
+ private ChapterMerger() {
+
+ }
+
+ /**
+ * This method might modify the input data.
+ */
+ @Nullable
+ public static List<Chapter> merge(@Nullable List<Chapter> chapters1, @Nullable List<Chapter> chapters2) {
+ Log.d(TAG, "Merging chapters");
+ if (chapters1 == null) {
+ return chapters2;
+ } else if (chapters2 == null) {
+ return chapters1;
+ } else if (chapters2.size() > chapters1.size()) {
+ return chapters2;
+ } else if (chapters2.size() < chapters1.size()) {
+ return chapters1;
+ } else {
+ // Merge chapter lists of same length. Store in chapters2 array.
+ // In case the lists can not be merged, return chapters1 array.
+ for (int i = 0; i < chapters2.size(); i++) {
+ Chapter chapterTarget = chapters2.get(i);
+ Chapter chapterOther = chapters1.get(i);
+
+ if (Math.abs(chapterTarget.start - chapterOther.start) > 1000) {
+ Log.e(TAG, "Chapter lists are too different. Cancelling merge.");
+ return chapters1;
+ }
+
+ if (TextUtils.isEmpty(chapterTarget.imageUrl)) {
+ chapterTarget.imageUrl = chapterOther.imageUrl;
+ }
+ if (TextUtils.isEmpty(chapterTarget.link)) {
+ chapterTarget.link = chapterOther.link;
+ }
+ if (TextUtils.isEmpty(chapterTarget.title)) {
+ chapterTarget.title = chapterOther.title;
+ }
+ }
+ return chapters2;
+ }
+ }
+}
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 92e45376a..88945b930 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
@@ -11,6 +11,7 @@ import androidx.annotation.Nullable;
import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaDescriptionCompat;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
@@ -383,19 +384,30 @@ public class FeedMedia extends FeedFile implements Playable {
if (item == null || item.getChapters() != null) {
return;
}
- // check if chapters are stored in db and not loaded yet.
+
+ List<Chapter> chapters = loadChapters(context);
+ if (chapters == null) {
+ // Do not try loading again. There are no chapters.
+ item.setChapters(Collections.emptyList());
+ } else {
+ item.setChapters(chapters);
+ }
+ }
+
+ private List<Chapter> loadChapters(Context context) {
+ List<Chapter> chaptersFromDatabase = null;
if (item.hasChapters()) {
- DBReader.loadChaptersOfFeedItem(item);
+ chaptersFromDatabase = DBReader.loadChaptersOfFeedItem(item);
+ }
+
+ List<Chapter> chaptersFromMediaFile;
+ if (localFileAvailable()) {
+ chaptersFromMediaFile = ChapterUtils.loadChaptersFromFileUrl(this);
} else {
- if (localFileAvailable()) {
- ChapterUtils.loadChaptersFromFileUrl(this);
- } else {
- ChapterUtils.loadChaptersFromStreamUrl(this, context);
- }
- if (item.getChapters() != null) {
- DBWriter.setFeedItem(item);
- }
+ chaptersFromMediaFile = ChapterUtils.loadChaptersFromStreamUrl(this, context);
}
+
+ return ChapterMerger.merge(chaptersFromDatabase, chaptersFromMediaFile);
}
@Override
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 1dc4b6093..56dd95fe6 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
@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Build;
-import androidx.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
@@ -12,6 +11,7 @@ import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.core.app.NotificationCompat;
+import androidx.preference.PreferenceManager;
import org.json.JSONArray;
import org.json.JSONException;
@@ -23,7 +23,7 @@ import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
+import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@@ -115,6 +115,7 @@ public class UserPreferences {
private static final String PREF_DATA_FOLDER = "prefDataFolder";
public static final String PREF_IMAGE_CACHE_SIZE = "prefImageCacheSize";
public static final String PREF_DELETE_REMOVES_FROM_QUEUE = "prefDeleteRemovesFromQueue";
+ public static final String PREF_USAGE_COUNTING_DATE = "prefUsageCounting";
// Mediaplayer
public static final String PREF_MEDIA_PLAYER = "prefMediaPlayer";
@@ -1056,4 +1057,19 @@ public class UserPreferences {
.apply();
}
+ public static long getUsageCountingDateMillis() {
+ return prefs.getLong(PREF_USAGE_COUNTING_DATE, -1);
+ }
+
+ private static void setUsageCountingDateMillis(long value) {
+ prefs.edit().putLong(PREF_USAGE_COUNTING_DATE, value).apply();
+ }
+
+ public static void resetUsageCountingDate() {
+ setUsageCountingDateMillis(Calendar.getInstance().getTimeInMillis());
+ }
+
+ public static void unsetUsageCountingDate() {
+ setUsageCountingDateMillis(-1);
+ }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java
index 9e2b69810..501214399 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java
@@ -56,7 +56,7 @@ public class MediaDownloadedHandler implements Runnable {
// check if file has chapters
if (media.getItem() != null && !media.getItem().hasChapters()) {
- ChapterUtils.loadChaptersFromFileUrl(media);
+ media.setChapters(ChapterUtils.loadChaptersFromFileUrl(media));
}
// Get duration
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 fbdc9a52b..ae5d62872 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
@@ -2,9 +2,7 @@ package de.danoeh.antennapod.core.service.playback;
import android.content.Context;
import android.media.AudioAttributes;
-import android.media.AudioFocusRequest;
import android.media.AudioManager;
-import android.os.Build;
import android.os.PowerManager;
import androidx.annotation.NonNull;
import android.telephony.TelephonyManager;
@@ -12,11 +10,13 @@ import android.util.Log;
import android.util.Pair;
import android.view.SurfaceHolder;
+import androidx.media.AudioAttributesCompat;
+import androidx.media.AudioFocusRequestCompat;
+import androidx.media.AudioManagerCompat;
import org.antennapod.audio.MediaPlayer;
import java.io.File;
import java.io.IOException;
-import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
@@ -57,6 +57,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
private final AtomicBoolean startWhenPrepared;
private volatile boolean pausedBecauseOfTransientAudiofocusLoss;
private volatile Pair<Integer, Integer> videoSize;
+ private final AudioFocusRequestCompat audioFocusRequest;
/**
* Some asynchronous calls might change the state of the MediaPlayer object. Therefore calls in other threads
@@ -154,6 +155,16 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
pausedBecauseOfTransientAudiofocusLoss = false;
mediaType = MediaType.UNKNOWN;
videoSize = null;
+
+ AudioAttributesCompat audioAttributes = new AudioAttributesCompat.Builder()
+ .setUsage(AudioAttributesCompat.USAGE_MEDIA)
+ .setContentType(AudioAttributesCompat.CONTENT_TYPE_SPEECH)
+ .build();
+ audioFocusRequest = new AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
+ .setAudioAttributes(audioAttributes)
+ .setOnAudioFocusChangeListener(audioFocusChangeListener)
+ .setWillPauseWhenDucked(true)
+ .build();
}
/**
@@ -287,25 +298,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
private void resumeSync() {
if (playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) {
- int focusGained;
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- AudioAttributes audioAttributes = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_MEDIA)
- .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
- .build();
- AudioFocusRequest audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
- .setAudioAttributes(audioAttributes)
- .setOnAudioFocusChangeListener(audioFocusChangeListener)
- .setAcceptsDelayedFocusGain(true)
- .setWillPauseWhenDucked(true)
- .build();
- focusGained = audioManager.requestAudioFocus(audioFocusRequest);
- } else {
- focusGained = audioManager.requestAudioFocus(
- audioFocusChangeListener, AudioManager.STREAM_MUSIC,
- AudioManager.AUDIOFOCUS_GAIN);
- }
+ int focusGained = AudioManagerCompat.requestAudioFocus(audioManager, audioFocusRequest);
if (focusGained == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d(TAG, "Audiofocus successfully requested");
@@ -373,13 +366,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
}
private void abandonAudioFocus() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- AudioFocusRequest.Builder builder = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
- .setOnAudioFocusChangeListener(audioFocusChangeListener);
- audioManager.abandonAudioFocusRequest(builder.build());
- } else {
- audioManager.abandonAudioFocus(audioFocusChangeListener);
- }
+ AudioManagerCompat.abandonAudioFocusRequest(audioManager, audioFocusRequest);
}
/**
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 9f53c6da0..25c301ccc 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
@@ -504,16 +504,27 @@ public class PlaybackService extends MediaBrowserServiceCompat {
stateManager.stopService();
return Service.START_NOT_STICKY;
}
- if (playable instanceof FeedMedia) {
- playable = DBReader.getFeedMedia(((FeedMedia) playable).getId());
- }
- if (playable == null) {
- Log.d(TAG, "Playable was not found. Stopping service.");
- stateManager.stopService();
- return Service.START_NOT_STICKY;
- }
- mediaPlayer.playMediaObject(playable, stream, startWhenPrepared, prepareImmediately);
- addPlayableToQueue(playable);
+
+ Observable.fromCallable(
+ () -> {
+ if (playable instanceof FeedMedia) {
+ return DBReader.getFeedMedia(((FeedMedia) playable).getId());
+ } else {
+ return playable;
+ }
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ playableLoaded -> {
+ mediaPlayer.playMediaObject(playable, stream, startWhenPrepared,
+ prepareImmediately);
+ addPlayableToQueue(playable);
+ }, error -> {
+ Log.d(TAG, "Playable was not found. Stopping service.");
+ stateManager.stopService();
+ });
+ return Service.START_NOT_STICKY;
} else {
Log.d(TAG, "Did not handle intent to PlaybackService: " + intent);
Log.d(TAG, "Extras: " + intent.getExtras());
@@ -582,7 +593,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntentAllowThisTime)
.addAction(R.drawable.ic_stream_white,
- getString(R.string.stream_label),
+ getString(R.string.confirm_mobile_streaming_button_once),
pendingIntentAllowThisTime)
.addAction(R.drawable.ic_stream_white,
getString(R.string.confirm_mobile_streaming_button_always),
@@ -682,27 +693,33 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
private void startPlayingFromPreferences() {
- Playable playable = Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext());
- if (playable != null) {
- boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl());
- if (PlaybackPreferences.getCurrentEpisodeIsStream() && !NetworkUtils.isStreamingAllowed() && !localFeed) {
- displayStreamingNotAllowedNotification(
- new PlaybackServiceStarter(this, playable)
- .prepareImmediately(true)
- .startWhenPrepared(true)
- .shouldStream(true)
- .getIntent());
- PlaybackPreferences.writeNoMediaPlaying();
- stateManager.stopService();
- return;
- }
- mediaPlayer.playMediaObject(playable, PlaybackPreferences.getCurrentEpisodeIsStream(), true, true);
- stateManager.validStartCommandWasReceived();
- PlaybackService.this.updateMediaSessionMetadata(playable);
- addPlayableToQueue(playable);
- } else {
- stateManager.stopService();
- }
+ Observable.fromCallable(() -> Playable.PlayableUtils.createInstanceFromPreferences(getApplicationContext()))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ playable -> {
+ boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl());
+ if (PlaybackPreferences.getCurrentEpisodeIsStream()
+ && !NetworkUtils.isStreamingAllowed() && !localFeed) {
+ displayStreamingNotAllowedNotification(
+ new PlaybackServiceStarter(this, playable)
+ .prepareImmediately(true)
+ .startWhenPrepared(true)
+ .shouldStream(true)
+ .getIntent());
+ PlaybackPreferences.writeNoMediaPlaying();
+ stateManager.stopService();
+ return;
+ }
+ mediaPlayer.playMediaObject(playable, PlaybackPreferences.getCurrentEpisodeIsStream(),
+ true, true);
+ stateManager.validStartCommandWasReceived();
+ PlaybackService.this.updateMediaSessionMetadata(playable);
+ addPlayableToQueue(playable);
+ }, error -> {
+ Log.d(TAG, "Playable was not loaded from preferences. Stopping service.");
+ stateManager.stopService();
+ });
}
/**
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 892254507..b218a73f9 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
@@ -651,29 +651,30 @@ public final class DBReader {
*
* @param item The FeedItem
*/
- public static void loadChaptersOfFeedItem(final FeedItem item) {
+ public static List<Chapter> loadChaptersOfFeedItem(final FeedItem item) {
Log.d(TAG, "loadChaptersOfFeedItem() called with: " + "item = [" + item + "]");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
try {
- loadChaptersOfFeedItem(adapter, item);
+ return loadChaptersOfFeedItem(adapter, item);
} finally {
adapter.close();
}
}
- private static void loadChaptersOfFeedItem(PodDBAdapter adapter, FeedItem item) {
+ private static List<Chapter> loadChaptersOfFeedItem(PodDBAdapter adapter, FeedItem item) {
try (Cursor cursor = adapter.getSimpleChaptersOfFeedItemCursor(item)) {
int chaptersCount = cursor.getCount();
if (chaptersCount == 0) {
item.setChapters(null);
- return;
+ return null;
}
- item.setChapters(new ArrayList<>(chaptersCount));
+ ArrayList<Chapter> chapters = new ArrayList<>();
while (cursor.moveToNext()) {
- item.getChapters().add(Chapter.fromCursor(cursor));
+ chapters.add(Chapter.fromCursor(cursor));
}
+ return chapters;
}
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
index 859666464..d4a2cdca6 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
@@ -52,32 +52,34 @@ public class ChapterUtils {
return chapters.size() - 1;
}
- public static void loadChaptersFromStreamUrl(Playable media, Context context) {
- ChapterUtils.readID3ChaptersFromPlayableStreamUrl(media, context);
- if (media.getChapters() == null) {
- ChapterUtils.readOggChaptersFromPlayableStreamUrl(media, context);
+ public static List<Chapter> loadChaptersFromStreamUrl(Playable media, Context context) {
+ List<Chapter> chapters = ChapterUtils.readID3ChaptersFromPlayableStreamUrl(media, context);
+ if (chapters == null) {
+ chapters = ChapterUtils.readOggChaptersFromPlayableStreamUrl(media, context);
}
+ return chapters;
}
- public static void loadChaptersFromFileUrl(Playable media) {
+ public static List<Chapter> loadChaptersFromFileUrl(Playable media) {
if (!media.localFileAvailable()) {
Log.e(TAG, "Could not load chapters from file url: local file not available");
- return;
+ return null;
}
- ChapterUtils.readID3ChaptersFromPlayableFileUrl(media);
- if (media.getChapters() == null) {
- ChapterUtils.readOggChaptersFromPlayableFileUrl(media);
+ List<Chapter> chapters = ChapterUtils.readID3ChaptersFromPlayableFileUrl(media);
+ if (chapters == null) {
+ chapters = ChapterUtils.readOggChaptersFromPlayableFileUrl(media);
}
+ return chapters;
}
/**
* Uses the download URL of a media object of a feeditem to read its ID3
* chapters.
*/
- private static void readID3ChaptersFromPlayableStreamUrl(Playable p, Context context) {
+ private static List<Chapter> readID3ChaptersFromPlayableStreamUrl(Playable p, Context context) {
if (p == null || p.getStreamUrl() == null) {
Log.e(TAG, "Unable to read ID3 chapters: media or download URL was null");
- return;
+ return null;
}
Log.d(TAG, "Reading id3 chapters from item " + p.getEpisodeTitle());
CountingInputStream in = null;
@@ -93,7 +95,7 @@ public class ChapterUtils {
}
List<Chapter> chapters = readChaptersFrom(in);
if (!chapters.isEmpty()) {
- p.setChapters(chapters);
+ return chapters;
}
Log.i(TAG, "Chapters loaded");
} catch (IOException | ID3ReaderException | IllegalArgumentException e) {
@@ -101,21 +103,22 @@ public class ChapterUtils {
} finally {
IOUtils.closeQuietly(in);
}
+ return null;
}
/**
* Uses the file URL of a media object of a feeditem to read its ID3
* chapters.
*/
- private static void readID3ChaptersFromPlayableFileUrl(Playable p) {
+ private static List<Chapter> readID3ChaptersFromPlayableFileUrl(Playable p) {
if (p == null || !p.localFileAvailable() || p.getLocalMediaUrl() == null) {
- return;
+ return null;
}
Log.d(TAG, "Reading id3 chapters from item " + p.getEpisodeTitle());
File source = new File(p.getLocalMediaUrl());
if (!source.exists()) {
Log.e(TAG, "Unable to read id3 chapters: Source doesn't exist");
- return;
+ return null;
}
CountingInputStream in = null;
@@ -123,7 +126,7 @@ public class ChapterUtils {
in = new CountingInputStream(new BufferedInputStream(new FileInputStream(source)));
List<Chapter> chapters = readChaptersFrom(in);
if (!chapters.isEmpty()) {
- p.setChapters(chapters);
+ return chapters;
}
Log.i(TAG, "Chapters loaded");
} catch (IOException | ID3ReaderException e) {
@@ -131,6 +134,7 @@ public class ChapterUtils {
} finally {
IOUtils.closeQuietly(in);
}
+ return null;
}
@NonNull
@@ -152,9 +156,9 @@ public class ChapterUtils {
return chapters;
}
- private static void readOggChaptersFromPlayableStreamUrl(Playable media, Context context) {
+ private static List<Chapter> readOggChaptersFromPlayableStreamUrl(Playable media, Context context) {
if (media == null || !media.streamAvailable()) {
- return;
+ return null;
}
InputStream input = null;
try {
@@ -168,34 +172,36 @@ public class ChapterUtils {
input = urlConnection.getInputStream();
}
if (input != null) {
- readOggChaptersFromInputStream(media, input);
+ return readOggChaptersFromInputStream(media, input);
}
} catch (IOException | IllegalArgumentException e) {
Log.e(TAG, Log.getStackTraceString(e));
} finally {
IOUtils.closeQuietly(input);
}
+ return null;
}
- private static void readOggChaptersFromPlayableFileUrl(Playable media) {
+ private static List<Chapter> readOggChaptersFromPlayableFileUrl(Playable media) {
if (media == null || media.getLocalMediaUrl() == null) {
- return;
+ return null;
}
File source = new File(media.getLocalMediaUrl());
if (source.exists()) {
InputStream input = null;
try {
input = new BufferedInputStream(new FileInputStream(source));
- readOggChaptersFromInputStream(media, input);
+ return readOggChaptersFromInputStream(media, input);
} catch (FileNotFoundException e) {
Log.e(TAG, Log.getStackTraceString(e));
} finally {
IOUtils.closeQuietly(input);
}
}
+ return null;
}
- private static void readOggChaptersFromInputStream(Playable p, InputStream input) {
+ private static List<Chapter> readOggChaptersFromInputStream(Playable p, InputStream input) {
Log.d(TAG, "Trying to read chapters from item with title " + p.getEpisodeTitle());
try {
VorbisCommentChapterReader reader = new VorbisCommentChapterReader();
@@ -203,19 +209,20 @@ public class ChapterUtils {
List<Chapter> chapters = reader.getChapters();
if (chapters == null) {
Log.i(TAG, "ChapterReader could not find any Ogg vorbis chapters");
- return;
+ return null;
}
Collections.sort(chapters, new ChapterStartTimeComparator());
enumerateEmptyChapterTitles(chapters);
if (chaptersValid(chapters)) {
- p.setChapters(chapters);
Log.i(TAG, "Chapters loaded");
+ return chapters;
} else {
Log.e(TAG, "Chapter data was invalid");
}
} catch (VorbisCommentReaderException e) {
e.printStackTrace();
}
+ return null;
}
/**
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java
index 81937b62e..6c107996f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java
@@ -99,7 +99,7 @@ public class ExternalMedia implements Playable {
e.printStackTrace();
throw new PlayableException("NumberFormatException when reading duration of media file");
}
- ChapterUtils.loadChaptersFromFileUrl(this);
+ setChapters(ChapterUtils.loadChaptersFromFileUrl(this));
}
@Override
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/RemoteMedia.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/RemoteMedia.java
index 669279294..29eb20aca 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/RemoteMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/RemoteMedia.java
@@ -130,7 +130,7 @@ public class RemoteMedia implements Playable {
@Override
public void loadChapterMarks(Context context) {
- ChapterUtils.loadChaptersFromStreamUrl(this, context);
+ setChapters(ChapterUtils.loadChaptersFromStreamUrl(this, context));
}
@Override
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 30f64b35f..542b90120 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -41,6 +41,7 @@
<string name="statistics_speed_not_counted">Notice: Playback speed is never taken into account.</string>
<string name="statistics_reset_data">Reset statistics data</string>
<string name="statistics_reset_data_msg">This will erase the history of duration played for all episodes. Are you sure you want to proceed?</string>
+ <string name="statistics_counting_since">Since %s,\nyou played</string>
<!-- Download Statistics fragment -->
<string name="total_size_downloaded_podcasts">Total size of episodes on the device:</string>
@@ -269,7 +270,8 @@
<string name="confirm_mobile_download_dialog_message">Downloading over mobile data connection is disabled in the settings.\n\nDo you want to allow downloading temporarily?\n\n<small>Your choice will be remembered for 10 minutes.</small></string>
<string name="confirm_mobile_streaming_notification_title">Confirm Mobile streaming</string>
<string name="confirm_mobile_streaming_notification_message">Streaming over mobile data connection is disabled in the settings. Tap to stream anyway.</string>
- <string name="confirm_mobile_streaming_button_always">Always allow</string>
+ <string name="confirm_mobile_streaming_button_always">Always</string>
+ <string name="confirm_mobile_streaming_button_once">Once</string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Enqueue</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Allow temporarily</string>