summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2013-08-09 21:51:13 +0200
committerdaniel oeh <daniel.oeh@gmail.com>2013-08-09 21:51:13 +0200
commitfa155f833b43e0a484c4b8cb227b61c7ce97942c (patch)
tree4ab584bf5167a695611b557b718dd02b6dfe3c8e
parentce9f87ff3eb4ffcaf3c8174b97baac967026e1fa (diff)
downloadAntennaPod-fa155f833b43e0a484c4b8cb227b61c7ce97942c.zip
Added documentation to DBWriter
-rw-r--r--src/de/danoeh/antennapod/service/PlaybackService.java3
-rw-r--r--src/de/danoeh/antennapod/storage/DBReader.java2
-rw-r--r--src/de/danoeh/antennapod/storage/DBWriter.java1142
-rw-r--r--src/de/danoeh/antennapod/storage/PodDBAdapter.java4
4 files changed, 647 insertions, 504 deletions
diff --git a/src/de/danoeh/antennapod/service/PlaybackService.java b/src/de/danoeh/antennapod/service/PlaybackService.java
index a173dfdfb..63a4d0471 100644
--- a/src/de/danoeh/antennapod/service/PlaybackService.java
+++ b/src/de/danoeh/antennapod/service/PlaybackService.java
@@ -775,7 +775,6 @@ public class PlaybackService extends Service {
if (media instanceof FeedMedia) {
FeedItem item = ((FeedMedia) media).getItem();
- ((FeedMedia) media).setPlaybackCompletionDate(new Date());
DBWriter.markItemRead(PlaybackService.this, item, true, true);
nextItem = DBTasks.getQueueSuccessorOfItem(this, item.getId(), queue);
isInQueue = media instanceof FeedMedia
@@ -783,7 +782,7 @@ public class PlaybackService extends Service {
if (isInQueue) {
DBWriter.removeQueueItem(PlaybackService.this, item.getId(), true);
}
- DBWriter.addItemToPlaybackHistory(PlaybackService.this, item);
+ DBWriter.addItemToPlaybackHistory(PlaybackService.this, (FeedMedia) media);
DBWriter.setFeedMedia(PlaybackService.this, (FeedMedia) media);
long autoDeleteMediaId = ((FeedComponent) media).getId();
if (shouldStream) {
diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java
index 71d11f13b..b1ebbc45d 100644
--- a/src/de/danoeh/antennapod/storage/DBReader.java
+++ b/src/de/danoeh/antennapod/storage/DBReader.java
@@ -27,6 +27,8 @@ import de.danoeh.antennapod.util.comparator.FeedItemPubdateComparator;
* Provides methods for reading data from the AntennaPod database.
* In general, all database calls in DBReader-methods are executed on the caller's thread.
* This means that the caller should make sure that DBReader-methods are not executed on the GUI-thread.
+ * This class will use the {@link de.danoeh.antennapod.feed.EventDistributor} to notify listeners about changes in the database.
+
*/
public final class DBReader {
private static final String TAG = "DBReader";
diff --git a/src/de/danoeh/antennapod/storage/DBWriter.java b/src/de/danoeh/antennapod/storage/DBWriter.java
index 3db0b8a33..4ad9e9e1f 100644
--- a/src/de/danoeh/antennapod/storage/DBWriter.java
+++ b/src/de/danoeh/antennapod/storage/DBWriter.java
@@ -1,7 +1,7 @@
package de.danoeh.antennapod.storage;
import java.io.File;
-import java.util.Collections;
+import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
@@ -22,517 +22,645 @@ import de.danoeh.antennapod.service.PlaybackService;
import de.danoeh.antennapod.service.download.DownloadStatus;
import de.danoeh.antennapod.util.QueueAccess;
+/**
+ * Provides methods for writing data to AntennaPod's database.
+ * In general, DBWriter-methods will be executed on an internal ExecutorService.
+ * Some methods return a Future-object which the caller can use for waiting for the method's completion. The returned Future's
+ * will NOT contain any results.
+ * The caller can also use the {@link EventDistributor} in order to be notified about the method's completion asynchronously.
+ * This class will use the {@link EventDistributor} to notify listeners about changes in the database.
+ */
public class DBWriter {
- private static final String TAG = "DBWriter";
-
- private static final ExecutorService dbExec;
- static {
- dbExec = Executors.newSingleThreadExecutor(new ThreadFactory() {
-
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setPriority(Thread.MIN_PRIORITY);
- return t;
- }
- });
- }
-
- private DBWriter() {
- }
-
- public static void deleteFeedMediaOfItem(final Context context,
- final long itemId) {
- dbExec.submit(new Runnable() {
- @Override
- public void run() {
- final FeedItem item = DBReader.getFeedItem(context, itemId);
- if (item != null && item.hasMedia()) {
- final FeedMedia media = item.getMedia();
- boolean result = false;
- if (media.isDownloaded()) {
- // delete downloaded media file
- File mediaFile = new File(media.getFile_url());
- if (mediaFile.exists()) {
- result = mediaFile.delete();
- }
- media.setDownloaded(false);
- media.setFile_url(null);
- setFeedMedia(context, media);
-
- // If media is currently being played, change playback
- // type to 'stream' and shutdown playback service
- SharedPreferences prefs = PreferenceManager
- .getDefaultSharedPreferences(context);
- if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA) {
- if (media.getId() == PlaybackPreferences
- .getCurrentlyPlayingFeedMediaId()) {
- SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean(
- PlaybackPreferences.PREF_CURRENT_EPISODE_IS_STREAM,
- true);
- editor.commit();
- }
- if (PlaybackPreferences
- .getCurrentlyPlayingFeedMediaId() == media
- .getId()) {
- context.sendBroadcast(new Intent(
- PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
- }
- }
- }
- if (AppConfig.DEBUG)
- Log.d(TAG, "Deleting File. Result: " + result);
- }
- }
- });
- }
-
- public static Future<?> deleteFeed(final Context context, final long feedId) {
- return dbExec.submit(new Runnable() {
- @Override
- public void run() {
- DownloadRequester requester = DownloadRequester.getInstance();
- SharedPreferences prefs = PreferenceManager
- .getDefaultSharedPreferences(context
- .getApplicationContext());
- final Feed feed = DBReader.getFeed(context, feedId);
- if (feed != null) {
- if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA
- && PlaybackPreferences.getLastPlayedFeedId() == feed
- .getId()) {
- context.sendBroadcast(new Intent(
- PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
- SharedPreferences.Editor editor = prefs.edit();
- editor.putLong(
- PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID,
- -1);
- editor.commit();
- }
-
- PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- // delete image file
- if (feed.getImage() != null) {
- if (feed.getImage().isDownloaded()
- && feed.getImage().getFile_url() != null) {
- File imageFile = new File(feed.getImage()
- .getFile_url());
- imageFile.delete();
- } else if (requester.isDownloadingFile(feed.getImage())) {
- requester.cancelDownload(context, feed.getImage());
- }
- }
- // delete stored media files and mark them as read
- List<FeedItem> queue = DBReader.getQueue(context);
- boolean queueWasModified = false;
- if (feed.getItems() == null) {
- DBReader.getFeedItemList(context, feed);
- }
-
- for (FeedItem item : feed.getItems()) {
- queueWasModified |= queue.remove(item);
- if (item.getMedia() != null
- && item.getMedia().isDownloaded()) {
- File mediaFile = new File(item.getMedia()
- .getFile_url());
- mediaFile.delete();
- } else if (item.getMedia() != null
- && requester.isDownloadingFile(item.getMedia())) {
- requester.cancelDownload(context, item.getMedia());
- }
- }
- if (queueWasModified) {
- adapter.setQueue(queue);
- }
- adapter.removeFeed(feed);
- adapter.close();
- EventDistributor.getInstance().sendFeedUpdateBroadcast();
- }
- }
- });
- }
-
- public static void clearPlaybackHistory(final Context context) {
- dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- adapter.clearPlaybackHistory();
- adapter.close();
- EventDistributor.getInstance()
- .sendPlaybackHistoryUpdateBroadcast();
- }
- });
- }
-
- public static void addItemToPlaybackHistory(final Context context,
- final FeedItem item) {
- if (item.hasMedia()
- && item.getMedia().getPlaybackCompletionDate() != null) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Adding new item to playback history");
- EventDistributor.getInstance().sendPlaybackHistoryUpdateBroadcast();
- }
-
- }
-
- private static void cleanupDownloadLog(final PodDBAdapter adapter) {
- final int DOWNLOAD_LOG_SIZE = 50;
- final long logSize = adapter.getDownloadLogSize();
- if (logSize > DOWNLOAD_LOG_SIZE) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Cleaning up download log");
- adapter.removeDownloadLogItems(logSize - DOWNLOAD_LOG_SIZE);
- }
- }
-
- public static void addDownloadStatus(final Context context,
- final DownloadStatus status) {
- dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
-
- PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
-
- adapter.setDownloadStatus(status);
- cleanupDownloadLog(adapter);
- adapter.close();
- EventDistributor.getInstance().sendDownloadLogUpdateBroadcast();
- }
- });
-
- }
-
- public static void addQueueItemAt(final Context context, final long itemId,
- final int index, final boolean performAutoDownload) {
- dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- final PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- final List<FeedItem> queue = DBReader
- .getQueue(context, adapter);
- FeedItem item = null;
-
- if (queue != null) {
- boolean queueModified = false;
- boolean unreadItemsModfied = false;
-
- if (!itemListContains(queue, itemId)) {
- item = DBReader.getFeedItem(context, itemId);
- if (item != null) {
- queue.add(index, item);
- queueModified = true;
- if (!item.isRead()) {
- item.setRead(true);
- unreadItemsModfied = true;
- }
- }
- }
- if (queueModified) {
- adapter.setQueue(queue);
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
- }
- if (unreadItemsModfied && item != null) {
- adapter.setSingleFeedItem(item);
- EventDistributor.getInstance()
- .sendUnreadItemsUpdateBroadcast();
- }
- }
- adapter.close();
- if (performAutoDownload) {
-
- new Thread() {
- @Override
- public void run() {
- DBTasks.autodownloadUndownloadedItems(context);
-
- }
- }.start();
- }
-
- }
- });
-
- }
-
- public static void addQueueItem(final Context context,
- final long... itemIds) {
- if (itemIds.length > 0) {
- dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- final PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- final List<FeedItem> queue = DBReader.getQueue(context,
- adapter);
-
- if (queue != null) {
- boolean queueModified = false;
- boolean unreadItemsModfied = false;
- List<FeedItem> itemsToSave = new LinkedList<FeedItem>();
- for (int i = 0; i < itemIds.length; i++) {
- if (!itemListContains(queue, itemIds[i])) {
- final FeedItem item = DBReader.getFeedItem(
- context, itemIds[i]);
-
- if (item != null) {
- queue.add(item);
- queueModified = true;
- if (!item.isRead()) {
- item.setRead(true);
- itemsToSave.add(item);
- unreadItemsModfied = true;
- }
- }
- }
- }
- if (queueModified) {
- adapter.setQueue(queue);
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
- }
- if (unreadItemsModfied) {
- adapter.setFeedItemlist(itemsToSave);
- EventDistributor.getInstance()
- .sendUnreadItemsUpdateBroadcast();
- }
- }
- adapter.close();
- new Thread() {
- @Override
- public void run() {
- DBTasks.autodownloadUndownloadedItems(context);
-
- }
- }.start();
- }
- });
- }
- }
-
- public static void clearQueue(final Context context) {
- dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- adapter.clearQueue();
- adapter.close();
-
- EventDistributor.getInstance().sendQueueUpdateBroadcast();
- }
- });
- }
-
- public static void removeQueueItem(final Context context,
- final long itemId, final boolean performAutoDownload) {
- dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- final PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- final List<FeedItem> queue = DBReader
- .getQueue(context, adapter);
- FeedItem item = null;
-
- if (queue != null) {
- boolean queueModified = false;
+ private static final String TAG = "DBWriter";
+
+ private static final ExecutorService dbExec;
+
+ static {
+ dbExec = Executors.newSingleThreadExecutor(new ThreadFactory() {
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setPriority(Thread.MIN_PRIORITY);
+ return t;
+ }
+ });
+ }
+
+ private DBWriter() {
+ }
+
+ /**
+ * Deletes a downloaded FeedMedia file from the storage device.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param mediaId ID of the FeedMedia object whose downloaded file should be deleted.
+ */
+ public static Future<?> deleteFeedMediaOfItem(final Context context,
+ final long mediaId) {
+ return dbExec.submit(new Runnable() {
+ @Override
+ public void run() {
+
+ final FeedMedia media = DBReader.getFeedMedia(context, mediaId);
+ if (media != null) {
+ boolean result = false;
+ if (media.isDownloaded()) {
+ // delete downloaded media file
+ File mediaFile = new File(media.getFile_url());
+ if (mediaFile.exists()) {
+ result = mediaFile.delete();
+ }
+ media.setDownloaded(false);
+ media.setFile_url(null);
+ setFeedMedia(context, media);
+
+ // If media is currently being played, change playback
+ // type to 'stream' and shutdown playback service
+ SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(context);
+ if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA) {
+ if (media.getId() == PlaybackPreferences
+ .getCurrentlyPlayingFeedMediaId()) {
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putBoolean(
+ PlaybackPreferences.PREF_CURRENT_EPISODE_IS_STREAM,
+ true);
+ editor.commit();
+ }
+ if (PlaybackPreferences
+ .getCurrentlyPlayingFeedMediaId() == media
+ .getId()) {
+ context.sendBroadcast(new Intent(
+ PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
+ }
+ }
+ }
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Deleting File. Result: " + result);
+ }
+ }
+ });
+ }
+
+ /**
+ * Deletes a Feed and all downloaded files of its components like images and downloaded episodes.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param feedId ID of the Feed that should be deleted.
+ */
+ public static Future<?> deleteFeed(final Context context, final long feedId) {
+ return dbExec.submit(new Runnable() {
+ @Override
+ public void run() {
+ DownloadRequester requester = DownloadRequester.getInstance();
+ SharedPreferences prefs = PreferenceManager
+ .getDefaultSharedPreferences(context
+ .getApplicationContext());
+ final Feed feed = DBReader.getFeed(context, feedId);
+ if (feed != null) {
+ if (PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA
+ && PlaybackPreferences.getLastPlayedFeedId() == feed
+ .getId()) {
+ context.sendBroadcast(new Intent(
+ PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putLong(
+ PlaybackPreferences.PREF_CURRENTLY_PLAYING_FEED_ID,
+ -1);
+ editor.commit();
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ // delete image file
+ if (feed.getImage() != null) {
+ if (feed.getImage().isDownloaded()
+ && feed.getImage().getFile_url() != null) {
+ File imageFile = new File(feed.getImage()
+ .getFile_url());
+ imageFile.delete();
+ } else if (requester.isDownloadingFile(feed.getImage())) {
+ requester.cancelDownload(context, feed.getImage());
+ }
+ }
+ // delete stored media files and mark them as read
+ List<FeedItem> queue = DBReader.getQueue(context);
+ boolean queueWasModified = false;
+ if (feed.getItems() == null) {
+ DBReader.getFeedItemList(context, feed);
+ }
+
+ for (FeedItem item : feed.getItems()) {
+ queueWasModified |= queue.remove(item);
+ if (item.getMedia() != null
+ && item.getMedia().isDownloaded()) {
+ File mediaFile = new File(item.getMedia()
+ .getFile_url());
+ mediaFile.delete();
+ } else if (item.getMedia() != null
+ && requester.isDownloadingFile(item.getMedia())) {
+ requester.cancelDownload(context, item.getMedia());
+ }
+ }
+ if (queueWasModified) {
+ adapter.setQueue(queue);
+ }
+ adapter.removeFeed(feed);
+ adapter.close();
+ EventDistributor.getInstance().sendFeedUpdateBroadcast();
+ }
+ }
+ });
+ }
+
+ /**
+ * Deletes the entire playback history.
+ *
+ * @param context A context that is used for opening a database connection.
+ */
+ public static Future<?> clearPlaybackHistory(final Context context) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.clearPlaybackHistory();
+ adapter.close();
+ EventDistributor.getInstance()
+ .sendPlaybackHistoryUpdateBroadcast();
+ }
+ });
+ }
+
+ /**
+ * Adds a FeedMedia object to the playback history. A FeedMedia object is in the playback history if
+ * its playback completion date is set to a non-null value. This method will set the playback completion date to the
+ * current date regardless of the current value.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param media FeedMedia that should be added to the playback history.
+ */
+ public static Future<?> addItemToPlaybackHistory(final Context context,
+ final FeedMedia media) {
+ return dbExec.submit(new Runnable() {
+ @Override
+ public void run() {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Adding new item to playback history");
+ media.setPlaybackCompletionDate(new Date());
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setMedia(media);
+ adapter.close();
+ EventDistributor.getInstance().sendPlaybackHistoryUpdateBroadcast();
+
+ }
+ });
+ }
+
+ private static void cleanupDownloadLog(final PodDBAdapter adapter) {
+ final long logSize = adapter.getDownloadLogSize();
+ if (logSize > DBReader.DOWNLOAD_LOG_SIZE) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Cleaning up download log");
+ adapter.removeDownloadLogItems(logSize - DBReader.DOWNLOAD_LOG_SIZE);
+ }
+ }
+
+ /**
+ * Adds a Download status object to the download log.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param status The DownloadStatus object.
+ */
+ public static Future<?> addDownloadStatus(final Context context,
+ final DownloadStatus status) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+
+ adapter.setDownloadStatus(status);
+ cleanupDownloadLog(adapter);
+ adapter.close();
+ EventDistributor.getInstance().sendDownloadLogUpdateBroadcast();
+ }
+ });
+
+ }
+
+ /**
+ * Inserts a FeedItem in the queue at the specified index. The 'read'-attribute of the FeedItem will be set to
+ * true. If the FeedItem is already in the queue, the queue will not be modified.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param itemId ID of the FeedItem that should be added to the queue.
+ * @param index Destination index. Must be in range 0..queue.size()
+ * @param performAutoDownload True if an auto-download process should be started after the operation
+ * @throws IndexOutOfBoundsException if index < 0 || index >= queue.size()
+ */
+ public static Future<?> addQueueItemAt(final Context context, final long itemId,
+ final int index, final boolean performAutoDownload) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ final List<FeedItem> queue = DBReader
+ .getQueue(context, adapter);
+ FeedItem item = null;
+
+ if (queue != null) {
+ boolean queueModified = false;
+ boolean unreadItemsModified = false;
+
+ if (!itemListContains(queue, itemId)) {
+ item = DBReader.getFeedItem(context, itemId);
+ if (item != null) {
+ queue.add(index, item);
+ queueModified = true;
+ if (!item.isRead()) {
+ item.setRead(true);
+ unreadItemsModified = true;
+ }
+ }
+ }
+ if (queueModified) {
+ adapter.setQueue(queue);
+ EventDistributor.getInstance()
+ .sendQueueUpdateBroadcast();
+ }
+ if (unreadItemsModified && item != null) {
+ adapter.setSingleFeedItem(item);
+ EventDistributor.getInstance()
+ .sendUnreadItemsUpdateBroadcast();
+ }
+ }
+ adapter.close();
+ if (performAutoDownload) {
+
+ new Thread() {
+ @Override
+ public void run() {
+ DBTasks.autodownloadUndownloadedItems(context);
+
+ }
+ }.start();
+ }
+
+ }
+ });
+
+ }
+
+ /**
+ * Appends FeedItem objects to the end of the queue. The 'read'-attribute of all items will be set to true.
+ * If a FeedItem is already in the queue, the FeedItem will not change its position in the queue.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param itemIds IDs of the FeedItem objects that should be added to the queue.
+ */
+ public static Future<?> addQueueItem(final Context context,
+ final long... itemIds) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ if (itemIds.length > 0) {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ final List<FeedItem> queue = DBReader.getQueue(context,
+ adapter);
+
+ if (queue != null) {
+ boolean queueModified = false;
+ boolean unreadItemsModified = false;
+ List<FeedItem> itemsToSave = new LinkedList<FeedItem>();
+ for (int i = 0; i < itemIds.length; i++) {
+ if (!itemListContains(queue, itemIds[i])) {
+ final FeedItem item = DBReader.getFeedItem(
+ context, itemIds[i]);
+
+ if (item != null) {
+ queue.add(item);
+ queueModified = true;
+ if (!item.isRead()) {
+ item.setRead(true);
+ itemsToSave.add(item);
+ unreadItemsModified = true;
+ }
+ }
+ }
+ }
+ if (queueModified) {
+ adapter.setQueue(queue);
+ EventDistributor.getInstance()
+ .sendQueueUpdateBroadcast();
+ }
+ if (unreadItemsModified) {
+ adapter.setFeedItemlist(itemsToSave);
+ EventDistributor.getInstance()
+ .sendUnreadItemsUpdateBroadcast();
+ }
+ }
+ adapter.close();
+ new Thread() {
+ @Override
+ public void run() {
+ DBTasks.autodownloadUndownloadedItems(context);
+
+ }
+ }.start();
+ }
+ }
+ });
+
+ }
+
+ /**
+ * Removes all FeedItem objects from the queue.
+ *
+ * @param context A context that is used for opening a database connection.
+ */
+ public static Future<?> clearQueue(final Context context) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.clearQueue();
+ adapter.close();
+
+ EventDistributor.getInstance().sendQueueUpdateBroadcast();
+ }
+ });
+ }
+
+ /**
+ * Removes a FeedItem object from the queue.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param itemId ID of the FeedItem that should be removed.
+ * @param performAutoDownload true if an auto-download process should be started after the operation.
+ */
+ public static Future<?> removeQueueItem(final Context context,
+ final long itemId, final boolean performAutoDownload) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ final List<FeedItem> queue = DBReader
+ .getQueue(context, adapter);
+ FeedItem item = null;
+
+ if (queue != null) {
+ boolean queueModified = false;
QueueAccess queueAccess = QueueAccess.ItemListAccess(queue);
if (queueAccess.contains(itemId)) {
- item = DBReader.getFeedItem(context, itemId);
- if (item != null) {
- queueModified = queueAccess.remove(itemId);
- }
- }
- if (queueModified) {
- adapter.setQueue(queue);
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
- } else {
+ item = DBReader.getFeedItem(context, itemId);
+ if (item != null) {
+ queueModified = queueAccess.remove(itemId);
+ }
+ }
+ if (queueModified) {
+ adapter.setQueue(queue);
+ EventDistributor.getInstance()
+ .sendQueueUpdateBroadcast();
+ } else {
Log.w(TAG, "Queue was not modified by call to removeQueueItem");
}
- } else {
+ } else {
Log.e(TAG, "removeQueueItem: Could not load queue");
}
- adapter.close();
- if (performAutoDownload) {
+ adapter.close();
+ if (performAutoDownload) {
- new Thread() {
- @Override
- public void run() {
- DBTasks.autodownloadUndownloadedItems(context);
+ new Thread() {
+ @Override
+ public void run() {
+ DBTasks.autodownloadUndownloadedItems(context);
- }
- }.start();
- }
- }
- });
+ }
+ }.start();
+ }
+ }
+ });
- }
+ }
- public static void moveQueueItem(final Context context, final int from,
- final int to, final boolean broadcastUpdate) {
- dbExec.submit(new Runnable() {
+ /**
+ * Changes the position of a FeedItem in the queue.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param from Source index. Must be in range 0..queue.size()-1.
+ * @param to Destination index. Must be in range 0..queue.size()-1.
+ * @param broadcastUpdate true if this operation should trigger a QueueUpdateBroadcast. This option should be set to
+ * false if the caller wants to avoid unexpected updates of the GUI.
+ * @throws IndexOutOfBoundsException if (to < 0 || to >= queue.size()) || (from < 0 || from >= queue.size())
+ */
+ public static Future<?> moveQueueItem(final Context context, final int from,
+ final int to, final boolean broadcastUpdate) {
+ return dbExec.submit(new Runnable() {
- @Override
- public void run() {
- final PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- final List<FeedItem> queue = DBReader
- .getQueue(context, adapter);
+ @Override
+ public void run() {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ final List<FeedItem> queue = DBReader
+ .getQueue(context, adapter);
- if (queue != null) {
- if (from >= 0 && from < queue.size() && to >= 0
- && to < queue.size()) {
+ if (queue != null) {
+ if (from >= 0 && from < queue.size() && to >= 0
+ && to < queue.size()) {
- final FeedItem item = queue.remove(from);
- queue.add(to, item);
+ final FeedItem item = queue.remove(from);
+ queue.add(to, item);
adapter.setQueue(queue);
- if (broadcastUpdate) {
- EventDistributor.getInstance()
- .sendQueueUpdateBroadcast();
- }
+ if (broadcastUpdate) {
+ EventDistributor.getInstance()
+ .sendQueueUpdateBroadcast();
+ }
- }
- } else {
+ }
+ } else {
Log.e(TAG, "moveQueueItem: Could not load queue");
}
- adapter.close();
- }
- });
- }
+ adapter.close();
+ }
+ });
+ }
- public static void markItemRead(Context context, FeedItem item, boolean read, boolean resetMediaPosition) {
+ /**
+ * Sets the 'read'-attribute of a FeedItem to the specified value.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param item The FeedItem object
+ * @param read New value of the 'read'-attribute
+ * @param resetMediaPosition true if this method should also reset the position of the FeedItem's FeedMedia object.
+ * If the FeedItem has no FeedMedia object, this parameter will be ignored.
+ */
+ public static Future<?> markItemRead(Context context, FeedItem item, boolean read, boolean resetMediaPosition) {
long mediaId = (item.hasMedia()) ? item.getMedia().getId() : 0;
- markItemRead(context, item.getId(), read, mediaId, resetMediaPosition);
+ return markItemRead(context, item.getId(), read, mediaId, resetMediaPosition);
+ }
+
+ /**
+ * Sets the 'read'-attribute of a FeedItem to the specified value.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param itemId ID of the FeedItem
+ * @param read New value of the 'read'-attribute
+ */
+ public static Future<?> markItemRead(final Context context, final long itemId,
+ final boolean read) {
+ return markItemRead(context, itemId, read, 0, false);
}
- 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 Future<?> addNewFeed(final Context context, final Feed feed) {
- return dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- final PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- adapter.setCompleteFeed(feed);
- adapter.close();
-
- EventDistributor.getInstance().sendFeedUpdateBroadcast();
- }
- });
- }
-
- static Future<?> setCompleteFeed(final Context context, final Feed feed) {
- return dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- adapter.setCompleteFeed(feed);
- adapter.close();
-
- EventDistributor.getInstance().sendFeedUpdateBroadcast();
- }});
-
- }
-
- public static Future<?> setFeedMedia(final Context context,
- final FeedMedia media) {
- return dbExec.submit(new Runnable() {
-
- @Override
- public void run() {
- PodDBAdapter adapter = new PodDBAdapter(context);
- adapter.open();
- adapter.setMedia(media);
- adapter.close();
- }});
- }
+ private static Future<?> markItemRead(final Context context, final long itemId,
+ final boolean read, final long mediaId,
+ final boolean resetMediaPosition) {
+ return 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();
+ }
+ });
+ }
+ /**
+ * Sets the 'read'-attribute of all FeedItems of a specific Feed to true.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param feedId ID of the Feed.
+ */
+ public static Future<?> markFeedRead(final Context context, final long feedId) {
+ return 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();
+ }
+ });
+
+ }
+
+ /**
+ * Sets the 'read'-attribute of all FeedItems to true.
+ *
+ * @param context A context that is used for opening a database connection.
+ */
+ public static Future<?> markAllItemsRead(final Context context) {
+ return 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 Future<?> addNewFeed(final Context context, final Feed feed) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ final PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ EventDistributor.getInstance().sendFeedUpdateBroadcast();
+ }
+ });
+ }
+
+ static Future<?> setCompleteFeed(final Context context, final Feed feed) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ EventDistributor.getInstance().sendFeedUpdateBroadcast();
+ }
+ });
+
+ }
+
+ /**
+ * Saves a FeedMedia object in the database. This method will save all attributes of the FeedMedia object. The
+ * contents of FeedComponent-attributes (e.g. the FeedMedia's 'item'-attribute) will not be saved.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param media The FeedMedia object.
+ */
+ public static Future<?> setFeedMedia(final Context context,
+ final FeedMedia media) {
+ return dbExec.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setMedia(media);
+ adapter.close();
+ }
+ });
+ }
+
+ /**
+ * Saves only value of the 'position'-attribute of a FeedMedia object.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param media The FeedMedia object.
+ */
public static Future<?> setFeedMediaPosition(final Context context, final FeedMedia media) {
- return dbExec.submit(new Runnable(){
+ return dbExec.submit(new Runnable() {
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
@@ -543,8 +671,15 @@ public class DBWriter {
});
}
+ /**
+ * Saves a FeedItem object in the database. This method will save all attributes of the FeedItem object including
+ * the content of FeedComponent-attributes.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param item The FeedItem object.
+ */
public static Future<?> setFeedItem(final Context context,
- final FeedItem item) {
+ final FeedItem item) {
return dbExec.submit(new Runnable() {
@Override
@@ -553,11 +688,19 @@ public class DBWriter {
adapter.open();
adapter.setSingleFeedItem(item);
adapter.close();
- }});
+ }
+ });
}
+ /**
+ * Saves a FeedImage object in the database. This method will save all attributes of the FeedImage object. The
+ * contents of FeedComponent-attributes (e.g. the FeedImages's 'feed'-attribute) will not be saved.
+ *
+ * @param context A context that is used for opening a database connection.
+ * @param image The FeedImage object.
+ */
public static Future<?> setFeedImage(final Context context,
- final FeedImage image) {
+ final FeedImage image) {
return dbExec.submit(new Runnable() {
@Override
@@ -566,15 +709,16 @@ public class DBWriter {
adapter.open();
adapter.setImage(image);
adapter.close();
- }});
+ }
+ });
}
- private static boolean itemListContains(List<FeedItem> items, long itemId) {
- for (FeedItem item : items) {
- if (item.getId() == itemId) {
- return true;
- }
- }
- return false;
- }
+ private static boolean itemListContains(List<FeedItem> items, long itemId) {
+ for (FeedItem item : items) {
+ if (item.getId() == itemId) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java
index a0c6cb11f..ac9309674 100644
--- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java
+++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java
@@ -438,7 +438,7 @@ public class PodDBAdapter {
}
values.put(KEY_PUBDATE, item.getPubDate().getTime());
values.put(KEY_PAYMENT_LINK, item.getPaymentLink());
- if (item.getFeed().getId() == 0) {
+ if (item.getFeed() != null) {
setFeed(item.getFeed());
}
values.put(KEY_FEED, item.getFeed().getId());
@@ -452,9 +452,7 @@ public class PodDBAdapter {
new String[]{String.valueOf(item.getId())});
}
if (item.getMedia() != null) {
- if (item.getMedia().getId() == 0) {
setMedia(item.getMedia());
- }
}
if (item.getChapters() != null) {
setChapters(item);