diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2014-06-14 14:09:52 +0200 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2014-06-14 14:30:17 +0200 |
commit | 1673f6eaf83606a78ce3928b2d7c33d4ff0de862 (patch) | |
tree | 2f31961d0f389f8bebe04ba10473317d9881c97b /src/de | |
parent | b2ae4c15d13840619fb09cc141b290449e40a6a4 (diff) | |
parent | 7aa0d3be100c4d7cc79c3a71000378975ae96c8b (diff) | |
download | AntennaPod-1673f6eaf83606a78ce3928b2d7c33d4ff0de862.zip |
Merge branch 'develop'0.9.9.1
Diffstat (limited to 'src/de')
19 files changed, 347 insertions, 329 deletions
diff --git a/src/de/danoeh/antennapod/AppConfig.java b/src/de/danoeh/antennapod/AppConfig.java index 1f55e73a6..cac946f84 100644 --- a/src/de/danoeh/antennapod/AppConfig.java +++ b/src/de/danoeh/antennapod/AppConfig.java @@ -2,5 +2,6 @@ package de.danoeh.antennapod; public final class AppConfig { /** Should be used when setting User-Agent header for HTTP-requests. */ - public final static String USER_AGENT = "AntennaPod/0.9.9.0"; + public final static String USER_AGENT = "AntennaPod/0.9.9.1"; + } diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java index 2ffaae967..090c3f1f5 100644 --- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java @@ -34,8 +34,6 @@ import de.danoeh.antennapod.storage.DBReader; import de.danoeh.antennapod.util.playback.ExternalMedia; import de.danoeh.antennapod.util.playback.Playable; -import java.util.List; - /** * Activity for playing audio files. */ @@ -624,20 +622,20 @@ public class AudioplayerActivity extends MediaplayerActivity { } } - private List<Feed> feeds; - private AsyncTask<Void, Void, List<Feed>> loadTask; + private DBReader.NavDrawerData navDrawerData; + private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask; private void loadData() { - loadTask = new AsyncTask<Void, Void, List<Feed>>() { + loadTask = new AsyncTask<Void, Void, DBReader.NavDrawerData>() { @Override - protected List<Feed> doInBackground(Void... params) { - return DBReader.getFeedList(AudioplayerActivity.this); + protected DBReader.NavDrawerData doInBackground(Void... params) { + return DBReader.getNavDrawerData(AudioplayerActivity.this); } @Override - protected void onPostExecute(List<Feed> result) { + protected void onPostExecute(DBReader.NavDrawerData result) { super.onPostExecute(result); - feeds = result; + navDrawerData = result; if (navAdapter != null) { navAdapter.notifyDataSetChanged(); } @@ -667,8 +665,8 @@ public class AudioplayerActivity extends MediaplayerActivity { private final NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() { @Override public int getCount() { - if (feeds != null) { - return feeds.size(); + if (navDrawerData != null) { + return navDrawerData.feeds.size(); } else { return 0; } @@ -676,8 +674,8 @@ public class AudioplayerActivity extends MediaplayerActivity { @Override public Feed getItem(int position) { - if (feeds != null && position < feeds.size()) { - return feeds.get(position); + if (navDrawerData != null && position < navDrawerData.feeds.size()) { + return navDrawerData.feeds.get(position); } else { return null; } @@ -687,5 +685,15 @@ public class AudioplayerActivity extends MediaplayerActivity { public int getSelectedItemIndex() { return -1; } + + @Override + public int getQueueSize() { + return (navDrawerData != null) ? navDrawerData.queueSize : 0; + } + + @Override + public int getNumberOfUnreadItems() { + return (navDrawerData != null) ? navDrawerData.numUnreadItems : 0; + } }; } diff --git a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java index f00ce13e8..7f60d0b10 100644 --- a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java +++ b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java @@ -166,6 +166,7 @@ public class FeedInfoActivity extends ActionBarActivity { menu.findItem(R.id.support_item).setVisible( feed != null && feed.getPaymentLink() != null); menu.findItem(R.id.share_link_item).setVisible(feed != null &&feed.getLink() != null); + menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null); return true; } diff --git a/src/de/danoeh/antennapod/activity/MainActivity.java b/src/de/danoeh/antennapod/activity/MainActivity.java index 92afea77c..257bea82d 100644 --- a/src/de/danoeh/antennapod/activity/MainActivity.java +++ b/src/de/danoeh/antennapod/activity/MainActivity.java @@ -39,10 +39,11 @@ public class MainActivity extends ActionBarActivity { private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | EventDistributor.DOWNLOAD_QUEUED | EventDistributor.FEED_LIST_UPDATE - | EventDistributor.UNREAD_ITEMS_UPDATE; + | EventDistributor.UNREAD_ITEMS_UPDATE + | EventDistributor.QUEUE_UPDATE; - private static final String PREF_NAME = "MainActivityPrefs"; - private static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch"; + public static final String PREF_NAME = "MainActivityPrefs"; + public static final String PREF_IS_FIRST_LAUNCH = "prefMainActivityIsFirstLaunch"; public static final String EXTRA_NAV_INDEX = "nav_index"; public static final String EXTRA_NAV_TYPE = "nav_type"; @@ -147,7 +148,7 @@ public class MainActivity extends ActionBarActivity { } public List<Feed> getFeeds() { - return feeds; + return (navDrawerData != null) ? navDrawerData.feeds : null; } private void loadFragment(int viewType, int relPos, Bundle args) { @@ -207,9 +208,9 @@ public class MainActivity extends ActionBarActivity { } public void loadFeedFragment(long feedID) { - if (feeds != null) { - for (int i = 0; i < feeds.size(); i++) { - if (feeds.get(i).getId() == feedID) { + if (navDrawerData != null) { + for (int i = 0; i < navDrawerData.feeds.size(); i++) { + if (navDrawerData.feeds.get(i).getId() == feedID) { loadFragment(NavListAdapter.VIEW_TYPE_SUBSCRIPTION, i, null); break; } @@ -279,7 +280,7 @@ public class MainActivity extends ActionBarActivity { EventDistributor.getInstance().register(contentUpdate); Intent intent = getIntent(); - if (feeds != null && intent.hasExtra(EXTRA_NAV_INDEX) && intent.hasExtra(EXTRA_NAV_TYPE)) { + if (navDrawerData != null && intent.hasExtra(EXTRA_NAV_INDEX) && intent.hasExtra(EXTRA_NAV_TYPE)) { handleNavIntent(); } @@ -322,15 +323,15 @@ public class MainActivity extends ActionBarActivity { return true; } - private List<Feed> feeds; - private AsyncTask<Void, Void, List<Feed>> loadTask; + private DBReader.NavDrawerData navDrawerData; + private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask; private int selectedNavListIndex = 0; private NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() { @Override public int getCount() { - if (feeds != null) { - return feeds.size(); + if (navDrawerData != null) { + return navDrawerData.feeds.size(); } else { return 0; } @@ -338,8 +339,8 @@ public class MainActivity extends ActionBarActivity { @Override public Feed getItem(int position) { - if (feeds != null && position < feeds.size()) { - return feeds.get(position); + if (navDrawerData != null && position < navDrawerData.feeds.size()) { + return navDrawerData.feeds.get(position); } else { return null; } @@ -350,23 +351,33 @@ public class MainActivity extends ActionBarActivity { return selectedNavListIndex; } + @Override + public int getQueueSize() { + return (navDrawerData != null) ? navDrawerData.queueSize : 0; + } + + @Override + public int getNumberOfUnreadItems() { + return (navDrawerData != null) ? navDrawerData.numUnreadItems : 0; + } + }; private void loadData() { cancelLoadTask(); - loadTask = new AsyncTask<Void, Void, List<Feed>>() { + loadTask = new AsyncTask<Void, Void, DBReader.NavDrawerData>() { @Override - protected List<Feed> doInBackground(Void... params) { - return DBReader.getFeedList(MainActivity.this); + protected DBReader.NavDrawerData doInBackground(Void... params) { + return DBReader.getNavDrawerData(MainActivity.this); } @Override - protected void onPostExecute(List<Feed> result) { - super.onPostExecute(result); - boolean handleIntent = (feeds == null); + protected void onPostExecute(DBReader.NavDrawerData result) { + super.onPostExecute(navDrawerData); + boolean handleIntent = (navDrawerData == null); - feeds = result; + navDrawerData = result; navAdapter.notifyDataSetChanged(); if (handleIntent) { diff --git a/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java index 271cc19d5..e397ff2ca 100644 --- a/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -61,6 +61,8 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { private Map<String, String> alternateFeedUrls; private Downloader downloader; + private boolean isPaused; + @Override protected void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getTheme()); @@ -97,6 +99,18 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { } @Override + protected void onResume() { + super.onResume(); + isPaused = false; + } + + @Override + protected void onPause() { + super.onPause(); + isPaused = true; + } + + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (feed != null && feed.getPreferences() != null) { @@ -126,9 +140,11 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { if (status.isSuccessful()) { parseFeed(); } else if (status.getReason() == DownloadError.ERROR_UNAUTHORIZED) { - Dialog dialog = new FeedViewAuthenticationDialog(OnlineFeedViewActivity.this, - R.string.authentication_notification_title, downloader.getDownloadRequest().getSource()); - dialog.show(); + 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); @@ -276,32 +292,30 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity { } private void showErrorDialog(String errorMsg) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.error_label); - if (errorMsg != null) { - builder.setMessage(getString(R.string.error_msg_prefix) + errorMsg); - } else { - builder.setMessage(R.string.error_msg_prefix); - } - builder.setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { + if (!isFinishing() && !isPaused) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.error_label); + if (errorMsg != null) { + builder.setMessage(getString(R.string.error_msg_prefix) + errorMsg); + } else { + 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(); + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } } + ); + builder.setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + setResult(RESULT_ERROR); + finish(); } - ); - builder.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - setResult(RESULT_ERROR); - finish(); - } - }); - - if (!isFinishing()) { - builder.show(); + }); } } diff --git a/src/de/danoeh/antennapod/activity/PreferenceActivity.java b/src/de/danoeh/antennapod/activity/PreferenceActivity.java index 1070c71f8..77ec579ed 100644 --- a/src/de/danoeh/antennapod/activity/PreferenceActivity.java +++ b/src/de/danoeh/antennapod/activity/PreferenceActivity.java @@ -15,6 +15,7 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; +import android.support.v4.app.NavUtils; import android.util.Log; import android.view.Menu; import android.view.MenuItem; @@ -46,7 +47,7 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { private static final String PREF_FLATTR_THIS_APP = "prefFlattrThisApp"; private static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate"; private static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; - private static final String PREF_AUTO_FLATTR = "pref_auto_flattr"; + private static final String PREF_AUTO_FLATTR = "pref_auto_flattr"; private static final String PREF_OPML_EXPORT = "prefOpmlExport"; private static final String PREF_ABOUT = "prefAbout"; private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; @@ -89,7 +90,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { return true; } - }); + } + ); findPreference(PREF_FLATTR_REVOKE).setOnPreferenceClickListener( new OnPreferenceClickListener() { @@ -101,7 +103,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { return true; } - }); + } + ); findPreference(PREF_ABOUT).setOnPreferenceClickListener( new OnPreferenceClickListener() { @@ -113,7 +116,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { return true; } - }); + } + ); findPreference(PREF_OPML_EXPORT).setOnPreferenceClickListener( new OnPreferenceClickListener() { @@ -125,7 +129,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { return true; } - }); + } + ); findPreference(PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener( new OnPreferenceClickListener() { @@ -135,10 +140,12 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { startActivityForResult( new Intent(PreferenceActivity.this, DirectoryChooserActivity.class), - DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); + DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED + ); return true; } - }); + } + ); findPreference(UserPreferences.PREF_THEME) .setOnPreferenceChangeListener( new OnPreferenceChangeListener() { @@ -153,18 +160,19 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { startActivity(i); return true; } - }); + } + ); findPreference(UserPreferences.PREF_ENABLE_AUTODL) .setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (newValue instanceof Boolean) { - findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled((Boolean) newValue); - setSelectedNetworksEnabled((Boolean) newValue && UserPreferences.isEnableAutodownloadWifiFilter()); - } - return true; - } - }); + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (newValue instanceof Boolean) { + findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled((Boolean) newValue); + setSelectedNetworksEnabled((Boolean) newValue && UserPreferences.isEnableAutodownloadWifiFilter()); + } + return true; + } + }); findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER) .setOnPreferenceChangeListener( new OnPreferenceChangeListener() { @@ -179,7 +187,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { return false; } } - }); + } + ); findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE) .setOnPreferenceChangeListener( new OnPreferenceChangeListener() { @@ -190,7 +199,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { } return true; } - }); + } + ); findPreference(PREF_PLAYBACK_SPEED_LAUNCHER) .setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override @@ -343,12 +353,14 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: + Intent destIntent = new Intent(this, MainActivity.class); + destIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(destIntent); finish(); - break; + return true; default: return false; } - return true; } @Override @@ -389,7 +401,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { String key = preference.getKey(); ArrayList<String> prefValuesList = new ArrayList<String>( Arrays.asList(UserPreferences - .getAutodownloadSelectedNetworks())); + .getAutodownloadSelectedNetworks()) + ); boolean newValue = ((CheckBoxPreference) preference) .isChecked(); if (BuildConfig.DEBUG) @@ -406,8 +419,9 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { UserPreferences.setAutodownloadSelectedNetworks( PreferenceActivity.this, prefValuesList - .toArray(new String[prefValuesList - .size()])); + .toArray(new String[prefValuesList + .size()]) + ); return true; } else { return false; @@ -461,7 +475,17 @@ public class PreferenceActivity extends android.preference.PreferenceActivity { .setBackgroundDrawable( this.getWindow().getDecorView() .getBackground().getConstantState() - .newDrawable()); + .newDrawable() + ); return false; } + + @Override + public void onBackPressed() { + // The default back button behavior has to be overwritten because changing the theme clears the back stack + Intent destIntent = new Intent(this, MainActivity.class); + destIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(destIntent); + finish(); + } } diff --git a/src/de/danoeh/antennapod/adapter/AdapterUtils.java b/src/de/danoeh/antennapod/adapter/AdapterUtils.java new file mode 100644 index 000000000..f393fb7d7 --- /dev/null +++ b/src/de/danoeh/antennapod/adapter/AdapterUtils.java @@ -0,0 +1,57 @@ +package de.danoeh.antennapod.adapter; + +import android.content.res.Resources; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.util.Converter; + +/** + * Utility methods for adapters + */ +public class AdapterUtils { + + private AdapterUtils() { + + } + + /** + * Updates the contents of the TextView that shows the current playback position and the ProgressBar. + */ + public static void updateEpisodePlaybackProgress(FeedItem item, Resources res, TextView txtvPos, ProgressBar episodeProgress) { + FeedMedia media = item.getMedia(); + episodeProgress.setVisibility(View.GONE); + if (media == null) { + txtvPos.setVisibility(View.GONE); + return; + } else { + txtvPos.setVisibility(View.VISIBLE); + } + + FeedItem.State state = item.getState(); + if (state == FeedItem.State.PLAYING + || state == FeedItem.State.IN_PROGRESS) { + if (media.getDuration() > 0) { + episodeProgress.setVisibility(View.VISIBLE); + episodeProgress + .setProgress((int) (((double) media + .getPosition()) / media.getDuration() * 100)); + txtvPos.setText(Converter + .getDurationStringLong(media.getDuration() + - media.getPosition())); + } + } else if (!media.isDownloaded()) { + txtvPos.setText(res.getString( + R.string.size_prefix) + + Converter.byteToString(media.getSize())); + } else { + txtvPos.setText(res.getString( + R.string.length_prefix) + + Converter.getDurationStringLong(media + .getDuration())); + } + } +} diff --git a/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java b/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java index 5475f122f..c4a16d4db 100644 --- a/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java +++ b/src/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java @@ -134,28 +134,8 @@ public class FeedItemlistAdapter extends BaseAdapter { holder.lenSize.setVisibility(View.INVISIBLE); } else { - if (state == FeedItem.State.PLAYING - || state == FeedItem.State.IN_PROGRESS) { - if (media.getDuration() > 0) { - holder.episodeProgress - .setProgress((int) (((double) media - .getPosition()) / media.getDuration() * 100)); - holder.lenSize.setText(Converter - .getDurationStringLong(media.getDuration() - - media.getPosition())); - } - } else if (!media.isDownloaded()) { - holder.lenSize.setText(context.getString( - R.string.size_prefix) - + Converter.byteToString(media.getSize())); - } else { - holder.lenSize.setText(context.getString( - R.string.length_prefix) - + Converter.getDurationStringLong(media - .getDuration())); - } + AdapterUtils.updateEpisodePlaybackProgress(item, context.getResources(), holder.lenSize, holder.episodeProgress); - holder.lenSize.setVisibility(View.VISIBLE); if (((ItemAccess) itemAccess).isInQueue(item)) { holder.inPlaylist.setVisibility(View.VISIBLE); } else { @@ -166,9 +146,6 @@ public class FeedItemlistAdapter extends BaseAdapter { item.getMedia())) { holder.episodeProgress.setVisibility(View.VISIBLE); holder.episodeProgress.setProgress(((ItemAccess) itemAccess).getItemDownloadProgressPercent(item)); - } else if (!(state == FeedItem.State.IN_PROGRESS - || state == FeedItem.State.PLAYING)) { - holder.episodeProgress.setVisibility(View.GONE); } TypedArray typeDrawables = context.obtainStyledAttributes( diff --git a/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java b/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java deleted file mode 100644 index 30c1ff880..000000000 --- a/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java +++ /dev/null @@ -1,174 +0,0 @@ -package de.danoeh.antennapod.adapter; - -import android.content.Context; -import android.text.format.DateUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.TextView; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.asynctask.ImageLoader; -import de.danoeh.antennapod.feed.Feed; -import de.danoeh.antennapod.storage.DownloadRequester; -import de.danoeh.antennapod.storage.FeedItemStatistics; -import de.danoeh.antennapod.util.ThemeUtils; - -public class FeedlistAdapter extends BaseAdapter { - private static final String TAG = "FeedlistAdapter"; - - private Context context; - protected ItemAccess itemAccess; - - private int selectedItemIndex; - private ImageLoader imageLoader; - public static final int SELECTION_NONE = -1; - - public FeedlistAdapter(Context context, ItemAccess itemAccess) { - super(); - if (context == null) { - throw new IllegalArgumentException("context must not be null"); - } - if (itemAccess == null) { - throw new IllegalArgumentException("itemAccess must not be null"); - } - - this.context = context; - this.itemAccess = itemAccess; - selectedItemIndex = SELECTION_NONE; - imageLoader = ImageLoader.getInstance(); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final Holder holder; - final Feed feed = getItem(position); - final FeedItemStatistics feedItemStatistics = itemAccess.getFeedItemStatistics(position); - - // Inflate Layout - if (convertView == null) { - holder = new Holder(); - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - convertView = inflater.inflate(R.layout.feedlist_item, null); - holder.title = (TextView) convertView - .findViewById(R.id.txtvFeedname); - - holder.newEpisodes = (TextView) convertView - .findViewById(R.id.txtvNewEps); - holder.inProgressEpisodes = (TextView) convertView - .findViewById(R.id.txtvProgressEps); - holder.newEpisodesLabel = (View) convertView - .findViewById(R.id.lNewStatusLabel); - holder.inProgressEpisodesLabel = (View) convertView - .findViewById(R.id.lProgressStatusLabel); - holder.image = (ImageView) convertView - .findViewById(R.id.imgvFeedimage); - holder.lastUpdate = (TextView) convertView - .findViewById(R.id.txtvLastUpdate); - holder.numberOfEpisodes = (TextView) convertView - .findViewById(R.id.txtvNumEpisodes); - convertView.setTag(holder); - } else { - holder = (Holder) convertView.getTag(); - - } - - if (position == selectedItemIndex) { - convertView.setBackgroundColor(convertView.getResources().getColor( - ThemeUtils.getSelectionBackgroundColor())); - } else { - convertView.setBackgroundResource(0); - } - - holder.title.setText(feed.getTitle()); - - if (feedItemStatistics != null) { - if (DownloadRequester.getInstance().isDownloadingFile(feed)) { - holder.lastUpdate.setText(R.string.refreshing_label); - } else { - if (feedItemStatistics.lastUpdateKnown()) { - holder.lastUpdate.setText(convertView.getResources().getString( - R.string.most_recent_prefix) - + DateUtils.getRelativeTimeSpanString( - feedItemStatistics.getLastUpdate().getTime(), - System.currentTimeMillis(), 0, 0)); - } else { - holder.lastUpdate.setText(""); - } - } - holder.numberOfEpisodes.setText(feedItemStatistics.getNumberOfItems() - + convertView.getResources() - .getString(R.string.episodes_suffix)); - - if (feedItemStatistics.getNumberOfNewItems() > 0) { - holder.newEpisodes.setText(Integer.toString(feedItemStatistics.getNumberOfNewItems())); - holder.newEpisodesLabel.setVisibility(View.VISIBLE); - } else { - holder.newEpisodesLabel.setVisibility(View.INVISIBLE); - } - - if (feedItemStatistics.getNumberOfInProgressItems() > 0) { - holder.inProgressEpisodes - .setText(Integer.toString(feedItemStatistics.getNumberOfInProgressItems())); - holder.inProgressEpisodesLabel.setVisibility(View.VISIBLE); - } else { - holder.inProgressEpisodesLabel.setVisibility(View.INVISIBLE); - } - } - final String imageUrl = (feed.getImage() != null && feed.getImage().isDownloaded()) ? feed.getImage() - .getFile_url() : null; - imageLoader.loadThumbnailBitmap( - feed.getImage(), - holder.image, - (int) convertView.getResources().getDimension( - R.dimen.thumbnail_length)); - - return convertView; - } - - static class Holder { - TextView title; - TextView lastUpdate; - TextView numberOfEpisodes; - TextView newEpisodes; - TextView inProgressEpisodes; - ImageView image; - View newEpisodesLabel; - View inProgressEpisodesLabel; - } - - public int getSelectedItemIndex() { - return selectedItemIndex; - } - - public void setSelectedItemIndex(int selectedItemIndex) { - this.selectedItemIndex = selectedItemIndex; - notifyDataSetChanged(); - } - - @Override - public int getCount() { - return itemAccess.getCount(); - } - - @Override - public Feed getItem(int position) { - return itemAccess.getItem(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - public interface ItemAccess { - int getCount(); - - Feed getItem(int position); - - FeedItemStatistics getFeedItemStatistics(int position); - } -} diff --git a/src/de/danoeh/antennapod/adapter/NavListAdapter.java b/src/de/danoeh/antennapod/adapter/NavListAdapter.java index 928ec5dde..536bf80e3 100644 --- a/src/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/src/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -36,9 +36,9 @@ public class NavListAdapter extends BaseAdapter { this.itemAccess = itemAccess; this.context = context; - TypedArray ta = context.obtainStyledAttributes(new int[] {R.attr.ic_new, R.attr.stat_playlist, + TypedArray ta = context.obtainStyledAttributes(new int[]{R.attr.ic_new, R.attr.stat_playlist, R.attr.av_download, R.attr.device_access_time, R.attr.content_new}); - drawables = new Drawable[] {ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2), + drawables = new Drawable[]{ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2), ta.getDrawable(3), ta.getDrawable(4)}; ta.recycle(); } @@ -113,6 +113,7 @@ public class NavListAdapter extends BaseAdapter { convertView = inflater.inflate(R.layout.nav_listitem, null); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.count = (TextView) convertView.findViewById(R.id.txtvCount); holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); convertView.setTag(holder); } else { @@ -120,6 +121,27 @@ public class NavListAdapter extends BaseAdapter { } holder.title.setText(title); + + if (NAV_TITLES[position] == R.string.queue_label) { + int queueSize = itemAccess.getQueueSize(); + if (queueSize > 0) { + holder.count.setVisibility(View.VISIBLE); + holder.count.setText(String.valueOf(queueSize)); + } else { + holder.count.setVisibility(View.GONE); + } + } else if (NAV_TITLES[position] == R.string.all_episodes_label) { + int unreadItems = itemAccess.getNumberOfUnreadItems(); + if (unreadItems > 0) { + holder.count.setVisibility(View.VISIBLE); + holder.count.setText(String.valueOf(unreadItems)); + } else { + holder.count.setVisibility(View.GONE); + } + } else { + holder.count.setVisibility(View.GONE); + } + holder.image.setImageDrawable(drawables[position]); return convertView; @@ -174,6 +196,7 @@ public class NavListAdapter extends BaseAdapter { static class NavHolder { TextView title; + TextView count; ImageView image; } @@ -193,6 +216,10 @@ public class NavListAdapter extends BaseAdapter { public Feed getItem(int position); public int getSelectedItemIndex(); + + public int getQueueSize(); + + public int getNumberOfUnreadItems(); } } diff --git a/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java index 4a959dfd2..555a334f6 100644 --- a/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java +++ b/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java @@ -66,6 +66,7 @@ public class NewEpisodesListAdapter extends BaseAdapter { holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); holder.pubDate = (TextView) convertView .findViewById(R.id.txtvPublished); + holder.statusUnread = convertView.findViewById(R.id.statusUnread); holder.butSecondary = (ImageButton) convertView .findViewById(R.id.butSecondaryAction); holder.queueStatus = (ImageView) convertView @@ -81,6 +82,11 @@ public class NewEpisodesListAdapter extends BaseAdapter { holder.title.setText(item.getTitle()); holder.pubDate.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_SHOW_DATE)); + if (item.isRead()) { + holder.statusUnread.setVisibility(View.GONE); + } else { + holder.statusUnread.setVisibility(View.VISIBLE); + } FeedMedia media = item.getMedia(); if (media != null) { @@ -140,6 +146,7 @@ public class NewEpisodesListAdapter extends BaseAdapter { static class Holder { TextView title; TextView pubDate; + View statusUnread; ImageView queueStatus; ImageView imageView; ProgressBar downloadProgress; diff --git a/src/de/danoeh/antennapod/adapter/QueueListAdapter.java b/src/de/danoeh/antennapod/adapter/QueueListAdapter.java index fb6848a1e..ecce1b473 100644 --- a/src/de/danoeh/antennapod/adapter/QueueListAdapter.java +++ b/src/de/danoeh/antennapod/adapter/QueueListAdapter.java @@ -61,7 +61,8 @@ public class QueueListAdapter extends BaseAdapter { holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); holder.butSecondary = (ImageButton) convertView .findViewById(R.id.butSecondaryAction); - holder.downloadProgress = (ProgressBar) convertView + holder.position = (TextView) convertView.findViewById(R.id.txtvPosition); + holder.progress = (ProgressBar) convertView .findViewById(R.id.pbar_download_progress); holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); convertView.setTag(holder); @@ -71,20 +72,17 @@ public class QueueListAdapter extends BaseAdapter { holder.title.setText(item.getTitle()); + AdapterUtils.updateEpisodePlaybackProgress(item, context.getResources(), holder.position, holder.progress); + FeedMedia media = item.getMedia(); if (media != null) { final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media); - - if (isDownloadingMedia) { - holder.downloadProgress.setVisibility(View.VISIBLE); - } else { - holder.downloadProgress.setVisibility(View.GONE); - } if (!media.isDownloaded()) { if (isDownloadingMedia) { // item is being downloaded - holder.downloadProgress.setProgress(itemAccess.getItemDownloadProgressPercent(item)); + holder.progress.setVisibility(View.VISIBLE); + holder.progress.setProgress(itemAccess.getItemDownloadProgressPercent(item)); } } } @@ -116,7 +114,8 @@ public class QueueListAdapter extends BaseAdapter { static class Holder { TextView title; ImageView imageView; - ProgressBar downloadProgress; + TextView position; + ProgressBar progress; ImageButton butSecondary; } diff --git a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java index b90d78c14..1d069daa5 100644 --- a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java +++ b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java @@ -189,6 +189,10 @@ public class ImageDiskCache { * The image will be stored in the thumbnail cache. */ public void loadThumbnailBitmap(final String url, final ImageView target, final int length) { + if (url == null) { + Log.w(TAG, "loadThumbnailBitmap: Call was ignored because url = null"); + return; + } final ImageLoader il = ImageLoader.getInstance(); target.setTag(R.id.image_disk_cache_key, url); if (diskCache != null) { @@ -217,6 +221,10 @@ public class ImageDiskCache { * The image will be stored in the cover cache. */ public void loadCoverBitmap(final String url, final ImageView target, final int length) { + if (url == null) { + Log.w(TAG, "loadCoverBitmap: Call was ignored because url = null"); + return; + } final ImageLoader il = ImageLoader.getInstance(); target.setTag(R.id.image_disk_cache_key, url); if (diskCache != null) { diff --git a/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java index 0c42bdd65..a0861779c 100644 --- a/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java +++ b/src/de/danoeh/antennapod/fragment/NewEpisodesFragment.java @@ -7,7 +7,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.view.*; @@ -55,7 +54,6 @@ public class NewEpisodesFragment extends Fragment { private DragSortListView listView; - private SwipeRefreshLayout swipeRefreshLayout; private NewEpisodesListAdapter listAdapter; private TextView txtvEmpty; private ProgressBar progLoading; @@ -202,7 +200,6 @@ public class NewEpisodesFragment extends Fragment { View root = inflater.inflate(R.layout.new_episodes_fragment, container, false); - swipeRefreshLayout = (SwipeRefreshLayout) root.findViewById(R.id.swipeRefreshLayout); listView = (DragSortListView) root.findViewById(android.R.id.list); txtvEmpty = (TextView) root.findViewById(android.R.id.empty); progLoading = (ProgressBar) root.findViewById(R.id.progLoading); @@ -220,16 +217,6 @@ public class NewEpisodesFragment extends Fragment { }); final int secondColor = (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) ? R.color.swipe_refresh_secondary_color_dark : R.color.swipe_refresh_secondary_color_light; - swipeRefreshLayout.setColorScheme(R.color.bright_blue, secondColor, R.color.bright_blue, secondColor); - swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - List<Feed> feeds = ((MainActivity) getActivity()).getFeeds(); - if (feeds != null) { - DBTasks.refreshAllFeeds(getActivity(), feeds); - } - } - }); if (!itemsLoaded) { progLoading.setVisibility(View.VISIBLE); @@ -331,18 +318,9 @@ public class NewEpisodesFragment extends Fragment { if (!viewsCreated) { return; } - - if (DownloadService.isRunning - && DownloadRequester.getInstance().isDownloadingFeeds()) { - swipeRefreshLayout.setRefreshing(true); - - } else { - swipeRefreshLayout.setRefreshing(false); - - // if case other fragments have set this to true, this fragment should remove the progress indicator - ((ActionBarActivity) getActivity()) - .setSupportProgressBarIndeterminateVisibility(false); - } + ((ActionBarActivity) getActivity()) + .setSupportProgressBarIndeterminateVisibility(DownloadService.isRunning + && DownloadRequester.getInstance().isDownloadingFeeds()); } private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { diff --git a/src/de/danoeh/antennapod/service/download/DownloadService.java b/src/de/danoeh/antennapod/service/download/DownloadService.java index ed2f5d532..4f60ef8d6 100644 --- a/src/de/danoeh/antennapod/service/download/DownloadService.java +++ b/src/de/danoeh/antennapod/service/download/DownloadService.java @@ -890,6 +890,7 @@ public class DownloadService extends Service { if (successful) { return savedFeed; } else { + numberOfDownloads.decrementAndGet(); saveDownloadStatus(new DownloadStatus(savedFeed, savedFeed.getHumanReadableIdentifier(), reason, successful, reasonDetailed)); diff --git a/src/de/danoeh/antennapod/service/playback/PlaybackService.java b/src/de/danoeh/antennapod/service/playback/PlaybackService.java index fb2569bfd..b7ff62129 100644 --- a/src/de/danoeh/antennapod/service/playback/PlaybackService.java +++ b/src/de/danoeh/antennapod/service/playback/PlaybackService.java @@ -541,6 +541,7 @@ public class PlaybackService extends Service { (nextMedia.getMediaType() == MediaType.VIDEO) ? EXTRA_CODE_VIDEO : EXTRA_CODE_AUDIO); } else { sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_END, 0); + mediaPlayer.stop(); //stopSelf(); } } diff --git a/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java b/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java index 24ff9b3fa..2915da5a1 100644 --- a/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java +++ b/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java @@ -77,7 +77,8 @@ public class PlaybackServiceMediaPlayer { public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { if (BuildConfig.DEBUG) Log.d(TAG, "Rejected execution of runnable"); } - }); + } + ); mediaPlayer = null; statusBeforeSeeking = null; @@ -150,6 +151,8 @@ public class PlaybackServiceMediaPlayer { if (media != null) { if (!forceReset && media.getIdentifier().equals(playable.getIdentifier())) { // episode is already playing -> ignore method call + if (BuildConfig.DEBUG) + Log.d(TAG, "Method call to playMediaObject was ignored: media file already playing."); return; } else { // stop playback of this episode @@ -284,7 +287,8 @@ public class PlaybackServiceMediaPlayer { reinit(); } } else { - if (BuildConfig.DEBUG) Log.d(TAG, "Ignoring call to pause: Player is in " + playerStatus + " state"); + if (BuildConfig.DEBUG) + Log.d(TAG, "Ignoring call to pause: Player is in " + playerStatus + " state"); } playerLock.unlock(); @@ -385,9 +389,10 @@ public class PlaybackServiceMediaPlayer { /** * Seeks to the specified position. If the PSMP object is in an invalid state, this method will do nothing. + * * @param t The position to seek to in milliseconds. t < 0 will be interpreted as t = 0 - * <p/> - * This method is executed on the caller's thread. + * <p/> + * This method is executed on the caller's thread. */ private void seekToSync(int t) { if (t < 0) { @@ -758,6 +763,29 @@ public class PlaybackServiceMediaPlayer { } /** + * Moves the PlaybackServiceMediaPlayer into STOPPED state. This call is only valid if the player is currently in + * INDETERMINATE state, for example after a call to endPlayback. + * This method will only take care of changing the PlayerStatus of this object! Other tasks like + * abandoning audio focus have to be done with other methods. + */ + public void stop() { + executor.submit(new Runnable() { + @Override + public void run() { + playerLock.lock(); + + if (playerStatus == PlayerStatus.INDETERMINATE) { + setPlayerStatus(PlayerStatus.STOPPED, null); + } else { + if (BuildConfig.DEBUG) Log.d(TAG, "Ignored call to stop: Current player state is: " + playerStatus); + } + playerLock.unlock(); + + } + }); + } + + /** * Holds information about a PSMP object. */ public class PSMPInfo { diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java index 4aeca7cd6..e49ea4f83 100644 --- a/src/de/danoeh/antennapod/storage/DBReader.java +++ b/src/de/danoeh/antennapod/storage/DBReader.java @@ -56,6 +56,14 @@ public final class DBReader { PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); + List<Feed> result = getFeedList(adapter); + adapter.close(); + return result; + } + + private static List<Feed> getFeedList(PodDBAdapter adapter) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Extracting Feedlist"); Cursor feedlistCursor = adapter.getAllFeedsCursor(); List<Feed> feeds = new ArrayList<Feed>(feedlistCursor.getCount()); @@ -509,8 +517,8 @@ public final class DBReader { * Loads a list of FeedItems sorted by pubDate in descending order. * * @param context A context that is used for opening a database connection. - * @param limit The maximum number of episodes that should be loaded. - * */ + * @param limit The maximum number of episodes that should be loaded. + */ public static List<FeedItem> getRecentlyPublishedEpisodes(Context context, int limit) { if (BuildConfig.DEBUG) Log.d(TAG, "Extracting recently published items list"); @@ -596,7 +604,8 @@ public final class DBReader { .getString(PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE_INDEX); Date completionDate = new Date( logCursor - .getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX)); + .getLong(PodDBAdapter.KEY_COMPLETION_DATE_INDEX) + ); downloadLog.add(new DownloadStatus(id, title, feedfileId, feedfileType, successful, DownloadError.fromCode(reason), completionDate, reasonDetailed)); @@ -787,7 +796,8 @@ public final class DBReader { cursor.getString(cursor .getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL)), cursor.getInt(cursor - .getColumnIndex(PodDBAdapter.KEY_DOWNLOADED)) > 0); + .getColumnIndex(PodDBAdapter.KEY_DOWNLOADED)) > 0 + ); cursor.close(); return image; } @@ -865,4 +875,34 @@ public final class DBReader { adapter.close(); return empty; } + + /** + * Returns data necessary for displaying the navigation drawer. This includes + * the list of subscriptions, the number of items in the queue and the number of unread + * items. + * + * @param context A context that is used for opening a database connection. + */ + public static NavDrawerData getNavDrawerData(Context context) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + List<Feed> feeds = getFeedList(adapter); + int queueSize = adapter.getQueueSize(); + int numUnreadItems = adapter.getNumberOfUnreadItems(); + NavDrawerData result = new NavDrawerData(feeds, queueSize, numUnreadItems); + adapter.close(); + return result; + } + + public static class NavDrawerData { + public List<Feed> feeds; + public int queueSize; + public int numUnreadItems; + + public NavDrawerData(List<Feed> feeds, int queueSize, int numUnreadItems) { + this.feeds = feeds; + this.queueSize = queueSize; + this.numUnreadItems = numUnreadItems; + } + } } diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java index 285709537..06c8b1fc9 100644 --- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java +++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java @@ -1,6 +1,5 @@ package de.danoeh.antennapod.storage; -import android.app.backup.BackupManager; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -1107,6 +1106,17 @@ public class PodDBAdapter { } + public int getQueueSize() { + final String query = String.format("SELECT COUNT(%s) FROM %s", KEY_ID, TABLE_NAME_QUEUE); + Cursor c = db.rawQuery(query, null); + int result = 0; + if (c.moveToFirst()) { + result = c.getInt(0); + } + c.close(); + return result; + } + public final int getNumberOfUnreadItems() { final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_ITEMS + " WHERE " + KEY_READ + " = 0"; |