summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java73
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java37
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java19
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java53
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java9
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java172
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java4
7 files changed, 270 insertions, 97 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
index a96c9a6d3..1f6a907d4 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
@@ -2,6 +2,12 @@ package de.test.antennapod.storage;
import android.content.Context;
import android.test.InstrumentationTestCase;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
@@ -10,11 +16,6 @@ import de.danoeh.antennapod.core.storage.FeedItemStatistics;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Random;
-
import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
/**
@@ -325,7 +326,7 @@ public class DBReaderTest extends InstrumentationTestCase {
public void testGetPlaybackHistory() {
final Context context = getInstrumentation().getTargetContext();
- final int numItems = (DBReader.PLAYBACK_HISTORY_SIZE+1) * 2;
+ final int numItems = (DBReader.PLAYBACK_HISTORY_SIZE + 1) * 2;
final int playedItems = DBReader.PLAYBACK_HISTORY_SIZE + 1;
final int numReturnedItems = Math.min(playedItems, DBReader.PLAYBACK_HISTORY_SIZE);
final int numFeeds = 1;
@@ -405,4 +406,64 @@ public class DBReaderTest extends InstrumentationTestCase {
assertEquals(NUM_UNREAD, navDrawerData.numUnreadItems);
assertEquals(NUM_QUEUE, navDrawerData.queueSize);
}
+
+ public void testGetFeedItemlistCheckChaptersFalse() throws Exception {
+ Context context = getInstrumentation().getTargetContext();
+ List<Feed> feeds = DBTestUtils.saveFeedlist(context, 10, 10, false, false, 0);
+ for (Feed feed : feeds) {
+ for (FeedItem item : feed.getItems()) {
+ assertFalse(item.hasChapters());
+ }
+ }
+ }
+
+ public void testGetFeedItemlistCheckChaptersTrue() throws Exception {
+ Context context = getInstrumentation().getTargetContext();
+ List<Feed> feeds = saveFeedlist(context, 10, 10, false, true, 10);
+ for (Feed feed : feeds) {
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.hasChapters());
+ }
+ }
+ }
+
+ public void testLoadChaptersOfFeedItemNoChapters() throws Exception {
+ Context context = getInstrumentation().getTargetContext();
+ List<Feed> feeds = saveFeedlist(context, 1, 3, false, false, 0);
+ saveFeedlist(context, 1, 3, false, true, 3);
+ for (Feed feed : feeds) {
+ for (FeedItem item : feed.getItems()) {
+ assertFalse(item.hasChapters());
+ DBReader.loadChaptersOfFeedItem(context, item);
+ assertFalse(item.hasChapters());
+ assertNull(item.getChapters());
+ }
+ }
+ }
+
+ public void testLoadChaptersOfFeedItemWithChapters() throws Exception {
+ Context context = getInstrumentation().getTargetContext();
+ final int NUM_CHAPTERS = 3;
+ DBTestUtils.saveFeedlist(context, 1, 3, false, false, 0);
+ List<Feed> feeds = saveFeedlist(context, 1, 3, false, true, NUM_CHAPTERS);
+ for (Feed feed : feeds) {
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.hasChapters());
+ DBReader.loadChaptersOfFeedItem(context, item);
+ assertTrue(item.hasChapters());
+ assertNotNull(item.getChapters());
+ assertEquals(NUM_CHAPTERS, item.getChapters().size());
+ }
+ }
+ }
+
+ public void testGetItemWithChapters() throws Exception {
+ Context context = getInstrumentation().getTargetContext();
+ final int NUM_CHAPTERS = 3;
+ List<Feed> feeds = saveFeedlist(context, 1, 1, false, true, NUM_CHAPTERS);
+ FeedItem item1 = feeds.get(0).getItems().get(0);
+ FeedItem item2 = DBReader.getFeedItem(context, item1.getId());
+ assertTrue(item2.hasChapters());
+ assertEquals(item1.getChapters(), item2.getChapters());
+ }
}
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
index 9e5f6546d..17c926cc2 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
@@ -1,12 +1,7 @@
package de.test.antennapod.storage;
import android.content.Context;
-import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
-import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator;
-import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
+
import junit.framework.Assert;
import java.util.ArrayList;
@@ -14,12 +9,32 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
+import de.danoeh.antennapod.core.feed.Chapter;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.feed.SimpleChapter;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator;
+import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
+
/**
* Utility methods for DB* tests.
*/
public class DBTestUtils {
+ /**
+ * Use this method when tests don't involve chapters.
+ */
public static List<Feed> saveFeedlist(Context context, int numFeeds, int numItems, boolean withMedia) {
+ return saveFeedlist(context, numFeeds, numItems, withMedia, false, 0);
+ }
+
+ /**
+ * Use this method when tests involve chapters.
+ */
+ public static List<Feed> saveFeedlist(Context context, int numFeeds, int numItems, boolean withMedia,
+ boolean withChapters, int numChapters) {
if (numFeeds <= 0) {
throw new IllegalArgumentException("numFeeds<=0");
}
@@ -36,11 +51,18 @@ public class DBTestUtils {
f.setItems(new ArrayList<FeedItem>());
for (int j = 0; j < numItems; j++) {
FeedItem item = new FeedItem(0, "item " + j, "id" + j, "link" + j, new Date(),
- true, f);
+ true, f, withChapters);
if (withMedia) {
FeedMedia media = new FeedMedia(item, "url" + j, 1, "audio/mp3");
item.setMedia(media);
}
+ if (withChapters) {
+ List<Chapter> chapters = new ArrayList<>();
+ item.setChapters(chapters);
+ for (int k = 0; k < numChapters; k++) {
+ chapters.add(new SimpleChapter(k, "item " + j + " chapter " + k, item, "http://example.com"));
+ }
+ }
f.getItems().add(item);
}
Collections.sort(f.getItems(), new FeedItemPubdateComparator());
@@ -52,6 +74,7 @@ public class DBTestUtils {
feeds.add(f);
}
adapter.close();
+
return feeds;
}
}
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
index 4678a843b..ec8e19e22 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -4,10 +4,13 @@ import android.content.Context;
import android.database.Cursor;
import android.test.InstrumentationTestCase;
import android.util.Log;
+
+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.SimpleChapter;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
@@ -101,7 +104,7 @@ public class DBWriterTest extends InstrumentationTestCase {
List<File> itemFiles = new ArrayList<File>();
// create items with downloaded media files
for (int i = 0; i < 10; i++) {
- FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), true, feed);
+ FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), true, feed, true);
feed.getItems().add(item);
File enc = new File(destFolder, "file " + i);
@@ -110,6 +113,9 @@ public class DBWriterTest extends InstrumentationTestCase {
FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null, 0);
item.setMedia(media);
+
+ item.setChapters(new ArrayList<Chapter>());
+ item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com"));
}
PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext());
@@ -122,6 +128,7 @@ public class DBWriterTest extends InstrumentationTestCase {
for (FeedItem item : feed.getItems()) {
assertTrue(item.getId() != 0);
assertTrue(item.getMedia().getId() != 0);
+ assertTrue(item.getChapters().get(0).getId() != 0);
}
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
@@ -135,18 +142,20 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter = new PodDBAdapter(getInstrumentation().getContext());
adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId());
- assertTrue(c.getCount() == 0);
+ assertEquals(0, c.getCount());
c.close();
c = adapter.getImageCursor(image.getId());
- assertTrue(c.getCount() == 0);
+ assertEquals(0, c.getCount());
c.close();
for (FeedItem item : feed.getItems()) {
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
- assertTrue(c.getCount() == 0);
+ assertEquals(0, c.getCount());
c.close();
c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
- assertTrue(c.getCount() == 0);
+ assertEquals(0, c.getCount());
c.close();
+ c = adapter.getSimpleChaptersOfFeedItemCursor(item);
+ assertEquals(0, c.getCount());
}
}
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 d056917e1..42e4191f6 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
@@ -44,12 +44,45 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
private boolean read;
private String paymentLink;
private FlattrStatus flattrStatus;
+
+ /**
+ * Is true if the database contains any chapters that belong to this item. This attribute is only
+ * written once by DBReader on initialization.
+ * The FeedItem might still have a non-null chapters value. In this case, the list of chapters
+ * has not been saved in the database yet.
+ * */
+ private final boolean hasChapters;
+
+ /**
+ * The list of chapters of this item. This might be null even if there are chapters of this item
+ * in the database. The 'hasChapters' attribute should be used to check if this item has any chapters.
+ * */
private List<Chapter> chapters;
private FeedImage image;
public FeedItem() {
this.read = true;
this.flattrStatus = new FlattrStatus();
+ this.hasChapters = false;
+ }
+
+ /**
+ * 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, boolean read,
+ String itemIdentifier) {
+ this.id = id;
+ this.title = title;
+ this.link = link;
+ this.pubDate = pubDate;
+ this.paymentLink = paymentLink;
+ this.feedId = feedId;
+ this.flattrStatus = flattrStatus;
+ this.hasChapters = hasChapters;
+ this.image = image;
+ this.read = read;
+ this.itemIdentifier = itemIdentifier;
}
/**
@@ -64,6 +97,22 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
this.read = read;
this.feed = feed;
this.flattrStatus = new FlattrStatus();
+ this.hasChapters = false;
+ }
+
+ /**
+ * This constructor should be used for creating test objects involving chapter marks.
+ */
+ public FeedItem(long id, String title, String itemIdentifier, String link, Date pubDate, boolean read, Feed feed, boolean hasChapters) {
+ this.id = id;
+ this.title = title;
+ this.itemIdentifier = itemIdentifier;
+ this.link = link;
+ this.pubDate = (pubDate != null) ? (Date) pubDate.clone() : null;
+ this.read = read;
+ this.feed = feed;
+ this.flattrStatus = new FlattrStatus();
+ this.hasChapters = hasChapters;
}
public void updateFromOther(FeedItem other) {
@@ -331,4 +380,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
public String getHumanReadableIdentifier() {
return title;
}
+
+ public boolean hasChapters() {
+ return hasChapters;
+ }
}
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 defcfd598..2434ee0cf 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
@@ -245,14 +245,19 @@ public class FeedMedia extends FeedFile implements Playable {
@Override
public void loadChapterMarks() {
- if (getChapters() == null && !localFileAvailable()) {
+ if (item == null && itemID != 0) {
+ item = DBReader.getFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), itemID);
+ }
+ // check if chapters are stored in db and not loaded yet.
+ if (item != null && item.hasChapters() && item.getChapters() == null) {
+ DBReader.loadChaptersOfFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), item);
+ } else if (item != null && item.getChapters() == null && !localFileAvailable()) {
ChapterUtils.loadChaptersFromStreamUrl(this);
if (getChapters() != null && item != null) {
DBWriter.setFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(),
item);
}
}
-
}
@Override
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 6c0b6df74..217e6fba5 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
@@ -4,8 +4,22 @@ import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
import de.danoeh.antennapod.core.BuildConfig;
-import de.danoeh.antennapod.core.feed.*;
+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;
+import de.danoeh.antennapod.core.feed.ID3Chapter;
+import de.danoeh.antennapod.core.feed.SimpleChapter;
+import de.danoeh.antennapod.core.feed.VorbisCommentChapter;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
import de.danoeh.antennapod.core.util.DownloadError;
import de.danoeh.antennapod.core.util.comparator.DownloadStatusComparator;
@@ -14,11 +28,6 @@ import de.danoeh.antennapod.core.util.comparator.PlaybackCompletionDateComparato
import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrThing;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
/**
* Provides methods for reading data from the AntennaPod database.
* In general, all database calls in DBReader-methods are executed on the caller's thread.
@@ -203,75 +212,26 @@ public final class DBReader {
if (itemlistCursor.moveToFirst()) {
do {
- FeedItem item = new FeedItem();
-
- item.setId(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_ID));
- item.setTitle(itemlistCursor
- .getString(PodDBAdapter.IDX_FI_SMALL_TITLE));
- item.setLink(itemlistCursor
- .getString(PodDBAdapter.IDX_FI_SMALL_LINK));
- item.setPubDate(new Date(itemlistCursor
- .getLong(PodDBAdapter.IDX_FI_SMALL_PUBDATE)));
- item.setPaymentLink(itemlistCursor
- .getString(PodDBAdapter.IDX_FI_SMALL_PAYMENT_LINK));
- item.setFeedId(itemlistCursor
- .getLong(PodDBAdapter.IDX_FI_SMALL_FEED));
- itemIds.add(String.valueOf(item.getId()));
-
- item.setRead((itemlistCursor
- .getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0));
- item.setItemIdentifier(itemlistCursor
- .getString(PodDBAdapter.IDX_FI_SMALL_ITEM_IDENTIFIER));
- item.setFlattrStatus(new FlattrStatus(itemlistCursor
- .getLong(PodDBAdapter.IDX_FI_SMALL_FLATTR_STATUS)));
-
long imageIndex = itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_IMAGE);
+ FeedImage image = null;
if (imageIndex != 0) {
- item.setImage(getFeedImage(adapter, imageIndex));
+ image = getFeedImage(adapter, imageIndex);
}
- // extract chapters
- boolean hasSimpleChapters = itemlistCursor
- .getInt(PodDBAdapter.IDX_FI_SMALL_HAS_CHAPTERS) > 0;
- if (hasSimpleChapters) {
- Cursor chapterCursor = adapter
- .getSimpleChaptersOfFeedItemCursor(item);
- if (chapterCursor.moveToFirst()) {
- item.setChapters(new ArrayList<Chapter>());
- do {
- int chapterType = chapterCursor
- .getInt(PodDBAdapter.KEY_CHAPTER_TYPE_INDEX);
- Chapter chapter = null;
- long start = chapterCursor
- .getLong(PodDBAdapter.KEY_CHAPTER_START_INDEX);
- String title = chapterCursor
- .getString(PodDBAdapter.KEY_TITLE_INDEX);
- String link = chapterCursor
- .getString(PodDBAdapter.KEY_CHAPTER_LINK_INDEX);
-
- switch (chapterType) {
- case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER:
- chapter = new SimpleChapter(start, title, item,
- link);
- break;
- case ID3Chapter.CHAPTERTYPE_ID3CHAPTER:
- chapter = new ID3Chapter(start, title, item,
- link);
- break;
- case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER:
- chapter = new VorbisCommentChapter(start,
- title, item, link);
- break;
- }
- if (chapter != null) {
- chapter.setId(chapterCursor
- .getLong(PodDBAdapter.KEY_ID_INDEX));
- item.getChapters().add(chapter);
- }
- } while (chapterCursor.moveToNext());
- }
- chapterCursor.close();
- }
+ FeedItem item = new FeedItem(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_ID),
+ itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_TITLE),
+ itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_LINK),
+ new Date(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_PUBDATE)),
+ itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_PAYMENT_LINK),
+ itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_FEED),
+ new FlattrStatus(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_FLATTR_STATUS)),
+ itemlistCursor.getInt(PodDBAdapter.IDX_FI_SMALL_HAS_CHAPTERS) > 0,
+ image,
+ (itemlistCursor.getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0),
+ itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_ITEM_IDENTIFIER));
+
+ itemIds.add(String.valueOf(item.getId()));
+
items.add(item);
} while (itemlistCursor.moveToNext());
}
@@ -367,6 +327,7 @@ public final class DBReader {
return feed;
}
+
private static FeedItem getMatchingItemForMedia(long itemId,
List<FeedItem> items) {
for (FeedItem item : items) {
@@ -689,6 +650,9 @@ public final class DBReader {
if (list.size() > 0) {
item = list.get(0);
loadFeedDataOfFeedItemlist(context, list);
+ if (item.hasChapters()) {
+ loadChaptersOfFeedItem(adapter, item);
+ }
}
}
return item;
@@ -696,12 +660,13 @@ public final class DBReader {
}
/**
- * Loads a specific FeedItem from the database.
+ * Loads a specific FeedItem from the database. This method should not be used for loading more
+ * than one FeedItem because this method might query the database several times for each item.
*
* @param context A context that is used for opening a database connection.
* @param itemId The ID of the FeedItem
- * @return The FeedItem or null if the FeedItem could not be found. All FeedComponent-attributes of the FeedItem will
- * also be loaded from the database.
+ * @return The FeedItem or null if the FeedItem could not be found. All FeedComponent-attributes
+ * as well as chapter marks of the FeedItem will also be loaded from the database.
*/
public static FeedItem getFeedItem(final Context context, final long itemId) {
if (BuildConfig.DEBUG)
@@ -737,6 +702,63 @@ public final class DBReader {
}
/**
+ * Loads the list of chapters that belongs to this FeedItem if available. This method overwrites
+ * any chapters that this FeedItem has. If no chapters were found in the database, the chapters
+ * reference of the FeedItem will be set to null.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param item The FeedItem
+ */
+ public static void loadChaptersOfFeedItem(final Context context, final FeedItem item) {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ loadChaptersOfFeedItem(adapter, item);
+ adapter.close();
+ }
+
+ static void loadChaptersOfFeedItem(PodDBAdapter adapter, FeedItem item) {
+ Cursor chapterCursor = adapter
+ .getSimpleChaptersOfFeedItemCursor(item);
+ if (chapterCursor.moveToFirst()) {
+ item.setChapters(new ArrayList<Chapter>());
+ do {
+ int chapterType = chapterCursor
+ .getInt(PodDBAdapter.KEY_CHAPTER_TYPE_INDEX);
+ Chapter chapter = null;
+ long start = chapterCursor
+ .getLong(PodDBAdapter.KEY_CHAPTER_START_INDEX);
+ String title = chapterCursor
+ .getString(PodDBAdapter.KEY_TITLE_INDEX);
+ String link = chapterCursor
+ .getString(PodDBAdapter.KEY_CHAPTER_LINK_INDEX);
+
+ switch (chapterType) {
+ case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER:
+ chapter = new SimpleChapter(start, title, item,
+ link);
+ break;
+ case ID3Chapter.CHAPTERTYPE_ID3CHAPTER:
+ chapter = new ID3Chapter(start, title, item,
+ link);
+ break;
+ case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER:
+ chapter = new VorbisCommentChapter(start,
+ title, item, link);
+ break;
+ }
+ if (chapter != null) {
+ chapter.setId(chapterCursor
+ .getLong(PodDBAdapter.KEY_ID_INDEX));
+ item.getChapters().add(chapter);
+ }
+ } while (chapterCursor.moveToNext());
+ } else {
+ item.setChapters(null);
+ }
+ chapterCursor.close();
+ }
+
+ /**
* Returns the number of downloaded episodes.
*
* @param context A context that is used for opening a database connection.
@@ -788,7 +810,7 @@ public final class DBReader {
static FeedImage getFeedImage(PodDBAdapter adapter, final long id) {
Cursor cursor = adapter.getImageCursor(id);
if ((cursor.getCount() == 0) || !cursor.moveToFirst()) {
- throw new SQLException("No FeedImage found at index: " + id);
+ return null;
}
FeedImage image = new FeedImage(id, cursor.getString(cursor
.getColumnIndex(PodDBAdapter.KEY_TITLE)),
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 79124521f..ce41147e1 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
@@ -693,7 +693,7 @@ public class PodDBAdapter {
}
values.put(KEY_FEED, item.getFeed().getId());
values.put(KEY_READ, item.isRead());
- values.put(KEY_HAS_CHAPTERS, item.getChapters() != null);
+ values.put(KEY_HAS_CHAPTERS, item.getChapters() != null || item.hasChapters());
values.put(KEY_ITEM_IDENTIFIER, item.getItemIdentifier());
values.put(KEY_FLATTR_STATUS, item.getFlattrStatus().toLong());
if (item.hasItemImage()) {
@@ -848,7 +848,7 @@ public class PodDBAdapter {
if (item.getMedia() != null) {
removeFeedMedia(item.getMedia());
}
- if (item.getChapters() != null) {
+ if (item.hasChapters() || item.getChapters() != null) {
removeChaptersOfItem(item);
}
if (item.hasItemImage()) {