diff --git a/res/values/strings.xml b/res/values/strings.xml index 4554f3d27..ff7b189d7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -78,6 +78,7 @@ Malformed URL IO Error External storage unavailable + Request error \u0020Downloads left Downloading podcast data %1$d downloads succeeded, %2$d failed @@ -85,7 +86,8 @@ Feed Media file Image - + An error occurred when trying to download the file:\u0020 + Error! No media playing diff --git a/src/de/danoeh/antennapod/activity/AddFeedActivity.java b/src/de/danoeh/antennapod/activity/AddFeedActivity.java index 8670e0cd1..c12ca4088 100644 --- a/src/de/danoeh/antennapod/activity/AddFeedActivity.java +++ b/src/de/danoeh/antennapod/activity/AddFeedActivity.java @@ -20,6 +20,7 @@ import com.actionbarsherlock.view.MenuItem; import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.feed.Feed; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.ConnectionTester; import de.danoeh.antennapod.util.DownloadError; @@ -123,11 +124,17 @@ public class AddFeedActivity extends SherlockActivity { @Override public void onConnectionSuccessful() { - requester.downloadFeed(AddFeedActivity.this, feed); - if (progDialog.isShowing()) { - progDialog.dismiss(); - finish(); + try { + requester.downloadFeed(AddFeedActivity.this, feed); + if (progDialog.isShowing()) { + progDialog.dismiss(); + finish(); + } + } catch (DownloadRequestException e) { + e.printStackTrace(); + onConnectionFailure(DownloadError.ERROR_REQUEST_ERROR); } + } @Override diff --git a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java index af91fc296..36d3844a5 100644 --- a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java +++ b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java @@ -13,8 +13,10 @@ import com.actionbarsherlock.view.MenuItem; import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.asynctask.FeedImageLoader; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedManager; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.util.LangUtils; import de.danoeh.antennapod.util.menuhandler.FeedMenuHandler; @@ -97,7 +99,13 @@ public class FeedInfoActivity extends SherlockActivity { finish(); return true; default: - return FeedMenuHandler.onOptionsItemClicked(this, item, feed); + try { + return FeedMenuHandler.onOptionsItemClicked(this, item, feed); + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(this, e.getMessage()); + } + return super.onOptionsItemSelected(item); } } } diff --git a/src/de/danoeh/antennapod/activity/FeedItemlistActivity.java b/src/de/danoeh/antennapod/activity/FeedItemlistActivity.java index a134cd23b..f37d726cf 100644 --- a/src/de/danoeh/antennapod/activity/FeedItemlistActivity.java +++ b/src/de/danoeh/antennapod/activity/FeedItemlistActivity.java @@ -17,11 +17,13 @@ import com.actionbarsherlock.view.Window; import de.danoeh.antennapod.R; import de.danoeh.antennapod.asynctask.FeedRemover; import de.danoeh.antennapod.dialog.ConfirmationDialog; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.fragment.ExternalPlayerFragment; import de.danoeh.antennapod.fragment.FeedlistFragment; import de.danoeh.antennapod.fragment.ItemlistFragment; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.util.StorageUtils; import de.danoeh.antennapod.util.menuhandler.FeedMenuHandler; @@ -89,40 +91,45 @@ public class FeedItemlistActivity extends SherlockFragmentActivity { @SuppressLint("NewApi") @Override public boolean onOptionsItemSelected(MenuItem item) { - if (FeedMenuHandler.onOptionsItemClicked(this, item, feed)) { - filf.getListAdapter().notifyDataSetChanged(); - } else { - switch (item.getItemId()) { - case R.id.remove_item: - final FeedRemover remover = new FeedRemover( - FeedItemlistActivity.this, feed) { - @Override - protected void onPostExecute(Void result) { - super.onPostExecute(result); - finish(); - } - }; - ConfirmationDialog conDialog = new ConfirmationDialog(this, - R.string.remove_feed_label, - R.string.feed_delete_confirmation_msg) { + try { + if (FeedMenuHandler.onOptionsItemClicked(this, item, feed)) { + filf.getListAdapter().notifyDataSetChanged(); + } else { + switch (item.getItemId()) { + case R.id.remove_item: + final FeedRemover remover = new FeedRemover( + FeedItemlistActivity.this, feed) { + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + finish(); + } + }; + ConfirmationDialog conDialog = new ConfirmationDialog(this, + R.string.remove_feed_label, + R.string.feed_delete_confirmation_msg) { - @Override - public void onConfirmButtonPressed(DialogInterface dialog) { - dialog.dismiss(); - remover.executeAsync(); - } - }; - conDialog.createNewDialog().show(); - break; - case R.id.search_item: - onSearchRequested(); - break; - case android.R.id.home: - Intent intent = new Intent(this, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - break; + @Override + public void onConfirmButtonPressed(DialogInterface dialog) { + dialog.dismiss(); + remover.executeAsync(); + } + }; + conDialog.createNewDialog().show(); + break; + case R.id.search_item: + onSearchRequested(); + break; + case android.R.id.home: + Intent intent = new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + break; + } } + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(this, e.getMessage()); } return true; } diff --git a/src/de/danoeh/antennapod/activity/ItemviewActivity.java b/src/de/danoeh/antennapod/activity/ItemviewActivity.java index 2ba1f3579..c651cdaa7 100644 --- a/src/de/danoeh/antennapod/activity/ItemviewActivity.java +++ b/src/de/danoeh/antennapod/activity/ItemviewActivity.java @@ -17,12 +17,14 @@ import com.actionbarsherlock.view.Window; import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedItem; import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.fragment.FeedlistFragment; import de.danoeh.antennapod.fragment.ItemDescriptionFragment; import de.danoeh.antennapod.fragment.ItemlistFragment; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.util.StorageUtils; import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler; @@ -104,12 +106,17 @@ public class ItemviewActivity extends SherlockFragmentActivity { @Override public boolean onOptionsItemSelected(MenuItem menuItem) { - if (!FeedItemMenuHandler.onMenuItemClicked(this, menuItem, item)) { - switch (menuItem.getItemId()) { - case android.R.id.home: - finish(); - break; + try { + if (!FeedItemMenuHandler.onMenuItemClicked(this, menuItem, item)) { + switch (menuItem.getItemId()) { + case android.R.id.home: + finish(); + break; + } } + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(this, e.getMessage()); } invalidateOptionsMenu(); return true; diff --git a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java index 4bb6dc74a..ef4260bd7 100644 --- a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -19,9 +19,11 @@ import com.actionbarsherlock.view.MenuItem; import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.dialog.TimeDialog; import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.util.Converter; import de.danoeh.antennapod.util.MediaPlayerError; import de.danoeh.antennapod.util.PlaybackController; @@ -210,8 +212,10 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: - Intent intent = new Intent(MediaplayerActivity.this, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + Intent intent = new Intent(MediaplayerActivity.this, + MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); break; case R.id.disable_sleeptimer_item: @@ -259,8 +263,14 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity } default: - return FeedItemMenuHandler.onMenuItemClicked(this, item, controller - .getMedia().getItem()); + try { + return FeedItemMenuHandler.onMenuItemClicked(this, item, + controller.getMedia().getItem()); + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(this, + e.getMessage()); + } } return true; } diff --git a/src/de/danoeh/antennapod/activity/MiroGuideChannelViewActivity.java b/src/de/danoeh/antennapod/activity/MiroGuideChannelViewActivity.java index 6383a4993..46bbcc554 100644 --- a/src/de/danoeh/antennapod/activity/MiroGuideChannelViewActivity.java +++ b/src/de/danoeh/antennapod/activity/MiroGuideChannelViewActivity.java @@ -23,11 +23,13 @@ import com.actionbarsherlock.view.MenuItem; import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.MiroGuideItemlistAdapter; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.miroguide.con.MiroGuideException; import de.danoeh.antennapod.miroguide.con.MiroGuideService; import de.danoeh.antennapod.miroguide.model.MiroGuideChannel; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; /** @@ -154,8 +156,13 @@ public class MiroGuideChannelViewActivity extends SherlockActivity { startActivity(new Intent(Intent.ACTION_VIEW, uri)); return true; case R.id.add_feed: - DownloadRequester.getInstance().downloadFeed(this, - new Feed(channel.getDownloadUrl(), new Date(), channel.getName())); + try { + DownloadRequester.getInstance().downloadFeed(this, + new Feed(channel.getDownloadUrl(), new Date(), channel.getName())); + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(this, e.getMessage()); + } Toast toast = Toast.makeText(this, R.string.miro_feed_added, Toast.LENGTH_LONG); toast.show(); diff --git a/src/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java b/src/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java index e244432ef..08c038206 100644 --- a/src/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java +++ b/src/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java @@ -10,6 +10,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.OpmlImportActivity; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.opml.OpmlElement; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; /** Queues items for download in the background. */ @@ -17,24 +18,18 @@ public class OpmlFeedQueuer extends AsyncTask { private Context context; private ProgressDialog progDialog; private int[] selection; - - - + public OpmlFeedQueuer(Context context, int[] selection) { super(); this.context = context; this.selection = selection; } - - @Override protected void onPostExecute(Void result) { progDialog.dismiss(); } - - @Override protected void onPreExecute() { progDialog = new ProgressDialog(context); @@ -44,19 +39,23 @@ public class OpmlFeedQueuer extends AsyncTask { progDialog.show(); } - - @Override protected Void doInBackground(Void... params) { DownloadRequester requester = DownloadRequester.getInstance(); for (int idx = 0; idx < selection.length; idx++) { - OpmlElement element = OpmlImportActivity.getReadElements().get(selection[idx]); - Feed feed = new Feed(element.getXmlUrl(), new Date(), element.getText()); - requester.downloadFeed(context.getApplicationContext(), feed); + OpmlElement element = OpmlImportActivity.getReadElements().get( + selection[idx]); + Feed feed = new Feed(element.getXmlUrl(), new Date(), + element.getText()); + try { + requester.downloadFeed(context.getApplicationContext(), feed); + } catch (DownloadRequestException e) { + e.printStackTrace(); + } } return null; } - + @SuppressLint("NewApi") public void executeAsync() { if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { diff --git a/src/de/danoeh/antennapod/dialog/DownloadRequestErrorDialogCreator.java b/src/de/danoeh/antennapod/dialog/DownloadRequestErrorDialogCreator.java new file mode 100644 index 000000000..349b39682 --- /dev/null +++ b/src/de/danoeh/antennapod/dialog/DownloadRequestErrorDialogCreator.java @@ -0,0 +1,31 @@ +package de.danoeh.antennapod.dialog; + +import de.danoeh.antennapod.R; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.content.Context; +import android.content.DialogInterface; + +/** Creates Alert Dialogs if a DownloadRequestException has happened. */ +public class DownloadRequestErrorDialogCreator { + private DownloadRequestErrorDialogCreator() { + } + + public static void newRequestErrorDialog(Context context, + String errorMessage) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setNeutralButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .setTitle(R.string.download_error_request_error) + .setMessage( + context.getString(R.string.download_request_error_dialog_message_prefix) + + errorMessage); + builder.create().show(); + } +} diff --git a/src/de/danoeh/antennapod/feed/FeedManager.java b/src/de/danoeh/antennapod/feed/FeedManager.java index 370c515f6..9f6c3c0df 100644 --- a/src/de/danoeh/antennapod/feed/FeedManager.java +++ b/src/de/danoeh/antennapod/feed/FeedManager.java @@ -22,8 +22,10 @@ import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.PodcastApp; import de.danoeh.antennapod.asynctask.DownloadStatus; import de.danoeh.antennapod.service.PlaybackService; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.storage.PodDBAdapter; +import de.danoeh.antennapod.util.DownloadError; import de.danoeh.antennapod.util.FeedtitleComparator; import de.danoeh.antennapod.util.comparator.DownloadStatusComparator; import de.danoeh.antennapod.util.comparator.FeedItemPubdateComparator; @@ -305,7 +307,17 @@ public class FeedManager { @Override protected Void doInBackground(Void... params) { for (Feed feed : feeds) { - refreshFeed(context, feed); + try { + refreshFeed(context, feed); + } catch (DownloadRequestException e) { + e.printStackTrace(); + addDownloadStatus( + context, + new DownloadStatus(feed, feed + .getHumanReadableIdentifier(), + DownloadError.ERROR_REQUEST_ERROR, + false, e.getMessage())); + } } return null; } @@ -327,10 +339,16 @@ public class FeedManager { public void notifyInvalidImageFile(Context context, FeedImage image) { Log.i(TAG, "The feedmanager was notified about an invalid image download. It will now try to redownload the image file"); - requester.downloadImage(context, image); + try { + requester.downloadImage(context, image); + } catch (DownloadRequestException e) { + e.printStackTrace(); + Log.w(TAG, "Failed to download invalid feed image"); + } } - public void refreshFeed(Context context, Feed feed) { + public void refreshFeed(Context context, Feed feed) + throws DownloadRequestException { requester.downloadFeed(context, new Feed(feed.getDownload_url(), new Date(), feed.getTitle())); } @@ -370,11 +388,17 @@ public class FeedManager { public void downloadAllItemsInQueue(final Context context) { if (!queue.isEmpty()) { - downloadFeedItem(context, queue.toArray(new FeedItem[queue.size()])); + try { + downloadFeedItem(context, + queue.toArray(new FeedItem[queue.size()])); + } catch (DownloadRequestException e) { + e.printStackTrace(); + } } } - public void downloadFeedItem(final Context context, FeedItem... items) { + public void downloadFeedItem(final Context context, FeedItem... items) + throws DownloadRequestException { boolean autoQueue = PreferenceManager.getDefaultSharedPreferences( context.getApplicationContext()).getBoolean( PodcastApp.PREF_AUTO_QUEUE, true); @@ -384,7 +408,21 @@ public class FeedManager { if (item.getMedia() != null && !requester.isDownloadingFile(item.getMedia()) && !item.getMedia().isDownloaded()) { - requester.downloadMedia(context, item.getMedia()); + if (items.length > 1) { + try { + requester.downloadMedia(context, item.getMedia()); + } catch (DownloadRequestException e) { + e.printStackTrace(); + addDownloadStatus(context, + new DownloadStatus(item.getMedia(), item + .getMedia() + .getHumanReadableIdentifier(), + DownloadError.ERROR_REQUEST_ERROR, + false, e.getMessage())); + } + } else { + requester.downloadMedia(context, item.getMedia()); + } addToQueue.add(item); } } diff --git a/src/de/danoeh/antennapod/fragment/FeedlistFragment.java b/src/de/danoeh/antennapod/fragment/FeedlistFragment.java index 6df922554..1a205f521 100644 --- a/src/de/danoeh/antennapod/fragment/FeedlistFragment.java +++ b/src/de/danoeh/antennapod/fragment/FeedlistFragment.java @@ -29,9 +29,11 @@ import de.danoeh.antennapod.activity.FeedItemlistActivity; import de.danoeh.antennapod.adapter.FeedlistAdapter; import de.danoeh.antennapod.asynctask.FeedRemover; import de.danoeh.antennapod.dialog.ConfirmationDialog; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.service.download.DownloadService; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.menuhandler.FeedMenuHandler; @@ -159,29 +161,40 @@ public class FeedlistFragment extends SherlockFragment implements @SuppressLint("NewApi") @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - if (FeedMenuHandler.onOptionsItemClicked(getSherlockActivity(), item, - selectedFeed)) { - fla.notifyDataSetChanged(); - } else { - switch (item.getItemId()) { - case R.id.remove_item: - final FeedRemover remover = new FeedRemover(getSherlockActivity(), selectedFeed) { - @Override - protected void onPostExecute(Void result) { - super.onPostExecute(result); - fla.notifyDataSetChanged(); - } - }; - ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(), R.string.remove_feed_label, R.string.feed_delete_confirmation_msg){ + try { + if (FeedMenuHandler.onOptionsItemClicked(getSherlockActivity(), + item, selectedFeed)) { + fla.notifyDataSetChanged(); + } else { + switch (item.getItemId()) { + case R.id.remove_item: + final FeedRemover remover = new FeedRemover( + getSherlockActivity(), selectedFeed) { + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + fla.notifyDataSetChanged(); + } + }; + ConfirmationDialog conDialog = new ConfirmationDialog( + getActivity(), R.string.remove_feed_label, + R.string.feed_delete_confirmation_msg) { - @Override - public void onConfirmButtonPressed(DialogInterface dialog) { - dialog.dismiss(); - remover.executeAsync(); - }}; - conDialog.createNewDialog().show(); - break; + @Override + public void onConfirmButtonPressed( + DialogInterface dialog) { + dialog.dismiss(); + remover.executeAsync(); + } + }; + conDialog.createNewDialog().show(); + break; + } } + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog( + getActivity(), e.getMessage()); } mode.finish(); return true; diff --git a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java index 5ba83183a..1b1ae2472 100644 --- a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -23,10 +23,12 @@ import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.ItemviewActivity; import de.danoeh.antennapod.adapter.FeedItemlistAdapter; +import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedItem; import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.service.download.DownloadService; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler; @@ -231,8 +233,15 @@ public class ItemlistFragment extends SherlockListFragment implements @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - boolean handled = FeedItemMenuHandler.onMenuItemClicked( - getSherlockActivity(), item, selectedItem); + boolean handled = false; + try { + handled = FeedItemMenuHandler.onMenuItemClicked( + getSherlockActivity(), item, selectedItem); + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog( + getActivity(), e.getMessage()); + } if (handled) { fila.notifyDataSetChanged(); } diff --git a/src/de/danoeh/antennapod/service/download/DownloadService.java b/src/de/danoeh/antennapod/service/download/DownloadService.java index 84641c94d..7101e4aaf 100644 --- a/src/de/danoeh/antennapod/service/download/DownloadService.java +++ b/src/de/danoeh/antennapod/service/download/DownloadService.java @@ -51,6 +51,7 @@ import de.danoeh.antennapod.feed.FeedFile; import de.danoeh.antennapod.feed.FeedImage; import de.danoeh.antennapod.feed.FeedManager; import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.syndication.handler.FeedHandler; import de.danoeh.antennapod.syndication.handler.UnsupportedFeedtypeException; @@ -561,8 +562,18 @@ public class DownloadService extends Service { if (AppConfig.DEBUG) Log.d(TAG, "Feed has image; Downloading...."); savedFeed.getImage().setFeed(savedFeed); - requester.downloadImage(DownloadService.this, - savedFeed.getImage()); + try { + requester.downloadImage(DownloadService.this, + savedFeed.getImage()); + } catch (DownloadRequestException e) { + e.printStackTrace(); + manager.addDownloadStatus(DownloadService.this, + new DownloadStatus(savedFeed.getImage(), + savedFeed.getImage() + .getHumanReadableIdentifier(), + DownloadError.ERROR_REQUEST_ERROR, + false, e.getMessage())); + } } } catch (SAXException e) { @@ -693,7 +704,8 @@ public class DownloadService extends Service { } if (media.getItem().getChapters() == null) { - ChapterUtils.readID3ChaptersFromFeedMediaFileUrl(media.getItem()); + ChapterUtils.readID3ChaptersFromFeedMediaFileUrl(media + .getItem()); if (media.getItem().getChapters() != null) { chaptersRead = true; } diff --git a/src/de/danoeh/antennapod/storage/DownloadRequestException.java b/src/de/danoeh/antennapod/storage/DownloadRequestException.java new file mode 100644 index 000000000..0ef766e58 --- /dev/null +++ b/src/de/danoeh/antennapod/storage/DownloadRequestException.java @@ -0,0 +1,25 @@ +package de.danoeh.antennapod.storage; + +/** + * Thrown by the DownloadRequester if a download request contains invalid data + * or something went wrong while processing the request. + */ +public class DownloadRequestException extends Exception { + + public DownloadRequestException() { + super(); + } + + public DownloadRequestException(String detailMessage, Throwable throwable) { + super(detailMessage, throwable); + } + + public DownloadRequestException(String detailMessage) { + super(detailMessage); + } + + public DownloadRequestException(Throwable throwable) { + super(throwable); + } + +} diff --git a/src/de/danoeh/antennapod/storage/DownloadRequester.java b/src/de/danoeh/antennapod/storage/DownloadRequester.java index 13c8f58d0..928b923fd 100644 --- a/src/de/danoeh/antennapod/storage/DownloadRequester.java +++ b/src/de/danoeh/antennapod/storage/DownloadRequester.java @@ -60,7 +60,7 @@ public class DownloadRequester { DownloadService.Request request = new DownloadService.Request( item.getFile_url(), item.getDownload_url()); - + if (!DownloadService.isRunning) { Intent launchIntent = new Intent(context, DownloadService.class); launchIntent.putExtra(DownloadService.EXTRA_REQUEST, request); @@ -78,20 +78,44 @@ public class DownloadRequester { } } - public void downloadFeed(Context context, Feed feed) { - download(context, feed, new File(getFeedfilePath(context), - getFeedfileName(feed))); + public void downloadFeed(Context context, Feed feed) + throws DownloadRequestException { + if (feedFileValid(feed)) { + download(context, feed, new File(getFeedfilePath(context), + getFeedfileName(feed))); + } } - public void downloadImage(Context context, FeedImage image) { - download(context, image, new File(getImagefilePath(context), - getImagefileName(image))); + public void downloadImage(Context context, FeedImage image) + throws DownloadRequestException { + if (feedFileValid(image)) { + download(context, image, new File(getImagefilePath(context), + getImagefileName(image))); + } } - public void downloadMedia(Context context, FeedMedia feedmedia) { - download(context, feedmedia, - new File(getMediafilePath(context, feedmedia), - getMediafilename(feedmedia))); + public void downloadMedia(Context context, FeedMedia feedmedia) throws DownloadRequestException { + if (feedFileValid(feedmedia)) { + download(context, feedmedia, + new File(getMediafilePath(context, feedmedia), + getMediafilename(feedmedia))); + } + } + + /** + * Throws a DownloadRequestException if the feedfile or the download url of + * the feedfile is null. + * + * @throws DownloadRequestException + */ + private boolean feedFileValid(FeedFile f) throws DownloadRequestException { + if (f == null) { + throw new DownloadRequestException("Feedfile was null"); + } else if (f.getDownload_url() == null) { + throw new DownloadRequestException("File has no download URL"); + } else { + return true; + } } /** @@ -158,7 +182,8 @@ public class DownloadRequester { /** Remove an object from the downloads-list of the requester. */ public void removeDownload(FeedFile f) { if (downloads.remove(f.getDownload_url()) == null) { - Log.e(TAG, "Could not remove object with url " + f.getDownload_url()); + Log.e(TAG, + "Could not remove object with url " + f.getDownload_url()); } } @@ -167,29 +192,46 @@ public class DownloadRequester { return downloads.size(); } - public String getFeedfilePath(Context context) { - return context.getExternalFilesDir(FEED_DOWNLOADPATH).toString() + "/"; + public String getFeedfilePath(Context context) + throws DownloadRequestException { + return getExternalFilesDirOrThrowException(context, 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 getImagefilePath(Context context) + throws DownloadRequestException { + return getExternalFilesDirOrThrowException(context, IMAGE_DOWNLOADPATH) + .toString() + "/"; } public String getImagefileName(FeedImage image) { return "image-" + NumberGenerator.generateLong(image.getDownload_url()); } - public String getMediafilePath(Context context, FeedMedia media) { - File externalStorage = context.getExternalFilesDir(MEDIA_DOWNLOADPATH - + NumberGenerator.generateLong(media.getItem().getFeed() - .getTitle()) + "/"); + public String getMediafilePath(Context context, FeedMedia media) + throws DownloadRequestException { + File externalStorage = getExternalFilesDirOrThrowException( + context, + MEDIA_DOWNLOADPATH + + NumberGenerator.generateLong(media.getItem() + .getFeed().getTitle()) + "/"); return externalStorage.toString(); } + private File getExternalFilesDirOrThrowException(Context context, + String type) throws DownloadRequestException { + File result = context.getExternalFilesDir(type); + if (result == null) { + throw new DownloadRequestException( + "Failed to access external storage"); + } + return result; + } + public String getMediafilename(FeedMedia media) { return URLUtil.guessFileName(media.getDownload_url(), null, media.getMime_type()); diff --git a/src/de/danoeh/antennapod/util/DownloadError.java b/src/de/danoeh/antennapod/util/DownloadError.java index f5eaba733..4723a521c 100644 --- a/src/de/danoeh/antennapod/util/DownloadError.java +++ b/src/de/danoeh/antennapod/util/DownloadError.java @@ -16,6 +16,7 @@ public class DownloadError { public static final int ERROR_HTTP_DATA_ERROR = 9; public static final int ERROR_NOT_ENOUGH_SPACE = 10; public static final int ERROR_UNKNOWN_HOST = 11; + public static final int ERROR_REQUEST_ERROR = 12; /** Get a human-readable string for a specific error code. */ public static String getErrorString(Context context, int code) { @@ -45,6 +46,9 @@ public class DownloadError { case ERROR_UNKNOWN_HOST: resId = R.string.download_error_unknown_host; break; + case ERROR_REQUEST_ERROR: + resId = R.string.download_error_request_error; + break; default: resId = R.string.download_error_error_unknown; } diff --git a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java index 1acb5a9f7..91f199ce0 100644 --- a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java +++ b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java @@ -13,6 +13,7 @@ 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.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.ShareUtils; @@ -64,7 +65,7 @@ public class FeedItemMenuHandler { } public static boolean onMenuItemClicked(Context context, MenuItem item, - FeedItem selectedItem) { + FeedItem selectedItem) throws DownloadRequestException { DownloadRequester requester = DownloadRequester.getInstance(); FeedManager manager = FeedManager.getInstance(); switch (item.getItemId()) { diff --git a/src/de/danoeh/antennapod/util/menuhandler/FeedMenuHandler.java b/src/de/danoeh/antennapod/util/menuhandler/FeedMenuHandler.java index 631169f8a..3a78ffb30 100644 --- a/src/de/danoeh/antennapod/util/menuhandler/FeedMenuHandler.java +++ b/src/de/danoeh/antennapod/util/menuhandler/FeedMenuHandler.java @@ -16,6 +16,7 @@ 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.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.ShareUtils; @@ -51,9 +52,10 @@ public class FeedMenuHandler { return true; } - /** NOTE: This method does not handle clicks on the 'remove feed' - item. */ + /** NOTE: This method does not handle clicks on the 'remove feed' - item. + * @throws DownloadRequestException */ public static boolean onOptionsItemClicked(Context context, MenuItem item, - Feed selectedFeed) { + Feed selectedFeed) throws DownloadRequestException { FeedManager manager = FeedManager.getInstance(); switch (item.getItemId()) { case R.id.show_info_item: