package de.podfetcher.storage; import java.util.ArrayList; import java.io.File; import java.util.concurrent.Callable; import de.podfetcher.feed.*; import de.podfetcher.service.DownloadService; import de.podfetcher.util.NumberGenerator; import de.podfetcher.R; import android.util.Log; import android.database.Cursor; import android.app.DownloadManager; import android.content.Context; import android.net.Uri; import android.os.Messenger; import android.content.ServiceConnection; import android.os.IBinder; import android.content.ComponentName; import android.os.Message; import android.os.RemoteException; import android.content.Intent; import android.webkit.URLUtil; public class DownloadRequester { private static final String TAG = "DownloadRequester"; public static String EXTRA_DOWNLOAD_ID = "extra.de.podfetcher.storage.download_id"; public static String EXTRA_ITEM_ID = "extra.de.podfetcher.storage.item_id"; public static String ACTION_FEED_DOWNLOAD_COMPLETED = "action.de.podfetcher.storage.feed_download_completed"; public static String ACTION_MEDIA_DOWNLOAD_COMPLETED = "action.de.podfetcher.storage.media_download_completed"; public static String ACTION_IMAGE_DOWNLOAD_COMPLETED = "action.de.podfetcher.storage.image_download_completed"; 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; public ArrayList feeds; public ArrayList images; public ArrayList media; private DownloadRequester(){ feeds = new ArrayList(); images = new ArrayList(); media = new ArrayList(); } public static DownloadRequester getInstance() { if(downloader == null) { downloader = new DownloadRequester(); } return downloader; } private long download(Context context, ArrayList type, FeedFile item, File dest, boolean visibleInUI) { Log.d(TAG, "Requesting download of url "+ item.getDownload_url()); type.add(item); 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); context.startService(new Intent(context, DownloadService.class)); long downloadId = manager.enqueue(request); item.setDownloadId(downloadId); item.setFile_url(dest.toString()); return downloadId; } public long downloadFeed(Context context, Feed feed) { return download(context, feeds, feed, new File(getFeedfilePath(context), getFeedfileName(feed)), true); } public long downloadImage(Context context, FeedImage image) { return download(context, images, image, new File(getImagefilePath(context), getImagefileName(image)), true); } public long downloadMedia(Context context, FeedMedia feedmedia) { return download(context, media, feedmedia, new File(getMediafilePath(context, feedmedia), getMediafilename(feedmedia)), true); } /** 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) { Log.d(TAG, "Cancelling download with id " + id); DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); int removed = manager.remove(id); if (removed > 0) { // Delete downloads in lists Feed feed = getFeed(id); if (feed != null) { feeds.remove(feed); } else { FeedImage image = getFeedImage(id); if (image != null) { images.remove(image); } else { FeedMedia m = getFeedMedia(id); if (media != null) { media.remove(m); } } } } } /** 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); } public ArrayList getMediaDownloads() { return media; } /** Get the number of uncompleted Downloads */ public int getNumberOfDownloads() { return feeds.size() + images.size() + media.size(); } public int getNumberOfFeedDownloads() { return feeds.size(); } public String getFeedfilePath(Context context) { return context.getExternalFilesDir(FEED_DOWNLOADPATH).toString() + "/"; } public String getFeedfileName(Feed feed) { return "feed-" + NumberGenerator.generateLong(feed.getDownload_url()); } public String getImagefilePath(Context context) { return context.getExternalFilesDir(IMAGE_DOWNLOADPATH).toString() + "/"; } public String getImagefileName(FeedImage image) { return "image-" + NumberGenerator.generateLong(image.getDownload_url()); } public String getMediafilePath(Context context, FeedMedia media) { return context.getExternalFilesDir(MEDIA_DOWNLOADPATH + media.getItem().getFeed().getTitle() + "/").toString(); } public String getMediafilename(FeedMedia media) { return URLUtil.guessFileName(media.getDownload_url(), null, media.getMime_type()); } public boolean isDownloaded(Feed feed) { return feed.getFile_url() != null && !feeds.contains(feed); } public boolean isDownloaded(FeedImage image) { return image.getFile_url() != null && !images.contains(image); } public boolean isDownloaded(FeedMedia m) { return m.getFile_url() != null && media.contains(m); } public boolean isDownloading(Feed feed) { return feed.getFile_url() != null && feeds.contains(feed); } public boolean isDownloading(FeedImage image) { return image.getFile_url() != null && images.contains(image); } public boolean isDownloading(FeedMedia m) { return m.getFile_url() != null && media.contains(m); } /* ------------ Methods for communicating with the DownloadService ------------- */ private Messenger mService = null; boolean mIsBound; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mService = new Messenger(service); try { Message msg = Message.obtain(null, DownloadService.MSG_QUERY_DOWNLOADS_LEFT); Log.d(TAG, "Sending message to DownloadService."); mService.send(msg); } catch(RemoteException e) { Log.e(TAG, "An Exception happened while communication with the DownloadService"); } } public void onServiceDisconnected(ComponentName className) { mService = null; Log.i(TAG, "Closed connection with DownloadService."); } }; /** Notifies the DownloadService to check if there are any Downloads left */ public void notifyDownloadService(Context context) { context.bindService(new Intent(context, DownloadService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; context.unbindService(mConnection); mIsBound = false; } }