diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 50c70d77d..b7859cf1e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,10 +27,5 @@
-
-
-
-
-
diff --git a/src/de/podfetcher/feed/FeedFile.java b/src/de/podfetcher/feed/FeedFile.java
index 99871c9a2..fce50d08f 100644
--- a/src/de/podfetcher/feed/FeedFile.java
+++ b/src/de/podfetcher/feed/FeedFile.java
@@ -1,8 +1,10 @@
package de.podfetcher.feed;
+/** 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
public String getFile_url() {
return file_url;
@@ -16,7 +18,12 @@ public abstract class FeedFile extends FeedComponent {
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;
+ }
}
diff --git a/src/de/podfetcher/service/DownloadService.java b/src/de/podfetcher/service/DownloadService.java
index 34f992b74..871ca969d 100644
--- a/src/de/podfetcher/service/DownloadService.java
+++ b/src/de/podfetcher/service/DownloadService.java
@@ -7,6 +7,8 @@
package de.podfetcher.service;
import java.io.File;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import de.podfetcher.feed.*;
import de.podfetcher.storage.DownloadRequester;
import android.app.Service;
@@ -21,14 +23,19 @@ import android.util.Log;
public class DownloadService extends Service {
public static String ACTION_ALL_FEED_DOWNLOADS_COMPLETED = "action.de.podfetcher.storage.all_feed_downloads_completed";
-
+ public static final String ACTION_FEED_SYNC_COMPLETED = "action.de.podfetcher.service.feed_sync_completed";
+
+ private volatile ScheduledThreadPoolExecutor syncExecutor;
private DownloadRequester requester;
private FeedManager manager;
@Override
public void onCreate() {
Log.d(this.toString(), "Service started");
- registerReceiver(receiver, createIntentFilter());
+ registerReceiver(downloadReceiver, createIntentFilter());
+ syncExecutor = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 2);
+ manager = FeedManager.getInstance();
+ requester = DownloadRequester.getInstance();
}
@Override
@@ -38,49 +45,62 @@ public class DownloadService extends Service {
@Override
public void onDestroy() {
- unregisterReceiver(receiver);
+ Log.d(this.toString(), "Service shutting down");
+ sendBroadcast(new Intent(ACTION_FEED_SYNC_COMPLETED));
}
private IntentFilter createIntentFilter() {
IntentFilter filter = new IntentFilter();
-
filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-
return filter;
}
- private BroadcastReceiver receiver = new BroadcastReceiver() {
+ /** Shuts down Executor service and prepares for shutdown */
+ private void initiateShutdown() {
+ Log.d(this.toString(), "Initiating shutdown");
+ // Wait until PoolExecutor is done
+ Thread waiter = new Thread() {
+ @Override
+ public void run() {
+ syncExecutor.shutdown();
+ try {
+ syncExecutor.awaitTermination(20, TimeUnit.SECONDS);
+ stopSelf();
+ }catch(InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ waiter.start();
+ }
+
+ private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
- requester = DownloadRequester.getInstance();
- manager = FeedManager.getInstance();
- Intent item_intent = requester.getItemIntent(id);
- String action = item_intent.getAction();
- if(action.equals(DownloadRequester.ACTION_FEED_DOWNLOAD_COMPLETED)) {
- handleCompletedFeedDownload(context, item_intent);
- if(requester.getNumberOfFeedDownloads() == 0) {
- sendBroadcast(new Intent(ACTION_ALL_FEED_DOWNLOADS_COMPLETED));
+ long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
+ Feed feed = requester.getFeed(downloadId);
+ if(feed != null) {
+ handleCompletedFeedDownload(context, feed);
+ }else {
+ FeedImage image = requester.getFeedImage(downloadId);
+ if(image != null) {
+ handleCompletedImageDownload(context, image);
}
- } else if(action.equals(DownloadRequester.ACTION_MEDIA_DOWNLOAD_COMPLETED)) {
- requester.removeMediaByID(item_intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
- } else if(action.equals(DownloadRequester.ACTION_IMAGE_DOWNLOAD_COMPLETED)) {
- handleCompletedImageDownload(context, item_intent);
}
// Check if there's something else to download, otherwise stop
if(requester.getNumberOfDownloads() == 0) {
- stopSelf();
+ unregisterReceiver(downloadReceiver);
+ initiateShutdown();
}
}
};
/** Is called whenever a Feed is downloaded */
- private void handleCompletedFeedDownload(Context context, Intent intent) {
- requester.removeFeedByID(intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
+ private void handleCompletedFeedDownload(Context context, Feed feed) {
+ requester.removeFeed(feed);
// Get Feed Information
- Feed feed = manager.getFeed(intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
feed.setFile_url((new File(requester.getFeedfilePath(context), requester.getFeedfileName(feed.getId()))).toString());
// Update Information in Database
manager.setFeed(context, feed);
@@ -88,15 +108,39 @@ public class DownloadService extends Service {
if(feed.getImage() != null) {
requester.downloadImage(context, feed.getImage());
}
- context.startService(intent);
+ syncExecutor.submit(new FeedSyncThread(feed, this));
}
/** Is called whenever a Feed-Image is downloaded */
- private void handleCompletedImageDownload(Context context, Intent intent) {
- requester.removeImageByID(intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
- FeedImage image = manager.getFeedImage(intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
+ private void handleCompletedImageDownload(Context context, FeedImage image) {
+ requester.removeFeedImage(image);
image.setFile_url(requester.getImagefilePath(context) + requester.getImagefileName(image.getId()));
}
+
+ /** Takes a single Feed, parses the corresponding file and refreshes information in the manager */
+ class FeedSyncThread implements Runnable {
+
+ private Feed feed;
+ private DownloadService service;
+
+ public FeedSyncThread(Feed feed, DownloadService service) {
+ this.feed = feed;
+ this.service = service;
+ }
+
+ public void run() {
+ FeedManager manager = FeedManager.getInstance();
+ FeedHandler handler = new FeedHandler();
+
+ feed = handler.parseFeed(feed);
+ Log.d(this.toString(), feed.getTitle() + " parsed");
+ // Add Feeditems to the database
+ for(FeedItem item : feed.getItems()) {
+ manager.addFeedItem(service, item);
+ }
+ }
+
+ }
}
diff --git a/src/de/podfetcher/service/FeedSyncService.java b/src/de/podfetcher/service/FeedSyncService.java
index c03e6ef69..7cb54d855 100644
--- a/src/de/podfetcher/service/FeedSyncService.java
+++ b/src/de/podfetcher/service/FeedSyncService.java
@@ -65,6 +65,7 @@ public class FeedSyncService extends Service {
/** Prepares itself for stopping */
private void initiateShutdown() {
+ Log.d(this.toString(), "Initiating shutdown");
// Wait until PoolExecutor is done
Thread waiter = new Thread() {
@Override
diff --git a/src/de/podfetcher/storage/DownloadRequester.java b/src/de/podfetcher/storage/DownloadRequester.java
index 66effe92f..ac2935a8e 100644
--- a/src/de/podfetcher/storage/DownloadRequester.java
+++ b/src/de/podfetcher/storage/DownloadRequester.java
@@ -3,11 +3,10 @@ package de.podfetcher.storage;
import java.util.ArrayList;
import java.io.File;
-import de.podfetcher.feed.Feed;
-import de.podfetcher.feed.FeedImage;
-import de.podfetcher.feed.FeedMedia;
+import de.podfetcher.feed.*;
import de.podfetcher.service.DownloadService;
+import android.util.Log;
import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
@@ -30,14 +29,14 @@ public class DownloadRequester {
private static DownloadRequester downloader;
- public ArrayList feeds;
- public ArrayList images;
- public ArrayList media;
+ public ArrayList feeds;
+ public ArrayList images;
+ public ArrayList media;
private DownloadRequester(){
- feeds = new ArrayList();
- images = new ArrayList();
- media = new ArrayList();
+ feeds = new ArrayList();
+ images = new ArrayList();
+ media = new ArrayList();
}
@@ -48,89 +47,81 @@ public class DownloadRequester {
return downloader;
}
- private void download(Context context, ArrayList type, String str_uri, File dest, boolean visibleInUI, String action, long id) {
- DownloadManager.Request request = new DownloadManager.Request(Uri.parse(str_uri));
+ private void download(Context context, ArrayList type, FeedFile item, File dest, boolean visibleInUI) {
+ DownloadManager.Request request = new DownloadManager.Request(Uri.parse(item.getDownload_url()));
//request.allowScanningByMediaScanner();
request.setDestinationUri(Uri.fromFile(dest));
request.setVisibleInDownloadsUi(visibleInUI);
// TODO Set Allowed Network Types
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
- Intent i = new Intent(action);
context.startService(new Intent(context, DownloadService.class));
- i.putExtra(EXTRA_DOWNLOAD_ID, manager.enqueue(request));
- i.putExtra(EXTRA_ITEM_ID, id);
- type.add(i);
+ item.setDownloadId(manager.enqueue(request));
+ type.add(item);
}
public void downloadFeed(Context context, Feed feed) {
- download(context, feeds, feed.getDownload_url(),
+ download(context, feeds, feed,
new File(getFeedfilePath(context), getFeedfileName(feed.getId())),
- true, ACTION_FEED_DOWNLOAD_COMPLETED, feed.getId());
+ true);
}
public void downloadImage(Context context, FeedImage image) {
- download(context, images, image.getDownload_url(),
+ download(context, images, image,
new File(getImagefilePath(context), getImagefileName(image.getId())),
- true, ACTION_IMAGE_DOWNLOAD_COMPLETED, image.getId());
+ true);
}
public void downloadMedia(Context context, FeedMedia feedmedia) {
- download(context, media, feedmedia.getDownload_url(),
+ download(context, media, feedmedia,
new File(context.getExternalFilesDir(MEDIA_DOWNLOADPATH), "media-" + feedmedia.getId()),
- true, ACTION_MEDIA_DOWNLOAD_COMPLETED, feedmedia.getId());
+ true);
}
-
- public void removeFeedByID(long id) {
- int len = feeds.size();
- for(int x = 0; x < len; x++) {
- if(feeds.get(x).getLongExtra(EXTRA_ITEM_ID, -1) == id) {
- feeds.remove(x);
- break;
- }
- }
- }
-
- public void removeMediaByID(long id) {
- int len = media.size();
- for(int x = 0; x < len; x++) {
- if(media.get(x).getLongExtra(EXTRA_ITEM_ID, -1) == id) {
- media.remove(x);
- break;
- }
- }
- }
-
- public void removeImageByID(long id) {
- int len = images.size();
- for(int x = 0; x < len; x++) {
- if(images.get(x).getLongExtra(EXTRA_ITEM_ID, -1) == id) {
- images.remove(x);
- break;
- }
- }
- }
-
- /* Returns the stored intent by looking for the right download id */
- public Intent getItemIntent(long id) {
- for(Intent i : feeds) {
- if(i.getLongExtra(EXTRA_DOWNLOAD_ID, -1) == id) {
- return i;
- }
- }
- for(Intent i : media) {
- if(i.getLongExtra(EXTRA_DOWNLOAD_ID, -1) == id) {
- return i;
- }
- }
- for(Intent i : images) {
- if(i.getLongExtra(EXTRA_DOWNLOAD_ID, -1) == id) {
- return i;
+
+ /** Get a Feed by its download id */
+ public Feed getFeed(long id) {
+ for(FeedFile f: feeds) {
+ if(f.getDownloadId() == id) {
+ return (Feed) f;
}
}
return null;
}
+ /** Get a FeedImage by its download id */
+ public FeedImage getFeedImage(long id) {
+ for(FeedFile f: images) {
+ if(f.getDownloadId() == id) {
+ return (FeedImage) f;
+ }
+ }
+ return null;
+ }
+
+
+ /** Get media by its download id */
+ public FeedMedia getFeedMedia(long id) {
+ for(FeedFile f: media) {
+ if(f.getDownloadId() == id) {
+ return (FeedMedia) f;
+ }
+ }
+ return null;
+ }
+
+ public void removeFeed(Feed f) {
+ feeds.remove(f);
+ }
+
+ public void removeFeedMedia(FeedMedia m) {
+ media.remove(m);
+ }
+
+ public void removeFeedImage(FeedImage fi) {
+ images.remove(fi);
+ }
+
+
/** Get the number of uncompleted Downloads */
public int getNumberOfDownloads() {
return feeds.size() + images.size() + media.size();