Organizing the queue now works, several bugfixes etc.

This commit is contained in:
daniel oeh 2013-08-02 23:54:50 +02:00
parent 71a47c0a5b
commit 2071793e6a
20 changed files with 297 additions and 144 deletions

View File

@ -22,6 +22,7 @@ import de.danoeh.antennapod.fragment.ItemlistFragment;
import de.danoeh.antennapod.preferences.UserPreferences;
import de.danoeh.antennapod.storage.DBReader;
import de.danoeh.antennapod.storage.DownloadRequestException;
import de.danoeh.antennapod.util.QueueAccess;
import de.danoeh.antennapod.util.StorageUtils;
import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler;
@ -149,13 +150,13 @@ public class ItemviewActivity extends SherlockFragmentActivity {
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
return FeedItemMenuHandler.onPrepareMenu(
new FeedItemMenuHandler.MenuInterface() {
new FeedItemMenuHandler.MenuInterface() {
@Override
public void setItemVisibility(int id, boolean visible) {
menu.findItem(id).setVisible(visible);
}
}, item, true);
@Override
public void setItemVisibility(int id, boolean visible) {
menu.findItem(id).setVisible(visible);
}
}, item, true, QueueAccess.NotInQueueAccess());
}
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {

View File

@ -113,9 +113,10 @@ public class OrganizeQueueActivity extends SherlockListActivity implements
@Override
public void drop(int from, int to) {
final FeedItem item = queue.remove(from);
queue.add(to, item);
adapter.notifyDataSetChanged();
DBWriter.moveQueueItem(OrganizeQueueActivity.this, from, to, true);
//adapter.notifyDataSetChanged();
}
};

View File

@ -156,7 +156,7 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter {
}
holder.lenSize.setVisibility(View.VISIBLE);
if (isInQueue(item)) {
if (((ItemAccess) itemAccess).isInQueue(item)) {
holder.inPlaylist.setVisibility(View.VISIBLE);
} else {
holder.inPlaylist.setVisibility(View.GONE);
@ -205,19 +205,6 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter {
}
private boolean isInQueue(FeedItem item) {
Iterator<FeedItem> iter = ((ItemAccess) itemAccess).queueIterator();
if (iter != null) {
while (iter.hasNext()) {
FeedItem current = iter.next();
if (current.getId() == item.getId()) {
return true;
}
}
}
return false;
}
static class Holder extends DefaultFeedItemlistAdapter.Holder {
TextView feedtitle;
ImageView inPlaylist;
@ -239,7 +226,7 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter {
}
public static interface ItemAccess extends DefaultFeedItemlistAdapter.ItemAccess {
public Iterator<FeedItem> queueIterator();
public boolean isInQueue(FeedItem item);
}
}

View File

@ -17,6 +17,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.opml.OpmlWriter;
import de.danoeh.antennapod.preferences.UserPreferences;
import de.danoeh.antennapod.storage.DBReader;
/** Writes an OPML file into the export directory in the background. */
public class OpmlExportWorker extends AsyncTask<Void, Void, Void> {
@ -51,8 +52,7 @@ public class OpmlExportWorker extends AsyncTask<Void, Void, Void> {
}
try {
FileWriter writer = new FileWriter(output);
opmlWriter.writeDocument(Arrays.asList(FeedManager.getInstance().getFeedsArray()),
writer);
opmlWriter.writeDocument(DBReader.getFeedList(context), writer);
writer.close();
} catch (IOException e) {
e.printStackTrace();

View File

@ -9,7 +9,7 @@ import org.apache.commons.io.IOUtils;
import de.danoeh.antennapod.asynctask.ImageLoader;
;
public class FeedImage extends FeedFile implements
ImageLoader.ImageWorkerTaskResource {

View File

@ -31,6 +31,7 @@ import de.danoeh.antennapod.storage.DBReader;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.storage.DBWriter;
import de.danoeh.antennapod.storage.DownloadRequestException;
import de.danoeh.antennapod.util.QueueAccess;
import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler;
import java.util.List;
@ -220,13 +221,13 @@ public class EpisodesFragment extends SherlockFragment {
menu.setHeaderTitle(selectedItem.getTitle());
FeedItemMenuHandler.onPrepareMenu(
new FeedItemMenuHandler.MenuInterface() {
new FeedItemMenuHandler.MenuInterface() {
@Override
public void setItemVisibility(int id, boolean visible) {
menu.findItem(id).setVisible(visible);
}
}, selectedItem, false);
@Override
public void setItemVisibility(int id, boolean visible) {
menu.findItem(id).setVisible(visible);
}
}, selectedItem, false, QueueAccess.ItemListAccess(queue));
} else if (selectedGroupId == ExternalEpisodesListAdapter.GROUP_POS_QUEUE) {
menu.add(Menu.NONE, R.id.organize_queue_item, Menu.NONE,

View File

@ -29,6 +29,7 @@ import de.danoeh.antennapod.service.download.DownloadService;
import de.danoeh.antennapod.storage.DBReader;
import de.danoeh.antennapod.storage.DownloadRequestException;
import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.util.QueueAccess;
import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler;
import java.util.Iterator;
@ -50,7 +51,7 @@ public class ItemlistFragment extends SherlockListFragment {
protected DownloadRequester requester = DownloadRequester.getInstance();
private Feed feed;
protected List<FeedItem> queue;
protected List<Long> queue;
protected FeedItem selectedItem = null;
protected boolean contextMenuClosed = true;
@ -99,8 +100,8 @@ public class ItemlistFragment extends SherlockListFragment {
}
@Override
public Iterator<FeedItem> queueIterator() {
return (queue != null) ? queue.iterator() : null;
public boolean isInQueue(FeedItem item) {
return (queue != null) && queue.contains(item.getId());
}
};
}
@ -127,7 +128,7 @@ public class ItemlistFragment extends SherlockListFragment {
feedId = feed.getId();
}
AsyncTask<Long, Void, Feed> loadTask = new AsyncTask<Long, Void, Feed>(){
private volatile List<FeedItem> queueRef;
private volatile List<Long> queueRef;
@Override
protected Feed doInBackground(Long... longs) {
@ -136,7 +137,7 @@ public class ItemlistFragment extends SherlockListFragment {
Feed result = DBReader.getFeed(context, longs[0]);
if (result != null) {
result.setItems(DBReader.getFeedItemList(context, result));
queueRef = DBReader.getQueue(context);
queueRef = DBReader.getQueueIDList(context);
return result;
}
}
@ -277,13 +278,13 @@ public class ItemlistFragment extends SherlockListFragment {
menu.setHeaderTitle(selectedItem.getTitle());
FeedItemMenuHandler.onPrepareMenu(
new FeedItemMenuHandler.MenuInterface() {
new FeedItemMenuHandler.MenuInterface() {
@Override
public void setItemVisibility(int id, boolean visible) {
menu.findItem(id).setVisible(visible);
}
}, selectedItem, false);
@Override
public void setItemVisibility(int id, boolean visible) {
menu.findItem(id).setVisible(visible);
}
}, selectedItem, false, QueueAccess.IDListAccess(queue));
}
}

View File

@ -39,8 +39,8 @@ public class PlaybackHistoryFragment extends ItemlistFragment {
}
@Override
public Iterator<FeedItem> queueIterator() {
return (queue != null) ? queue.iterator() : null;
public boolean isInQueue(FeedItem item) {
return (queue != null) ? queue.contains(item.getId()) : false;
}
};
}
@ -76,13 +76,13 @@ public class PlaybackHistoryFragment extends ItemlistFragment {
protected void loadData() {
AsyncTask<Void, Void, Void> loadTask = new AsyncTask<Void, Void, Void>() {
private volatile List<FeedItem> phRef;
private volatile List<FeedItem> queueRef;
private volatile List<Long> queueRef;
@Override
protected Void doInBackground(Void... voids) {
Context context = PlaybackHistoryFragment.this.getActivity();
if (context != null) {
queueRef = DBReader.getQueue(context);
queueRef = DBReader.getQueueIDList(context);
phRef = DBReader.getPlaybackHistory(context);
}
return null;

View File

@ -8,6 +8,7 @@ import android.net.NetworkInfo;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.util.NetworkUtils;
@ -27,7 +28,7 @@ public class ConnectivityActionReceiver extends BroadcastReceiver {
new Thread() {
@Override
public void run() {
FeedManager.getInstance()
DBTasks
.autodownloadUndownloadedItems(context);
}
}.start();

View File

@ -9,6 +9,7 @@ import android.util.Log;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.preferences.UserPreferences;
import de.danoeh.antennapod.storage.DBTasks;
/** Refreshes all feeds when it receives an intent */
public class FeedUpdateReceiver extends BroadcastReceiver {
@ -22,7 +23,7 @@ public class FeedUpdateReceiver extends BroadcastReceiver {
Log.d(TAG, "Received intent");
boolean mobileUpdate = UserPreferences.isAllowMobileUpdate();
if (mobileUpdate || connectedToWifi(context)) {
FeedManager.getInstance().refreshExpiredFeeds(context);
DBTasks.refreshExpiredFeeds(context);
} else {
if (AppConfig.DEBUG)
Log.d(TAG,

View File

@ -11,18 +11,12 @@ import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import javax.xml.parsers.ParserConfigurationException;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.storage.DBWriter;
import org.xml.sax.SAXException;
import android.annotation.SuppressLint;
@ -93,7 +87,6 @@ public class DownloadService extends Service {
private static final int NUM_PARALLEL_DOWNLOADS = 4;
private DownloadRequester requester;
private FeedManager manager;
private NotificationCompat.Builder notificationCompatBuilder;
private Notification.BigTextStyle notificationBuilder;
private int NOTIFICATION_ID = 2;
@ -150,23 +143,23 @@ public class DownloadService extends Service {
registerReceiver(cancelDownloadReceiver, cancelDownloadReceiverFilter);
syncExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setPriority(Thread.MIN_PRIORITY);
t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setPriority(Thread.MIN_PRIORITY);
t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e(TAG, "Thread exited with uncaught exception");
ex.printStackTrace();
downloadsBeingHandled -= 1;
queryDownloads();
}
});
return t;
}
});
@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e(TAG, "Thread exited with uncaught exception");
ex.printStackTrace();
downloadsBeingHandled -= 1;
queryDownloads();
}
});
return t;
}
});
downloadExecutor = Executors.newFixedThreadPool(NUM_PARALLEL_DOWNLOADS,
new ThreadFactory() {
@ -195,7 +188,6 @@ public class DownloadService extends Service {
}
});
setupNotificationBuilders();
manager = FeedManager.getInstance();
requester = DownloadRequester.getInstance();
}
@ -473,7 +465,7 @@ public class DownloadService extends Service {
*/
private void saveDownloadStatus(DownloadStatus status) {
completedDownloads.add(status);
manager.addDownloadStatus(this, status);
DBWriter.addDownloadStatus(this, status);
}
private void sendDownloadHandledIntent() {
@ -610,7 +602,6 @@ public class DownloadService extends Service {
reason = 0;
String reasonDetailed = null;
successful = true;
final FeedManager manager = FeedManager.getInstance();
FeedHandler feedHandler = new FeedHandler();
try {
@ -621,7 +612,7 @@ public class DownloadService extends Service {
throw new InvalidFeedException();
}
// Save information of feed in DB
savedFeed = manager.updateFeed(DownloadService.this, feed);
savedFeed = DBTasks.updateFeed(DownloadService.this, feed);
// Download Feed Image if provided and not downloaded
if (savedFeed.getImage() != null
&& savedFeed.getImage().isDownloaded() == false) {
@ -638,15 +629,15 @@ public class DownloadService extends Service {
savedFeedRef.getImage());
} catch (DownloadRequestException e) {
e.printStackTrace();
manager.addDownloadStatus(
DownloadService.this,
new DownloadStatus(
savedFeedRef.getImage(),
savedFeedRef
.getImage()
.getHumanReadableIdentifier(),
DownloadError.ERROR_REQUEST_ERROR,
false, e.getMessage()));
DBWriter.addDownloadStatus(
DownloadService.this,
new DownloadStatus(
savedFeedRef.getImage(),
savedFeedRef
.getImage()
.getHumanReadableIdentifier(),
DownloadError.ERROR_REQUEST_ERROR,
false, e.getMessage()));
}
}
});
@ -779,13 +770,7 @@ public class DownloadService extends Service {
saveDownloadStatus(status);
sendDownloadHandledIntent();
manager.setFeedImage(DownloadService.this, image);
if (image.getFeed() != null) {
manager.setFeed(DownloadService.this, image.getFeed());
} else {
Log.e(TAG,
"Image has no feed, image might not be saved correctly!");
}
DBWriter.setFeedImage(DownloadService.this, image);
downloadsBeingHandled -= 1;
handler.post(new Runnable() {
@ -852,12 +837,19 @@ public class DownloadService extends Service {
saveDownloadStatus(status);
sendDownloadHandledIntent();
if (chaptersRead) {
manager.setFeedItem(DownloadService.this, media.getItem());
}
manager.setFeedMedia(DownloadService.this, media);
if (!FeedManager.getInstance().isInQueue(media.getItem())) {
try {
if (chaptersRead) {
DBWriter.setFeedItem(DownloadService.this, media.getItem()).get();
}
DBWriter.setFeedMedia(DownloadService.this, media).get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!FeedManager.getInstance().isInQueue(media.getItem())) {
FeedManager.getInstance().addQueueItem(DownloadService.this,
media.getItem());
}

View File

@ -18,7 +18,7 @@ import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.feed.ID3Chapter;
import de.danoeh.antennapod.feed.SimpleChapter;
import de.danoeh.antennapod.feed.VorbisCommentChapter;
import de.danoeh.antennapod.service.download.DownloadStatus;
import de.danoeh.antennapod.service.download.*;
import de.danoeh.antennapod.util.comparator.DownloadStatusComparator;
import de.danoeh.antennapod.util.comparator.FeedItemPubdateComparator;
@ -132,8 +132,7 @@ public final class DBReader {
itemIds.add(String.valueOf(item.getId()));
item.setRead((itemlistCursor
.getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0) ? true
: false);
.getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0));
item.setItemIdentifier(itemlistCursor
.getString(PodDBAdapter.IDX_FI_SMALL_ITEM_IDENTIFIER));
@ -182,7 +181,6 @@ public final class DBReader {
}
extractMediafromItemlist(adapter, items, itemIds);
Collections.sort(items, new FeedItemPubdateComparator());
return items;
}
@ -275,11 +273,33 @@ public final class DBReader {
itemlistCursor);
itemlistCursor.close();
loadFeedDataOfFeedItemlist(context, items);
Collections.sort(items, new FeedItemPubdateComparator());
return items;
}
public static List<Long> getQueueIDList(Context context) {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
List<Long> result = getQueueIDList(adapter);
adapter.close();
return result;
}
static List<Long> getQueueIDList(PodDBAdapter adapter) {
adapter.open();
Cursor queueCursor = adapter.getQueueIDCursor();
List<Long> queueIds = new ArrayList<Long>(queueCursor.getCount());
if (queueCursor.moveToFirst()) {
do {
queueIds.add(queueCursor.getLong(0));
} while (queueCursor.moveToNext());
}
return queueIds;
}
public static List<FeedItem> getQueue(Context context) {
if (AppConfig.DEBUG)
Log.d(TAG, "Extracting queue");

View File

@ -87,7 +87,7 @@ public final class DBTasks {
}
}
public void refreshExpiredFeeds(final Context context) {
public static void refreshExpiredFeeds(final Context context) {
if (AppConfig.DEBUG)
Log.d(TAG, "Refreshing expired feeds");
@ -130,7 +130,7 @@ public final class DBTasks {
}
/** Updates a specific feed. */
private static void refreshFeed(Context context, Feed feed)
public static void refreshFeed(Context context, Feed feed)
throws DownloadRequestException {
DownloadRequester.getInstance().downloadFeed(context,
new Feed(feed.getDownload_url(), new Date(), feed.getTitle()));

View File

@ -1,6 +1,7 @@
package de.danoeh.antennapod.storage;
import java.io.File;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
@ -15,13 +16,11 @@ import android.database.Cursor;
import android.preference.PreferenceManager;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.feed.EventDistributor;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.feed.*;
import de.danoeh.antennapod.preferences.PlaybackPreferences;
import de.danoeh.antennapod.service.PlaybackService;
import de.danoeh.antennapod.service.download.DownloadStatus;
import de.danoeh.antennapod.util.QueueAccess;
public class DBWriter {
private static final String TAG = "DBWriter";
@ -349,20 +348,23 @@ public class DBWriter {
if (queue != null) {
boolean queueModified = false;
if (itemListContains(queue, itemId)) {
QueueAccess queueAccess = QueueAccess.ItemListAccess(queue);
if (queueAccess.contains(itemId)) {
item = DBReader.getFeedItem(context, itemId);
if (item != null) {
queue.remove(item);
queueModified = true;
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 {
Log.e(TAG, "removeQueueItem: Could not load queue");
}
adapter.close();
if (performAutoDownload) {
@ -393,21 +395,30 @@ public class DBWriter {
if (queue != null) {
if (from >= 0 && from < queue.size() && to >= 0
&& to < queue.size()) {
final FeedItem item = queue.remove(from);
queue.add(to, item);
adapter.setQueue(queue);
adapter.setQueue(queue);
if (broadcastUpdate) {
EventDistributor.getInstance()
.sendQueueUpdateBroadcast();
}
}
}
} else {
Log.e(TAG, "moveQueueItem: Could not load queue");
}
adapter.close();
}
});
}
public static void markItemRead(Context context, FeedItem item, boolean read, boolean resetMediaPosition) {
long mediaId = (item.hasMedia()) ? item.getMedia().getId() : 0;
markItemRead(context, item.getId(), read, mediaId, resetMediaPosition);
}
public static void markItemRead(final Context context, final long itemId,
final boolean read) {
markItemRead(context, itemId, read, 0, false);
@ -507,9 +518,9 @@ public class DBWriter {
}
static void setFeedMedia(final Context context,
public static Future<?> setFeedMedia(final Context context,
final FeedMedia media) {
dbExec.submit(new Runnable() {
return dbExec.submit(new Runnable() {
@Override
public void run() {
@ -522,6 +533,32 @@ public class DBWriter {
}
public static Future<?> setFeedItem(final Context context,
final FeedItem item) {
return dbExec.submit(new Runnable() {
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.setSingleFeedItem(item);
adapter.close();
}});
}
public static Future<?> setFeedImage(final Context context,
final FeedImage image) {
return dbExec.submit(new Runnable() {
@Override
public void run() {
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
adapter.setImage(image);
adapter.close();
}});
}
private static boolean itemListContains(List<FeedItem> items, long itemId) {
for (FeedItem item : items) {
if (item.getId() == itemId) {

View File

@ -305,6 +305,7 @@ public class PodDBAdapter {
* @return the id of the entry
* */
public long setImage(FeedImage image) {
db.beginTransaction();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, image.getTitle());
values.put(KEY_DOWNLOAD_URL, image.getDownload_url());
@ -316,6 +317,13 @@ public class PodDBAdapter {
db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID + "=?",
new String[] { String.valueOf(image.getId()) });
}
if (image.getFeed() != null && image.getFeed().getId() != 0 ) {
values.clear();
values.put(KEY_IMAGE, image.getId());
db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[] {String.valueOf(image.getFeed().getId())});
}
db.setTransactionSuccessful();
db.endTransaction();
return image.getId();
}
@ -686,11 +694,11 @@ public class PodDBAdapter {
open();
String selFiSmall = Arrays.toString(SEL_FI_SMALL);
Object[] args = (Object[]) new String[] {
selFiSmall.substring(1, selFiSmall.length() - 1),
selFiSmall.substring(1, selFiSmall.length() - 1) + "," + TABLE_NAME_QUEUE + "." + KEY_ID,
TABLE_NAME_FEED_ITEMS, TABLE_NAME_QUEUE,
TABLE_NAME_FEED_ITEMS + "." + KEY_ID,
TABLE_NAME_QUEUE + "." + KEY_FEEDITEM,
TABLE_NAME_QUEUE + "." + KEY_FEEDITEM };
TABLE_NAME_QUEUE + "." + KEY_ID };
String query = String.format(
"SELECT %s FROM %s INNER JOIN %s ON %s=%s ORDER BY %s", args);
Cursor c = db.rawQuery(query, null);
@ -703,6 +711,12 @@ public class PodDBAdapter {
return c;
}
public Cursor getQueueIDCursor() {
open();
Cursor c = db.query(TABLE_NAME_QUEUE, new String[]{KEY_FEEDITEM}, null, null, null, null, KEY_ID + " ASC", null);
return c;
}
/**
* Returns a cursor which contains all feed items in the unread items list.
* The returned cursor uses the SEL_FI_SMALL selection.
@ -791,8 +805,11 @@ public class PodDBAdapter {
/** Builds an IN-operator argument depending on the number of items. */
private String buildInOperator(int size) {
if (size == 1) {
return "(?)";
}
StringBuffer buffer = new StringBuffer("(");
for (int i = 0; i <= size; i++) {
for (int i = 0; i < size - 1; i++) {
buffer.append("?,");
}
buffer.append("?)");

View File

@ -0,0 +1,89 @@
package de.danoeh.antennapod.util;
import de.danoeh.antennapod.feed.FeedItem;
import java.util.Iterator;
import java.util.List;
/**
* Provides methods for accessing the queue. It is possible to load only a part of the information about the queue that
* is stored in the database (e.g. sometimes the user just has to test if a specific item is contained in the List.
* QueueAccess provides an interface for accessing the queue without having to care about the type of the queue
* representation.
*/
public abstract class QueueAccess {
/**
* Returns true if the item is in the queue, false otherwise.
*/
public abstract boolean contains(long id);
/**
* Removes the item from the queue.
*
* @return true if the queue was modified by this operation.
*/
public abstract boolean remove(long id);
private QueueAccess() {
}
public static QueueAccess IDListAccess(final List<Long> ids) {
return new QueueAccess() {
@Override
public boolean contains(long id) {
return (ids != null) && ids.contains(id);
}
@Override
public boolean remove(long id) {
return ids.remove(id);
}
};
}
public static QueueAccess ItemListAccess(final List<FeedItem> items) {
return new QueueAccess() {
@Override
public boolean contains(long id) {
Iterator<FeedItem> it = items.iterator();
for (FeedItem i = it.next(); it.hasNext(); i = it.next()) {
if (i.getId() == id) {
return true;
}
}
return false;
}
@Override
public boolean remove(long id) {
Iterator<FeedItem> it = items.iterator();
for (FeedItem i = it.next(); it.hasNext(); i = it.next()) {
if (i.getId() == id) {
it.remove();
return true;
}
}
return false;
}
};
}
public static QueueAccess NotInQueueAccess() {
return new QueueAccess() {
@Override
public boolean contains(long id) {
return false;
}
@Override
public boolean remove(long id) {
return false;
}
};
}
}

View File

@ -2,7 +2,7 @@ package de.danoeh.antennapod.util.comparator;
import java.util.Comparator;
import de.danoeh.antennapod.service.download.DownloadStatus;
import de.danoeh.antennapod.service.download.*;
/** Compares the completion date of two Downloadstatus objects. */
public class DownloadStatusComparator implements Comparator<DownloadStatus> {

View File

@ -7,12 +7,16 @@ import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.asynctask.FlattrClickWorker;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.service.PlaybackService;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.storage.DBWriter;
import de.danoeh.antennapod.storage.DownloadRequestException;
import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.util.QueueAccess;
import de.danoeh.antennapod.util.ShareUtils;
import java.util.List;
/** Handles interactions with the FeedItemMenu. */
public class FeedItemMenuHandler {
private FeedItemMenuHandler() {
@ -45,11 +49,12 @@ public class FeedItemMenuHandler {
* True if MenuItems that let the user share information about
* the FeedItem and visit its website should be set visible. This
* parameter should be set to false if the menu space is limited.
* @param queueAccess
* Used for testing if the queue contains the selected item
* @return Always returns true
* */
public static boolean onPrepareMenu(MenuInterface mi,
FeedItem selectedItem, boolean showExtendedMenu) {
FeedManager manager = FeedManager.getInstance();
FeedItem selectedItem, boolean showExtendedMenu, QueueAccess queueAccess) {
DownloadRequester requester = DownloadRequester.getInstance();
boolean hasMedia = selectedItem.getMedia() != null;
boolean downloaded = hasMedia && selectedItem.getMedia().isDownloaded();
@ -79,7 +84,7 @@ public class FeedItemMenuHandler {
mi.setItemVisibility(R.id.cancel_download_item, false);
}
boolean isInQueue = manager.isInQueue(selectedItem);
boolean isInQueue = queueAccess.contains(selectedItem.getId());
if (!isInQueue || isPlaying) {
mi.setItemVisibility(R.id.remove_from_queue_item, false);
}
@ -111,39 +116,38 @@ public class FeedItemMenuHandler {
public static boolean onMenuItemClicked(Context context, int menuItemId,
FeedItem selectedItem) throws DownloadRequestException {
DownloadRequester requester = DownloadRequester.getInstance();
FeedManager manager = FeedManager.getInstance();
switch (menuItemId) {
case R.id.skip_episode_item:
context.sendBroadcast(new Intent(
PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
break;
case R.id.download_item:
manager.downloadFeedItem(context, selectedItem);
DBTasks.downloadFeedItems(context, selectedItem);
break;
case R.id.play_item:
manager.playMedia(context, selectedItem.getMedia(), true, true,
DBTasks.playMedia(context, selectedItem.getMedia(), true, true,
false);
break;
case R.id.remove_item:
manager.deleteFeedMedia(context, selectedItem.getMedia());
DBWriter.deleteFeedMediaOfItem(context, selectedItem.getId());
break;
case R.id.cancel_download_item:
requester.cancelDownload(context, selectedItem.getMedia());
break;
case R.id.mark_read_item:
manager.markItemRead(context, selectedItem, true, true);
DBWriter.markItemRead(context, selectedItem, true, true);
break;
case R.id.mark_unread_item:
manager.markItemRead(context, selectedItem, false, true);
DBWriter.markItemRead(context, selectedItem, false, true);
break;
case R.id.add_to_queue_item:
manager.addQueueItem(context, selectedItem);
DBWriter.addQueueItem(context, selectedItem.getId());
break;
case R.id.remove_from_queue_item:
manager.removeQueueItem(context, selectedItem, true);
DBWriter.removeQueueItem(context, selectedItem.getId(), true);
break;
case R.id.stream_item:
manager.playMedia(context, selectedItem.getMedia(), true, true,
DBTasks.playMedia(context, selectedItem.getMedia(), true, true,
true);
break;
case R.id.visit_website_item:

View File

@ -14,8 +14,9 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.FeedInfoActivity;
import de.danoeh.antennapod.asynctask.FlattrClickWorker;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.service.download.DownloadService;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.storage.DBWriter;
import de.danoeh.antennapod.storage.DownloadRequestException;
import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.util.ShareUtils;
@ -56,7 +57,6 @@ public class FeedMenuHandler {
*/
public static boolean onOptionsItemClicked(Context context, MenuItem item,
Feed selectedFeed) throws DownloadRequestException {
FeedManager manager = FeedManager.getInstance();
switch (item.getItemId()) {
case R.id.show_info_item:
Intent startIntent = new Intent(context, FeedInfoActivity.class);
@ -65,10 +65,10 @@ public class FeedMenuHandler {
context.startActivity(startIntent);
break;
case R.id.refresh_item:
manager.refreshFeed(context, selectedFeed);
DBTasks.refreshFeed(context, selectedFeed);
break;
case R.id.mark_all_read_item:
manager.markFeedRead(context, selectedFeed);
DBWriter.markFeedRead(context, selectedFeed.getId());
break;
case R.id.visit_website_item:
Uri uri = Uri.parse(selectedFeed.getLink());

View File

@ -33,6 +33,7 @@ import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.preferences.PlaybackPreferences;
import de.danoeh.antennapod.service.PlaybackService;
import de.danoeh.antennapod.service.PlayerStatus;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.util.Converter;
import de.danoeh.antennapod.util.playback.Playable.PlayableUtils;
@ -214,8 +215,8 @@ public abstract class PlaybackController {
boolean lastIsStream = PlaybackPreferences
.getCurrentEpisodeIsStream();
if (!fileExists && !lastIsStream && media instanceof FeedMedia) {
FeedManager.getInstance().notifyMissingFeedMediaFile(
activity, (FeedMedia) media);
DBTasks.notifyMissingFeedMediaFile(
activity, (FeedMedia) media);
}
serviceIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM,
lastIsStream || !fileExists);