diff options
author | Tom Hennen <TomHennen@users.noreply.github.com> | 2015-09-04 19:00:36 -0400 |
---|---|---|
committer | Tom Hennen <TomHennen@users.noreply.github.com> | 2015-09-04 19:00:36 -0400 |
commit | 26ca16bfa205638ca45610c5c766921a87d8f9d7 (patch) | |
tree | 2992c77031797ec49a32edb4da97004a6ade2e5d /app/src/main | |
parent | 794cf98ffb50eca97261af3fe67142d8022732b7 (diff) | |
parent | a2941e4509b3506ca6a0e6d78e033c6acf3eba03 (diff) | |
download | AntennaPod-26ca16bfa205638ca45610c5c766921a87d8f9d7.zip |
Merge pull request #1151 from mfietz/issue/1149-load-destroyed-activity
Fix loading in destroyed feed view activity
Diffstat (limited to 'app/src/main')
6 files changed, 365 insertions, 472 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 710446885..72e7752b1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -203,7 +203,7 @@ android:value="de.danoeh.antennapod.activity.PreferenceActivity"/> <activity - android:name=".activity.DefaultOnlineFeedViewActivity" + android:name=".activity.OnlineFeedViewActivity" android:configChanges="orientation" android:label="@string/add_feed_label"> <meta-data diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java deleted file mode 100644 index 0993ed6d6..000000000 --- a/app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java +++ /dev/null @@ -1,255 +0,0 @@ -package de.danoeh.antennapod.activity; - -import android.content.Context; -import android.content.Intent; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.v4.app.NavUtils; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.Spinner; -import android.widget.TextView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.DiskCacheStrategy; - -import org.apache.commons.lang3.StringUtils; -import org.jsoup.Jsoup; -import org.jsoup.examples.HtmlToPlainText; -import org.jsoup.nodes.Document; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.adapter.FeedItemlistDescriptionAdapter; -import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; -import de.danoeh.antennapod.core.feed.EventDistributor; -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.glide.ApGlideSettings; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DownloadRequestException; -import de.danoeh.antennapod.core.storage.DownloadRequester; - -/** - * Default implementation of OnlineFeedViewActivity. Shows the downloaded feed's items with their descriptions, - * a subscribe button and a spinner for choosing alternate feed URLs. - */ -public class DefaultOnlineFeedViewActivity extends OnlineFeedViewActivity { - private static final String TAG = "DefaultOnlineFeedViewActivity"; - - private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | EventDistributor.DOWNLOAD_QUEUED | EventDistributor.FEED_LIST_UPDATE; - private volatile List<Feed> feeds; - private Feed feed; - private String selectedDownloadUrl; - - private Button subscribeButton; - - @Override - protected void onCreate(Bundle arg0) { - super.onCreate(arg0); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - Intent destIntent = new Intent(this, MainActivity.class); - if (NavUtils.shouldUpRecreateTask(this, destIntent)) { - startActivity(destIntent); - } else { - NavUtils.navigateUpFromSameTask(this); - } - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void loadData() { - super.loadData(); - feeds = DBReader.getFeedList(this); - } - - @Override - protected void beforeShowFeedInformation(Feed feed, Map<String, String> alternateFeedUrls) { - super.beforeShowFeedInformation(feed, alternateFeedUrls); - - // remove HTML tags from descriptions - - if (BuildConfig.DEBUG) Log.d(TAG, "Removing HTML from shownotes"); - if (feed.getItems() != null) { - HtmlToPlainText formatter = new HtmlToPlainText(); - for (FeedItem item : feed.getItems()) { - if (item.getDescription() != null) { - Document description = Jsoup.parse(item.getDescription()); - item.setDescription(StringUtils.trim(formatter.getPlainText(description))); - } - } - } - } - - @Override - protected void showFeedInformation(final Feed feed, final Map<String, String> alternateFeedUrls) { - super.showFeedInformation(feed, alternateFeedUrls); - setContentView(R.layout.listview_activity); - - this.feed = feed; - this.selectedDownloadUrl = feed.getDownload_url(); - EventDistributor.getInstance().register(listener); - ListView listView = (ListView) findViewById(R.id.listview); - LayoutInflater inflater = (LayoutInflater) - getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View header = inflater.inflate(R.layout.onlinefeedview_header, listView, false); - listView.addHeaderView(header); - - listView.setAdapter(new FeedItemlistDescriptionAdapter(this, 0, feed.getItems())); - - ImageView cover = (ImageView) header.findViewById(R.id.imgvCover); - TextView title = (TextView) header.findViewById(R.id.txtvTitle); - TextView author = (TextView) header.findViewById(R.id.txtvAuthor); - TextView description = (TextView) header.findViewById(R.id.txtvDescription); - Spinner spAlternateUrls = (Spinner) header.findViewById(R.id.spinnerAlternateUrls); - - subscribeButton = (Button) header.findViewById(R.id.butSubscribe); - - if (feed.getImage() != null && StringUtils.isNotBlank(feed.getImage().getDownload_url())) { - Glide.with(this) - .load(feed.getImage().getDownload_url()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(cover); - } - - title.setText(feed.getTitle()); - author.setText(feed.getAuthor()); - description.setText(feed.getDescription()); - - subscribeButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - try { - Feed f = new Feed(selectedDownloadUrl, new Date(0), feed.getTitle()); - f.setPreferences(feed.getPreferences()); - DefaultOnlineFeedViewActivity.this.feed = f; - - DownloadRequester.getInstance().downloadFeed( - DefaultOnlineFeedViewActivity.this, - f); - } catch (DownloadRequestException e) { - e.printStackTrace(); - DownloadRequestErrorDialogCreator.newRequestErrorDialog(DefaultOnlineFeedViewActivity.this, - e.getMessage()); - } - setSubscribeButtonState(feed); - } - }); - - if (alternateFeedUrls.isEmpty()) { - spAlternateUrls.setVisibility(View.GONE); - } else { - spAlternateUrls.setVisibility(View.VISIBLE); - - final List<String> alternateUrlsList = new ArrayList<String>(); - final List<String> alternateUrlsTitleList = new ArrayList<String>(); - - alternateUrlsList.add(feed.getDownload_url()); - alternateUrlsTitleList.add(feed.getTitle()); - - - alternateUrlsList.addAll(alternateFeedUrls.keySet()); - for (String url : alternateFeedUrls.keySet()) { - alternateUrlsTitleList.add(alternateFeedUrls.get(url)); - } - ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, alternateUrlsTitleList); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spAlternateUrls.setAdapter(adapter); - spAlternateUrls.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - selectedDownloadUrl = alternateUrlsList.get(position); - } - - @Override - public void onNothingSelected(AdapterView<?> parent) { - - } - }); - - - } - setSubscribeButtonState(feed); - - } - - private boolean feedInFeedlist(Feed feed) { - if (feeds == null || feed == null) - return false; - for (Feed f : feeds) { - if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) { - return true; - } - } - return false; - } - - private void setSubscribeButtonState(Feed feed) { - if (subscribeButton != null && feed != null) { - if (DownloadRequester.getInstance().isDownloadingFile(feed.getDownload_url())) { - subscribeButton.setEnabled(false); - subscribeButton.setText(R.string.downloading_label); - } else if (feedInFeedlist(feed)) { - subscribeButton.setEnabled(false); - subscribeButton.setText(R.string.subscribed_label); - } else { - subscribeButton.setEnabled(true); - subscribeButton.setText(R.string.subscribe_label); - } - } - } - - EventDistributor.EventListener listener = new EventDistributor.EventListener() { - @Override - public void update(EventDistributor eventDistributor, Integer arg) { - if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) { - new AsyncTask<Void, Void, List<Feed>>() { - @Override - protected List<Feed> doInBackground(Void... params) { - return DBReader.getFeedList(DefaultOnlineFeedViewActivity.this); - } - - @Override - protected void onPostExecute(List<Feed> feeds) { - super.onPostExecute(feeds); - DefaultOnlineFeedViewActivity.this.feeds = feeds; - setSubscribeButtonState(feed); - } - }.execute(); - } else if ((arg & EVENTS) != 0) { - setSubscribeButtonState(feed); - } - } - }; - - @Override - protected void onStop() { - super.onStop(); - EventDistributor.getInstance().unregister(listener); - } -} - diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java index 3ab384012..13d5e7acf 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -4,18 +4,32 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.os.Bundle; +import android.os.Looper; +import android.support.v4.app.NavUtils; import android.support.v7.app.ActionBarActivity; import android.util.Log; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.ProgressBar; import android.widget.RelativeLayout; +import android.widget.Spinner; +import android.widget.TextView; + +import com.bumptech.glide.Glide; import org.apache.commons.lang3.StringUtils; -import org.xml.sax.SAXException; +import org.jsoup.Jsoup; +import org.jsoup.examples.HtmlToPlainText; +import org.jsoup.nodes.Document; import java.io.File; import java.io.IOException; @@ -24,16 +38,22 @@ import java.util.Date; import java.util.List; import java.util.Map; -import javax.xml.parsers.ParserConfigurationException; - import de.danoeh.antennapod.R; +import de.danoeh.antennapod.adapter.FeedItemlistDescriptionAdapter; +import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; +import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedPreferences; +import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.service.download.HttpDownloader; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.storage.DownloadRequestException; +import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.syndication.handler.FeedHandler; import de.danoeh.antennapod.core.syndication.handler.FeedHandlerResult; import de.danoeh.antennapod.core.syndication.handler.UnsupportedFeedtypeException; @@ -43,6 +63,11 @@ import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.URLChecker; import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer; import de.danoeh.antennapod.dialog.AuthenticationDialog; +import rx.Observable; +import rx.Subscriber; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; /** * Downloads a feed from a feed URL and parses it. Subclasses can display the @@ -52,27 +77,57 @@ import de.danoeh.antennapod.dialog.AuthenticationDialog; * If the feed cannot be downloaded or parsed, an error dialog will be displayed * and the activity will finish as soon as the error dialog is closed. */ -public abstract class OnlineFeedViewActivity extends ActionBarActivity { +public class OnlineFeedViewActivity extends ActionBarActivity { + private static final String TAG = "OnlineFeedViewActivity"; + public static final String ARG_FEEDURL = "arg.feedurl"; - /** - * Optional argument: specify a title for the actionbar. - */ + // Optional argument: specify a title for the actionbar. public static final String ARG_TITLE = "title"; + private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | EventDistributor.DOWNLOAD_QUEUED | EventDistributor.FEED_LIST_UPDATE; + public static final int RESULT_ERROR = 2; + private volatile List<Feed> feeds; private Feed feed; - private Map<String, String> alternateFeedUrls; + private String selectedDownloadUrl; private Downloader downloader; private boolean isPaused; + private Dialog dialog; + + private Button subscribeButton; + + private Subscription download; + private Subscription parser; + private Subscription updater; + + private EventDistributor.EventListener listener = new EventDistributor.EventListener() { + @Override + public void update(EventDistributor eventDistributor, Integer arg) { + if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) { + updater = Observable.defer(() -> Observable.just(DBReader.getFeedList(OnlineFeedViewActivity.this))) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(feeds -> { + OnlineFeedViewActivity.this.feeds = feeds; + setSubscribeButtonState(feed); + } + ); + } else if ((arg & EVENTS) != 0) { + setSubscribeButtonState(feed); + } + } + }; + @Override protected void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getTheme()); super.onCreate(savedInstanceState); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); if (getIntent() != null && getIntent().hasExtra(ARG_TITLE)) { getSupportActionBar().setTitle(getIntent().getStringExtra(ARG_TITLE)); @@ -87,7 +142,6 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { || StringUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { feedUrl = (StringUtils.equals(getIntent().getAction(), Intent.ACTION_SEND)) ? getIntent().getStringExtra(Intent.EXTRA_TEXT) : getIntent().getDataString(); - getSupportActionBar().setTitle(R.string.add_new_feed_label); } else { throw new IllegalArgumentException("Activity must be started with feedurl argument!"); @@ -102,16 +156,63 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { } } + /** + * Displays a progress indicator. + */ + private void setLoadingLayout() { + RelativeLayout rl = new RelativeLayout(this); + RelativeLayout.LayoutParams rlLayoutParams = new RelativeLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT); + + ProgressBar pb = new ProgressBar(this); + pb.setIndeterminate(true); + RelativeLayout.LayoutParams pbLayoutParams = new RelativeLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + pbLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); + rl.addView(pb, pbLayoutParams); + addContentView(rl, rlLayoutParams); + } + @Override protected void onResume() { super.onResume(); isPaused = false; + EventDistributor.getInstance().register(listener); + } @Override protected void onPause() { super.onPause(); isPaused = true; + EventDistributor.getInstance().unregister(listener); + } + + @Override + protected void onStop() { + super.onStop(); + if (downloader != null && !downloader.isFinished()) { + downloader.cancel(); + } + if(dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + if(updater != null) { + updater.unsubscribe(); + } + if(download != null) { + download.unsubscribe(); + } + if(parser != null) { + parser.unsubscribe(); + } } @Override @@ -123,14 +224,6 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { } } - @Override - protected void onStop() { - super.onStop(); - if (downloader != null && !downloader.isFinished()) { - downloader.cancel(); - } - } - private void resetIntent(String url, String title) { Intent intent = new Intent(); intent.putExtra(ARG_FEEDURL, url); @@ -138,41 +231,19 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { setIntent(intent); } - - private void onDownloadCompleted(final Downloader downloader) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - Log.d(TAG, "Download was completed"); - DownloadStatus status = downloader.getResult(); - if (status != null) { - if (!status.isCancelled()) { - if (status.isSuccessful()) { - parseFeed(); - } else if (status.getReason() == DownloadError.ERROR_UNAUTHORIZED) { - if (!isFinishing() && !isPaused) { - Dialog dialog = new FeedViewAuthenticationDialog(OnlineFeedViewActivity.this, - R.string.authentication_notification_title, downloader.getDownloadRequest().getSource()); - dialog.show(); - } - } else { - String errorMsg = status.getReason().getErrorString( - OnlineFeedViewActivity.this); - if (errorMsg != null - && status.getReasonDetailed() != null) { - errorMsg += " (" + status.getReasonDetailed() + ")"; - } - showErrorDialog(errorMsg); - } - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + Intent destIntent = new Intent(this, MainActivity.class); + if (NavUtils.shouldUpRecreateTask(this, destIntent)) { + startActivity(destIntent); } else { - Log.wtf(TAG, "DownloadStatus returned by Downloader was null"); - finish(); + NavUtils.navigateUpFromSameTask(this); } - } - }); - + return true; + } + return super.onOptionsItemSelected(item); } private void startFeedDownload(String url, String username, String password) { @@ -186,133 +257,226 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { FileNameGenerator.generateFileName(feed.getDownload_url())).toString(); feed.setFile_url(fileUrl); final DownloadRequest request = new DownloadRequest(feed.getFile_url(), - feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED, username, password, true, null); - downloader = new HttpDownloader(request); - new Thread() { - @Override - public void run() { - loadData(); - downloader.call(); - onDownloadCompleted(downloader); - } - }.start(); - - - } + feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED, username, password, + true, null); - /** - * Displays a progress indicator. - */ - private void setLoadingLayout() { - RelativeLayout rl = new RelativeLayout(this); - RelativeLayout.LayoutParams rlLayoutParams = new RelativeLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.MATCH_PARENT); - - ProgressBar pb = new ProgressBar(this); - pb.setIndeterminate(true); - RelativeLayout.LayoutParams pbLayoutParams = new RelativeLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, - LinearLayout.LayoutParams.WRAP_CONTENT); - pbLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); - rl.addView(pb, pbLayoutParams); - addContentView(rl, rlLayoutParams); + download = Observable.create(new Observable.OnSubscribe<DownloadStatus>() { + @Override + public void call(Subscriber<? super DownloadStatus> subscriber) { + feeds = DBReader.getFeedList(OnlineFeedViewActivity.this); + downloader = new HttpDownloader(request); + downloader.call(); + Log.d(TAG, "Download was completed"); + subscriber.onNext(downloader.getResult()); + subscriber.onCompleted(); + } + }) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(status -> { + if (status != null) { + if (!status.isCancelled()) { + if (status.isSuccessful()) { + parseFeed(); + } else if (status.getReason() == DownloadError.ERROR_UNAUTHORIZED) { + if (!isFinishing() && !isPaused) { + dialog = new FeedViewAuthenticationDialog(OnlineFeedViewActivity.this, + R.string.authentication_notification_title, downloader.getDownloadRequest().getSource()); + dialog.show(); + } + } else { + String errorMsg = status.getReason().getErrorString(OnlineFeedViewActivity.this); + if (errorMsg != null && status.getReasonDetailed() != null) { + errorMsg += " (" + status.getReasonDetailed() + ")"; + } + showErrorDialog(errorMsg); + } + } + } else { + Log.wtf(TAG, "DownloadStatus returned by Downloader was null"); + finish(); + } + }); } private void parseFeed() { if (feed == null || feed.getFile_url() == null && feed.isDownloaded()) { - throw new IllegalStateException( - "feed must be non-null and downloaded when parseFeed is called"); + throw new IllegalStateException("feed must be non-null and downloaded when parseFeed is called"); } - Log.d(TAG, "Parsing feed"); - Thread thread = new Thread() { - + parser = Observable.create(new Observable.OnSubscribe<FeedHandlerResult>() { @Override - public void run() { - String reasonDetailed = ""; - boolean successful = false; - FeedHandler handler = new FeedHandler(); - try { - FeedHandlerResult result = handler.parseFeed(feed); - feed = result.feed; - alternateFeedUrls = result.alternateFeedUrls; - successful = true; - } catch (SAXException e) { - e.printStackTrace(); - reasonDetailed = e.getMessage(); - } catch (IOException e) { - e.printStackTrace(); - reasonDetailed = e.getMessage(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - reasonDetailed = e.getMessage(); - } catch (UnsupportedFeedtypeException e) { - Log.d(TAG, "Unsupported feed type detected"); - if (StringUtils.equalsIgnoreCase("html", e.getRootElement())) { - if (showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url())) { - return; + public void call(Subscriber<? super FeedHandlerResult> subscriber) { + FeedHandler handler = new FeedHandler(); + try { + FeedHandlerResult result = handler.parseFeed(feed); + subscriber.onNext(result); + } catch (UnsupportedFeedtypeException e) { + Log.d(TAG, "Unsupported feed type detected"); + if (StringUtils.equalsIgnoreCase("html", e.getRootElement())) { + showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url()); + } else { + subscriber.onError(e); + } + } catch (Exception e) { + subscriber.onError(e); + } finally { + boolean rc = new File(feed.getFile_url()).delete(); + Log.d(TAG, "Deleted feed source file. Result: " + rc); + subscriber.onCompleted(); } - } else { - e.printStackTrace(); - reasonDetailed = e.getMessage(); } - } finally { - boolean rc = new File(feed.getFile_url()).delete(); - Log.d(TAG, "Deleted feed source file. Result: " + rc); - } - - if (successful) { - beforeShowFeedInformation(feed, alternateFeedUrls); - runOnUiThread(new Runnable() { - @Override - public void run() { - showFeedInformation(feed, alternateFeedUrls); - } - }); - } else { - final String errorMsg = - DownloadError.ERROR_PARSER_EXCEPTION.getErrorString( - OnlineFeedViewActivity.this) - + " (" + reasonDetailed + ")"; - runOnUiThread(new Runnable() { - - @Override - public void run() { - showErrorDialog(errorMsg); - } - }); - } - } - }; - thread.start(); - } - - /** - * Can be used to load data asynchronously. - */ - protected void loadData() { - + }) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> { + beforeShowFeedInformation(result.feed); + showFeedInformation(result.feed, result.alternateFeedUrls); + }, error -> { + String errorMsg = DownloadError.ERROR_PARSER_EXCEPTION.getErrorString( + OnlineFeedViewActivity.this) + " (" + error.getMessage() + ")"; + showErrorDialog(errorMsg); + }); } /** * Called after the feed has been downloaded and parsed and before showFeedInformation is called. * This method is executed on a background thread */ - protected void beforeShowFeedInformation(Feed feed, Map<String, String> alternateFeedUrls) { - + private void beforeShowFeedInformation(Feed feed) { + // remove HTML tags from descriptions + Log.d(TAG, "Removing HTML from shownotes"); + if (feed.getItems() != null) { + HtmlToPlainText formatter = new HtmlToPlainText(); + for (FeedItem item : feed.getItems()) { + if (item.getDescription() != null) { + Document description = Jsoup.parse(item.getDescription()); + item.setDescription(StringUtils.trim(formatter.getPlainText(description))); + } + } + } } /** * Called when feed parsed successfully. * This method is executed on the GUI thread. */ - protected void showFeedInformation(Feed feed, Map<String, String> alternateFeedUrls) { + private void showFeedInformation(final Feed feed, Map<String, String> alternateFeedUrls) { + setContentView(R.layout.listview_activity); + + this.feed = feed; + this.selectedDownloadUrl = feed.getDownload_url(); + EventDistributor.getInstance().register(listener); + ListView listView = (ListView) findViewById(R.id.listview); + LayoutInflater inflater = (LayoutInflater) + getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View header = inflater.inflate(R.layout.onlinefeedview_header, listView, false); + listView.addHeaderView(header); + + listView.setAdapter(new FeedItemlistDescriptionAdapter(this, 0, feed.getItems())); + + ImageView cover = (ImageView) header.findViewById(R.id.imgvCover); + TextView title = (TextView) header.findViewById(R.id.txtvTitle); + TextView author = (TextView) header.findViewById(R.id.txtvAuthor); + TextView description = (TextView) header.findViewById(R.id.txtvDescription); + Spinner spAlternateUrls = (Spinner) header.findViewById(R.id.spinnerAlternateUrls); + + subscribeButton = (Button) header.findViewById(R.id.butSubscribe); + + if (feed.getImage() != null && StringUtils.isNotBlank(feed.getImage().getDownload_url())) { + Glide.with(this) + .load(feed.getImage().getDownload_url()) + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate() + .into(cover); + } + + title.setText(feed.getTitle()); + author.setText(feed.getAuthor()); + description.setText(feed.getDescription()); + + subscribeButton.setOnClickListener(v -> { + try { + Feed f = new Feed(selectedDownloadUrl, new Date(0), feed.getTitle()); + f.setPreferences(feed.getPreferences()); + this.feed = f; + + DownloadRequester.getInstance().downloadFeed(this, f); + } catch (DownloadRequestException e) { + e.printStackTrace(); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(OnlineFeedViewActivity.this, + e.getMessage()); + } + setSubscribeButtonState(feed); + }); + + if (alternateFeedUrls.isEmpty()) { + spAlternateUrls.setVisibility(View.GONE); + } else { + spAlternateUrls.setVisibility(View.VISIBLE); + + final List<String> alternateUrlsList = new ArrayList<>(); + final List<String> alternateUrlsTitleList = new ArrayList<>(); + + alternateUrlsList.add(feed.getDownload_url()); + alternateUrlsTitleList.add(feed.getTitle()); + + alternateUrlsList.addAll(alternateFeedUrls.keySet()); + for (String url : alternateFeedUrls.keySet()) { + alternateUrlsTitleList.add(alternateFeedUrls.get(url)); + } + ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, alternateUrlsTitleList); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spAlternateUrls.setAdapter(adapter); + spAlternateUrls.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + selectedDownloadUrl = alternateUrlsList.get(position); + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + + } + }); + } + setSubscribeButtonState(feed); + } + + private void setSubscribeButtonState(Feed feed) { + if (subscribeButton != null && feed != null) { + if (DownloadRequester.getInstance().isDownloadingFile(feed.getDownload_url())) { + subscribeButton.setEnabled(false); + subscribeButton.setText(R.string.downloading_label); + } else if (feedInFeedlist(feed)) { + subscribeButton.setEnabled(false); + subscribeButton.setText(R.string.subscribed_label); + } else { + subscribeButton.setEnabled(true); + subscribeButton.setText(R.string.subscribe_label); + } + } + } + + private boolean feedInFeedlist(Feed feed) { + if (feeds == null || feed == null) { + return false; + } + for (Feed f : feeds) { + if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) { + return true; + } + } + return false; } private void showErrorDialog(String errorMsg) { + assert(Looper.myLooper() == Looper.getMainLooper()); // run on UI thread if (!isFinishing() && !isPaused) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.error_label); @@ -322,85 +486,71 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { builder.setMessage(R.string.error_msg_prefix); } builder.setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } + (dialog, which) -> { + dialog.cancel(); } ); - builder.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - setResult(RESULT_ERROR); - finish(); - } + builder.setOnCancelListener(dialog -> { + setResult(RESULT_ERROR); + finish(); }); - builder.show(); + if(dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + dialog = builder.show(); } } - private boolean showFeedDiscoveryDialog(File feedFile, String baseUrl) { + private void showFeedDiscoveryDialog(File feedFile, String baseUrl) { FeedDiscoverer fd = new FeedDiscoverer(); final Map<String, String> urlsMap; try { urlsMap = fd.findLinks(feedFile, baseUrl); if (urlsMap == null || urlsMap.isEmpty()) { - return false; + return; } } catch (IOException e) { e.printStackTrace(); - return false; + return; } - runOnUiThread(new Runnable() { - @Override - public void run() { - if (isPaused || isFinishing()) { - return; - } + if (isPaused || isFinishing()) { + return; + } - final List<String> titles = new ArrayList<String>(); - final List<String> urls = new ArrayList<String>(); + final List<String> titles = new ArrayList<>(); + final List<String> urls = new ArrayList<>(); - urls.addAll(urlsMap.keySet()); - for (String url : urls) { - titles.add(urlsMap.get(url)); - } + urls.addAll(urlsMap.keySet()); + for (String url : urls) { + titles.add(urlsMap.get(url)); + } - final ArrayAdapter<String> adapter = new ArrayAdapter<String>(OnlineFeedViewActivity.this, R.layout.ellipsize_start_listitem, R.id.txtvTitle, titles); - DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - String selectedUrl = urls.get(which); - dialog.dismiss(); - resetIntent(selectedUrl, titles.get(which)); - FeedPreferences prefs = feed.getPreferences(); - if(prefs != null) { - startFeedDownload(selectedUrl, prefs.getUsername(), prefs.getPassword()); - } else { - startFeedDownload(selectedUrl, null, null); - } - } - }; - - AlertDialog.Builder ab = new AlertDialog.Builder(OnlineFeedViewActivity.this) - .setTitle(R.string.feeds_label) - .setCancelable(true) - .setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - finish(); - } - }) - .setAdapter(adapter, onClickListener); - ab.show(); + final ArrayAdapter<String> adapter = new ArrayAdapter<>(OnlineFeedViewActivity.this, R.layout.ellipsize_start_listitem, R.id.txtvTitle, titles); + DialogInterface.OnClickListener onClickListener = (dialog, which) -> { + String selectedUrl = urls.get(which); + dialog.dismiss(); + resetIntent(selectedUrl, titles.get(which)); + FeedPreferences prefs = feed.getPreferences(); + if(prefs != null) { + startFeedDownload(selectedUrl, prefs.getUsername(), prefs.getPassword()); + } else { + startFeedDownload(selectedUrl, null, null); } - }); + }; + AlertDialog.Builder ab = new AlertDialog.Builder(OnlineFeedViewActivity.this) + .setTitle(R.string.feeds_label) + .setCancelable(true) + .setOnCancelListener(dialog -> finish()) + .setAdapter(adapter, onClickListener); - return true; + runOnUiThread(() -> { + if(dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + dialog = ab.show(); + }); } private class FeedViewAuthenticationDialog extends AuthenticationDialog { @@ -423,4 +573,5 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { startFeedDownload(feedUrl, username, password); } } + } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java index bbe6fab46..f6c80aa7c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -10,7 +10,6 @@ import android.widget.Button; import android.widget.EditText; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.DefaultOnlineFeedViewActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; import de.danoeh.antennapod.activity.OpmlImportFromPathActivity; @@ -73,7 +72,7 @@ public class AddFeedFragment extends Fragment { butConfirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(getActivity(), DefaultOnlineFeedViewActivity.class); + Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, etxtFeedurl.getText().toString()); intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, getString(R.string.add_feed_label)); startActivity(intent); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java index edd4da7fe..72704245f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java @@ -28,7 +28,6 @@ import java.util.ArrayList; import java.util.List; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.DefaultOnlineFeedViewActivity; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -96,13 +95,13 @@ public class ItunesSearchFragment extends Fragment { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(getActivity(), - DefaultOnlineFeedViewActivity.class); + OnlineFeedViewActivity.class); //Tell the OnlineFeedViewActivity where to go String url = searchResults.get(position).feedUrl; intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, url); - intent.putExtra(DefaultOnlineFeedViewActivity.ARG_TITLE, "iTunes"); + intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, "iTunes"); startActivity(intent); } }); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java index 623c6faa7..204f36956 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java @@ -23,7 +23,6 @@ import android.widget.TextView; import java.util.List; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.DefaultOnlineFeedViewActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; import de.danoeh.antennapod.adapter.gpodnet.PodcastListAdapter; @@ -104,9 +103,9 @@ public abstract class PodcastListFragment extends Fragment { protected void onPodcastSelected(GpodnetPodcast selection) { Log.d(TAG, "Selected podcast: " + selection.toString()); - Intent intent = new Intent(getActivity(), DefaultOnlineFeedViewActivity.class); + Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, selection.getUrl()); - intent.putExtra(DefaultOnlineFeedViewActivity.ARG_TITLE, getString(R.string.gpodnet_main_label)); + intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, getString(R.string.gpodnet_main_label)); startActivity(intent); } |