package de.danoeh.antennapodsp.fragment; import android.app.Activity; import android.app.AlertDialog; import android.content.*; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.ListFragment; import android.view.View; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.LinearLayout; import de.danoeh.antennapodsp.AppConfig; import de.danoeh.antennapodsp.R; import de.danoeh.antennapodsp.adapter.EpisodesListAdapter; import de.danoeh.antennapodsp.asynctask.DownloadObserver; import de.danoeh.antennapodsp.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapodsp.feed.EventDistributor; import de.danoeh.antennapodsp.feed.Feed; import de.danoeh.antennapodsp.feed.FeedItem; import de.danoeh.antennapodsp.feed.FeedMedia; import de.danoeh.antennapodsp.service.download.Downloader; import de.danoeh.antennapodsp.service.playback.PlaybackService; import de.danoeh.antennapodsp.service.playback.PlayerStatus; import de.danoeh.antennapodsp.storage.DBReader; import de.danoeh.antennapodsp.storage.DBTasks; import de.danoeh.antennapodsp.storage.DownloadRequestException; import de.danoeh.antennapodsp.storage.DownloadRequester; import org.apache.commons.lang3.StringUtils; import java.util.List; public class EpisodesFragment extends ListFragment { private static final String TAG = "EpisodesFragment"; private static final String ARG_FEED_ID = "feedID"; private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE | EventDistributor.DOWNLOAD_HANDLED; private Feed feed; private EpisodesListAdapter episodesListAdapter; private AsyncTask currentLoadTask = null; private DownloadObserver downloadObserver = null; private List<Downloader> downloaderList = null; private boolean feedsLoaded = false; private boolean listviewSetup = false; public static EpisodesFragment newInstance(long feedID) { EpisodesFragment f = new EpisodesFragment(); Bundle b = new Bundle(); b.putLong(ARG_FEED_ID, feedID); f.setArguments(b); return f; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); refreshFeed(); } private void refreshFeed() { AsyncTask<Void, Void, Feed> loadTask = new AsyncTask<Void, Void, Feed>() { volatile long feedID; @Override protected void onPreExecute() { super.onPreExecute(); feedID = getArguments().getLong(ARG_FEED_ID); } @Override protected void onPostExecute(Feed result) { super.onPostExecute(result); if (result != null) { onFeedLoaded(result); } } @Override protected Feed doInBackground(Void... params) { Context context = getActivity(); if (context != null) { return DBReader.getFeed(getActivity(), feedID); } else { return null; } } }; loadTask.execute(); currentLoadTask = loadTask; } private void onFeedLoaded(Feed result) { feed = result; if (feedsLoaded && listviewSetup) { // feed has only been refreshed episodesListAdapter.notifyDataSetChanged(); } else { EventDistributor.getInstance().register(contentUpdateListener); downloadObserver = new DownloadObserver(getActivity(), new Handler(), downloadObserverCallback); downloadObserver.onResume(); feedsLoaded = true; if (getListView() != null && !listviewSetup) { setupListView(); } } } private void setupListView() { setListShown(true); if (episodesListAdapter == null) { episodesListAdapter = new EpisodesListAdapter(getActivity(), itemAccess); getListView().setAdapter(episodesListAdapter); } listviewSetup = true; } @Override public void onPause() { super.onPause(); EventDistributor.getInstance().unregister(contentUpdateListener); try { getActivity().unregisterReceiver(playerStatusReceiver); } catch (IllegalArgumentException e) { e.printStackTrace(); } } @Override public void onResume() { super.onResume(); EventDistributor.getInstance().register(contentUpdateListener); getActivity().registerReceiver(playerStatusReceiver, new IntentFilter(PlaybackService.ACTION_PLAYER_STATUS_CHANGED)); } @Override public void onAttach(Activity activity) { super.onAttach(activity); if (feedsLoaded) { downloadObserver.setActivity(activity); downloadObserver.onResume(); } if (listviewSetup) { episodesListAdapter.notifyDataSetChanged(); } } @Override public void onDetach() { super.onDetach(); if (feedsLoaded) { downloadObserver.onPause(); } } @Override public void onDestroyView() { super.onDestroyView(); currentLoadTask.cancel(true); try { getActivity().unregisterReceiver(playerStatusReceiver); } catch (IllegalArgumentException e) { if (AppConfig.DEBUG) e.printStackTrace(); } listviewSetup = false; episodesListAdapter = null; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { position = position - getListView().getHeaderViewsCount(); if (position < 0) { return; } final FeedItem item = (FeedItem) episodesListAdapter.getItem(position); if (item.hasMedia() && item.getMedia().isDownloaded()) { // episode downloaded DBTasks.playMedia(getActivity(), item.getMedia(), false, true, false); } else if (item.hasMedia()) { final FeedMedia media = item.getMedia(); AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity()); dialog.setCancelable(true) .setTitle(media.getEpisodeTitle()); if (DownloadRequester.getInstance().isDownloadingFile(media)) { // episode downloading dialog.setMessage(R.string.episode_dialog_downloading_msg) .setNeutralButton(R.string.cancel_download_label, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); DownloadRequester.getInstance().cancelDownload(getActivity(), media); } }); dialog.create().show(); } else { // episode not downloaded try { DBTasks.downloadFeedItems(getActivity(), item); } catch (DownloadRequestException e) { e.printStackTrace(); DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage()); } } } } }); // add header so that list is below actionbar int actionBarHeight = getResources().getDimensionPixelSize(android.support.v7.appcompat.R.dimen.abc_action_bar_default_height); LinearLayout header = new LinearLayout(getActivity()); header.setOrientation(LinearLayout.HORIZONTAL); AbsListView.LayoutParams lp = new AbsListView.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, actionBarHeight); header.setLayoutParams(lp); getListView().addHeaderView(header); if (feedsLoaded) { setupListView(); } else { setListShown(false); } } private final EpisodesListAdapter.ItemAccess itemAccess = new EpisodesListAdapter.ItemAccess() { @Override public int getCount() { return (feed != null) ? feed.getItems().size() : 0; } @Override public FeedItem getItem(int position) { return (feed != null) ? feed.getItems().get(position) : null; } @Override public int getItemDownloadProgressPercent(FeedItem item) { if (downloaderList != null) { for (Downloader downloader : downloaderList) { if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA && downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) { return downloader.getDownloadRequest().getProgressPercent(); } } } return 0; } }; private final DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { @Override public void onContentChanged() { if (episodesListAdapter != null) { episodesListAdapter.notifyDataSetChanged(); } } @Override public void onDownloadDataAvailable(List<Downloader> downloaderList) { EpisodesFragment.this.downloaderList = downloaderList; if (episodesListAdapter != null) { episodesListAdapter.notifyDataSetChanged(); } } }; private final EventDistributor.EventListener contentUpdateListener = new EventDistributor.EventListener() { @Override public void update(EventDistributor eventDistributor, Integer arg) { if ((arg & EVENTS) != 0) { if (listviewSetup) { refreshFeed(); episodesListAdapter.notifyDataSetChanged(); } } } }; private final BroadcastReceiver playerStatusReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (StringUtils.equals(intent.getAction(), PlaybackService.ACTION_PLAYER_STATUS_CHANGED)) { int statusOrdinal = intent.getIntExtra(PlaybackService.EXTRA_NEW_PLAYER_STATUS, -1); if (statusOrdinal != -1) { if (PlayerStatus.fromOrdinal(statusOrdinal) == PlayerStatus.INITIALIZED) { if (episodesListAdapter != null) { episodesListAdapter.notifyDataSetChanged(); } } } } } }; }