summaryrefslogtreecommitdiff
path: root/src/de/danoeh
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/danoeh')
-rw-r--r--src/de/danoeh/antennapod/activity/DownloadActivity.java3
-rw-r--r--src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java4
-rw-r--r--src/de/danoeh/antennapod/feed/FeedFile.java20
-rw-r--r--src/de/danoeh/antennapod/feed/FeedManager.java6
-rw-r--r--src/de/danoeh/antennapod/service/download/DownloadService.java78
-rw-r--r--src/de/danoeh/antennapod/storage/DownloadRequester.java128
-rw-r--r--src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java3
7 files changed, 128 insertions, 114 deletions
diff --git a/src/de/danoeh/antennapod/activity/DownloadActivity.java b/src/de/danoeh/antennapod/activity/DownloadActivity.java
index 4ec7a9859..566d1099d 100644
--- a/src/de/danoeh/antennapod/activity/DownloadActivity.java
+++ b/src/de/danoeh/antennapod/activity/DownloadActivity.java
@@ -142,8 +142,7 @@ public class DownloadActivity extends SherlockListActivity implements
boolean handled = false;
switch (item.getItemId()) {
case R.id.cancel_download_item:
- requester.cancelDownload(this, selectedDownload.getFeedFile()
- .getDownloadId());
+ requester.cancelDownload(this, selectedDownload.getFeedFile());
handled = true;
break;
}
diff --git a/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java b/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
index 568768058..9dbc225d0 100644
--- a/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
@@ -5,6 +5,7 @@ import java.util.List;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedManager;
+import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.util.Converter;
import de.danoeh.antennapod.R;
import android.widget.ArrayAdapter;
@@ -121,7 +122,8 @@ public class FeedItemlistAdapter extends ArrayAdapter<FeedItem> {
holder.downloaded.setVisibility(View.GONE);
}
- if (item.getMedia().isDownloading()) {
+ if (DownloadRequester.getInstance().isDownloadingFile(
+ item.getMedia())) {
holder.downloading.setVisibility(View.VISIBLE);
} else {
holder.downloading.setVisibility(View.GONE);
diff --git a/src/de/danoeh/antennapod/feed/FeedFile.java b/src/de/danoeh/antennapod/feed/FeedFile.java
index c7a9b7bc1..5ec52d7d2 100644
--- a/src/de/danoeh/antennapod/feed/FeedFile.java
+++ b/src/de/danoeh/antennapod/feed/FeedFile.java
@@ -1,10 +1,9 @@
package de.danoeh.antennapod.feed;
-/** Represents a component of a Feed that has to be downloaded*/
+/** Represents a component of a Feed that has to be downloaded */
public abstract class FeedFile extends FeedComponent {
protected String file_url;
protected String download_url;
- protected long downloadId; // temporary id given by the Android DownloadManager
protected boolean downloaded;
public FeedFile(String file_url, String download_url, boolean downloaded) {
@@ -21,24 +20,19 @@ public abstract class FeedFile extends FeedComponent {
public String getFile_url() {
return file_url;
}
+
public void setFile_url(String file_url) {
this.file_url = file_url;
}
+
public String getDownload_url() {
return download_url;
}
+
public void setDownload_url(String download_url) {
this.download_url = download_url;
}
- public long getDownloadId() {
- return downloadId;
- }
-
- public void setDownloadId(long downloadId) {
- this.downloadId = downloadId;
- }
-
public boolean isDownloaded() {
return downloaded;
}
@@ -46,10 +40,4 @@ public abstract class FeedFile extends FeedComponent {
public void setDownloaded(boolean downloaded) {
this.downloaded = downloaded;
}
-
- public boolean isDownloading() {
- return downloadId != 0;
- }
-
-
}
diff --git a/src/de/danoeh/antennapod/feed/FeedManager.java b/src/de/danoeh/antennapod/feed/FeedManager.java
index 2aab5c5de..d49e73e0c 100644
--- a/src/de/danoeh/antennapod/feed/FeedManager.java
+++ b/src/de/danoeh/antennapod/feed/FeedManager.java
@@ -167,8 +167,7 @@ public class FeedManager {
imageFile.delete();
}
} else if (requester.isDownloadingFile(feed.getImage())) {
- requester.cancelDownload(context, feed.getImage()
- .getDownloadId());
+ requester.cancelDownload(context, feed.getImage());
}
// delete stored media files and mark them as read
for (FeedItem item : feed.getItems()) {
@@ -184,8 +183,7 @@ public class FeedManager {
mediaFile.delete();
} else if (item.getMedia() != null
&& requester.isDownloadingFile(item.getMedia())) {
- requester.cancelDownload(context, item.getMedia()
- .getDownloadId());
+ requester.cancelDownload(context, item.getMedia());
}
}
diff --git a/src/de/danoeh/antennapod/service/download/DownloadService.java b/src/de/danoeh/antennapod/service/download/DownloadService.java
index fba955e59..db9b293d5 100644
--- a/src/de/danoeh/antennapod/service/download/DownloadService.java
+++ b/src/de/danoeh/antennapod/service/download/DownloadService.java
@@ -51,6 +51,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
+import android.webkit.URLUtil;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Debug;
@@ -71,6 +72,7 @@ public class DownloadService extends Service {
* queryDownloads()
*/
public static final String ACTION_NOTIFY_DOWNLOADS_CHANGED = "action.de.danoeh.antennapod.service.notifyDownloadsChanged";
+ public static final String ACTION_ENQUEUE_DOWNLOAD = "action.de.danoeh.antennapod.service.enqueueDownload";
public static final String ACTION_DOWNLOAD_HANDLED = "action.de.danoeh.antennapod.service.download_handled";
/** True if handled feed has an image. */
@@ -78,6 +80,9 @@ public class DownloadService extends Service {
public static final String EXTRA_DOWNLOAD_ID = "extra.de.danoeh.antennapod.service.download_id";
public static final String EXTRA_IMAGE_DOWNLOAD_ID = "extra.de.danoeh.antennapod.service.image_download_id";
+ /** Extra for ACTION_ENQUEUE_DOWNLOAD intent. */
+ public static final String EXTRA_REQUEST = "request";
+
// Download types for ACTION_DOWNLOAD_HANDLED
public static final String EXTRA_DOWNLOAD_TYPE = "extra.de.danoeh.antennapod.service.downloadType";
public static final int DOWNLOAD_TYPE_FEED = 1;
@@ -87,6 +92,8 @@ public class DownloadService extends Service {
private ArrayList<DownloadStatus> completedDownloads;
private ExecutorService syncExecutor;
+ private ExecutorService downloadExecutor;
+
private DownloadRequester requester;
private FeedManager manager;
private NotificationCompat.Builder notificationBuilder;
@@ -98,7 +105,7 @@ public class DownloadService extends Service {
private DownloadObserver downloadObserver;
- private List<DownloadStatus> downloads;
+ private List<Downloader> downloads;
private volatile boolean shutdownInitiated = false;
/** True if service is running. */
@@ -117,10 +124,6 @@ public class DownloadService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- if (waiter != null) {
- waiter.interrupt();
- }
- queryDownloads();
return super.onStartCommand(intent, flags, startId);
}
@@ -131,10 +134,12 @@ public class DownloadService extends Service {
Log.d(TAG, "Service started");
isRunning = true;
completedDownloads = new ArrayList<DownloadStatus>();
- downloads = new ArrayList<DownloadStatus>();
+ downloads = new ArrayList<Downloader>();
registerReceiver(downloadReceiver, createIntentFilter());
registerReceiver(onDownloadsChanged, new IntentFilter(
ACTION_NOTIFY_DOWNLOADS_CHANGED));
+ registerReceiver(downloadQueued, new IntentFilter(
+ ACTION_ENQUEUE_DOWNLOAD));
syncExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
@@ -153,6 +158,15 @@ public class DownloadService extends Service {
return t;
}
});
+ downloadExecutor = Executors.newFixedThreadPool(2, new ThreadFactory() {
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setPriority(Thread.MIN_PRIORITY);
+ return t;
+ }
+ });
manager = FeedManager.getInstance();
requester = DownloadRequester.getInstance();
mediaplayer = new MediaPlayer();
@@ -179,6 +193,7 @@ public class DownloadService extends Service {
mediaplayer.release();
unregisterReceiver(downloadReceiver);
unregisterReceiver(onDownloadsChanged);
+ unregisterReceiver(downloadQueued);
downloadObserver.cancel(true);
createReport();
}
@@ -248,6 +263,47 @@ public class DownloadService extends Service {
}
};
+ private BroadcastReceiver downloadQueued = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ACTION_ENQUEUE_DOWNLOAD)) {
+ if (AppConfig.DEBUG) Log.d(TAG, "Received enqueue request");
+ Request request = intent.getParcelableExtra(EXTRA_REQUEST);
+ if (request == null) {
+ throw new IllegalArgumentException(
+ "ACTION_ENQUEUE_DOWNLOAD intent needs request extra");
+ }
+ DownloadRequester requester = DownloadRequester.getInstance();
+ FeedFile feedfile = requester.getDownload(request.source);
+ if (feedfile != null) {
+ if (waiter != null) {
+ waiter.interrupt();
+ }
+ DownloadStatus status = new DownloadStatus(feedfile);
+ Downloader downloader = getDownloader(status);
+ if (downloader != null) {
+ downloads.add(downloader);
+ downloadExecutor.submit(downloader);
+ }
+ } else {
+ Log.e(TAG,
+ "Could not find feedfile in download requester when trying to enqueue new download");
+ }
+ }
+ }
+
+ };
+
+ private Downloader getDownloader(DownloadStatus status) {
+ if (URLUtil.isHttpUrl(status.getFeedFile().getDownload_url())) {
+ return new HttpDownloader(this, status);
+ }
+ Log.e(TAG, "Could not find appropriate downloader for "
+ + status.getFeedFile().getDownload_url());
+ return null;
+ }
+
private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
@SuppressLint("NewApi")
@Override
@@ -703,9 +759,15 @@ public class DownloadService extends Service {
}
};
- }
+ public String getDestination() {
+ return destination;
+ }
+
+ public String getSource() {
+ return source;
+ }
-
+ }
public DownloadObserver getDownloadObserver() {
return downloadObserver;
diff --git a/src/de/danoeh/antennapod/storage/DownloadRequester.java b/src/de/danoeh/antennapod/storage/DownloadRequester.java
index ca81ed4a0..9399de465 100644
--- a/src/de/danoeh/antennapod/storage/DownloadRequester.java
+++ b/src/de/danoeh/antennapod/storage/DownloadRequester.java
@@ -1,7 +1,10 @@
package de.danoeh.antennapod.storage;
import java.io.File;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import android.annotation.SuppressLint;
@@ -23,27 +26,24 @@ import de.danoeh.antennapod.service.download.DownloadService;
import de.danoeh.antennapod.util.NumberGenerator;
import de.danoeh.antennapod.util.URLChecker;
-public class DownloadRequester {// TODO handle externalstorage missing
+public class DownloadRequester {
private static final String TAG = "DownloadRequester";
- private static final int currentApi = android.os.Build.VERSION.SDK_INT;
public static String EXTRA_DOWNLOAD_ID = "extra.de.danoeh.antennapod.storage.download_id";
public static String EXTRA_ITEM_ID = "extra.de.danoeh.antennapod.storage.item_id";
public static String ACTION_DOWNLOAD_QUEUED = "action.de.danoeh.antennapod.storage.downloadQueued";
- private static boolean STORE_ON_SD = true;
public static String IMAGE_DOWNLOADPATH = "images/";
public static String FEED_DOWNLOADPATH = "cache/";
public static String MEDIA_DOWNLOADPATH = "media/";
private static DownloadRequester downloader;
- private DownloadManager manager;
- private List<FeedFile> downloads;
+ Map<String, FeedFile> downloads;
private DownloadRequester() {
- downloads = new CopyOnWriteArrayList<FeedFile>();
+ downloads = new ConcurrentHashMap<String, FeedFile>();
}
public static DownloadRequester getInstance() {
@@ -53,8 +53,7 @@ public class DownloadRequester {// TODO handle externalstorage missing
return downloader;
}
- @SuppressLint("NewApi")
- private long download(Context context, FeedFile item, File dest) {
+ private void download(Context context, FeedFile item, File dest) {
if (!isDownloadingFile(item)) {
if (dest.exists()) {
if (AppConfig.DEBUG)
@@ -64,74 +63,58 @@ public class DownloadRequester {// TODO handle externalstorage missing
if (AppConfig.DEBUG)
Log.d(TAG,
"Requesting download of url " + item.getDownload_url());
- downloads.add(item);
+ downloads.put(item.getDownload_url(), item);
item.setDownload_url(URLChecker.prepareURL(item.getDownload_url()));
- DownloadManager.Request request = new DownloadManager.Request(
- Uri.parse(item.getDownload_url())).setDestinationUri(Uri
- .fromFile(dest));
- if (AppConfig.DEBUG)
- Log.d(TAG, "Version is " + currentApi);
- if (currentApi >= 11) {
- request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
- } else {
- request.setVisibleInDownloadsUi(false);
- request.setShowRunningNotification(false);
- }
-
- // TODO Set Allowed Network Types
- DownloadManager manager = (DownloadManager) context
- .getSystemService(Context.DOWNLOAD_SERVICE);
-
- long downloadId = manager.enqueue(request);
- item.setDownloadId(downloadId);
item.setFile_url(dest.toString());
- context.startService(new Intent(context, DownloadService.class));
+
+ DownloadService.Request request = new DownloadService.Request(
+ item.getFile_url(), item.getDownload_url());
+ Intent queueIntent = new Intent(
+ DownloadService.ACTION_ENQUEUE_DOWNLOAD);
+ queueIntent.putExtra(DownloadService.EXTRA_REQUEST, request);
+ if (!DownloadService.isRunning) {
+ context.startService(new Intent(context, DownloadService.class));
+ }
+ context.sendBroadcast(queueIntent);
context.sendBroadcast(new Intent(ACTION_DOWNLOAD_QUEUED));
- return downloadId;
} else {
Log.e(TAG, "URL " + item.getDownload_url()
+ " is already being downloaded");
- return 0;
}
}
- public long downloadFeed(Context context, Feed feed) {
- return download(context, feed, new File(getFeedfilePath(context),
+ public void downloadFeed(Context context, Feed feed) {
+ download(context, feed, new File(getFeedfilePath(context),
getFeedfileName(feed)));
}
- public long downloadImage(Context context, FeedImage image) {
- return download(context, image, new File(getImagefilePath(context),
+ public void downloadImage(Context context, FeedImage image) {
+ download(context, image, new File(getImagefilePath(context),
getImagefileName(image)));
}
- public long downloadMedia(Context context, FeedMedia feedmedia) {
- return download(context, feedmedia,
+ public void downloadMedia(Context context, FeedMedia feedmedia) {
+ download(context, feedmedia,
new File(getMediafilePath(context, feedmedia),
getMediafilename(feedmedia)));
}
/**
* Cancels a running download.
- *
- * @param context
- * A context needed to get the DownloadManager service
- * @param id
- * ID of the download to cancel
* */
- public void cancelDownload(final Context context, final long id) {
+ public void cancelDownload(final Context context, final FeedFile f) {
+ cancelDownload(context, f.getDownload_url());
+ }
+
+ /**
+ * Cancels a running download.
+ * */
+ public void cancelDownload(final Context context, final String download_url) {
if (AppConfig.DEBUG)
- Log.d(TAG, "Cancelling download with id " + id);
- DownloadManager dm = (DownloadManager) context
- .getSystemService(Context.DOWNLOAD_SERVICE);
- int removed = dm.remove(id);
- if (removed > 0) {
- FeedFile f = getFeedFile(id);
- if (f != null) {
- downloads.remove(f);
- f.setFile_url(null);
- f.setDownloadId(0);
- }
+ Log.d(TAG, "Cancelling download with url " + download_url);
+ FeedFile download = downloads.remove(download_url);
+ if (download != null) {
+ download.setFile_url(null);
notifyDownloadService(context);
}
}
@@ -142,28 +125,17 @@ public class DownloadRequester {// TODO handle externalstorage missing
Log.d(TAG, "Cancelling all running downloads");
DownloadManager dm = (DownloadManager) context
.getSystemService(Context.DOWNLOAD_SERVICE);
- for (FeedFile f : downloads) {
+ for (FeedFile f : downloads.values()) {
dm.remove(f.getDownloadId());
f.setFile_url(null);
- f.setDownloadId(0);
}
downloads.clear();
notifyDownloadService(context);
}
- /** Get a feedfile by its download id */
- public FeedFile getFeedFile(long id) {
- for (FeedFile f : downloads) {
- if (f.getDownloadId() == id) {
- return f;
- }
- }
- return null;
- }
-
/** Returns true if there is at least one Feed in the downloads queue. */
public boolean isDownloadingFeeds() {
- for (FeedFile f : downloads) {
+ for (FeedFile f : downloads.values()) {
if (f.getClass() == Feed.class) {
return true;
}
@@ -173,22 +145,19 @@ public class DownloadRequester {// TODO handle externalstorage missing
/** Checks if feedfile is in the downloads list */
public boolean isDownloadingFile(FeedFile item) {
- for (FeedFile f : downloads) {
- if (f.getDownload_url().equals(item.getDownload_url())) {
- return true;
- }
+ if (item.getDownload_url() != null) {
+ return downloads.containsKey(item.getDownload_url());
}
return false;
}
+ public FeedFile getDownload(String downloadUrl) {
+ return downloads.get(downloadUrl);
+ }
+
/** Checks if feedfile with the given download url is in the downloads list */
public boolean isDownloadingFile(String downloadUrl) {
- for (FeedFile f : downloads) {
- if (f.getDownload_url().equals(downloadUrl)) {
- return true;
- }
- }
- return false;
+ return downloads.get(downloadUrl) != null;
}
public boolean hasNoDownloads() {
@@ -204,10 +173,6 @@ public class DownloadRequester {// TODO handle externalstorage missing
downloads.remove(f);
}
- public List<FeedFile> getDownloads() {
- return downloads;
- }
-
/** Get the number of uncompleted Downloads */
public int getNumberOfDownloads() {
return downloads.size();
@@ -243,6 +208,7 @@ public class DownloadRequester {// TODO handle externalstorage missing
/** Notifies the DownloadService to check if there are any Downloads left */
public void notifyDownloadService(Context context) {
- context.sendBroadcast(new Intent(DownloadService.ACTION_NOTIFY_DOWNLOADS_CHANGED));
+ context.sendBroadcast(new Intent(
+ DownloadService.ACTION_NOTIFY_DOWNLOADS_CHANGED));
}
}
diff --git a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java
index 24100d8c4..d88902c6f 100644
--- a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java
+++ b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java
@@ -81,8 +81,7 @@ public class FeedItemMenuHandler {
manager.deleteFeedMedia(context, selectedItem.getMedia());
break;
case R.id.cancel_download_item:
- requester.cancelDownload(context, selectedItem.getMedia()
- .getDownloadId());
+ requester.cancelDownload(context, selectedItem.getMedia());
break;
case R.id.mark_read_item:
manager.markItemRead(context, selectedItem, true);