diff --git a/.classpath b/.classpath
index 3f9691c5d..3a0c88fe4 100644
--- a/.classpath
+++ b/.classpath
@@ -4,5 +4,6 @@
+
diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java
index 97c52d749..739ecd4be 100644
--- a/src/de/danoeh/antennapod/storage/DBReader.java
+++ b/src/de/danoeh/antennapod/storage/DBReader.java
@@ -290,6 +290,21 @@ public final class DBReader {
return items;
}
+
+ public static long[] getUnreadItemIds(Context context) {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor cursor = adapter.getUnreadItemIdsCursor();
+ long[] itemIds = new long[cursor.getCount()];
+ int i = 0;
+ if (cursor.moveToFirst()) {
+ do {
+ itemIds[i] = cursor.getLong(PodDBAdapter.KEY_ID_INDEX);
+ i++;
+ } while (cursor.moveToNext());
+ }
+ return itemIds;
+ }
public static List getPlaybackHistory(final Context context) {
if (AppConfig.DEBUG)
diff --git a/src/de/danoeh/antennapod/storage/DBTasks.java b/src/de/danoeh/antennapod/storage/DBTasks.java
index 75477d463..d71a5498b 100644
--- a/src/de/danoeh/antennapod/storage/DBTasks.java
+++ b/src/de/danoeh/antennapod/storage/DBTasks.java
@@ -1,29 +1,58 @@
package de.danoeh.antennapod.storage;
+import java.util.Iterator;
+import java.util.List;
+
import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedItem;
+import de.danoeh.antennapod.feed.FeedMedia;
+import de.danoeh.antennapod.service.PlaybackService;
+import de.danoeh.antennapod.util.exception.MediaFileNotFoundException;
public final class DBTasks {
private static final String TAG = "DBTasks";
-
+
private DBTasks() {
}
- public static void playMedia(final Context context, final long mediaId,
+ public static void playMedia(final Context context, final FeedMedia media,
boolean showPlayer, boolean startWhenPrepared, boolean shouldStream) {
-
- }
-
- public static void markItemRead(final Context context, final long itemId,
- final boolean read, boolean resetMediaPosition) {
- }
-
- public static void markFeedRead(final Context context, final long feedId) {
-
- }
-
- public static void markAllItemsRead(final Context context) {
+ try {
+ if (!shouldStream) {
+ if (media.fileExists() == false) {
+ throw new MediaFileNotFoundException(
+ "No episode was found at " + media.getFile_url(),
+ media);
+ }
+ }
+ // Start playback Service
+ Intent launchIntent = new Intent(context, PlaybackService.class);
+ launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
+ launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
+ startWhenPrepared);
+ launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM,
+ shouldStream);
+ launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
+ true);
+ context.startService(launchIntent);
+ if (showPlayer) {
+ // Launch Mediaplayer
+ context.startActivity(PlaybackService.getPlayerActivityIntent(
+ context, media));
+ }
+ DBWriter.addQueueItemAt(context, media.getItem().getId(), 0, false);
+ } catch (MediaFileNotFoundException e) {
+ e.printStackTrace();
+ if (media.isPlaying()) {
+ context.sendBroadcast(new Intent(
+ PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
+ }
+ notifyMissingFeedMediaFile(context, media);
+ }
}
public static void refreshAllFeeds(final Context context) {
@@ -37,41 +66,137 @@ public final class DBTasks {
}
public static void notifyMissingFeedMediaFile(final Context context,
- final long mediaId) {
+ final FeedMedia media) {
+ }
+
+ public static void downloadAllItemsInQueue(final Context context) {
}
-
- public static void downloadAllItemsInQueue(final Context context) {}
public static void refreshFeed(final Context context, final long feedId) {
}
-
- public static void downloadFeedItem(final Context context, long... itemIds) {}
-
+
+ public static void downloadFeedItem(final Context context, long... itemIds) {
+ }
+
static void downloadFeedItem(boolean performAutoCleanup,
final Context context, final long... itemIds)
- throws DownloadRequestException {}
+ throws DownloadRequestException {
+ }
public static void autodownloadUndownloadedItems(Context context) {
}
-
+
private static int getPerformAutoCleanupArgs(final int episodeNumber) {
return 0;
}
-
- public static void performAutoCleanup(final Context context) {}
-
- private static int performAutoCleanup(final Context context, final int episodeNumber) {
+
+ public static void performAutoCleanup(final Context context) {
+ }
+
+ private static int performAutoCleanup(final Context context,
+ final int episodeNumber) {
return 0;
}
- public static void enqueueAllNewItems(final Context context) {}
+ public static void enqueueAllNewItems(final Context context) {
+ long[] unreadItems = DBReader.getUnreadItemIds(context);
+ DBWriter.addQueueItem(context, unreadItems);
+ }
- public static FeedItem getQueueSuccessorOfItem(final long itemId) {
+ public static FeedItem getQueueSuccessorOfItem(Context context,
+ final long itemId) {
+ FeedItem result = null;
+ List queue = DBReader.getQueue(context);
+ if (queue != null) {
+ Iterator iterator = queue.iterator();
+ while (iterator.hasNext()) {
+ FeedItem item = iterator.next();
+ if (item.getId() == itemId) {
+ if (iterator.hasNext()) {
+ result = iterator.next();
+ }
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ private static Feed searchFeedByIdentifyingValue(Context context,
+ String identifier) {
+ List feeds = DBReader.getFeedList(context);
+ for (Feed feed : feeds) {
+ if (feed.getIdentifyingValue().equals(identifier)) {
+ return feed;
+ }
+ }
return null;
}
- public static Feed updateFeed(final Context context, final long feedId) {
+ /** Get a FeedItem by its identifying value. */
+ private static FeedItem searchFeedItemByIdentifyingValue(Feed feed,
+ String identifier) {
+ for (FeedItem item : feed.getItems()) {
+ if (item.getIdentifyingValue().equals(identifier)) {
+ return item;
+ }
+ }
return null;
}
+
+ public static synchronized Feed updateFeed(final Context context, final Feed newFeed) {
+ // Look up feed in the feedslist
+ final Feed savedFeed = searchFeedByIdentifyingValue(context,
+ newFeed.getIdentifyingValue());
+ if (savedFeed == null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "Found no existing Feed with title "
+ + newFeed.getTitle() + ". Adding as new one.");
+ // Add a new Feed
+ DBWriter.addNewFeed(context, newFeed);
+ return newFeed;
+ } else {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Feed with title " + newFeed.getTitle()
+ + " already exists. Syncing new with existing one.");
+
+ savedFeed.setItems(DBReader.getFeedItemList(context, savedFeed));
+ if (savedFeed.compareWithOther(newFeed)) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "Feed has updated attribute values. Updating old feed's attributes");
+ savedFeed.updateFromOther(newFeed);
+ }
+ // Look for new or updated Items
+ for (int idx = 0; idx < newFeed.getItems().size(); idx++) {
+ final FeedItem item = newFeed.getItems().get(idx);
+ FeedItem oldItem = searchFeedItemByIdentifyingValue(savedFeed,
+ item.getIdentifyingValue());
+ if (oldItem == null) {
+ // item is new
+ final int i = idx;
+ item.setFeed(savedFeed);
+ savedFeed.getItems().add(i, item);
+ DBWriter.markItemRead(context, item.getId(), false);
+ } else {
+ oldItem.updateFromOther(item);
+ }
+ }
+ // update attributes
+ savedFeed.setLastUpdate(newFeed.getLastUpdate());
+ savedFeed.setType(newFeed.getType());
+ DBWriter.setCompleteFeed(context, savedFeed);
+ new Thread() {
+ @Override
+ public void run() {
+ autodownloadUndownloadedItems(context);
+ }
+ }.start();
+ return savedFeed;
+ }
+
+ }
+
}
diff --git a/src/de/danoeh/antennapod/storage/DBWriter.java b/src/de/danoeh/antennapod/storage/DBWriter.java
index 996c3e028..aece811ca 100644
--- a/src/de/danoeh/antennapod/storage/DBWriter.java
+++ b/src/de/danoeh/antennapod/storage/DBWriter.java
@@ -10,6 +10,7 @@ import java.util.concurrent.ThreadFactory;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.database.Cursor;
import android.preference.PreferenceManager;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
@@ -406,7 +407,76 @@ public class DBWriter {
});
}
- void addNewFeed(final Context context, final Feed feed) {
+ public static void markItemRead(final Context context, final long itemId,
+ final boolean read) {
+ markItemRead(context, itemId, read, 0, false);
+ }
+
+ public static void markItemRead(final Context context, final long itemId,
+ final boolean read, final long mediaId,
+ final boolean resetMediaPosition) {
+ dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setFeedItemRead(read, itemId, mediaId,
+ resetMediaPosition);
+ adapter.close();
+
+ EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
+ }
+ });
+ }
+
+ public static void markFeedRead(final Context context, final long feedId) {
+ dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor itemCursor = adapter.getAllItemsOfFeedCursor(feedId);
+ long[] itemIds = new long[itemCursor.getCount()];
+ itemCursor.moveToFirst();
+ for (int i = 0; i < itemIds.length; i++) {
+ itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX);
+ }
+ itemCursor.close();
+ adapter.setFeedItemRead(true, itemIds);
+ adapter.close();
+
+ EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
+ }
+ });
+
+ }
+
+ public static void markAllItemsRead(final Context context) {
+ dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor itemCursor = adapter.getUnreadItemsCursor();
+ long[] itemIds = new long[itemCursor.getCount()];
+ itemCursor.moveToFirst();
+ for (int i = 0; i < itemIds.length; i++) {
+ itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX);
+ }
+ itemCursor.close();
+ adapter.setFeedItemRead(true, itemIds);
+ adapter.close();
+
+ EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
+ }
+ });
+
+ }
+
+ static void addNewFeed(final Context context, final Feed feed) {
dbExec.submit(new Runnable() {
@Override
@@ -420,13 +490,34 @@ public class DBWriter {
}
});
}
+
+ static void setCompleteFeed(final Context context, final Feed feed) {
+ dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ EventDistributor.getInstance().sendFeedUpdateBroadcast();
+ }});
+
+ }
private static void setFeedMedia(final Context context,
final FeedMedia media) {
- PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- adapter.setMedia(media);
- adapter.close();
+ dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setMedia(media);
+ adapter.close();
+ }});
+
}
diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java
index ef9b4bfe0..72c96b961 100644
--- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java
+++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java
@@ -340,7 +340,7 @@ public class PodDBAdapter {
db.setTransactionSuccessful();
db.endTransaction();
}
-
+
public void setFeedItemlist(List items) {
db.beginTransaction();
for (FeedItem item : items) {
@@ -400,6 +400,39 @@ public class PodDBAdapter {
return item.getId();
}
+ public void setFeedItemRead(boolean read, long itemId, long mediaId,
+ boolean resetMediaPosition) {
+ db.beginTransaction();
+ ContentValues values = new ContentValues();
+
+ values.put(KEY_READ, read);
+ db.update(TABLE_NAME_FEED_ITEMS, values, "?=?", new String[] { KEY_ID,
+ Long.toString(itemId) });
+
+ if (resetMediaPosition) {
+ values.clear();
+ values.put(KEY_POSITION, 0);
+ db.update(TABLE_NAME_FEED_MEDIA, values, "?=?", new String[] {
+ KEY_ID, Long.toString(mediaId) });
+ }
+
+ db.setTransactionSuccessful();
+ db.endTransaction();
+ }
+
+ public void setFeedItemRead(boolean read, long... itemIds) {
+ db.beginTransaction();
+ ContentValues values = new ContentValues();
+ for (long id : itemIds) {
+ values.clear();
+ values.put(KEY_READ, read);
+ db.update(TABLE_NAME_FEED_ITEMS, values, "?=?", new String[] {
+ KEY_ID, Long.toString(id) });
+ }
+ db.setTransactionSuccessful();
+ db.endTransaction();
+ }
+
public void setChapters(FeedItem item) {
ContentValues values = new ContentValues();
for (Chapter chapter : item.getChapters()) {
@@ -479,7 +512,7 @@ public class PodDBAdapter {
db.setTransactionSuccessful();
db.endTransaction();
}
-
+
public void clearQueue() {
db.delete(TABLE_NAME_QUEUE, null, null);
}
@@ -557,10 +590,14 @@ public class PodDBAdapter {
* @return The cursor of the query
* */
public final Cursor getAllItemsOfFeedCursor(final Feed feed) {
+ return getAllItemsOfFeedCursor(feed.getId());
+ }
+
+ public final Cursor getAllItemsOfFeedCursor(final long feedId) {
open();
Cursor c = db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED
- + "=?", new String[] { String.valueOf(feed.getId()) }, null,
- null, null);
+ + "=?", new String[] { String.valueOf(feedId) }, null, null,
+ null);
return c;
}
@@ -642,6 +679,14 @@ public class PodDBAdapter {
+ "=0", null, null, null, KEY_PUBDATE + " DESC");
return c;
}
+
+ public final Cursor getUnreadItemIdsCursor() {
+ open();
+ Cursor c = db.query(TABLE_NAME_FEED_ITEMS, new String[]{KEY_ID}, KEY_READ
+ + "=0", null, null, null, KEY_PUBDATE + " DESC");
+ return c;
+
+ }
/**
* Returns a cursor which contains feed media objects with a playback