From d0022e053e4abfe35dac4ae2d90c6960982181fd Mon Sep 17 00:00:00 2001 From: Raghul Jagannathan Date: Wed, 27 May 2015 08:31:42 +0800 Subject: Subscription view for managing feeds and Navigation drawer feed list cleanup --- .../danoeh/antennapod/activity/MainActivity.java | 44 +++++++-- .../danoeh/antennapod/adapter/NavListAdapter.java | 6 +- .../antennapod/adapter/SubscriptionsAdapter.java | 70 +++++++++++++ .../antennapod/fragment/SubscriptionFragment.java | 108 +++++++++++++++++++++ .../java/de/danoeh/antennapod/utils/TimeUtils.java | 64 ++++++++++++ .../antennapod/view/SubscriptionViewItem.java | 63 ++++++++++++ 6 files changed, 346 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java create mode 100644 app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index d62612c76..e3a48c050 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -23,12 +23,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.Validate; - -import java.util.List; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.NavListAdapter; import de.danoeh.antennapod.core.feed.EventDistributor; @@ -45,9 +39,13 @@ import de.danoeh.antennapod.fragment.ItemlistFragment; import de.danoeh.antennapod.fragment.NewEpisodesFragment; import de.danoeh.antennapod.fragment.PlaybackHistoryFragment; import de.danoeh.antennapod.fragment.QueueFragment; +import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.menuhandler.NavDrawerActivity; import de.danoeh.antennapod.preferences.PreferenceController; import de.greenrobot.event.EventBus; +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.Validate; /** * The activity that is shown when the user launches the app. @@ -79,6 +77,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity AllEpisodesFragment.TAG, DownloadsFragment.TAG, PlaybackHistoryFragment.TAG, + SubscriptionFragment.TAG, AddFeedFragment.TAG }; @@ -282,6 +281,11 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity case AddFeedFragment.TAG: fragment = new AddFeedFragment(); break; + case SubscriptionFragment.TAG: + SubscriptionFragment subscriptionFragment = new SubscriptionFragment(); + subscriptionFragment.setItemAccess(itemAccess); + fragment = subscriptionFragment; + break; } currentTitle = navAdapter.getLabel(tag); getSupportActionBar().setTitle(currentTitle); @@ -292,6 +296,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity loadFragment(fragment); } + private void loadFeedFragmentByPosition(int relPos, Bundle args) { if(relPos < 0) { return; @@ -305,7 +310,15 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity saveLastNavFragment(String.valueOf(feed.getId())); currentTitle = ""; getSupportActionBar().setTitle(currentTitle); - loadFragment(fragment); + loadChildFragment(fragment); + } + + private void loadFeedFragment(Feed feed){ + long feedId = feed.getId(); + Fragment fragment = ItemlistFragment.newInstance(feedId); + currentTitle = ""; + getSupportActionBar().setTitle(currentTitle); + loadChildFragment(fragment); } public void loadFeedFragmentById(long feedId) { @@ -537,7 +550,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity String lastFragment = getLastNavFragment(); if(!ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) { long feedId = Long.valueOf(lastFragment); - loadFeedFragmentById(feedId); + //loadFeedFragmentById(feedId); saveLastNavFragment(null); } @@ -560,6 +573,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity loadData(); } + public void onEvent(SubscriptionFragment.SubscriptionEvent event){ + loadFeedFragment(event.feed); + } + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { @Override @@ -593,4 +610,15 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity super.onNewIntent(intent); setIntent(intent); } + + @Override + public void onBackPressed() { + // Make sure to have consistent behaviour across android apps + // Close the nav drawer if open on the first back button press + if(drawerLayout.isDrawerOpen(navDrawer)){ + drawerLayout.closeDrawer(navDrawer); + return; + } + super.onBackPressed(); + } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java index 13982f57d..81d997d65 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -16,6 +16,7 @@ import android.widget.TextView; import com.squareup.picasso.Picasso; +import de.danoeh.antennapod.fragment.SubscriptionFragment; import org.apache.commons.lang3.ArrayUtils; import java.util.ArrayList; @@ -100,6 +101,9 @@ public class NavListAdapter extends BaseAdapter case PlaybackHistoryFragment.TAG: icon = R.attr.ic_history; break; + case SubscriptionFragment.TAG: + icon = R.attr.ic_folder; + break; case AddFeedFragment.TAG: icon = R.attr.content_new; break; @@ -119,7 +123,7 @@ public class NavListAdapter extends BaseAdapter @Override public int getCount() { - return getSubscriptionOffset() + itemAccess.getCount(); + return getSubscriptionOffset() ;//+ itemAccess.getCount(); //Avoid feed } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java new file mode 100644 index 000000000..5928ad119 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java @@ -0,0 +1,70 @@ +package de.danoeh.antennapod.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.view.SubscriptionViewItem; + +/** + * Adapter for subscriptions + */ +public class SubscriptionsAdapter extends BaseAdapter { + + private NavListAdapter.ItemAccess mItemAccess; + + private Context mContext; + + public SubscriptionsAdapter(Context context, NavListAdapter.ItemAccess itemAccess) { + mItemAccess = itemAccess; + mContext = context; + } + + public void setItemAccess(NavListAdapter.ItemAccess itemAccess) { + mItemAccess = itemAccess; + } + + @Override + public int getCount() { + return mItemAccess.getCount(); + } + + @Override + public Object getItem(int position) { + return mItemAccess.getItem(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Holder holder; + final Feed item = (Feed) getItem(position); + if (item == null) return null; + + if (convertView == null) { + holder = new Holder(); + LayoutInflater inflater = + (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = inflater.inflate(R.layout.subscription_item, parent, false); + holder.itemView = (SubscriptionViewItem) convertView.findViewById(R.id.subscription_item); + convertView.setTag(holder); + } else { + holder = (Holder) convertView.getTag(); + } + + holder.itemView.setFeed(item, mItemAccess.getNumberOfUnreadFeedItems(item.getId())); + return convertView; + } + + static class Holder { + SubscriptionViewItem itemView; + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java new file mode 100644 index 000000000..999da10ab --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -0,0 +1,108 @@ +package de.danoeh.antennapod.fragment; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.GridView; + +import java.util.ArrayList; +import java.util.List; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.adapter.NavListAdapter; +import de.danoeh.antennapod.adapter.SubscriptionsAdapter; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.storage.DBReader; +import de.greenrobot.event.EventBus; +import rx.Observable; +import rx.functions.Action1; + +/** + * Fragment for displaying feed subscriptions + */ +public class SubscriptionFragment extends Fragment { + + public static final String TAG = "SubscriptionFragment"; + + private GridView mSubscriptionGridLayout; + private DBReader.NavDrawerData mDrawerData; + private SubscriptionsAdapter mSubscriptionAdapter; + private NavListAdapter.ItemAccess mItemAccess; + + private List mSubscriptionList = new ArrayList<>(); + + + public SubscriptionFragment() { + } + + + public void setItemAccess(NavListAdapter.ItemAccess itemAccess) { + mItemAccess = itemAccess; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setRetainInstance(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_subscriptions, container, false); + mSubscriptionGridLayout = (GridView) root.findViewById(R.id.subscriptions_grid); + return root; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + mSubscriptionAdapter = new SubscriptionsAdapter(getActivity(), mItemAccess); + + mSubscriptionGridLayout.setAdapter(mSubscriptionAdapter); + + Observable.just(loadData()).subscribe(new Action1() { + @Override + public void call(DBReader.NavDrawerData navDrawerData) { + mDrawerData = navDrawerData; + mSubscriptionList = mDrawerData.feeds; + mSubscriptionAdapter.setItemAccess(mItemAccess); + mSubscriptionAdapter.notifyDataSetChanged(); + } + }); + + mSubscriptionGridLayout.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + EventBus.getDefault().post(new SubscriptionEvent(mSubscriptionList.get(position))); + } + }); + + if (getActivity() instanceof MainActivity) { + ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.my_subscriptions); + } + + } + + @Override + public void onResume() { + super.onResume(); + } + + public class SubscriptionEvent { + public final Feed feed; + + SubscriptionEvent(Feed f) { + feed = f; + } + } + + + private DBReader.NavDrawerData loadData() { + return DBReader.getNavDrawerData(getActivity()); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java b/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java new file mode 100644 index 000000000..bb0573e72 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java @@ -0,0 +1,64 @@ +package de.danoeh.antennapod.utils; + + +import android.content.Context; + +import java.util.Date; + +import de.danoeh.antennapod.R; + +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//http://stackoverflow.com/questions/13018550/time-since-ago-library-for-android-java + + +public class TimeUtils { + private static final int SECOND_MILLIS = 1000; + private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS; + private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS; + private static final int DAY_MILLIS = 24 * HOUR_MILLIS; + + + public static String getTimeAgo(long time, Context ctx) { + if (time < 1000000000000L) { + // if timestamp given in seconds, convert to millis + time *= 1000; + } + + long now = new Date().getTime(); + if (time > now || time <= 0) { + return null; + } + + final long diff = now - time; + if (diff < MINUTE_MILLIS) { + return ctx.getString(R.string.time_just_now); + } else if (diff < 2 * MINUTE_MILLIS) { + return ctx.getString(R.string.time_a_min_ago); + } else if (diff < 50 * MINUTE_MILLIS) { + return diff / MINUTE_MILLIS + ctx.getString(R.string.time_min_ago); + } else if (diff < 90 * MINUTE_MILLIS) { + return ctx.getString(R.string.time_an_hour_ago); + } else if (diff < 24 * HOUR_MILLIS) { + return diff / HOUR_MILLIS + ctx.getString(R.string.time_hours_ago); + } else if (diff < 48 * HOUR_MILLIS) { + return ctx.getString(R.string.time_yesterday); + } else { + return diff / DAY_MILLIS + ctx.getString(R.string.time_days_ago); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java new file mode 100644 index 000000000..1aca68610 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java @@ -0,0 +1,63 @@ +package de.danoeh.antennapod.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.squareup.picasso.Picasso; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.utils.TimeUtils; + +/** + * Custom view for handling feed item. + */ +public class SubscriptionViewItem extends RelativeLayout { + + private ImageView mImageView; + private TextView mTitle; + private TextView mUnreadCountText; + private Context mContext; + + public SubscriptionViewItem(Context context) { + super(context); + init(context); + } + + public SubscriptionViewItem(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public SubscriptionViewItem(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context); + } + + @Override + public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } + + private void init(Context context) { + mContext = context; + LayoutInflater mLayoutInflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = mLayoutInflater.inflate(R.layout.subscription_view, this); + mTitle = (TextView) view.findViewById(R.id.txtvTitle); + mImageView = (ImageView) view.findViewById(R.id.imgvCover); + mUnreadCountText = (TextView) view.findViewById(R.id.unread_count_text); + } + + public void setFeed(Feed feed, int unreadCount) { + Picasso.with(mContext).load(feed.getImageUri()).centerCrop().fit().into(mImageView); + mUnreadCountText.setText(unreadCount + ""); + mTitle.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext)); + } + +} -- cgit v1.2.3 From 9e09ad247b1cbb5dd19a630db4c55963dd714734 Mon Sep 17 00:00:00 2001 From: Raghul Date: Tue, 7 Jul 2015 12:00:10 +0800 Subject: Fix for title when image is not available --- .../antennapod/view/SubscriptionViewItem.java | 25 +++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java index 1aca68610..08d1006f1 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java +++ b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java @@ -8,6 +8,7 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; +import com.squareup.picasso.Callback; import com.squareup.picasso.Picasso; import de.danoeh.antennapod.R; @@ -20,8 +21,9 @@ import de.danoeh.antennapod.utils.TimeUtils; public class SubscriptionViewItem extends RelativeLayout { private ImageView mImageView; - private TextView mTitle; + private TextView mTextTime; private TextView mUnreadCountText; + private TextView mFeedTitle; private Context mContext; public SubscriptionViewItem(Context context) { @@ -49,15 +51,28 @@ public class SubscriptionViewItem extends RelativeLayout { LayoutInflater mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = mLayoutInflater.inflate(R.layout.subscription_view, this); - mTitle = (TextView) view.findViewById(R.id.txtvTitle); + mTextTime = (TextView) view.findViewById(R.id.txtvTime); + mFeedTitle = (TextView) view.findViewById(R.id.txtvTitle); mImageView = (ImageView) view.findViewById(R.id.imgvCover); mUnreadCountText = (TextView) view.findViewById(R.id.unread_count_text); } - public void setFeed(Feed feed, int unreadCount) { - Picasso.with(mContext).load(feed.getImageUri()).centerCrop().fit().into(mImageView); + public void setFeed(final Feed feed, int unreadCount) { + mFeedTitle.setVisibility(VISIBLE); + mFeedTitle.setText(feed.getTitle()); + + Picasso.with(mContext).load(feed.getImageUri()).centerCrop().fit().into(mImageView, new Callback() { + @Override + public void onSuccess() { + mFeedTitle.setVisibility(GONE); + } + + @Override + public void onError() { + } + }); mUnreadCountText.setText(unreadCount + ""); - mTitle.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext)); + mTextTime.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext)); } } -- cgit v1.2.3 From b4a363cecebdb15d885ab98cc48f5cc88142cfa1 Mon Sep 17 00:00:00 2001 From: Raghul Date: Wed, 8 Jul 2015 11:11:52 +0800 Subject: Handling update events in feed subscriptions, removed updated time in subscription view --- .../danoeh/antennapod/activity/MainActivity.java | 2 +- .../antennapod/fragment/SubscriptionFragment.java | 36 +++++++++++++++++----- .../antennapod/view/SubscriptionViewItem.java | 5 +-- 3 files changed, 32 insertions(+), 11 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index e3a48c050..0be521f8b 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -550,7 +550,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity String lastFragment = getLastNavFragment(); if(!ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) { long feedId = Long.valueOf(lastFragment); - //loadFeedFragmentById(feedId); + loadFeedFragmentById(feedId); saveLastNavFragment(null); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index 999da10ab..7f37ea680 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -15,6 +15,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.NavListAdapter; import de.danoeh.antennapod.adapter.SubscriptionsAdapter; +import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.storage.DBReader; import de.greenrobot.event.EventBus; @@ -64,7 +65,21 @@ public class SubscriptionFragment extends Fragment { mSubscriptionAdapter = new SubscriptionsAdapter(getActivity(), mItemAccess); mSubscriptionGridLayout.setAdapter(mSubscriptionAdapter); + refreshSubscriptionList(); + mSubscriptionGridLayout.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + EventBus.getDefault().post(new SubscriptionEvent(mSubscriptionList.get(position))); + } + }); + + if (getActivity() instanceof MainActivity) { + ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.my_subscriptions); + } + + } + private void refreshSubscriptionList() { Observable.just(loadData()).subscribe(new Action1() { @Override public void call(DBReader.NavDrawerData navDrawerData) { @@ -74,23 +89,28 @@ public class SubscriptionFragment extends Fragment { mSubscriptionAdapter.notifyDataSetChanged(); } }); + } - mSubscriptionGridLayout.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - EventBus.getDefault().post(new SubscriptionEvent(mSubscriptionList.get(position))); + EventDistributor.EventListener updateListener = new EventDistributor.EventListener() { + @Override + public void update(EventDistributor eventDistributor, Integer arg) { + if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) { + refreshSubscriptionList(); } - }); - - if (getActivity() instanceof MainActivity) { - ((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.my_subscriptions); } + }; + + @Override + public void onStop() { + super.onStop(); + EventDistributor.getInstance().unregister(updateListener); } @Override public void onResume() { super.onResume(); + EventDistributor.getInstance().register(updateListener); } public class SubscriptionEvent { diff --git a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java index 08d1006f1..ee2567364 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java +++ b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java @@ -13,7 +13,6 @@ import com.squareup.picasso.Picasso; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.utils.TimeUtils; /** * Custom view for handling feed item. @@ -72,7 +71,9 @@ public class SubscriptionViewItem extends RelativeLayout { } }); mUnreadCountText.setText(unreadCount + ""); - mTextTime.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext)); + // Removing the updated time. It could be the latest podcast updated time in the future. + //mTextTime.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext)); + mTextTime.setVisibility(GONE); } } -- cgit v1.2.3 From 4cd58a9b37899e0c886a930f268b701d29a9a989 Mon Sep 17 00:00:00 2001 From: Tom Hennen Date: Fri, 25 Mar 2016 10:50:41 -0400 Subject: updated and fixed PR AntennaPod/AntennPod#1624 --- .../main/java/de/danoeh/antennapod/PodcastApp.java | 12 +- .../java/de/danoeh/antennapod/UpdateManager.java | 88 ---- .../danoeh/antennapod/activity/AboutActivity.java | 6 +- .../antennapod/activity/AudioplayerActivity.java | 84 ++-- .../activity/DirectoryChooserActivity.java | 11 +- .../activity/DownloadAuthenticationActivity.java | 39 +- .../antennapod/activity/FeedInfoActivity.java | 24 +- .../antennapod/activity/FlattrAuthActivity.java | 36 +- .../danoeh/antennapod/activity/MainActivity.java | 98 ++-- .../antennapod/activity/MediaplayerActivity.java | 286 ++++++----- .../activity/OnlineFeedViewActivity.java | 49 +- .../activity/OpmlFeedChooserActivity.java | 98 ++-- .../activity/OpmlImportBaseActivity.java | 111 ++++- .../activity/OpmlImportFromIntentActivity.java | 22 +- .../activity/OpmlImportFromPathActivity.java | 32 +- .../antennapod/activity/PreferenceActivity.java | 6 +- .../antennapod/activity/StatisticsActivity.java | 107 ++++ .../antennapod/activity/StorageErrorActivity.java | 196 +++++++- .../antennapod/activity/VideoplayerActivity.java | 20 +- .../gpoddernet/GpodnetAuthenticationActivity.java | 42 +- .../antennapod/adapter/ActionButtonCallback.java | 2 +- .../de/danoeh/antennapod/adapter/AdapterUtils.java | 3 +- .../adapter/AllEpisodesRecycleAdapter.java | 14 +- .../antennapod/adapter/ChaptersListAdapter.java | 9 +- .../adapter/DefaultActionButtonCallback.java | 2 - .../antennapod/adapter/DownloadLogAdapter.java | 18 +- .../adapter/DownloadedEpisodesListAdapter.java | 40 +- .../antennapod/adapter/DownloadlistAdapter.java | 9 +- .../antennapod/adapter/FeedItemlistAdapter.java | 20 +- .../adapter/FeedItemlistDescriptionAdapter.java | 16 +- .../danoeh/antennapod/adapter/NavListAdapter.java | 35 +- .../antennapod/adapter/QueueRecyclerAdapter.java | 40 +- .../antennapod/adapter/SearchlistAdapter.java | 3 +- .../antennapod/adapter/StatisticsListAdapter.java | 97 ++++ .../antennapod/adapter/SubscriptionsAdapter.java | 2 +- .../adapter/gpodnet/PodcastListAdapter.java | 1 - .../antennapod/adapter/itunes/ItunesAdapter.java | 2 +- .../antennapod/asynctask/OpmlExportWorker.java | 10 +- .../antennapod/asynctask/OpmlFeedQueuer.java | 8 +- .../antennapod/asynctask/OpmlImportWorker.java | 11 +- .../antennapod/config/DBTasksCallbacksImpl.java | 1 - .../antennapod/dialog/AuthenticationDialog.java | 29 +- .../dialog/AutoFlattrPreferenceDialog.java | 36 +- .../dialog/EpisodesApplyActionFragment.java | 133 +++-- .../dialog/GpodnetSetHostnameDialog.java | 1 - .../de/danoeh/antennapod/dialog/ProxyDialog.java | 320 ++++++++++++ .../de/danoeh/antennapod/dialog/RatingDialog.java | 28 +- .../danoeh/antennapod/dialog/SleepTimerDialog.java | 19 +- .../antennapod/dialog/VariableSpeedDialog.java | 4 +- .../antennapod/fragment/AddFeedFragment.java | 36 +- .../antennapod/fragment/AllEpisodesFragment.java | 36 +- .../antennapod/fragment/ChaptersFragment.java | 18 +- .../fragment/CompletedDownloadsFragment.java | 72 ++- .../danoeh/antennapod/fragment/CoverFragment.java | 7 +- .../antennapod/fragment/DownloadLogFragment.java | 2 +- .../fragment/ExternalPlayerFragment.java | 29 +- .../fragment/ItemDescriptionFragment.java | 11 +- .../danoeh/antennapod/fragment/ItemFragment.java | 10 +- .../antennapod/fragment/ItemlistFragment.java | 13 +- .../antennapod/fragment/ItunesSearchFragment.java | 4 +- .../fragment/PlaybackHistoryFragment.java | 4 +- .../danoeh/antennapod/fragment/QueueFragment.java | 14 +- .../danoeh/antennapod/fragment/SearchFragment.java | 2 +- .../fragment/gpodnet/PodcastListFragment.java | 16 +- .../fragment/gpodnet/SuggestionListFragment.java | 8 +- .../fragment/gpodnet/TagListFragment.java | 12 +- .../menuhandler/FeedItemMenuHandler.java | 8 +- .../antennapod/menuhandler/FeedMenuHandler.java | 6 +- .../antennapod/menuhandler/MenuItemUtils.java | 1 + .../antennapod/menuhandler/NavDrawerActivity.java | 2 +- .../preferences/PreferenceController.java | 547 +++++++++++---------- .../receiver/ConnectivityActionReceiver.java | 4 +- .../danoeh/antennapod/receiver/PlayerWidget.java | 6 +- .../receiver/PowerConnectionReceiver.java | 4 +- .../de/danoeh/antennapod/receiver/SPAReceiver.java | 48 +- .../java/de/danoeh/antennapod/utils/TimeUtils.java | 64 --- .../antennapod/view/SubscriptionViewItem.java | 8 +- 77 files changed, 1963 insertions(+), 1309 deletions(-) delete mode 100644 app/src/main/java/de/danoeh/antennapod/UpdateManager.java create mode 100644 app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java create mode 100644 app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java create mode 100644 app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java index c1d4bc4fd..f6a8db5fb 100644 --- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java +++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java @@ -8,11 +8,8 @@ import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.fonts.FontAwesomeModule; import com.joanzapata.iconify.fonts.MaterialModule; +import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.feed.EventDistributor; -import de.danoeh.antennapod.core.preferences.PlaybackPreferences; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.PodDBAdapter; -import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.spa.SPAUtil; /** Main application class. */ @@ -56,11 +53,8 @@ public class PodcastApp extends Application { singleton = this; - PodDBAdapter.init(this); - UpdateManager.init(this); - UserPreferences.init(this); - PlaybackPreferences.init(this); - NetworkUtils.init(this); + ClientConfig.initialize(this); + EventDistributor.getInstance(); Iconify.with(new FontAwesomeModule()); Iconify.with(new MaterialModule()); diff --git a/app/src/main/java/de/danoeh/antennapod/UpdateManager.java b/app/src/main/java/de/danoeh/antennapod/UpdateManager.java deleted file mode 100644 index b1d7fffc8..000000000 --- a/app/src/main/java/de/danoeh/antennapod/UpdateManager.java +++ /dev/null @@ -1,88 +0,0 @@ -package de.danoeh.antennapod; - - -import android.content.Context; -import android.content.SharedPreferences; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.util.Log; - -import java.io.File; -import java.util.List; - -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedImage; -import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBWriter; - -/* - * This class's job is do perform maintenance tasks whenever the app has been updated - */ -public class UpdateManager { - - public static final String TAG = UpdateManager.class.getSimpleName(); - - private static final String PREF_NAME = "app_version"; - private static final String KEY_VERSION_CODE = "version_code"; - - private static int currentVersionCode; - - private static Context context; - private static SharedPreferences prefs; - - public static void init(Context context) { - UpdateManager.context = context; - prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); - PackageManager pm = context.getPackageManager(); - try { - PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0); - currentVersionCode = info.versionCode; - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "Failed to obtain package info for package name: " + context.getPackageName(), e); - currentVersionCode = 0; - return; - } - final int oldVersionCode = getStoredVersionCode(); - Log.d(TAG, "old: " + oldVersionCode + ", current: " + currentVersionCode); - if(oldVersionCode < currentVersionCode) { - onUpgrade(oldVersionCode, currentVersionCode); - setCurrentVersionCode(); - } - } - - public static int getStoredVersionCode() { - return prefs.getInt(KEY_VERSION_CODE, -1); - } - - public static void setCurrentVersionCode() { - prefs.edit().putInt(KEY_VERSION_CODE, currentVersionCode).apply(); - } - - private static void onUpgrade(final int oldVersionCode, final int newVersionCode) { - if(oldVersionCode < 1030099) { - // delete the now obsolete image cache - // from now on, Glide will handle caching images - new Thread() { - public void run() { - List feeds = DBReader.getFeedList(); - for (Feed podcast : feeds) { - List episodes = DBReader.getFeedItemList(podcast); - for (FeedItem episode : episodes) { - FeedImage image = episode.getImage(); - if (image != null && image.isDownloaded() && image.getFile_url() != null) { - File imageFile = new File(image.getFile_url()); - if (imageFile.exists()) { - imageFile.delete(); - } - image.setFile_url(null); // calls setDownloaded(false) - DBWriter.setFeedImage(image); - } - } - } - } - }.start(); - } - } - -} diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java index c835f8073..eef2fa4da 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/AboutActivity.java @@ -4,7 +4,7 @@ import android.content.res.TypedArray; import android.graphics.Color; import android.os.Build; import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.MenuItem; import android.view.View; @@ -30,7 +30,7 @@ import rx.schedulers.Schedulers; /** * Displays the 'about' screen */ -public class AboutActivity extends ActionBarActivity { +public class AboutActivity extends AppCompatActivity { private static final String TAG = AboutActivity.class.getSimpleName(); @@ -87,7 +87,7 @@ public class AboutActivity extends ActionBarActivity { res.recycle(); input = getAssets().open(filename); String webViewData = IOUtils.toString(input, Charset.defaultCharset()); - if(false == webViewData.startsWith("")) { + if(!webViewData.startsWith("")) { //webViewData = webViewData.replace("\n\n", "

"); webViewData = webViewData.replace("%", "%"); webViewData = diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java index 12bae2f51..107afcbfe 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java @@ -94,8 +94,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe private int mPosition = -1; private Playable media; - private ViewPager mPager; - private AudioplayerPagerAdapter mPagerAdapter; + private ViewPager pager; + private AudioplayerPagerAdapter pagerAdapter; private Subscription subscription; @@ -103,6 +103,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe protected void onStop() { super.onStop(); Log.d(TAG, "onStop()"); + pagerAdapter.setController(null); if(subscription != null) { subscription.unsubscribe(); } @@ -112,12 +113,16 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe @Override public void onDestroy() { + Log.d(TAG, "onDestroy()"); super.onDestroy(); // don't risk creating memory leaks + drawerLayout = null; navAdapter = null; + navList = null; + navDrawer = null; drawerToggle = null; - mPager = null; - mPagerAdapter = null; + pager = null; + pagerAdapter = null; } @Override @@ -126,27 +131,29 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe } private void saveCurrentFragment() { - if(mPager == null) { + if(pager == null) { return; } Log.d(TAG, "Saving preferences"); SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); prefs.edit() - .putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, mPager.getCurrentItem()) + .putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, pager.getCurrentItem()) .commit(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - drawerToggle.onConfigurationChanged(newConfig); + if(drawerToggle != null) { + drawerToggle.onConfigurationChanged(newConfig); + } } private void loadLastFragment() { Log.d(TAG, "Restoring instance state"); SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); int lastPosition = prefs.getInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, -1); - mPager.setCurrentItem(lastPosition); + pager.setCurrentItem(lastPosition); } @Override @@ -166,9 +173,10 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe true); startService(launchIntent); } - if(mPagerAdapter != null && controller != null && controller.getMedia() != media) { + if(pagerAdapter != null && controller != null && controller.getMedia() != media) { media = controller.getMedia(); - mPagerAdapter.onMediaChanged(media); + pagerAdapter.onMediaChanged(media); + pagerAdapter.setController(controller); } EventDistributor.getInstance().register(contentUpdate); @@ -255,13 +263,14 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe startActivity(new Intent(AudioplayerActivity.this, PreferenceController.getPreferenceActivity())); }); - mPager = (ViewPager) findViewById(R.id.pager); - mPagerAdapter = new AudioplayerPagerAdapter(getSupportFragmentManager()); - mPager.setAdapter(mPagerAdapter); + pager = (ViewPager) findViewById(R.id.pager); + pagerAdapter = new AudioplayerPagerAdapter(getSupportFragmentManager(), media); + pagerAdapter.setController(controller); + pager.setAdapter(pagerAdapter); CirclePageIndicator pageIndicator = (CirclePageIndicator) findViewById(R.id.page_indicator); - pageIndicator.setViewPager(mPager); + pageIndicator.setViewPager(pager); loadLastFragment(); - mPager.onSaveInstanceState(); + pager.onSaveInstanceState(); } @Override @@ -277,13 +286,16 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe } if(controller.getMedia() != media) { media = controller.getMedia(); - mPagerAdapter.onMediaChanged(media); + pagerAdapter.onMediaChanged(media); } return true; } public void notifyMediaPositionChanged() { - ChaptersFragment chaptersFragment = mPagerAdapter.getChaptersFragment(); + if(pagerAdapter == null) { + return; + } + ChaptersFragment chaptersFragment = pagerAdapter.getChaptersFragment(); if(chaptersFragment != null) { ChaptersListAdapter adapter = (ChaptersListAdapter) chaptersFragment.getListAdapter(); if (adapter != null) { @@ -329,11 +341,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe @Override public boolean onOptionsItemSelected(MenuItem item) { - if (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) { - return true; - } else { - return super.onOptionsItemSelected(item); - } + return drawerToggle != null && drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item); } @Override @@ -411,13 +419,13 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe public void onBackPressed() { if(isDrawerOpen()) { drawerLayout.closeDrawer(navDrawer); - } else if (mPager.getCurrentItem() == 0) { + } else if (pager == null || pager.getCurrentItem() == 0) { // If the user is currently looking at the first step, allow the system to handle the // Back button. This calls finish() on this activity and pops the back stack. super.onBackPressed(); } else { // Otherwise, select the previous step. - mPager.setCurrentItem(mPager.getCurrentItem() - 1); + pager.setCurrentItem(pager.getCurrentItem() - 1); } } @@ -452,7 +460,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe private DBReader.NavDrawerData navDrawerData; private void loadData() { - subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData()) + subscription = Observable.fromCallable(DBReader::getNavDrawerData) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { @@ -517,6 +525,11 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe return (navDrawerData != null) ? navDrawerData.numDownloadedItems : 0; } + @Override + public int getReclaimableItems() { + return (navDrawerData != null) ? navDrawerData.reclaimableSpace : 0; + } + @Override public int getFeedCounter(long feedId) { return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0; @@ -527,10 +540,16 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe void onMediaChanged(Playable media); } - private class AudioplayerPagerAdapter extends FragmentStatePagerAdapter { + private static class AudioplayerPagerAdapter extends FragmentStatePagerAdapter { + + private static final String TAG = "AudioplayerPagerAdapter"; + + private Playable media; + private PlaybackController controller; - public AudioplayerPagerAdapter(FragmentManager fm) { + public AudioplayerPagerAdapter(FragmentManager fm, Playable media) { super(fm); + this.media = media; } private CoverFragment coverFragment; @@ -538,6 +557,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe private ChaptersFragment chaptersFragment; public void onMediaChanged(Playable media) { + this.media = media; if(coverFragment != null) { coverFragment.onMediaChanged(media); } @@ -549,6 +569,13 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe } } + public void setController(PlaybackController controller) { + this.controller = controller; + if(chaptersFragment != null) { + chaptersFragment.setController(controller); + } + } + @Nullable public ChaptersFragment getChaptersFragment() { return chaptersFragment; @@ -570,7 +597,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements NavDrawe return itemDescriptionFragment; case POS_CHAPTERS: if(chaptersFragment == null) { - chaptersFragment = ChaptersFragment.newInstance(media, controller); + chaptersFragment = ChaptersFragment.newInstance(media); + chaptersFragment.setController(controller); } return chaptersFragment; default: diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java index 25dc64232..5fd69ef6a 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java @@ -6,8 +6,8 @@ import android.os.Bundle; import android.os.Environment; import android.os.FileObserver; import android.support.v4.app.NavUtils; -import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -34,7 +34,8 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; * Let's the user choose a directory on the storage device. The selected folder * will be sent back to the starting activity as an activity result. */ -public class DirectoryChooserActivity extends ActionBarActivity { +public class DirectoryChooserActivity extends AppCompatActivity { + private static final String TAG = "DirectoryChooserActivit"; private static final String CREATE_DIRECTORY_NAME = "AntennaPod"; @@ -242,7 +243,7 @@ public class DirectoryChooserActivity extends ActionBarActivity { @Override public void onEvent(int event, String path) { Log.d(TAG, "FileObserver received event " + event); - runOnUiThread(() -> refreshDirectory()); + runOnUiThread(DirectoryChooserActivity.this::refreshDirectory); } }; } @@ -250,8 +251,7 @@ public class DirectoryChooserActivity extends ActionBarActivity { @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - menu.findItem(R.id.new_folder_item) - .setVisible(isValidFile(selectedDir)); + menu.findItem(R.id.new_folder_item).setVisible(isValidFile(selectedDir)); return true; } @@ -333,4 +333,5 @@ public class DirectoryChooserActivity extends ActionBarActivity { private boolean isValidFile(File file) { return file != null && file.isDirectory() && file.canRead() && file.canWrite(); } + } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java index 365c4216d..41b2debdc 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java @@ -5,7 +5,6 @@ import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.util.Log; -import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; @@ -73,31 +72,25 @@ public class DownloadAuthenticationActivity extends ActionBarActivity { txtvDescription.setText(txtvDescription.getText() + ":\n\n" + request.getTitle()); - butCancel.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - setResult(Activity.RESULT_CANCELED); - finish(); - } + butCancel.setOnClickListener(v -> { + setResult(Activity.RESULT_CANCELED); + finish(); }); - butConfirm.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - String username = etxtUsername.getText().toString(); - String password = etxtPassword.getText().toString(); - request.setUsername(username); - request.setPassword(password); - Intent result = new Intent(); - result.putExtra(RESULT_REQUEST, request); - setResult(Activity.RESULT_OK, result); - - if (sendToDownloadRequester) { - if (BuildConfig.DEBUG) Log.d(TAG, "Sending request to DownloadRequester"); - DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request); - } - finish(); + butConfirm.setOnClickListener(v -> { + String username = etxtUsername.getText().toString(); + String password = etxtPassword.getText().toString(); + request.setUsername(username); + request.setPassword(password); + Intent result = new Intent(); + result.putExtra(RESULT_REQUEST, request); + setResult(Activity.RESULT_OK, result); + + if (sendToDownloadRequester) { + if (BuildConfig.DEBUG) Log.d(TAG, "Sending request to DownloadRequester"); + DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request); } + finish(); }); } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java index edb973a0c..805d82cf9 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java @@ -139,20 +139,14 @@ public class FeedInfoActivity extends ActionBarActivity { Log.d(TAG, "Author is " + feed.getAuthor()); Log.d(TAG, "URL is " + feed.getDownload_url()); FeedPreferences prefs = feed.getPreferences(); - imgvCover.post(new Runnable() { - - @Override - public void run() { - Glide.with(FeedInfoActivity.this) - .load(feed.getImageUri()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(imgvCover); - } - }); + imgvCover.post(() -> Glide.with(FeedInfoActivity.this) + .load(feed.getImageUri()) + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate() + .into(imgvCover)); txtvTitle.setText(feed.getTitle()); String description = feed.getDescription(); @@ -224,10 +218,12 @@ public class FeedInfoActivity extends ActionBarActivity { etxtFilterText.setText(filter.getIncludeFilter()); rdoFilterInclude.setChecked(true); rdoFilterExclude.setChecked(false); + filterInclude = true; } else if (filter.excludeOnly()) { etxtFilterText.setText(filter.getExcludeFilter()); rdoFilterInclude.setChecked(false); rdoFilterExclude.setChecked(true); + filterInclude = false; } else { Log.d(TAG, "No filter set"); rdoFilterInclude.setChecked(false); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java index 3b10ba4c3..be1c9f9e6 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/FlattrAuthActivity.java @@ -9,17 +9,17 @@ import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; + +import org.shredzone.flattr4j.exception.FlattrException; + import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.flattr.FlattrUtils; import de.danoeh.antennapod.preferences.PreferenceController; -import org.shredzone.flattr4j.exception.FlattrException; - /** Guides the user through the authentication process */ public class FlattrAuthActivity extends ActionBarActivity { @@ -46,25 +46,19 @@ public class FlattrAuthActivity extends ActionBarActivity { butAuthenticate = (Button) findViewById(R.id.but_authenticate); butReturn = (Button) findViewById(R.id.but_return_home); - butReturn.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(FlattrAuthActivity.this, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - } - }); + butReturn.setOnClickListener(v -> { + Intent intent = new Intent(FlattrAuthActivity.this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + }); - butAuthenticate.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - try { - FlattrUtils.startAuthProcess(FlattrAuthActivity.this); - } catch (FlattrException e) { - e.printStackTrace(); - } - } - }); + butAuthenticate.setOnClickListener(v -> { + try { + FlattrUtils.startAuthProcess(FlattrAuthActivity.this); + } catch (FlattrException e) { + e.printStackTrace(); + } + }); } public static FlattrAuthActivity getInstance() { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index d57199941..3b5168f51 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -44,11 +44,13 @@ import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedMedia; +import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; @@ -87,6 +89,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity public static final String EXTRA_NAV_INDEX = "nav_index"; public static final String EXTRA_FRAGMENT_TAG = "fragment_tag"; public static final String EXTRA_FRAGMENT_ARGS = "fragment_args"; + public static final String EXTRA_FEED_ID = "fragment_feed_id"; public static final String SAVE_BACKSTACK_COUNT = "backstackCount"; public static final String SAVE_TITLE = "title"; @@ -186,7 +189,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity loadFragment(lastFragment, null); } else { try { - loadFeedFragmentById(Integer.valueOf(lastFragment), null); + loadFeedFragmentById(Integer.parseInt(lastFragment), null); } catch (NumberFormatException e) { // it's not a number, this happens if we removed // a label from the NAV_DRAWER_TAGS @@ -203,10 +206,10 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity } private void saveLastNavFragment(String tag) { - Log.d(TAG, "saveLastNavFragment(tag: " + tag + ")"); + Log.d(TAG, "saveLastNavFragment(tag: " + tag +")"); SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE); SharedPreferences.Editor edit = prefs.edit(); - if (tag != null) { + if(tag != null) { edit.putString(PREF_LAST_FRAGMENT_TAG, tag); } else { edit.remove(PREF_LAST_FRAGMENT_TAG); @@ -322,9 +325,8 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity loadFragment(fragment); } - private void loadFeedFragmentByPosition(int relPos, Bundle args) { - if (relPos < 0) { + if(relPos < 0) { return; } Feed feed = itemAccess.getItem(relPos); @@ -333,21 +335,13 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity public void loadFeedFragmentById(long feedId, Bundle args) { Fragment fragment = ItemlistFragment.newInstance(feedId); - if (args != null) { + if(args != null) { fragment.setArguments(args); } saveLastNavFragment(String.valueOf(feedId)); currentTitle = ""; getSupportActionBar().setTitle(currentTitle); - loadChildFragment(fragment); - } - - private void loadFeedFragment(Feed feed) { - long feedId = feed.getId(); - Fragment fragment = ItemlistFragment.newInstance(feedId); - currentTitle = ""; - getSupportActionBar().setTitle(currentTitle); - loadChildFragment(fragment); + loadFragment(fragment); } private void loadFragment(Fragment fragment) { @@ -386,14 +380,14 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity private int getSelectedNavListIndex() { String currentFragment = getLastNavFragment(); - if (currentFragment == null) { + if(currentFragment == null) { // should not happen, but better safe than sorry return -1; } int tagIndex = navAdapter.getTags().indexOf(currentFragment); - if (tagIndex >= 0) { + if(tagIndex >= 0) { return tagIndex; - } else if (ArrayUtils.contains(NAV_DRAWER_TAGS, currentFragment)) { + } else if(ArrayUtils.contains(NAV_DRAWER_TAGS, currentFragment)) { // the fragment was just hidden return -1; } else { // last fragment was not a list, but a feed @@ -424,7 +418,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity private AdapterView.OnItemLongClickListener newListLongClickListener = new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { - if (position < navAdapter.getTags().size()) { + if(position < navAdapter.getTags().size()) { showDrawerPreferencesDialog(); return true; } else { @@ -480,8 +474,9 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity StorageUtils.checkStorageAvailability(this); Intent intent = getIntent(); - if (navDrawerData != null && intent.hasExtra(EXTRA_NAV_TYPE) && - (intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG))) { + if (intent.hasExtra(EXTRA_FEED_ID) || + (navDrawerData != null && intent.hasExtra(EXTRA_NAV_TYPE) && + (intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)))) { handleNavIntent(); } loadData(); @@ -493,10 +488,10 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity super.onStop(); EventDistributor.getInstance().unregister(contentUpdate); EventBus.getDefault().unregister(this); - if (subscription != null) { + if(subscription != null) { subscription.unsubscribe(); } - if (pd != null) { + if(pd != null) { pd.dismiss(); } } @@ -533,12 +528,12 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); - if (v.getId() != R.id.nav_list) { + if(v.getId() != R.id.nav_list) { return; } AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo; int position = adapterInfo.position; - if (position < navAdapter.getSubscriptionOffset()) { + if(position < navAdapter.getSubscriptionOffset()) { return; } MenuInflater inflater = getMenuInflater(); @@ -553,11 +548,11 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity public boolean onContextItemSelected(MenuItem item) { final int position = mPosition; mPosition = -1; // reset - if (position < 0) { + if(position < 0) { return false; } Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset()); - switch (item.getItemId()) { + switch(item.getItemId()) { case R.id.mark_all_seen_item: DBWriter.markFeedSeen(feed.getId()); return true; @@ -569,7 +564,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity @Override protected void onPostExecute(Void result) { super.onPostExecute(result); - if (getSelectedNavListIndex() == position) { + if(getSelectedNavListIndex() == position) { loadFragment(EpisodesFragment.TAG, null); } } @@ -581,21 +576,15 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity public void onConfirmButtonPressed( DialogInterface dialog) { dialog.dismiss(); - if (externalPlayerFragment != null) { - PlaybackController controller = externalPlayerFragment.getPlaybackControllerTestingOnly(); - if (controller != null) { - Playable playable = controller.getMedia(); - if (playable != null && playable instanceof FeedMedia) { - FeedMedia media = (FeedMedia) playable; - if (media.getItem().getFeed().getId() == feed.getId()) { - Log.d(TAG, "Currently playing episode is about to be deleted, skipping"); - remover.skipOnCompletion = true; - if (controller.getStatus() == PlayerStatus.PLAYING) { - sendBroadcast(new Intent( - PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); - } - } - } + long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId(); + if (mediaId > 0 && + FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) { + Log.d(TAG, "Currently playing episode is about to be deleted, skipping"); + remover.skipOnCompletion = true; + int playerStatus = PlaybackPreferences.getCurrentPlayerStatus(); + if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) { + sendBroadcast(new Intent( + PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE)); } } remover.executeAsync(); @@ -610,7 +599,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity @Override public void onBackPressed() { - if (isDrawerOpen()) { + if(isDrawerOpen()) { drawerLayout.closeDrawer(navDrawer); } else { super.onBackPressed(); @@ -659,6 +648,11 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity return (navDrawerData != null) ? navDrawerData.numDownloadedItems : 0; } + @Override + public int getReclaimableItems() { + return (navDrawerData != null) ? navDrawerData.reclaimableSpace : 0; + } + @Override public int getFeedCounter(long feedId) { return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0; @@ -667,7 +661,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity }; private void loadData() { - subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData()) + subscription = Observable.fromCallable(DBReader::getNavDrawerData) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { @@ -690,12 +684,12 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity } public void onEvent(SubscriptionFragment.SubscriptionEvent event) { - loadFeedFragment(event.feed); + loadFeedFragmentById(event.feed.getId(), null); } public void onEventMainThread(ProgressEvent event) { Log.d(TAG, "onEvent(" + event + ")"); - switch (event.action) { + switch(event.action) { case START: pd = new ProgressDialog(this); pd.setMessage(event.message); @@ -704,7 +698,7 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity pd.show(); break; case END: - if (pd != null) { + if(pd != null) { pd.dismiss(); } break; @@ -725,15 +719,19 @@ public class MainActivity extends AppCompatActivity implements NavDrawerActivity private void handleNavIntent() { Log.d(TAG, "handleNavIntent()"); Intent intent = getIntent(); - if (intent.hasExtra(EXTRA_NAV_TYPE) && - intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)) { + if (intent.hasExtra(EXTRA_FEED_ID) || + (intent.hasExtra(EXTRA_NAV_TYPE) && + (intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG)))) { int index = intent.getIntExtra(EXTRA_NAV_INDEX, -1); String tag = intent.getStringExtra(EXTRA_FRAGMENT_TAG); Bundle args = intent.getBundleExtra(EXTRA_FRAGMENT_ARGS); + long feedId = intent.getLongExtra(EXTRA_FEED_ID, 0); if (index >= 0) { loadFragment(index, args); } else if (tag != null) { loadFragment(tag, args); + } else if(feedId > 0) { + loadFeedFragmentById(feedId, args); } } setIntent(new Intent(MainActivity.this, MainActivity.class)); // to avoid handling the intent twice when the configuration changes diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index bdc210651..4911f61bc 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -31,6 +31,8 @@ import com.bumptech.glide.Glide; import com.joanzapata.iconify.IconDrawable; import com.joanzapata.iconify.fonts.FontAwesomeIcons; +import java.util.Locale; + import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; @@ -171,12 +173,21 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O super.setScreenOn(enable); MediaplayerActivity.this.setScreenOn(enable); } + + @Override + public void onSetSpeedAbilityChanged() { + MediaplayerActivity.this.onSetSpeedAbilityChanged(); + } }; + } + protected void onSetSpeedAbilityChanged() { + Log.d(TAG, "onSetSpeedAbilityChanged()"); + updatePlaybackSpeedButton(); } protected void onPlaybackSpeedChange() { - updateButPlaybackSpeed(); + updatePlaybackSpeedButtonText(); } protected void onServiceQueried() { @@ -206,8 +217,10 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O @Override protected void onPause() { super.onPause(); - controller.reinitServiceIfPaused(); - controller.pause(); + if(controller != null) { + controller.reinitServiceIfPaused(); + controller.pause(); + } } /** @@ -229,8 +242,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O protected void onBufferUpdate(float progress) { if (sbPosition != null) { - sbPosition.setSecondaryProgress((int) progress - * sbPosition.getMax()); + sbPosition.setSecondaryProgress((int) progress * sbPosition.getMax()); } } @@ -254,6 +266,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O Log.d(TAG, "onStop()"); if (controller != null) { controller.release(); + controller = null; // prevent leak } } @@ -383,18 +396,11 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O .getSleepTimerTimeLeft())); stDialog.positiveText(R.string.disable_sleeptimer_label); stDialog.negativeText(R.string.cancel_label); - stDialog.callback(new MaterialDialog.ButtonCallback() { - @Override - public void onPositive(MaterialDialog dialog) { - dialog.dismiss(); - controller.disableSleepTimer(); - } - - @Override - public void onNegative(MaterialDialog dialog) { - dialog.dismiss(); - } + stDialog.onPositive((dialog, which) -> { + dialog.dismiss(); + controller.disableSleepTimer(); }); + stDialog.onNegative((dialog, which) -> dialog.dismiss()); stDialog.build().show(); } break; @@ -412,7 +418,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O case R.id.audio_controls: MaterialDialog dialog = new MaterialDialog.Builder(this) .title(R.string.audio_controls) - .customView(R.layout.audio_controls, false) + .customView(R.layout.audio_controls, true) .neutralText(R.string.close_label) .onNeutral((dialog1, which) -> { final SeekBar left = (SeekBar) dialog1.findViewById(R.id.volume_left); @@ -454,14 +460,13 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O if(controller != null && controller.canSetPlaybackSpeed()) { float playbackSpeed = (progress + 10) / 20.0f; controller.setPlaybackSpeed(playbackSpeed); - String speed = String.format("%.2f", playbackSpeed); - UserPreferences.setPlaybackSpeed(speed); - txtvPlaybackSpeed.setText(speed + "x"); + String speedPref = String.format(Locale.US, "%.2f", playbackSpeed); + UserPreferences.setPlaybackSpeed(speedPref); + String speedStr = String.format("%.2fx", playbackSpeed); + txtvPlaybackSpeed.setText(speedStr); } else if(fromUser) { float speed = Float.valueOf(UserPreferences.getPlaybackSpeed()); - barPlaybackSpeed.post(() -> { - barPlaybackSpeed.setProgress((int) (20 * speed) - 10); - }); + barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress((int) (20 * speed) - 10)); } } @@ -479,9 +484,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O barPlaybackSpeed.setProgress((int) (20 * currentSpeed) - 10); final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left); - barLeftVolume.setProgress(100); + barLeftVolume.setProgress(UserPreferences.getLeftVolumePercentage()); final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right); - barRightVolume.setProgress(100); + barRightVolume.setProgress(UserPreferences.getRightVolumePercentage()); final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono); stereoToMono.setChecked(UserPreferences.stereoToMono()); if (controller != null && !controller.canDownmix()) { @@ -493,14 +498,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O barLeftVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - float leftVolume = 1.0f, rightVolume = 1.0f; - if (progress < 100) { - leftVolume = progress / 100.0f; - } - if (barRightVolume.getProgress() < 100) { - rightVolume = barRightVolume.getProgress() / 100.0f; - } - controller.setVolume(leftVolume, rightVolume); + controller.setVolume( + Converter.getVolumeFromPercentage(progress), + Converter.getVolumeFromPercentage(barRightVolume.getProgress())); } @Override @@ -514,14 +514,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O barRightVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - float leftVolume = 1.0f, rightVolume = 1.0f; - if (progress < 100) { - rightVolume = progress / 100.0f; - } - if (barLeftVolume.getProgress() < 100) { - leftVolume = barLeftVolume.getProgress() / 100.0f; - } - controller.setVolume(leftVolume, rightVolume); + controller.setVolume( + Converter.getVolumeFromPercentage(barLeftVolume.getProgress()), + Converter.getVolumeFromPercentage(progress)); } @Override @@ -583,7 +578,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O super.onResume(); Log.d(TAG, "onResume()"); StorageUtils.checkStorageAvailability(this); - controller.init(); + if(controller != null) { + controller.init(); + } } /** @@ -597,32 +594,31 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O protected abstract void clearStatusMsg(); protected void onPositionObserverUpdate() { - if (controller != null) { - int currentPosition = controller.getPosition(); - int duration = controller.getDuration(); - Log.d(TAG, "currentPosition " + Converter - .getDurationStringLong(currentPosition)); - if (currentPosition != PlaybackService.INVALID_TIME - && duration != PlaybackService.INVALID_TIME - && controller.getMedia() != null) { - txtvPosition.setText(Converter - .getDurationStringLong(currentPosition)); - if (showTimeLeft) { - txtvLength.setText("-" + Converter - .getDurationStringLong(duration - currentPosition)); - } else { - txtvLength.setText(Converter - .getDurationStringLong(duration)); - } - updateProgressbarPosition(currentPosition, duration); - } else { - Log.w(TAG, "Could not react to position observer update because of invalid time"); - } + if (controller == null || txtvPosition == null || txtvLength == null) { + return; + } + int currentPosition = controller.getPosition(); + int duration = controller.getDuration(); + Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition)); + if (currentPosition == PlaybackService.INVALID_TIME || + duration == PlaybackService.INVALID_TIME) { + Log.w(TAG, "Could not react to position observer update because of invalid time"); + return; + } + txtvPosition.setText(Converter.getDurationStringLong(currentPosition)); + if (showTimeLeft) { + txtvLength.setText("-" + Converter.getDurationStringLong(duration - currentPosition)); + } else { + txtvLength.setText(Converter.getDurationStringLong(duration)); } + updateProgressbarPosition(currentPosition, duration); } private void updateProgressbarPosition(int position, int duration) { Log.d(TAG, "updateProgressbarPosition(" + position + ", " + duration + ")"); + if(sbPosition == null) { + return; + } float progress = ((float) position) / duration; sbPosition.setProgress((int) (progress * sbPosition.getMax())); } @@ -639,37 +635,52 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); showTimeLeft = prefs.getBoolean(PREF_SHOW_TIME_LEFT, false); if (media != null) { - txtvPosition.setText(Converter.getDurationStringLong((media.getPosition()))); - - if (media.getDuration() != 0) { - txtvLength.setText(Converter.getDurationStringLong(media.getDuration())); - float progress = ((float) media.getPosition()) / media.getDuration(); - sbPosition.setProgress((int) (progress * sbPosition.getMax())); - if (showTimeLeft) { - int timeLeft = media.getDuration() - media.getPosition(); - txtvLength.setText("-" + Converter.getDurationStringLong(timeLeft)); - } - } + onPositionObserverUpdate(); checkFavorite(); - if(butPlaybackSpeed != null) { - if (controller == null) { - butPlaybackSpeed.setVisibility(View.GONE); - } else { - butPlaybackSpeed.setVisibility(View.VISIBLE); - if (controller.canSetPlaybackSpeed()) { - ViewCompat.setAlpha(butPlaybackSpeed, 1.0f); - } else { - ViewCompat.setAlpha(butPlaybackSpeed, 0.5f); - } - } - updateButPlaybackSpeed(); - } + updatePlaybackSpeedButton(); return true; } else { return false; } } + private void updatePlaybackSpeedButton() { + if(butPlaybackSpeed == null) { + return; + } + if (controller == null) { + butPlaybackSpeed.setVisibility(View.GONE); + return; + } + updatePlaybackSpeedButtonText(); + ViewCompat.setAlpha(butPlaybackSpeed, controller.canSetPlaybackSpeed() ? 1.0f : 0.5f); + butPlaybackSpeed.setVisibility(View.VISIBLE); + } + + private void updatePlaybackSpeedButtonText() { + if(butPlaybackSpeed == null) { + return; + } + if (controller == null) { + butPlaybackSpeed.setVisibility(View.GONE); + return; + } + float speed = 1.0f; + if(controller.canSetPlaybackSpeed()) { + try { + // we can only retrieve the playback speed from the controller/playback service + // once mediaplayer has been initialized + speed = Float.parseFloat(UserPreferences.getPlaybackSpeed()); + } catch (NumberFormatException e) { + Log.e(TAG, Log.getStackTraceString(e)); + UserPreferences.setPlaybackSpeed(String.valueOf(speed)); + } + } + String speedStr = String.format("%.2fx", speed); + butPlaybackSpeed.setText(speedStr); + } + + protected void setupGUI() { setContentView(getContentViewResourceId()); sbPosition = (SeekBar) findViewById(R.id.sbPosition); @@ -762,10 +773,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O } if (butRev != null) { - butRev.setOnClickListener(v -> { - int curr = controller.getPosition(); - controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000); - }); + butRev.setOnClickListener(v -> onRewind()); butRev.setOnLongClickListener(new View.OnLongClickListener() { int choice; @@ -792,7 +800,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O builder.setNegativeButton(R.string.cancel_label, null); builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { UserPreferences.setPrefRewindSecs(choice); - txtvRev.setText(String.valueOf(choice)); + if(txtvRev != null){ + txtvRev.setText(String.valueOf(choice)); + } }); builder.create().show(); return true; @@ -800,13 +810,10 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O }); } - butPlay.setOnClickListener(controller.newOnPlayButtonClickListener()); + butPlay.setOnClickListener(v -> onPlayPause()); if (butFF != null) { - butFF.setOnClickListener(v -> { - int curr = controller.getPosition(); - controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000); - }); + butFF.setOnClickListener(v -> onFastForward()); butFF.setOnLongClickListener(new View.OnLongClickListener() { int choice; @@ -833,7 +840,9 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O builder.setNegativeButton(R.string.cancel_label, null); builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { UserPreferences.setPrefFastForwardSecs(choice); - txtvFF.setText(String.valueOf(choice)); + if(txtvFF != null) { + txtvFF.setText(String.valueOf(choice)); + } }); builder.create().show(); return true; @@ -842,10 +851,31 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O } if (butSkip != null) { - butSkip.setOnClickListener(v -> { - sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); - }); + butSkip.setOnClickListener(v -> sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE))); + } + } + + protected void onRewind() { + if (controller == null) { + return; + } + int curr = controller.getPosition(); + controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000); + } + + protected void onPlayPause() { + if(controller == null) { + return; + } + controller.playPause(); + } + + protected void onFastForward() { + if (controller == null) { + return; } + int curr = controller.getPosition(); + controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000); } protected abstract int getContentViewResourceId(); @@ -853,8 +883,7 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O void handleError(int errorCode) { final AlertDialog.Builder errorDialog = new AlertDialog.Builder(this); errorDialog.setTitle(R.string.error_label); - errorDialog - .setMessage(MediaPlayerError.getErrorString(this, errorCode)); + errorDialog.setMessage(MediaPlayerError.getErrorString(this, errorCode)); errorDialog.setNeutralButton("OK", (dialog, which) -> { dialog.dismiss(); @@ -868,19 +897,14 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O @Override public void onProgressChanged (SeekBar seekBar,int progress, boolean fromUser) { - if (controller != null) { - prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser, txtvPosition); - if (showTimeLeft && prog != 0) { - int duration = controller.getDuration(); - String length = "-" + Converter.getDurationStringLong(duration - (int) (prog * duration)); - txtvLength.setText(length); - } + if (controller == null || txtvLength == null) { + return; } - } - - private void updateButPlaybackSpeed() { - if (controller != null && butPlaybackSpeed != null) { - butPlaybackSpeed.setText(UserPreferences.getPlaybackSpeed() + "x"); + prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser, txtvPosition); + if (showTimeLeft && prog != 0) { + int duration = controller.getDuration(); + String length = "-" + Converter.getDurationStringLong(duration - (int) (prog * duration)); + txtvLength.setText(length); } } @@ -900,21 +924,25 @@ public abstract class MediaplayerActivity extends AppCompatActivity implements O private void checkFavorite() { Playable playable = controller.getMedia(); - if (playable != null && playable instanceof FeedMedia) { - FeedItem feedItem = ((FeedMedia) playable).getItem(); - if (feedItem != null) { - Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId())) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(item -> { - boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE); - if(isFavorite != isFav) { - isFavorite = isFav; - invalidateOptionsMenu(); - } - }); - } + if (playable != null && playable instanceof FeedMedia) { + FeedItem feedItem = ((FeedMedia) playable).getItem(); + if (feedItem != null) { + Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId())) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + item -> { + boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE); + if (isFavorite != isFav) { + isFavorite = isFav; + invalidateOptionsMenu(); + } + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + } + ); } + } } } 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 8c2b7f838..a53f9bdb8 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -7,8 +7,8 @@ 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.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; @@ -35,7 +35,6 @@ import org.jsoup.nodes.Document; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; @@ -80,7 +79,7 @@ import rx.schedulers.Schedulers; * 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 class OnlineFeedViewActivity extends ActionBarActivity { +public class OnlineFeedViewActivity extends AppCompatActivity { private static final String TAG = "OnlineFeedViewActivity"; @@ -258,7 +257,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity { private void startFeedDownload(String url, String username, String password) { Log.d(TAG, "Starting feed download"); url = URLChecker.prepareURL(url); - feed = new Feed(url, new Date(0)); + feed = new Feed(url, null); if (username != null && password != null) { feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, username, password)); } @@ -329,6 +328,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity { subscriber.onError(e); } } catch (Exception e) { + Log.e(TAG, Log.getStackTraceString(e)); subscriber.onError(e); } finally { boolean rc = new File(feed.getFile_url()).delete(); @@ -409,18 +409,25 @@ public class OnlineFeedViewActivity extends ActionBarActivity { description.setText(feed.getDescription()); subscribeButton.setOnClickListener(v -> { - try { - Feed f = new Feed(selectedDownloadUrl, new Date(0), feed.getTitle()); + if(feed != null && feedInFeedlist(feed)) { + Intent intent = new Intent(OnlineFeedViewActivity.this, MainActivity.class); + // feed.getId() is always 0, we have to retrieve the id from the feed list from + // the database + intent.putExtra(MainActivity.EXTRA_FEED_ID, getFeedId(feed)); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + } else { + Feed f = new Feed(selectedDownloadUrl, null, 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()); + try { + DownloadRequester.getInstance().downloadFeed(this, f); + } catch (DownloadRequestException e) { + Log.e(TAG, Log.getStackTraceString(e)); + DownloadRequestErrorDialogCreator.newRequestErrorDialog(this, e.getMessage()); + } + setSubscribeButtonState(feed); } - setSubscribeButtonState(feed); }); if (alternateFeedUrls.isEmpty()) { @@ -463,8 +470,8 @@ public class OnlineFeedViewActivity extends ActionBarActivity { subscribeButton.setEnabled(false); subscribeButton.setText(R.string.downloading_label); } else if (feedInFeedlist(feed)) { - subscribeButton.setEnabled(false); - subscribeButton.setText(R.string.subscribed_label); + subscribeButton.setEnabled(true); + subscribeButton.setText(R.string.open_podcast); } else { subscribeButton.setEnabled(true); subscribeButton.setText(R.string.subscribe_label); @@ -484,6 +491,18 @@ public class OnlineFeedViewActivity extends ActionBarActivity { return false; } + private long getFeedId(Feed feed) { + if (feeds == null || feed == null) { + return 0; + } + for (Feed f : feeds) { + if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) { + return f.getId(); + } + } + return 0; + } + private void showErrorDialog(String errorMsg) { assert(Looper.myLooper() == Looper.getMainLooper()); // run on UI thread if (!isFinishing() && !isPaused) { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java index 8a9ec58d3..bc1a40b11 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlFeedChooserActivity.java @@ -2,28 +2,27 @@ package de.danoeh.antennapod.activity; import android.content.Intent; import android.os.Bundle; -import android.support.v4.view.MenuItemCompat; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.util.SparseBooleanArray; import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.opml.OpmlElement; -import de.danoeh.antennapod.core.preferences.UserPreferences; import java.util.ArrayList; import java.util.List; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.opml.OpmlElement; +import de.danoeh.antennapod.core.preferences.UserPreferences; + /** * Displays the feeds that the OPML-Importer has read and lets the user choose * which feeds he wants to import. */ -public class OpmlFeedChooserActivity extends ActionBarActivity { +public class OpmlFeedChooserActivity extends AppCompatActivity { private static final String TAG = "OpmlFeedChooserActivity"; public static final String EXTRA_SELECTED_ITEMS = "de.danoeh.antennapod.selectedItems"; @@ -33,6 +32,9 @@ public class OpmlFeedChooserActivity extends ActionBarActivity { private ListView feedlist; private ArrayAdapter listAdapter; + private MenuItem selectAll; + private MenuItem deselectAll; + @Override protected void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getTheme()); @@ -44,45 +46,54 @@ public class OpmlFeedChooserActivity extends ActionBarActivity { feedlist = (ListView) findViewById(R.id.feedlist); feedlist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - listAdapter = new ArrayAdapter(this, + listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_multiple_choice, getTitleList()); feedlist.setAdapter(listAdapter); - - butCancel.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - setResult(RESULT_CANCELED); - finish(); + feedlist.setOnItemClickListener((parent, view, position, id) -> { + SparseBooleanArray checked = feedlist.getCheckedItemPositions(); + int checkedCount = 0; + for (int i = 0; i < checked.size(); i++) { + if (checked.valueAt(i)) { + checkedCount++; + } + } + if(checkedCount == listAdapter.getCount()) { + selectAll.setVisible(false); + deselectAll.setVisible(true); + } else { + deselectAll.setVisible(false); + selectAll.setVisible(true); } }); - butConfirm.setOnClickListener(new OnClickListener() { + butCancel.setOnClickListener(v -> { + setResult(RESULT_CANCELED); + finish(); + }); - @Override - public void onClick(View v) { - Intent intent = new Intent(); - SparseBooleanArray checked = feedlist.getCheckedItemPositions(); + butConfirm.setOnClickListener(v -> { + Intent intent = new Intent(); + SparseBooleanArray checked = feedlist.getCheckedItemPositions(); - int checkedCount = 0; - // Get number of checked items - for (int i = 0; i < checked.size(); i++) { - if (checked.valueAt(i)) { - checkedCount++; - } + int checkedCount = 0; + // Get number of checked items + for (int i = 0; i < checked.size(); i++) { + if (checked.valueAt(i)) { + checkedCount++; } - int[] selection = new int[checkedCount]; - for (int i = 0, collected = 0; collected < checkedCount; i++) { - if (checked.valueAt(i)) { - selection[collected] = checked.keyAt(i); - collected++; - } + } + int[] selection = new int[checkedCount]; + for (int i = 0, collected = 0; collected < checkedCount; i++) { + if (checked.valueAt(i)) { + selection[collected] = checked.keyAt(i); + collected++; } - intent.putExtra(EXTRA_SELECTED_ITEMS, selection); - setResult(RESULT_OK, intent); - finish(); } + intent.putExtra(EXTRA_SELECTED_ITEMS, selection); + setResult(RESULT_OK, intent); + finish(); }); } @@ -93,7 +104,6 @@ public class OpmlFeedChooserActivity extends ActionBarActivity { for (OpmlElement element : OpmlImportHolder.getReadElements()) { result.add(element.getText()); } - } return result; } @@ -101,13 +111,11 @@ public class OpmlFeedChooserActivity extends ActionBarActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); - MenuItemCompat.setShowAsAction(menu.add(Menu.NONE, R.id.select_all_item, Menu.NONE, - R.string.select_all_label), - MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); - - MenuItemCompat.setShowAsAction(menu.add(Menu.NONE, R.id.deselect_all_item, Menu.NONE, - R.string.deselect_all_label), - MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.opml_selection_options, menu); + selectAll = menu.findItem(R.id.select_all_item); + deselectAll = menu.findItem(R.id.deselect_all_item); + deselectAll.setVisible(false); return true; } @@ -115,10 +123,14 @@ public class OpmlFeedChooserActivity extends ActionBarActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.select_all_item: + selectAll.setVisible(false); selectAllItems(true); + deselectAll.setVisible(true); return true; case R.id.deselect_all_item: + deselectAll.setVisible(false); selectAllItems(false); + selectAll.setVisible(true); return true; default: return false; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java index d974e0e1b..8726af281 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportBaseActivity.java @@ -1,40 +1,53 @@ package de.danoeh.antennapod.activity; import android.content.Intent; -import android.support.v7.app.ActionBarActivity; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Environment; +import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.support.v7.app.AppCompatActivity; import android.util.Log; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.asynctask.OpmlFeedQueuer; -import de.danoeh.antennapod.asynctask.OpmlImportWorker; -import de.danoeh.antennapod.core.opml.OpmlElement; +import com.afollestad.materialdialogs.MaterialDialog; + +import org.apache.commons.lang3.ArrayUtils; + +import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.asynctask.OpmlFeedQueuer; +import de.danoeh.antennapod.asynctask.OpmlImportWorker; +import de.danoeh.antennapod.core.opml.OpmlElement; +import de.danoeh.antennapod.core.util.LangUtils; + /** * Base activity for Opml Import - e.g. with code what to do afterwards * */ -public class OpmlImportBaseActivity extends ActionBarActivity { +public class OpmlImportBaseActivity extends AppCompatActivity { private static final String TAG = "OpmlImportBaseActivity"; private OpmlImportWorker importWorker; - /** + private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 5; + @Nullable private Uri uri; + + /** * Handles the choices made by the user in the OpmlFeedChooserActivity and * starts the OpmlFeedQueuer if necessary. */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Received result"); + Log.d(TAG, "Received result"); if (resultCode == RESULT_CANCELED) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Activity was cancelled"); - if (finishWhenCanceled()) - finish(); + Log.d(TAG, "Activity was cancelled"); + if (finishWhenCanceled()) { + finish(); + } } else { - int[] selected = data - .getIntArrayExtra(OpmlFeedChooserActivity.EXTRA_SELECTED_ITEMS); + int[] selected = data.getIntArrayExtra(OpmlFeedChooserActivity.EXTRA_SELECTED_ITEMS); if (selected != null && selected.length > 0) { OpmlFeedQueuer queuer = new OpmlFeedQueuer(this, selected) { @@ -50,35 +63,83 @@ public class OpmlImportBaseActivity extends ActionBarActivity { }; queuer.executeAsync(); } else { - if (BuildConfig.DEBUG) - Log.d(TAG, "No items were selected"); + Log.d(TAG, "No items were selected"); } } } - /** Starts the import process. */ - protected void startImport(Reader reader) { + protected void importUri(@Nullable Uri uri) { + if(uri == null) { + new MaterialDialog.Builder(this) + .content(R.string.opml_import_error_no_file) + .positiveText(android.R.string.ok) + .show(); + return; + } + this.uri = uri; + if(uri.toString().contains(Environment.getExternalStorageDirectory().toString())) { + int permission = ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE); + if (permission != PackageManager.PERMISSION_GRANTED) { + requestPermission(); + return; + } + } + startImport(); + } + + private void requestPermission() { + String[] permissions = { android.Manifest.permission.READ_EXTERNAL_STORAGE }; + ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_READ_EXTERNAL_STORAGE); + } + + @Override + public void onRequestPermissionsResult(int requestCode, + String[] permissions, + int[] grantResults) { + if (requestCode != PERMISSION_REQUEST_READ_EXTERNAL_STORAGE) { + return; + } + if (grantResults.length > 0 && ArrayUtils.contains(grantResults, PackageManager.PERMISSION_GRANTED)) { + startImport(); + } else { + new MaterialDialog.Builder(this) + .content(R.string.opml_import_ask_read_permission) + .positiveText(android.R.string.ok) + .negativeText(R.string.cancel_label) + .onPositive((dialog, which) -> requestPermission()) + .onNegative((dialog, which) -> finish()) + .show(); + } + } - if (reader != null) { - importWorker = new OpmlImportWorker(this, reader) { + /** Starts the import process. */ + protected void startImport() { + try { + Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8); + importWorker = new OpmlImportWorker(this, mReader) { @Override protected void onPostExecute(ArrayList result) { super.onPostExecute(result); if (result != null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Parsing was successful"); + Log.d(TAG, "Parsing was successful"); OpmlImportHolder.setReadElements(result); startActivityForResult(new Intent( OpmlImportBaseActivity.this, OpmlFeedChooserActivity.class), 0); } else { - if (BuildConfig.DEBUG) - Log.d(TAG, "Parser error occurred"); + Log.d(TAG, "Parser error occurred"); } } }; importWorker.executeAsync(); + } catch (Exception e) { + Log.d(TAG, Log.getStackTraceString(e)); + String message = getString(R.string.opml_reader_error); + new MaterialDialog.Builder(this) + .content(message + " " + e.getMessage()) + .positiveText(android.R.string.ok) + .show(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java index 46e5f0e8e..ab4b0d0ee 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromIntentActivity.java @@ -2,25 +2,14 @@ package de.danoeh.antennapod.activity; import android.net.Uri; import android.os.Bundle; -import android.support.v7.app.AlertDialog; -import android.util.Log; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.util.LangUtils; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; /** Lets the user start the OPML-import process. */ public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity { private static final String TAG = "OpmlImportFromIntentAct"; - @Override protected void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getTheme()); @@ -28,15 +17,8 @@ public class OpmlImportFromIntentActivity extends OpmlImportBaseActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); - try { - Uri uri = getIntent().getData(); - - Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8); - startImport(mReader); - } catch (Exception e) { - new AlertDialog.Builder(this).setMessage("Cannot open XML - Reason: " + e.getMessage()).show(); - } - + Uri uri = getIntent().getData(); + importUri(uri); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java index 6e3991739..b781e5141 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java @@ -11,16 +11,9 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStreamReader; -import java.io.Reader; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.IntentUtils; -import de.danoeh.antennapod.core.util.LangUtils; import de.danoeh.antennapod.core.util.StorageUtils; /** @@ -60,7 +53,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity { intentPickAction = new Intent(Intent.ACTION_PICK); intentPickAction.setData(Uri.parse("file://")); - if(false == IntentUtils.isCallable(getApplicationContext(), intentPickAction)) { + if(!IntentUtils.isCallable(getApplicationContext(), intentPickAction)) { intentPickAction.setData(null); if(false == IntentUtils.isCallable(getApplicationContext(), intentPickAction)) { txtvHeaderExplanation1.setVisibility(View.GONE); @@ -77,7 +70,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity { intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT); intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE); intentGetContentAction.setType("*/*"); - if(false == IntentUtils.isCallable(getApplicationContext(), intentGetContentAction)) { + if(!IntentUtils.isCallable(getApplicationContext(), intentGetContentAction)) { txtvHeaderExplanation2.setVisibility(View.GONE); txtvExplanation2.setVisibility(View.GONE); findViewById(R.id.divider2).setVisibility(View.GONE); @@ -114,19 +107,6 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity { } } - private void startImport(File file) { - Reader mReader = null; - try { - mReader = new InputStreamReader(new FileInputStream(file), - LangUtils.UTF_8); - Log.d(TAG, "Parsing " + file.toString()); - startImport(mReader); - } catch (FileNotFoundException e) { - Log.d(TAG, "File not found which really should be there"); - // this should never happen as it is a file we have just chosen - } - } - /* * Creates an implicit intent to launch a file manager which lets * the user choose a specific OPML-file to import from. @@ -155,13 +135,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == CHOOSE_OPML_FILE) { Uri uri = data.getData(); - - try { - Reader mReader = new InputStreamReader(getContentResolver().openInputStream(uri), LangUtils.UTF_8); - startImport(mReader); - } catch (FileNotFoundException e) { - Log.d(TAG, "File not found"); - } + importUri(uri); } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java index 80ccb7c99..ba22a42b4 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java @@ -8,7 +8,7 @@ import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceFragment; import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; import android.view.ViewGroup; @@ -24,7 +24,7 @@ import de.danoeh.antennapod.preferences.PreferenceController; * PreferenceActivity for API 11+. In order to change the behavior of the preference UI, see * PreferenceController. */ -public class PreferenceActivity extends ActionBarActivity { +public class PreferenceActivity extends AppCompatActivity { private PreferenceController preferenceController; private MainFragment prefFragment; @@ -49,7 +49,7 @@ public class PreferenceActivity extends ActionBarActivity { protected void onCreate(Bundle savedInstanceState) { // This must be the FIRST thing we do, otherwise other code may not have the // reference it needs - instance = new WeakReference(this); + instance = new WeakReference<>(this); setTheme(UserPreferences.getTheme()); super.onCreate(savedInstanceState); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java new file mode 100644 index 000000000..0254617e4 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/activity/StatisticsActivity.java @@ -0,0 +1,107 @@ +package de.danoeh.antennapod.activity; + +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.adapter.StatisticsListAdapter; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.util.Converter; +import rx.Observable; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +/** + * Displays the 'statistics' screen + */ +public class StatisticsActivity extends AppCompatActivity + implements AdapterView.OnItemClickListener { + + private static final String TAG = StatisticsActivity.class.getSimpleName(); + + private Subscription subscription; + private TextView totalTimeTextView; + private ListView feedStatisticsList; + private ProgressBar progressBar; + private StatisticsListAdapter listAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + setTheme(UserPreferences.getTheme()); + super.onCreate(savedInstanceState); + getSupportActionBar().setDisplayShowHomeEnabled(true); + setContentView(R.layout.statistics_activity); + + totalTimeTextView = (TextView) findViewById(R.id.total_time); + feedStatisticsList = (ListView) findViewById(R.id.statistics_list); + progressBar = (ProgressBar) findViewById(R.id.progressBar); + listAdapter = new StatisticsListAdapter(this); + feedStatisticsList.setAdapter(listAdapter); + feedStatisticsList.setOnItemClickListener(this); + } + + @Override + public void onResume() { + super.onResume(); + progressBar.setVisibility(View.VISIBLE); + totalTimeTextView.setVisibility(View.GONE); + feedStatisticsList.setVisibility(View.GONE); + loadStats(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } else { + return super.onOptionsItemSelected(item); + } + } + + private void loadStats() { + if(subscription != null) { + subscription.unsubscribe(); + } + subscription = Observable.fromCallable(() -> DBReader.getStatistics()) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> { + if (result != null) { + totalTimeTextView.setText(Converter + .shortLocalizedDuration(this, result.totalTime)); + listAdapter.update(result.feedTime); + progressBar.setVisibility(View.GONE); + totalTimeTextView.setVisibility(View.VISIBLE); + feedStatisticsList.setVisibility(View.VISIBLE); + } + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + }); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + DBReader.StatisticsItem stats = listAdapter.getItem(position); + + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle(stats.feed.getTitle()); + dialog.setMessage(getString(R.string.statistics_details_dialog, + stats.episodesStarted, + stats.episodes, + Converter.shortLocalizedDuration(this, stats.timePlayed), + Converter.shortLocalizedDuration(this, stats.time))); + dialog.setPositiveButton(android.R.string.ok, null); + dialog.show(); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java index b02e82f0b..e980764ec 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java @@ -1,30 +1,109 @@ package de.danoeh.antennapod.activity; +import android.Manifest; +import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.text.Html; import android.text.TextUtils; import android.util.Log; +import android.widget.Button; + +import com.afollestad.materialdialogs.MaterialDialog; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; -import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.StorageUtils; /** Is show if there is now external storage available. */ -public class StorageErrorActivity extends ActionBarActivity { +public class StorageErrorActivity extends AppCompatActivity { + private static final String TAG = "StorageErrorActivity"; + private static final String[] EXTERNAL_STORAGE_PERMISSIONS = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE }; + private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 42; + @Override protected void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getTheme()); super.onCreate(savedInstanceState); setContentView(R.layout.storage_error); - } + + Button btnChooseDataFolder = (Button) findViewById(R.id.btnChooseDataFolder); + btnChooseDataFolder.setOnClickListener(v -> { + if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT && + Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { + showChooseDataFolderDialog(); + } else { + openDirectoryChooser(); + } + }); + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { + int readPermission = ActivityCompat.checkSelfPermission(this, + Manifest.permission.READ_EXTERNAL_STORAGE); + int writePermission = ActivityCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (readPermission != PackageManager.PERMISSION_GRANTED || + writePermission != PackageManager.PERMISSION_GRANTED) { + requestPermission(); + } + } + } + + private void requestPermission() { + ActivityCompat.requestPermissions(this, EXTERNAL_STORAGE_PERMISSIONS, + PERMISSION_REQUEST_EXTERNAL_STORAGE); + } + + private void openDirectoryChooser() { + Intent intent = new Intent(this, DirectoryChooserActivity.class); + startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); + } + + @Override + public void onRequestPermissionsResult(int requestCode, + String[] permissions, + int[] grantResults) { + if (requestCode != PERMISSION_REQUEST_EXTERNAL_STORAGE || grantResults.length != 2) { + return; + } + if (grantResults[0] != PackageManager.PERMISSION_GRANTED || + grantResults[1] != PackageManager.PERMISSION_GRANTED) { + new MaterialDialog.Builder(this) + .content(R.string.choose_data_directory_permission_rationale) + .positiveText(android.R.string.ok) + .onPositive((dialog, which) -> requestPermission()) + .onNegative((dialog, which) -> finish()) + .show(); + } + } + + @Override + protected void onResume() { + super.onResume(); + if (StorageUtils.storageAvailable()) { + leaveErrorState(); + } else { + registerReceiver(mediaUpdate, new IntentFilter(Intent.ACTION_MEDIA_MOUNTED)); + } + } @Override protected void onPause() { @@ -32,18 +111,102 @@ public class StorageErrorActivity extends ActionBarActivity { try { unregisterReceiver(mediaUpdate); } catch (IllegalArgumentException e) { - + Log.e(TAG, Log.getStackTraceString(e)); } } - @Override - protected void onResume() { - super.onResume(); - if (StorageUtils.storageAvailable()) { - leaveErrorState(); - } else { - registerReceiver(mediaUpdate, new IntentFilter( - Intent.ACTION_MEDIA_MOUNTED)); + // see PreferenceController.showChooseDataFolderDialog() + private void showChooseDataFolderDialog() { + File dataFolder = UserPreferences.getDataFolder(null); + if(dataFolder == null) { + new MaterialDialog.Builder(this) + .title(R.string.error_label) + .content(R.string.external_storage_error_msg) + .neutralText(android.R.string.ok) + .show(); + return; + } + String dataFolderPath = dataFolder.getAbsolutePath(); + int selectedIndex = -1; + File[] mediaDirs = ContextCompat.getExternalFilesDirs(this, null); + List folders = new ArrayList<>(mediaDirs.length); + List choices = new ArrayList<>(mediaDirs.length); + for(int i=0; i < mediaDirs.length; i++) { + if(mediaDirs[i] == null) { + continue; + } + String path = mediaDirs[i].getAbsolutePath(); + folders.add(path); + if(dataFolderPath.equals(path)) { + selectedIndex = i; + } + int index = path.indexOf("Android"); + String choice; + if(index >= 0) { + choice = path.substring(0, index); + } else { + choice = path; + } + long bytes = StorageUtils.getFreeSpaceAvailable(path); + String freeSpace = String.format(getString(R.string.free_space_label), + Converter.byteToString(bytes)); + choices.add(Html.fromHtml("" + choice + " [" + freeSpace + "]" + + "")); + } + if(choices.size() == 0) { + new MaterialDialog.Builder(this) + .title(R.string.error_label) + .content(R.string.external_storage_error_msg) + .neutralText(android.R.string.ok) + .show(); + return; + } + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.choose_data_directory) + .content(R.string.choose_data_directory_message) + .items(choices.toArray(new CharSequence[choices.size()])) + .itemsCallbackSingleChoice(selectedIndex, (dialog1, itemView, which, text) -> { + String folder = folders.get(which); + UserPreferences.setDataFolder(folder); + leaveErrorState(); + return true; + }) + .negativeText(R.string.cancel_label) + .cancelable(true) + .build(); + dialog.show(); + } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == Activity.RESULT_OK && + requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { + String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); + + File path; + if (dir != null) { + path = new File(dir); + } else { + path = getExternalFilesDir(null); + } + String message = null; + if(!path.exists()) { + message = String.format(getString(R.string.folder_does_not_exist_error), dir); + } else if(!path.canRead()) { + message = String.format(getString(R.string.folder_not_readable_error), dir); + } else if(!path.canWrite()) { + message = String.format(getString(R.string.folder_not_writable_error), dir); + } + + if(message == null) { + Log.d(TAG, "Setting data folder: " + dir); + UserPreferences.setDataFolder(dir); + leaveErrorState(); + } else { + AlertDialog.Builder ab = new AlertDialog.Builder(this); + ab.setMessage(message); + ab.setPositiveButton(android.R.string.ok, null); + ab.show(); + } } } @@ -58,13 +221,10 @@ public class StorageErrorActivity extends ActionBarActivity { public void onReceive(Context context, Intent intent) { if (TextUtils.equals(intent.getAction(), Intent.ACTION_MEDIA_MOUNTED)) { if (intent.getBooleanExtra("read-only", true)) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Media was mounted; Finishing activity"); + Log.d(TAG, "Media was mounted; Finishing activity"); leaveErrorState(); } else { - if (BuildConfig.DEBUG) - Log.d(TAG, - "Media seemed to have been mounted read only"); + Log.d(TAG, "Media seemed to have been mounted read only"); } } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index ee459dbc6..42c9edd99 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -202,6 +202,24 @@ public class VideoplayerActivity extends MediaplayerActivity { videoControlsShowing = !videoControlsShowing; } + @Override + protected void onRewind() { + super.onRewind(); + setupVideoControlsToggler(); + } + + @Override + protected void onPlayPause() { + super.onPlayPause(); + setupVideoControlsToggler(); + } + + @Override + protected void onFastForward() { + super.onFastForward(); + setupVideoControlsToggler(); + } + private final SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback() { @Override @@ -312,7 +330,7 @@ public class VideoplayerActivity extends MediaplayerActivity { private static class VideoControlsHider extends Handler { - private static final int DELAY = 5000; + private static final int DELAY = 2500; private WeakReference activity; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java index 28c2b7206..e5418c924 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java @@ -5,7 +5,6 @@ import android.content.Intent; import android.content.res.Configuration; import android.os.AsyncTask; import android.os.Bundle; -import android.support.v4.app.NavUtils; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.LayoutInflater; @@ -42,7 +41,7 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService; * Step 3: Choose from a list of actions */ public class GpodnetAuthenticationActivity extends ActionBarActivity { - private static final String TAG = "GpodnetAuthenticationActivity"; + private static final String TAG = "GpodnetAuthActivity"; private static final String CURRENT_STEP = "current_step"; @@ -177,7 +176,7 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity { // load device list - final AtomicReference> devices = new AtomicReference>(); + final AtomicReference> devices = new AtomicReference<>(); new AsyncTask>() { private volatile Exception exception; @@ -194,11 +193,11 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity { protected void onPostExecute(List gpodnetDevices) { super.onPostExecute(gpodnetDevices); if (gpodnetDevices != null) { - List deviceNames = new ArrayList(); + List deviceNames = new ArrayList<>(); for (GpodnetDevice device : gpodnetDevices) { deviceNames.add(device.getCaption()); } - spinnerDevices.setAdapter(new ArrayAdapter(GpodnetAuthenticationActivity.this, + spinnerDevices.setAdapter(new ArrayAdapter<>(GpodnetAuthenticationActivity.this, android.R.layout.simple_spinner_dropdown_item, deviceNames)); spinnerDevices.setEnabled(true); if (!deviceNames.isEmpty()) { @@ -274,14 +273,11 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity { }); deviceID.setText(generateDeviceID()); - chooseDevice.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final int position = spinnerDevices.getSelectedItemPosition(); - if (position != AdapterView.INVALID_POSITION) { - selectedDevice = devices.get().get(position); - advance(); - } + chooseDevice.setOnClickListener(v -> { + final int position = spinnerDevices.getSelectedItemPosition(); + if (position != AdapterView.INVALID_POSITION) { + selectedDevice = devices.get().get(position); + advance(); } }); } @@ -325,20 +321,14 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity { final Button sync = (Button) view.findViewById(R.id.butSyncNow); final Button back = (Button) view.findViewById(R.id.butGoMainscreen); - sync.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - GpodnetSyncService.sendSyncIntent(GpodnetAuthenticationActivity.this); - finish(); - } + sync.setOnClickListener(v -> { + GpodnetSyncService.sendSyncIntent(GpodnetAuthenticationActivity.this); + finish(); }); - back.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - } + back.setOnClickListener(v -> { + Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); }); } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java index a75789815..66e6f9a00 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonCallback.java @@ -4,5 +4,5 @@ import de.danoeh.antennapod.core.feed.FeedItem; public interface ActionButtonCallback { /** Is called when the action button of a list item has been pressed. */ - abstract void onActionButtonPressed(FeedItem item); + void onActionButtonPressed(FeedItem item); } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java index 1ea7daaa3..8aaf0055a 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java @@ -47,9 +47,10 @@ public class AdapterUtils { - media.getPosition())); } } else if (!media.isDownloaded()) { + Log.d(TAG, "size: " + media.getSize()); if (media.getSize() > 0) { txtvPos.setText(Converter.byteToString(media.getSize())); - } else if(false == media.checkedOnSizeButUnknown()) { + } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) { txtvPos.setText("{fa-spinner}"); Iconify.addIcons(txtvPos); NetworkUtils.getFeedMediaSizeObservable(media) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java index d749b0313..d141e0239 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.adapter; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.Log; @@ -70,11 +71,11 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter 0) { holder.txtvDuration.setText(Converter.byteToString(media.getSize())); - } else if(false == media.checkedOnSizeButUnknown()) { + } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) { holder.txtvDuration.setText("{fa-spinner}"); Iconify.addIcons(holder.txtvDuration); NetworkUtils.getFeedMediaSizeObservable(media) @@ -201,7 +202,8 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter { if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { link[0].onClick(widget); - } else if (action == MotionEvent.ACTION_DOWN) { + } else if (action == MotionEvent.ACTION_DOWN){ Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); @@ -132,13 +133,13 @@ public class ChaptersListAdapter extends ArrayAdapter { if (current == sc) { int playingBackGroundColor; if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { - playingBackGroundColor = getContext().getResources().getColor(R.color.highlight_dark); + playingBackGroundColor = ContextCompat.getColor(getContext(), R.color.highlight_dark); } else { - playingBackGroundColor = getContext().getResources().getColor(R.color.highlight_light); + playingBackGroundColor = ContextCompat.getColor(getContext(), R.color.highlight_light); } holder.view.setBackgroundColor(playingBackGroundColor); } else { - holder.view.setBackgroundColor(getContext().getResources().getColor(android.R.color.transparent)); + holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent)); holder.title.setTextColor(defaultTextColor); holder.start.setTextColor(defaultTextColor); } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java index 469a807e1..00ab96f6c 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java @@ -1,9 +1,7 @@ package de.danoeh.antennapod.adapter; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.support.v7.app.AlertDialog; import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java index 582538fb8..a017983f0 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.adapter; import android.content.Context; +import android.support.v4.content.ContextCompat; import android.text.format.DateUtils; import android.util.Log; import android.view.LayoutInflater; @@ -10,10 +11,8 @@ import android.widget.BaseAdapter; import android.widget.TextView; import android.widget.Toast; -import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconButton; - -import java.util.Date; +import com.joanzapata.iconify.widget.IconTextView; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; @@ -49,7 +48,7 @@ public class DownloadLogAdapter extends BaseAdapter { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.downloadlog_item, parent, false); - holder.icon = (TextView) convertView.findViewById(R.id.txtvIcon); + holder.icon = (IconTextView) convertView.findViewById(R.id.txtvIcon); holder.retry = (IconButton) convertView.findViewById(R.id.btnRetry); holder.date = (TextView) convertView.findViewById(R.id.txtvDate); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); @@ -76,17 +75,15 @@ public class DownloadLogAdapter extends BaseAdapter { status.getCompletionDate().getTime(), System.currentTimeMillis(), 0, 0)); if (status.isSuccessful()) { - holder.icon.setTextColor(convertView.getResources().getColor( + holder.icon.setTextColor(ContextCompat.getColor(convertView.getContext(), R.color.download_success_green)); holder.icon.setText("{fa-check-circle}"); - Iconify.addIcons(holder.icon); holder.retry.setVisibility(View.GONE); holder.reason.setVisibility(View.GONE); } else { - holder.icon.setTextColor(convertView.getResources().getColor( + holder.icon.setTextColor(ContextCompat.getColor(convertView.getContext(), R.color.download_failed_red)); holder.icon.setText("{fa-times-circle}"); - Iconify.addIcons(holder.icon); String reasonText = status.getReason().getErrorString(context); if (status.getReasonDetailed() != null) { reasonText += ": " + status.getReasonDetailed(); @@ -123,9 +120,8 @@ public class DownloadLogAdapter extends BaseAdapter { if(holder.typeId == Feed.FEEDFILETYPE_FEED) { Feed feed = DBReader.getFeed(holder.id); if (feed != null) { - feed.setLastUpdate(new Date(0)); // force refresh try { - DBTasks.refreshFeed(context, feed); + DBTasks.forceRefreshFeed(context, feed); } catch (DownloadRequestException e) { e.printStackTrace(); } @@ -162,7 +158,7 @@ public class DownloadLogAdapter extends BaseAdapter { } static class Holder { - TextView icon; + IconTextView icon; IconButton retry; TextView title; TextView type; diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java index ca747b9b0..53dedd496 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java @@ -25,13 +25,10 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter { private final Context context; private final ItemAccess itemAccess; - private final int imageSize; - public DownloadedEpisodesListAdapter(Context context, ItemAccess itemAccess) { super(); this.context = context; this.itemAccess = itemAccess; - this.imageSize = (int) context.getResources().getDimension(R.dimen.thumbnail_length_downloaded_item); } @Override @@ -52,7 +49,7 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter { @Override public View getView(int position, View convertView, ViewGroup parent) { Holder holder; - final FeedItem item = (FeedItem) getItem(position); + final FeedItem item = getItem(position); if (item == null) return null; if (convertView == null) { @@ -61,44 +58,44 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.downloaded_episodeslist_item, parent, false); + holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.txtvSize = (TextView) convertView.findViewById(R.id.txtvSize); + holder.queueStatus = (ImageView) convertView.findViewById(R.id.imgvInPlaylist); holder.pubDate = (TextView) convertView .findViewById(R.id.txtvPublished); holder.butSecondary = (ImageButton) convertView .findViewById(R.id.butSecondaryAction); - holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); - holder.txtvSize = (TextView) convertView.findViewById(R.id.txtvSize); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); } + Glide.with(context) + .load(item.getImageUri()) + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate() + .into(holder.imageView); + holder.title.setText(item.getTitle()); + holder.txtvSize.setText(Converter.byteToString(item.getMedia().getSize())); + holder.queueStatus.setVisibility(item.isTagged(FeedItem.TAG_QUEUE) ? View.VISIBLE : View.GONE); String pubDateStr = DateUtils.formatAbbrev(context, item.getPubDate()); holder.pubDate.setText(pubDateStr); - holder.txtvSize.setText(Converter.byteToString(item.getMedia().getSize())); - FeedItem.State state = item.getState(); + FeedItem.State state = item.getState(); if (state == FeedItem.State.PLAYING) { holder.butSecondary.setEnabled(false); } else { holder.butSecondary.setEnabled(true); } - holder.butSecondary.setFocusable(false); holder.butSecondary.setTag(item); holder.butSecondary.setOnClickListener(secondaryActionListener); - - Glide.with(context) - .load(item.getImageUri()) - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate() - .into(holder.imageView); - return convertView; } @@ -112,10 +109,11 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter { static class Holder { - TextView title; - TextView pubDate; ImageView imageView; + TextView title; TextView txtvSize; + ImageView queueStatus; + TextView pubDate; ImageButton butSecondary; } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java index 206d07f0f..e1efdaa7b 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.adapter; import android.content.Context; +import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -74,7 +75,7 @@ public class DownloadlistAdapter extends BaseAdapter { } if (position == selectedItemIndex) { - convertView.setBackgroundColor(convertView.getResources().getColor( + convertView.setBackgroundColor(ContextCompat.getColor(convertView.getContext(), ThemeUtils.getSelectionBackgroundColor())); } else { convertView.setBackgroundResource(0); @@ -130,11 +131,11 @@ public class DownloadlistAdapter extends BaseAdapter { } public interface ItemAccess { - public int getCount(); + int getCount(); - public Downloader getItem(int position); + Downloader getItem(int position); - public void onSecondaryActionClick(Downloader downloader); + void onSecondaryActionClick(Downloader downloader); } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java index e483738b4..0de1ca1ff 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.adapter; import android.content.Context; import android.content.res.TypedArray; +import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -59,11 +60,11 @@ public class FeedItemlistAdapter extends BaseAdapter { this.makePlayedItemsTransparent = makePlayedItemsTransparent; if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { - playingBackGroundColor = context.getResources().getColor(R.color.highlight_dark); + playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_dark); } else { - playingBackGroundColor = context.getResources().getColor(R.color.highlight_light); + playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_light); } - normalBackGroundColor = context.getResources().getColor(android.R.color.transparent); + normalBackGroundColor = ContextCompat.getColor(context, android.R.color.transparent); } @Override @@ -118,8 +119,8 @@ public class FeedItemlistAdapter extends BaseAdapter { if (!(getItemViewType(position) == Adapter.IGNORE_ITEM_VIEW_TYPE)) { convertView.setVisibility(View.VISIBLE); if (position == selectedItemIndex) { - convertView.setBackgroundColor(convertView.getResources() - .getColor(ThemeUtils.getSelectionBackgroundColor())); + convertView.setBackgroundColor(ContextCompat.getColor(convertView.getContext(), + ThemeUtils.getSelectionBackgroundColor())); } else { convertView.setBackgroundResource(0); } @@ -188,13 +189,12 @@ public class FeedItemlistAdapter extends BaseAdapter { holder.type.setImageBitmap(null); holder.type.setVisibility(View.GONE); } + typeDrawables.recycle(); if(media.isCurrentlyPlaying()) { - if(media.isCurrentlyPlaying()) { - holder.container.setBackgroundColor(playingBackGroundColor); - } else { - holder.container.setBackgroundColor(normalBackGroundColor); - } + holder.container.setBackgroundColor(playingBackGroundColor); + } else { + holder.container.setBackgroundColor(normalBackGroundColor); } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java index 9011c8b02..5b205e91f 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java @@ -6,11 +6,13 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.feed.FeedItem; import java.util.List; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.util.DateUtils; + /** * List adapter for showing a list of FeedItems with their title and description. */ @@ -33,6 +35,7 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.itemdescription_listitem, parent, false); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate); holder.description = (TextView) convertView.findViewById(R.id.txtvDescription); convertView.setTag(holder); @@ -41,15 +44,20 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter { } holder.title.setText(item.getTitle()); + holder.pubDate.setText(DateUtils.formatAbbrev(getContext(), item.getPubDate())); if (item.getDescription() != null) { - holder.description.setText(item.getDescription()); + String description = item.getDescription() + .replaceAll("\n", " ") + .replaceAll("\\s+", " ") + .trim(); + holder.description.setText(description); } - return convertView; } static class Holder { TextView title; + TextView pubDate; TextView description; } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java index b20af1773..0227aeee4 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -74,7 +74,7 @@ public class NavListAdapter extends BaseAdapter } private void loadItems() { - List newTags = new ArrayList(Arrays.asList(MainActivity.NAV_DRAWER_TAGS)); + List newTags = new ArrayList<>(Arrays.asList(MainActivity.NAV_DRAWER_TAGS)); List hiddenFragments = UserPreferences.getHiddenDrawerItems(); for(String hidden : hiddenFragments) { newTags.remove(hidden); @@ -131,7 +131,11 @@ public class NavListAdapter extends BaseAdapter @Override public int getCount() { - return getSubscriptionOffset() ;//+ itemAccess.getCount(); //Avoid feed + int baseCount = getSubscriptionOffset(); + if (UserPreferences.showSubscriptionsInDrawer()) { + baseCount += itemAccess.getCount(); + } + return baseCount; } @Override @@ -181,7 +185,7 @@ public class NavListAdapter extends BaseAdapter } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) { v = getSectionDividerView(convertView, parent); } else { - v = getFeedView(position - getSubscriptionOffset(), convertView, parent); + v = getFeedView(position, convertView, parent); } if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) { TextView txtvTitle = (TextView) v.findViewById(R.id.txtvTitle); @@ -232,17 +236,21 @@ public class NavListAdapter extends BaseAdapter } } else if(tag.equals(DownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) { int epCacheSize = UserPreferences.getEpisodeCacheSize(); - if(itemAccess.getNumberOfDownloadedItems() >= epCacheSize) { + // don't count episodes that can be reclaimed + int spaceUsed = itemAccess.getNumberOfDownloadedItems() - + itemAccess.getReclaimableItems(); + + if (epCacheSize > 0 && spaceUsed >= epCacheSize) { holder.count.setText("{md-disc-full 150%}"); Iconify.addIcons(holder.count); holder.count.setVisibility(View.VISIBLE); - holder.count.setOnClickListener(v -> { + holder.count.setOnClickListener(v -> new AlertDialog.Builder(context) .setTitle(R.string.episode_cache_full_title) .setMessage(R.string.episode_cache_full_message) .setPositiveButton(android.R.string.ok, (dialog, which) -> {}) - .show(); - }); + .show() + ); } else { holder.count.setVisibility(View.GONE); } @@ -267,10 +275,11 @@ public class NavListAdapter extends BaseAdapter return convertView; } - private View getFeedView(int feedPos, View convertView, ViewGroup parent) { - FeedHolder holder; + private View getFeedView(int position, View convertView, ViewGroup parent) { + int feedPos = position - getSubscriptionOffset(); Feed feed = itemAccess.getItem(feedPos); + FeedHolder holder; if (convertView == null) { holder = new FeedHolder(); LayoutInflater inflater = (LayoutInflater) context @@ -298,7 +307,6 @@ public class NavListAdapter extends BaseAdapter holder.title.setText(feed.getTitle()); - if(feed.hasLastUpdateFailed()) { RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) holder.title.getLayoutParams(); p.addRule(RelativeLayout.LEFT_OF, R.id.itxtvFailure); @@ -312,7 +320,11 @@ public class NavListAdapter extends BaseAdapter if(counter > 0) { holder.count.setVisibility(View.VISIBLE); holder.count.setText(String.valueOf(counter)); - holder.count.setTypeface(holder.title.getTypeface()); + if (itemAccess.getSelectedItemIndex() == position) { + holder.count.setTypeface(null, Typeface.BOLD); + } else { + holder.count.setTypeface(null, Typeface.NORMAL); + } } else { holder.count.setVisibility(View.GONE); } @@ -339,6 +351,7 @@ public class NavListAdapter extends BaseAdapter int getQueueSize(); int getNumberOfNewItems(); int getNumberOfDownloadedItems(); + int getReclaimableItems(); int getFeedCounter(long feedId); } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java index d0266be6d..981d7563a 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java @@ -3,9 +3,11 @@ package de.danoeh.antennapod.adapter; import android.graphics.drawable.Drawable; import android.net.Uri; import android.support.annotation.Nullable; +import android.support.v4.content.ContextCompat; import android.support.v4.view.MotionEventCompat; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; +import android.text.TextUtils; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -27,8 +29,6 @@ import com.bumptech.glide.request.target.GlideDrawableImageViewTarget; import com.joanzapata.iconify.Iconify; import com.nineoldandroids.view.ViewHelper; -import org.apache.commons.lang3.StringUtils; - import java.lang.ref.WeakReference; import de.danoeh.antennapod.R; @@ -78,11 +78,11 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter 0) { @@ -252,7 +258,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter 0) { progressLeft.setText(Converter.byteToString(media.getSize())); - } else if(false == media.checkedOnSizeButUnknown()) { + } else if(NetworkUtils.isDownloadAllowed() && !media.checkedOnSizeButUnknown()) { progressLeft.setText("{fa-spinner}"); Iconify.addIcons(progressLeft); NetworkUtils.getFeedMediaSizeObservable(media) @@ -375,4 +381,18 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter feedTime = new ArrayList<>(); + + public StatisticsListAdapter(Context context) { + this.context = context; + } + + + @Override + public int getCount() { + return feedTime.size(); + } + + @Override + public DBReader.StatisticsItem getItem(int position) { + return feedTime.get(position); + } + + @Override + public long getItemId(int position) { + return feedTime.get(position).feed.getId(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + StatisticsHolder holder; + Feed feed = feedTime.get(position).feed; + + if (convertView == null) { + holder = new StatisticsHolder(); + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + convertView = inflater.inflate(R.layout.statistics_listitem, parent, false); + + holder.image = (ImageView) convertView.findViewById(R.id.imgvCover); + holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); + holder.time = (TextView) convertView.findViewById(R.id.txtvTime); + convertView.setTag(holder); + } else { + holder = (StatisticsHolder) convertView.getTag(); + } + + Glide.with(context) + .load(feed.getImageUri()) + .placeholder(R.color.light_gray) + .error(R.color.light_gray) + .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) + .fitCenter() + .dontAnimate() + .into(holder.image); + + holder.title.setText(feed.getTitle()); + holder.time.setText(Converter.shortLocalizedDuration(context, + feedTime.get(position).timePlayed)); + return convertView; + } + + public void update(List feedTime) { + this.feedTime = feedTime; + notifyDataSetChanged(); + } + + static class StatisticsHolder { + ImageView image; + TextView title; + TextView time; + } + +} diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java index 0ff976b98..de000570b 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java @@ -40,7 +40,7 @@ public class SubscriptionsAdapter extends BaseAdapter { @Override public long getItemId(int position) { - return 0; + return mItemAccess.getItem(position).getId(); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java index 743f9fc86..aea3d583f 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java @@ -9,7 +9,6 @@ import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.DiskCacheStrategy; import org.apache.commons.lang3.StringUtils; diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java index 47ac4c757..e9756b467 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java @@ -167,7 +167,7 @@ public class ItunesAdapter extends ArrayAdapter { for(int i=0; imageUrl == null && i < images.length(); i++) { JSONObject image = images.getJSONObject(i); String height = image.getJSONObject("attributes").getString("height"); - if(Integer.valueOf(height) >= 100) { + if(Integer.parseInt(height) >= 100) { imageUrl = image.getString("label"); } } diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java index 5c24c2822..13abb26ea 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java @@ -3,7 +3,6 @@ package de.danoeh.antennapod.asynctask; import android.annotation.SuppressLint; import android.app.ProgressDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; @@ -80,14 +79,7 @@ public class OpmlExportWorker extends AsyncTask { progDialog.dismiss(); AlertDialog.Builder alert = new AlertDialog.Builder(context) .setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - dialog.dismiss(); - } - }); + (dialog, which) -> dialog.dismiss()); if (exception != null) { alert.setTitle(R.string.export_error_label); alert.setMessage(exception.getMessage()); diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java index 00327bce0..1cb653f01 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java @@ -6,7 +6,6 @@ import android.content.Context; import android.os.AsyncTask; import java.util.Arrays; -import java.util.Date; import de.danoeh.antennapod.activity.OpmlImportHolder; import de.danoeh.antennapod.core.R; @@ -44,10 +43,9 @@ public class OpmlFeedQueuer extends AsyncTask { @Override protected Void doInBackground(Void... params) { DownloadRequester requester = DownloadRequester.getInstance(); - for (int idx = 0; idx < selection.length; idx++) { - OpmlElement element = OpmlImportHolder.getReadElements().get( - selection[idx]); - Feed feed = new Feed(element.getXmlUrl(), new Date(0), + for (int selected : selection) { + OpmlElement element = OpmlImportHolder.getReadElements().get(selected); + Feed feed = new Feed(element.getXmlUrl(), null, element.getText()); try { requester.downloadFeed(context.getApplicationContext(), feed); diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java index 86636485d..45ec6c5fa 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlImportWorker.java @@ -3,21 +3,20 @@ package de.danoeh.antennapod.asynctask; import android.annotation.SuppressLint; import android.app.ProgressDialog; import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.os.AsyncTask; import android.support.v7.app.AlertDialog; import android.util.Log; -import de.danoeh.antennapod.core.BuildConfig; -import de.danoeh.antennapod.core.R; -import de.danoeh.antennapod.core.opml.OpmlElement; -import de.danoeh.antennapod.core.opml.OpmlReader; + import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; +import de.danoeh.antennapod.core.R; +import de.danoeh.antennapod.core.opml.OpmlElement; +import de.danoeh.antennapod.core.opml.OpmlReader; + public class OpmlImportWorker extends AsyncTask> { private static final String TAG = "OpmlImportWorker"; diff --git a/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java index 9f8af1142..c3f7ae9c8 100644 --- a/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java +++ b/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.config; import de.danoeh.antennapod.core.DBTasksCallbacks; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; import de.danoeh.antennapod.core.storage.APDownloadAlgorithm; import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm; import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java index bdb2d68ba..6f9e221ec 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java @@ -2,13 +2,13 @@ package de.danoeh.antennapod.dialog; import android.app.Dialog; import android.content.Context; -import android.content.DialogInterface; import android.os.Bundle; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; + import de.danoeh.antennapod.R; /** @@ -58,26 +58,13 @@ public abstract class AuthenticationDialog extends Dialog { if (passwordInitialValue != null) { etxtPassword.setText(passwordInitialValue); } - setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - onCancelled(); - } - }); - butCancel.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - cancel(); - } - }); - butConfirm.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onConfirmed(etxtUsername.getText().toString(), - etxtPassword.getText().toString(), - showSaveCredentialsCheckbox && saveUsernamePassword.isChecked()); - dismiss(); - } + setOnCancelListener(dialog -> onCancelled()); + butCancel.setOnClickListener(v -> cancel()); + butConfirm.setOnClickListener(v -> { + onConfirmed(etxtUsername.getText().toString(), + etxtPassword.getText().toString(), + showSaveCredentialsCheckbox && saveUsernamePassword.isChecked()); + dismiss(); }); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java index 75b1bc8d2..93425949c 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java @@ -3,7 +3,6 @@ package de.danoeh.antennapod.dialog; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; import android.support.v7.app.AlertDialog; import android.view.View; import android.widget.CheckBox; @@ -42,12 +41,9 @@ public class AutoFlattrPreferenceDialog { setStatusMsgText(activity, txtvStatus, initialValue); skbPercent.setProgress(initialValue); - chkAutoFlattr.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - skbPercent.setEnabled(chkAutoFlattr.isChecked()); - txtvStatus.setEnabled(chkAutoFlattr.isChecked()); - } + chkAutoFlattr.setOnClickListener(v -> { + skbPercent.setEnabled(chkAutoFlattr.isChecked()); + txtvStatus.setEnabled(chkAutoFlattr.isChecked()); }); skbPercent.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @@ -69,20 +65,14 @@ public class AutoFlattrPreferenceDialog { builder.setTitle(R.string.pref_auto_flattr_title) .setView(view) - .setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - float progDouble = ((float) skbPercent.getProgress()) / 100.0f; - callback.onConfirmed(chkAutoFlattr.isChecked(), progDouble); - dialog.dismiss(); - } + .setPositiveButton(R.string.confirm_label, (dialog, which) -> { + float progDouble = ((float) skbPercent.getProgress()) / 100.0f; + callback.onConfirmed(chkAutoFlattr.isChecked(), progDouble); + dialog.dismiss(); }) - .setNegativeButton(R.string.cancel_label, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - callback.onCancelled(); - dialog.dismiss(); - } + .setNegativeButton(R.string.cancel_label, (dialog, which) -> { + callback.onCancelled(); + dialog.dismiss(); }) .setCancelable(false).show(); } @@ -97,10 +87,10 @@ public class AutoFlattrPreferenceDialog { } } - public static interface AutoFlattrPreferenceDialogInterface { - public void onCancelled(); + public interface AutoFlattrPreferenceDialogInterface { + void onCancelled(); - public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue); + void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java index 6432ebd4e..577a3ecbe 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.dialog; import android.content.res.TypedArray; -import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.app.ActivityCompat; @@ -18,10 +17,6 @@ import android.widget.Button; import android.widget.ListView; import android.widget.Toast; -import com.joanzapata.iconify.Icon; -import com.joanzapata.iconify.IconDrawable; -import com.joanzapata.iconify.fonts.FontAwesomeIcons; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -39,6 +34,14 @@ public class EpisodesApplyActionFragment extends Fragment { public String TAG = "EpisodeActionFragment"; + public static final int ACTION_QUEUE = 1; + public static final int ACTION_MARK_PLAYED = 2; + public static final int ACTION_MARK_UNPLAYED = 4; + public static final int ACTION_DOWNLOAD = 8; + public static final int ACTION_REMOVE = 16; + public static final int ACTION_ALL = ACTION_QUEUE | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED + | ACTION_DOWNLOAD | ACTION_REMOVE; + private ListView mListView; private ArrayAdapter mAdapter; @@ -48,27 +51,26 @@ public class EpisodesApplyActionFragment extends Fragment { private Button btnDownload; private Button btnDelete; - private final Map idMap; - private final List episodes; - private final List titles = new ArrayList(); + private final Map idMap = new ArrayMap<>(); + private final List episodes = new ArrayList<>(); + private int actions; + private final List titles = new ArrayList<>(); private final LongList checkedIds = new LongList(); private MenuItem mSelectToggle; - private int textColor; - - public EpisodesApplyActionFragment() { - this.episodes = new ArrayList<>(); - this.idMap = new ArrayMap<>(); + public static EpisodesApplyActionFragment newInstance(List items) { + return newInstance(items, ACTION_ALL); } - public void setEpisodes(List episodes) { - this.episodes.clear(); - this.episodes.addAll(episodes); - this.idMap.clear(); - for(FeedItem episode : episodes) { - this.idMap.put(episode.getId(), episode); + public static EpisodesApplyActionFragment newInstance(List items, int actions) { + EpisodesApplyActionFragment f = new EpisodesApplyActionFragment(); + f.episodes.addAll(items); + for(FeedItem episode : items) { + f.idMap.put(episode.getId(), episode); } + f.actions = actions; + return f; } @Override @@ -103,16 +105,48 @@ public class EpisodesApplyActionFragment extends Fragment { mListView.setAdapter(mAdapter); checkAll(); + int lastVisibleDiv = 0; btnAddToQueue = (Button) view.findViewById(R.id.btnAddToQueue); - btnAddToQueue.setOnClickListener(v -> queueChecked()); + if((actions & ACTION_QUEUE) != 0) { + btnAddToQueue.setOnClickListener(v -> queueChecked()); + lastVisibleDiv = R.id.divider1; + } else { + btnAddToQueue.setVisibility(View.GONE); + view.findViewById(R.id.divider1).setVisibility(View.GONE); + } btnMarkAsPlayed = (Button) view.findViewById(R.id.btnMarkAsPlayed); - btnMarkAsPlayed.setOnClickListener(v -> markedCheckedPlayed()); + if((actions & ACTION_MARK_PLAYED) != 0) { + btnMarkAsPlayed.setOnClickListener(v -> markedCheckedPlayed()); + lastVisibleDiv = R.id.divider2; + } else { + btnMarkAsPlayed.setVisibility(View.GONE); + view.findViewById(R.id.divider2).setVisibility(View.GONE); + } btnMarkAsUnplayed = (Button) view.findViewById(R.id.btnMarkAsUnplayed); - btnMarkAsUnplayed.setOnClickListener(v -> markedCheckedUnplayed()); + if((actions & ACTION_MARK_UNPLAYED) != 0) { + btnMarkAsUnplayed.setOnClickListener(v -> markedCheckedUnplayed()); + lastVisibleDiv = R.id.divider3; + } else { + btnMarkAsUnplayed.setVisibility(View.GONE); + view.findViewById(R.id.divider3).setVisibility(View.GONE); + } btnDownload = (Button) view.findViewById(R.id.btnDownload); - btnDownload.setOnClickListener(v -> downloadChecked()); + if((actions & ACTION_DOWNLOAD) != 0) { + btnDownload.setOnClickListener(v -> downloadChecked()); + lastVisibleDiv = R.id.divider4; + } else { + btnDownload.setVisibility(View.GONE); + view.findViewById(R.id.divider4).setVisibility(View.GONE); + } btnDelete = (Button) view.findViewById(R.id.btnDelete); - btnDelete.setOnClickListener(v -> deleteChecked()); + if((actions & ACTION_REMOVE) != 0) { + btnDelete.setOnClickListener(v -> deleteChecked()); + } else { + btnDelete.setVisibility(View.GONE); + if(lastVisibleDiv > 0) { + view.findViewById(lastVisibleDiv).setVisibility(View.GONE); + } + } return view; } @@ -122,11 +156,6 @@ public class EpisodesApplyActionFragment extends Fragment { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.episodes_apply_action_options, menu); - int[] attrs = { android.R.attr.textColor }; - TypedArray ta = getActivity().obtainStyledAttributes(attrs); - textColor = ta.getColor(0, Color.GRAY); - ta.recycle(); - mSelectToggle = menu.findItem(R.id.select_toggle); mSelectToggle.setOnMenuItemClickListener(item -> { if (checkedIds.size() == episodes.size()) { @@ -140,22 +169,21 @@ public class EpisodesApplyActionFragment extends Fragment { @Override public void onPrepareOptionsMenu (Menu menu) { - /* - * Prepare icon for select toggle button - */ + // Prepare icon for select toggle button - // Find icon attribute int[] icon = new int[1]; - if(checkedIds.size() == episodes.size()) icon[0] = R.attr.ic_check_box; - else if(checkedIds.size() == 0) icon[0] = R.attr.ic_check_box_outline; - else icon[0] = R.attr.ic_indeterminate_check_box; + if (checkedIds.size() == episodes.size()) { + icon[0] = R.attr.ic_check_box; + } else if (checkedIds.size() == 0) { + icon[0] = R.attr.ic_check_box_outline; + } else { + icon[0] = R.attr.ic_indeterminate_check_box; + } - // Get Drawable from attribute TypedArray a = getActivity().obtainStyledAttributes(icon); Drawable iconDrawable = a.getDrawable(0); a.recycle(); - // Set icon mSelectToggle.setIcon(iconDrawable); } @@ -189,6 +217,14 @@ public class EpisodesApplyActionFragment extends Fragment { checkDownloaded(false); resId = R.string.selected_not_downloaded_label; break; + case R.id.check_queued: + checkQueued(true); + resId = R.string.selected_queued_label; + break; + case R.id.check_not_queued: + checkQueued(false); + resId = R.string.selected_not_queued_label; + break; case R.id.sort_title_a_z: sortByTitle(false); return true; @@ -249,9 +285,9 @@ public class EpisodesApplyActionFragment extends Fragment { private void sortByDuration(final boolean reverse) { Collections.sort(episodes, (lhs, rhs) -> { int ordering; - if (false == lhs.hasMedia()) { + if (!lhs.hasMedia()) { ordering = 1; - } else if (false == rhs.hasMedia()) { + } else if (!rhs.hasMedia()) { ordering = -1; } else { ordering = lhs.getMedia().getDuration() - rhs.getMedia().getDuration(); @@ -268,7 +304,7 @@ public class EpisodesApplyActionFragment extends Fragment { private void checkAll() { for (FeedItem episode : episodes) { - if(false == checkedIds.contains(episode.getId())) { + if(!checkedIds.contains(episode.getId())) { checkedIds.add(episode.getId()); } } @@ -310,6 +346,17 @@ public class EpisodesApplyActionFragment extends Fragment { refreshCheckboxes(); } + private void checkQueued(boolean isQueued) { + for (FeedItem episode : episodes) { + if(episode.isTagged(FeedItem.TAG_QUEUE) == isQueued) { + checkedIds.add(episode.getId()); + } else { + checkedIds.remove(episode.getId()); + } + } + refreshCheckboxes(); + } + private void refreshTitles() { titles.clear(); for(FeedItem episode : episodes) { @@ -344,14 +391,14 @@ public class EpisodesApplyActionFragment extends Fragment { private void downloadChecked() { // download the check episodes in the same order as they are currently displayed - List toDownload = new ArrayList(checkedIds.size()); + List toDownload = new ArrayList<>(checkedIds.size()); for(FeedItem episode : episodes) { if(checkedIds.contains(episode.getId())) { toDownload.add(episode); } } try { - DBTasks.downloadFeedItems(getActivity(), toDownload.toArray(new FeedItem[0])); + DBTasks.downloadFeedItems(getActivity(), toDownload.toArray(new FeedItem[toDownload.size()])); } catch (DownloadRequestException e) { e.printStackTrace(); DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage()); diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java index 5f531e88f..b50e21d15 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.dialog; import android.content.Context; -import android.content.DialogInterface; import android.support.v7.app.AlertDialog; import android.text.Editable; import android.text.InputType; diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java new file mode 100644 index 000000000..98a4b5356 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java @@ -0,0 +1,320 @@ +package de.danoeh.antennapod.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.content.res.TypedArray; +import android.support.v4.content.ContextCompat; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.Patterns; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.afollestad.materialdialogs.internal.MDButton; +import com.squareup.okhttp.Credentials; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.SocketAddress; +import java.util.concurrent.TimeUnit; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.service.download.AntennapodHttpClient; +import de.danoeh.antennapod.core.service.download.ProxyConfig; +import rx.Observable; +import rx.Subscriber; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class ProxyDialog { + + private static final String TAG = "ProxyDialog"; + + private Context context; + + private MaterialDialog dialog; + + private Spinner spType; + private EditText etHost; + private EditText etPort; + private EditText etUsername; + private EditText etPassword; + + private boolean testSuccessful = false; + private TextView txtvMessage; + private Subscription subscription; + + public ProxyDialog(Context context) { + this.context = context; + } + + public Dialog createDialog() { + dialog = new MaterialDialog.Builder(context) + .title(R.string.pref_proxy_title) + .customView(R.layout.proxy_settings, true) + .positiveText(R.string.proxy_test_label) + .negativeText(R.string.cancel_label) + .onPositive((dialog1, which) -> { + if(!testSuccessful) { + dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false); + test(); + return; + } + String type = (String) ((Spinner) dialog1.findViewById(R.id.spType)).getSelectedItem(); + ProxyConfig proxy; + if(Proxy.Type.valueOf(type) == Proxy.Type.DIRECT) { + proxy = ProxyConfig.direct(); + } else { + String host = etHost.getText().toString(); + String port = etPort.getText().toString(); + String username = etUsername.getText().toString(); + if(TextUtils.isEmpty(username)) { + username = null; + } + String password = etPassword.getText().toString(); + if(TextUtils.isEmpty(password)) { + password = null; + } + int portValue = 0; + if(!TextUtils.isEmpty(port)) { + portValue = Integer.valueOf(port); + } + proxy = ProxyConfig.http(host, portValue, username, password); + } + UserPreferences.setProxyConfig(proxy); + AntennapodHttpClient.reinit(); + dialog.dismiss(); + }) + .onNegative((dialog1, which) -> dialog1.dismiss()) + .autoDismiss(false) + .build(); + View view = dialog.getCustomView(); + spType = (Spinner) view.findViewById(R.id.spType); + String[] types = { Proxy.Type.DIRECT.name(), Proxy.Type.HTTP.name() }; + ArrayAdapter adapter = new ArrayAdapter<>(context, + android.R.layout.simple_spinner_item, types); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spType.setAdapter(adapter); + ProxyConfig proxyConfig = UserPreferences.getProxyConfig(); + spType.setSelection(adapter.getPosition(proxyConfig.type.name())); + etHost = (EditText) view.findViewById(R.id.etHost); + if(!TextUtils.isEmpty(proxyConfig.host)) { + etHost.setText(proxyConfig.host); + } + etHost.addTextChangedListener(requireTestOnChange); + etPort = (EditText) view.findViewById(R.id.etPort); + if(proxyConfig.port > 0) { + etPort.setText(String.valueOf(proxyConfig.port)); + } + etPort.addTextChangedListener(requireTestOnChange); + etUsername = (EditText) view.findViewById(R.id.etUsername); + if(!TextUtils.isEmpty(proxyConfig.username)) { + etUsername.setText(proxyConfig.username); + } + etUsername.addTextChangedListener(requireTestOnChange); + etPassword = (EditText) view.findViewById(R.id.etPassword); + if(!TextUtils.isEmpty(proxyConfig.password)) { + etPassword.setText(proxyConfig.username); + } + etPassword.addTextChangedListener(requireTestOnChange); + if(proxyConfig.type == Proxy.Type.DIRECT) { + enableSettings(false); + setTestRequired(false); + } + spType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + enableSettings(position > 0); + setTestRequired(position > 0); + } + + @Override + public void onNothingSelected(AdapterView parent) { + enableSettings(false); + } + }); + txtvMessage = (TextView) view.findViewById(R.id.txtvMessage); + checkValidity(); + return dialog; + } + + private final TextWatcher requireTestOnChange = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + setTestRequired(true); + } + }; + + private void enableSettings(boolean enable) { + etHost.setEnabled(enable); + etPort.setEnabled(enable); + etUsername.setEnabled(enable); + etPassword.setEnabled(enable); + } + + private boolean checkValidity() { + boolean valid = true; + if(spType.getSelectedItemPosition() > 0) { + valid &= checkHost(); + } + valid &= checkPort(); + return valid; + } + + private boolean checkHost() { + String host = etHost.getText().toString(); + if(host.length() == 0) { + etHost.setError(context.getString(R.string.proxy_host_empty_error)); + return false; + } + if(!"localhost".equals(host) && !Patterns.DOMAIN_NAME.matcher(host).matches()) { + etHost.setError(context.getString(R.string.proxy_host_invalid_error)); + return false; + } + return true; + } + + private boolean checkPort() { + int port = getPort(); + if(port < 0 && port > 65535) { + etPort.setError(context.getString(R.string.proxy_port_invalid_error)); + return false; + } + return true; + } + + private int getPort() { + String port = etPort.getText().toString(); + if(port.length() > 0) { + try { + return Integer.parseInt(port); + } catch(NumberFormatException e) { + // ignore + } + } + return 0; + } + + private void setTestRequired(boolean required) { + if(required) { + testSuccessful = false; + MDButton button = dialog.getActionButton(DialogAction.POSITIVE); + button.setText(context.getText(R.string.proxy_test_label)); + button.setEnabled(true); + } else { + testSuccessful = true; + MDButton button = dialog.getActionButton(DialogAction.POSITIVE); + button.setText(context.getText(android.R.string.ok)); + button.setEnabled(true); + } + } + + private void test() { + if(subscription != null) { + subscription.unsubscribe(); + } + if(!checkValidity()) { + setTestRequired(true); + return; + } + TypedArray res = context.getTheme().obtainStyledAttributes(new int[] { android.R.attr.textColorPrimary }); + int textColorPrimary = res.getColor(0, 0); + res.recycle(); + String checking = context.getString(R.string.proxy_checking); + txtvMessage.setTextColor(textColorPrimary); + txtvMessage.setText("{fa-circle-o-notch spin} " + checking); + txtvMessage.setVisibility(View.VISIBLE); + subscription = Observable.create(new Observable.OnSubscribe() { + @Override + public void call(Subscriber subscriber) { + String type = (String) spType.getSelectedItem(); + String host = etHost.getText().toString(); + String port = etPort.getText().toString(); + String username = etUsername.getText().toString(); + String password = etPassword.getText().toString(); + int portValue = 8080; + if(!TextUtils.isEmpty(port)) { + portValue = Integer.valueOf(port); + } + SocketAddress address = InetSocketAddress.createUnresolved(host, portValue); + Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase()); + Proxy proxy = new Proxy(proxyType, address); + OkHttpClient client = AntennapodHttpClient.newHttpClient(); + client.setConnectTimeout(10, TimeUnit.SECONDS); + client.setProxy(proxy); + client.interceptors().clear(); + if(!TextUtils.isEmpty(username)) { + String credentials = Credentials.basic(username, password); + client.interceptors().add(chain -> { + Request request = chain.request().newBuilder() + .header("Proxy-Authorization", credentials).build(); + return chain.proceed(request); + }); + } + Request request = new Request.Builder() + .url("http://www.google.com") + .head() + .build(); + try { + Response response = client.newCall(request).execute(); + subscriber.onNext(response); + } catch(IOException e) { + subscriber.onError(e); + } + subscriber.onCompleted(); + } + }) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + response -> { + int colorId; + String icon; + String result; + if(response.isSuccessful()) { + colorId = R.color.download_success_green; + icon = "{fa-check}"; + result = context.getString(R.string.proxy_test_successful); + } else { + colorId = R.color.download_failed_red; + icon = "{fa-close}"; + result = context.getString(R.string.proxy_test_failed); + } + int color = ContextCompat.getColor(context, colorId); + txtvMessage.setTextColor(color); + String message = String.format("%s %s: %s", icon, result, response.message()); + txtvMessage.setText(message); + setTestRequired(!response.isSuccessful()); + }, + error -> { + String icon = "{fa-close}"; + String result = context.getString(R.string.proxy_test_failed); + int color = ContextCompat.getColor(context, R.color.download_failed_red); + txtvMessage.setTextColor(color); + String message = String.format("%s %s: %s", icon, result, error.getMessage()); + txtvMessage.setText(message); + setTestRequired(true); + } + ); + } + +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java index ed0db92a4..64fc1fda4 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java @@ -94,11 +94,7 @@ public class RatingDialog { long firstDate = mPreferences.getLong(KEY_FIRST_START_DATE, now); long diff = now - firstDate; long diffDays = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS); - if (diffDays >= AFTER_DAYS) { - return true; - } else { - return false; - } + return diffDays >= AFTER_DAYS; } @Nullable @@ -107,30 +103,16 @@ public class RatingDialog { if(context == null) { return null; } - MaterialDialog dialog = new MaterialDialog.Builder(context) + return new MaterialDialog.Builder(context) .title(R.string.rating_title) .content(R.string.rating_message) .positiveText(R.string.rating_now_label) .negativeText(R.string.rating_never_label) .neutralText(R.string.rating_later_label) - .callback(new MaterialDialog.ButtonCallback() { - @Override - public void onPositive(MaterialDialog dialog) { - rateNow(); - } - - @Override - public void onNegative(MaterialDialog dialog) { - saveRated(); - } - - @Override - public void onNeutral(MaterialDialog dialog) { - resetStartDate(); - } - }) + .onPositive((dialog, which) -> rateNow()) + .onNegative((dialog, which) -> saveRated()) + .onNeutral((dialog, which) -> resetStartDate()) .cancelListener(dialog1 -> resetStartDate()) .build(); - return dialog; } } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java index 930079e40..8a13a75d9 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java @@ -1,17 +1,13 @@ package de.danoeh.antennapod.dialog; -import android.app.Dialog; import android.content.Context; import android.content.SharedPreferences; -import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.View; -import android.view.Window; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Spinner; @@ -58,14 +54,8 @@ public abstract class SleepTimerDialog { builder.customView(R.layout.time_dialog, false); builder.positiveText(R.string.set_sleeptimer_label); builder.negativeText(R.string.cancel_label); - builder.callback(new MaterialDialog.ButtonCallback() { - @Override - public void onNegative(MaterialDialog dialog) { - dialog.dismiss(); - } - - @Override - public void onPositive(MaterialDialog dialog) { + builder.onNegative((dialog, which) -> dialog.dismiss()); + builder.onPositive((dialog, which) -> { try { savePreferences(); long input = readTimeMillis(); @@ -77,8 +67,7 @@ public abstract class SleepTimerDialog { Toast.LENGTH_LONG); toast.show(); } - } - }); + }); dialog = builder.build(); View view = dialog.getView(); @@ -138,7 +127,7 @@ public abstract class SleepTimerDialog { private long readTimeMillis() { TimeUnit selectedUnit = units[spTimeUnit.getSelectedItemPosition()]; - long value = Long.valueOf(etxtTime.getText().toString()); + long value = Long.parseLong(etxtTime.getText().toString()); return selectedUnit.toMillis(value); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java index 3ed82b9bd..2bf9c4e7a 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java @@ -102,8 +102,8 @@ public class VariableSpeedDialog { builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { int choiceCount = 0; - for (int i = 0; i < speedChecked.length; i++) { - if (speedChecked[i]) { + for (boolean checked : speedChecked) { + if (checked) { choiceCount++; } } 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 d979dc382..45364ca07 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -47,36 +47,18 @@ public class AddFeedFragment extends Fragment { final MainActivity activity = (MainActivity) getActivity(); activity.getSupportActionBar().setTitle(R.string.add_feed_label); - butSearchITunes.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - activity.loadChildFragment(new ItunesSearchFragment()); - } - }); + butSearchITunes.setOnClickListener(v -> activity.loadChildFragment(new ItunesSearchFragment())); - butBrowserGpoddernet.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - activity.loadChildFragment(new GpodnetMainFragment()); - } - }); + butBrowserGpoddernet.setOnClickListener(v -> activity.loadChildFragment(new GpodnetMainFragment())); - butOpmlImport.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(new Intent(getActivity(), - OpmlImportFromPathActivity.class)); - } - }); + butOpmlImport.setOnClickListener(v -> startActivity(new Intent(getActivity(), + OpmlImportFromPathActivity.class))); - butConfirm.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - 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); - } + butConfirm.setOnClickListener(v -> { + 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); }); return root; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java index 273c75240..335cf5414 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -1,6 +1,5 @@ package de.danoeh.antennapod.fragment; -import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; @@ -24,7 +23,6 @@ import android.widget.Toast; import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; @@ -81,8 +79,6 @@ public class AllEpisodesFragment extends Fragment { private boolean itemsLoaded = false; private boolean viewsCreated = false; - private AtomicReference activity = new AtomicReference(); - private boolean isUpdatingFeeds; protected Subscription subscription; @@ -101,7 +97,6 @@ public class AllEpisodesFragment extends Fragment { public void onStart() { super.onStart(); EventDistributor.getInstance().register(contentUpdate); - this.activity.set((MainActivity) getActivity()); if (viewsCreated && itemsLoaded) { onFragmentLoaded(); } @@ -132,12 +127,6 @@ public class AllEpisodesFragment extends Fragment { } } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - this.activity.set((MainActivity) getActivity()); - } - @Override public void onDestroyView() { super.onDestroyView(); @@ -176,18 +165,13 @@ public class AllEpisodesFragment extends Fragment { } protected void resetViewState() { - listAdapter = null; - activity.set(null); viewsCreated = false; + listAdapter = null; } - private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() { - @Override - public boolean isRefreshing() { - return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); - } - }; + private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = + () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { @@ -325,7 +309,7 @@ public class AllEpisodesFragment extends Fragment { viewsCreated = true; - if (itemsLoaded && activity.get() != null) { + if (itemsLoaded) { onFragmentLoaded(); } @@ -334,9 +318,10 @@ public class AllEpisodesFragment extends Fragment { private void onFragmentLoaded() { if (listAdapter == null) { - MainActivity mainActivity = activity.get(); + MainActivity mainActivity = (MainActivity) getActivity(); listAdapter = new AllEpisodesRecycleAdapter(mainActivity, itemAccess, new DefaultActionButtonCallback(mainActivity), showOnlyNewEpisodes()); + listAdapter.setHasStableIds(true); recyclerView.setAdapter(listAdapter); } listAdapter.notifyDataSetChanged(); @@ -378,10 +363,7 @@ public class AllEpisodesFragment extends Fragment { @Override public boolean isInQueue(FeedItem item) { - if (item != null) { - return item.isTagged(FeedItem.TAG_QUEUE); - } - return false; + return item != null && item.isTagged(FeedItem.TAG_QUEUE); } @Override @@ -470,7 +452,7 @@ public class AllEpisodesFragment extends Fragment { recyclerView.setVisibility(View.GONE); progLoading.setVisibility(View.VISIBLE); } - subscription = Observable.fromCallable(() -> loadData()) + subscription = Observable.fromCallable(this::loadData) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { @@ -479,7 +461,7 @@ public class AllEpisodesFragment extends Fragment { if (data != null) { episodes = data; itemsLoaded = true; - if (viewsCreated && activity.get() != null) { + if (viewsCreated) { onFragmentLoaded(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java index ce1d753e8..aea911f79 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment; import android.os.Bundle; import android.support.v4.app.ListFragment; +import android.util.Log; import android.view.View; import android.widget.ListView; @@ -15,15 +16,16 @@ import de.danoeh.antennapod.core.util.playback.PlaybackController; public class ChaptersFragment extends ListFragment implements AudioplayerContentFragment { + private static final String TAG = "ChaptersFragment"; + private Playable media; private PlaybackController controller; private ChaptersListAdapter adapter; - public static ChaptersFragment newInstance(Playable media, PlaybackController controller) { + public static ChaptersFragment newInstance(Playable media) { ChaptersFragment f = new ChaptersFragment(); f.media = media; - f.controller = controller; return f; } @@ -37,6 +39,10 @@ public class ChaptersFragment extends ListFragment implements AudioplayerContent lv.setPadding(0, vertPadding, 0, vertPadding); adapter = new ChaptersListAdapter(getActivity(), 0, pos -> { + if(controller == null) { + Log.d(TAG, "controller is null"); + return; + } Chapter chapter = (Chapter) getListAdapter().getItem(pos); controller.seekToChapter(chapter); }); @@ -58,6 +64,7 @@ public class ChaptersFragment extends ListFragment implements AudioplayerContent public void onDestroy() { super.onDestroy(); adapter = null; + controller = null; } @Override @@ -68,10 +75,15 @@ public class ChaptersFragment extends ListFragment implements AudioplayerContent this.media = media; adapter.setMedia(media); adapter.notifyDataSetChanged(); - if(media.getChapters() == null) { + if(media == null || media.getChapters() == null || media.getChapters().size() == 0) { setEmptyText(getString(R.string.no_items_label)); } else { setEmptyText(null); } } + + public void setController(PlaybackController controller) { + this.controller = controller; + } + } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java index 954c4c9e2..261974f2f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -1,12 +1,20 @@ package de.danoeh.antennapod.fragment; -import android.app.Activity; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.widget.ListView; +import com.joanzapata.iconify.IconDrawable; +import com.joanzapata.iconify.fonts.FontAwesomeIcons; + import java.util.List; import de.danoeh.antennapod.R; @@ -14,8 +22,10 @@ import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DownloadedEpisodesListAdapter; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; @@ -28,22 +38,21 @@ public class CompletedDownloadsFragment extends ListFragment { private static final String TAG = CompletedDownloadsFragment.class.getSimpleName(); - private static final int EVENTS = - EventDistributor.DOWNLOAD_HANDLED | - EventDistributor.DOWNLOADLOG_UPDATE | - EventDistributor.UNREAD_ITEMS_UPDATE; + private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | + EventDistributor.DOWNLOADLOG_UPDATE | + EventDistributor.UNREAD_ITEMS_UPDATE; private List items; private DownloadedEpisodesListAdapter listAdapter; private boolean viewCreated = false; - private boolean itemsLoaded = false; private Subscription subscription; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setHasOptionsMenu(true); loadItems(); } @@ -81,9 +90,9 @@ public class CompletedDownloadsFragment extends ListFragment { } @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - if (viewCreated && itemsLoaded) { + public void onAttach(Context context) { + super.onAttach(context); + if (viewCreated && items != null) { onFragmentLoaded(); } } @@ -99,7 +108,7 @@ public class CompletedDownloadsFragment extends ListFragment { lv.setPadding(0, vertPadding, 0, vertPadding); viewCreated = true; - if (itemsLoaded && getActivity() != null) { + if (items != null && getActivity() != null) { onFragmentLoaded(); } } @@ -111,7 +120,6 @@ public class CompletedDownloadsFragment extends ListFragment { if (item != null) { ((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId())); } - } private void onFragmentLoaded() { @@ -121,6 +129,43 @@ public class CompletedDownloadsFragment extends ListFragment { } setListShown(true); listAdapter.notifyDataSetChanged(); + getActivity().supportInvalidateOptionsMenu(); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + if(!isAdded()) { + return; + } + super.onCreateOptionsMenu(menu, inflater); + if(items != null) { + inflater.inflate(R.menu.downloads_completed, menu); + MenuItem episodeActions = menu.findItem(R.id.episode_actions); + if(items.size() > 0) { + int[] attrs = {R.attr.action_bar_icon_color}; + TypedArray ta = getActivity().obtainStyledAttributes(UserPreferences.getTheme(), attrs); + int textColor = ta.getColor(0, Color.GRAY); + ta.recycle(); + episodeActions.setIcon(new IconDrawable(getActivity(), + FontAwesomeIcons.fa_gears).color(textColor).actionBarSize()); + episodeActions.setVisible(true); + } else { + episodeActions.setVisible(false); + } + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.episode_actions: + EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment + .newInstance(items, EpisodesApplyActionFragment.ACTION_REMOVE); + ((MainActivity) getActivity()).loadChildFragment(fragment); + return true; + default: + return false; + } } private DownloadedEpisodesListAdapter.ItemAccess itemAccess = new DownloadedEpisodesListAdapter.ItemAccess() { @@ -157,16 +202,15 @@ public class CompletedDownloadsFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - if (!itemsLoaded && viewCreated) { + if (items == null && viewCreated) { setListShown(false); } - subscription = Observable.fromCallable(() -> DBReader.getDownloadedItems()) + subscription = Observable.fromCallable(DBReader::getDownloadedItems) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { if (result != null) { items = result; - itemsLoaded = true; if (viewCreated && getActivity() != null) { onFragmentLoaded(); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java index 931d14924..d3b97f9df 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java @@ -63,12 +63,7 @@ public class CoverFragment extends Fragment implements AudioplayerContentFragmen } private void loadMediaInfo() { - if(imgvCover == null) { - return; - } if (media != null) { - Log.d(TAG, "feed title: " + media.getFeedTitle()); - Log.d(TAG, "episode title: " + media.getEpisodeTitle()); txtvPodcastTitle.setText(media.getFeedTitle()); txtvEpisodeTitle.setText(media.getEpisodeTitle()); Glide.with(this) @@ -103,7 +98,7 @@ public class CoverFragment extends Fragment implements AudioplayerContentFragmen @Override public void onMediaChanged(Playable media) { - if(this.media == media) { + if(!isAdded() || this.media == media) { return; } this.media = media; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java index b470d379a..93527b149 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java @@ -154,7 +154,7 @@ public class DownloadLogFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.fromCallable(() -> DBReader.getDownloadLog()) + subscription = Observable.fromCallable(DBReader::getDownloadLog) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index 80a9bf0b3..ca60e7bf2 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -5,7 +5,6 @@ import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; @@ -53,16 +52,12 @@ public class ExternalPlayerFragment extends Fragment { mFeedName = (TextView) root.findViewById(R.id.txtvAuthor); mProgressBar = (ProgressBar) root.findViewById(R.id.episodeProgress); - fragmentLayout.setOnClickListener(new OnClickListener() { + fragmentLayout.setOnClickListener(v -> { + Log.d(TAG, "layoutInfo was clicked"); - @Override - public void onClick(View v) { - Log.d(TAG, "layoutInfo was clicked"); - - if (controller != null && controller.getMedia() != null) { - startActivity(PlaybackService.getPlayerActivityIntent( - getActivity(), controller.getMedia())); - } + if (controller != null && controller.getMedia() != null) { + startActivity(PlaybackService.getPlayerActivityIntent( + getActivity(), controller.getMedia())); } }); return root; @@ -72,7 +67,11 @@ public class ExternalPlayerFragment extends Fragment { public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); controller = setupPlaybackController(); - butPlay.setOnClickListener(controller.newOnPlayButtonClickListener()); + butPlay.setOnClickListener(v -> { + if(controller != null) { + controller.playPause(); + } + }); } private PlaybackController setupPlaybackController() { @@ -88,7 +87,6 @@ public class ExternalPlayerFragment extends Fragment { return butPlay; } - @Override public boolean loadMediaInfo() { ExternalPlayerFragment fragment = ExternalPlayerFragment.this; @@ -145,8 +143,11 @@ public class ExternalPlayerFragment extends Fragment { } controller = setupPlaybackController(); if (butPlay != null) { - butPlay.setOnClickListener(controller - .newOnPlayButtonClickListener()); + butPlay.setOnClickListener(v -> { + if(controller != null) { + controller.playPause(); + } + }); } controller.init(); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java index 4c723e5ff..5b301333e 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java @@ -62,7 +62,6 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont private static final String ARG_HIGHLIGHT_TIMECODES = "arg.highlightTimecodes"; private WebView webvDescription; - private String webvData; private ShownotesProvider shownotesProvider; private Playable media; @@ -112,7 +111,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG, "Creating view"); - webvDescription = new WebView(getActivity()); + webvDescription = new WebView(getActivity().getApplicationContext()); if (Build.VERSION.SDK_INT >= 11) { webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } @@ -149,7 +148,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont super.onPageFinished(view, url); Log.d(TAG, "Page finished"); // Restoring the scroll position might not always work - view.postDelayed(() -> restoreFromPreference(), 50); + view.postDelayed(ItemDescriptionFragment.this::restoreFromPreference, 50); } }); @@ -309,7 +308,6 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { - webvData = data; webvDescription.loadDataWithBaseURL(null, data, "text/html", "utf-8", "about:blank"); Log.d(TAG, "Webview loaded"); @@ -320,8 +318,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont private String loadData() { Timeline timeline = new Timeline(getActivity(), shownotesProvider); - String data = timeline.processShownotes(highlightTimecodes); - return data; + return timeline.processShownotes(highlightTimecodes); } @Override @@ -384,7 +381,7 @@ public class ItemDescriptionFragment extends Fragment implements AudioplayerCont @Override public void onMediaChanged(Playable media) { - if(this.media == media) { + if(this.media == media || webvDescription == null) { return; } this.media = media; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index ce80dc827..92f4a9f7c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -9,6 +9,7 @@ import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.util.Log; import android.view.ContextMenu; @@ -101,6 +102,7 @@ public class ItemFragment extends Fragment { private ViewGroup root; private WebView webvDescription; + private TextView txtvPodcast; private TextView txtvTitle; private TextView txtvDuration; private TextView txtvPublished; @@ -134,6 +136,7 @@ public class ItemFragment extends Fragment { View layout = inflater.inflate(R.layout.feeditem_fragment, container, false); root = (ViewGroup) layout.findViewById(R.id.content_root); + txtvPodcast = (TextView) layout.findViewById(R.id.txtvPodcast); txtvTitle = (TextView) layout.findViewById(R.id.txtvTitle); txtvDuration = (TextView) layout.findViewById(R.id.txtvDuration); txtvPublished = (TextView) layout.findViewById(R.id.txtvPublished); @@ -146,8 +149,7 @@ public class ItemFragment extends Fragment { && Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } - webvDescription.setBackgroundColor(getResources().getColor( - R.color.black)); + webvDescription.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.black)); } webvDescription.getSettings().setUseWideViewPort(false); webvDescription.getSettings().setLayoutAlgorithm( @@ -219,6 +221,7 @@ public class ItemFragment extends Fragment { EventDistributor.getInstance().register(contentUpdate); EventBus.getDefault().registerSticky(this); if(itemsLoaded) { + progbarLoading.setVisibility(View.GONE); updateAppearance(); } } @@ -295,6 +298,7 @@ public class ItemFragment extends Fragment { return; } getActivity().supportInvalidateOptionsMenu(); + txtvPodcast.setText(item.getFeed().getTitle()); txtvTitle.setText(item.getTitle()); if (item.getPubDate() != null) { @@ -503,7 +507,7 @@ public class ItemFragment extends Fragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.fromCallable(() -> loadInBackground()) + subscription = Observable.fromCallable(this::loadInBackground) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java index 7a9b73982..4faa7be2d 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -185,11 +185,7 @@ public class ItemlistFragment extends ListFragment { private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() { @Override public boolean isRefreshing() { - if (feed != null && DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFile(feed)) { - return true; - } else { - return false; - } + return feed != null && DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFile(feed); } }; @@ -252,8 +248,8 @@ public class ItemlistFragment extends ListFragment { if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) { switch (item.getItemId()) { case R.id.episode_actions: - EpisodesApplyActionFragment fragment = new EpisodesApplyActionFragment(); - fragment.setEpisodes(feed.getItems()); + EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment + .newInstance(feed.getItems()); ((MainActivity)getActivity()).loadChildFragment(fragment); return true; case R.id.remove_item: @@ -405,7 +401,6 @@ public class ItemlistFragment extends ListFragment { public void onEventMainThread(FeedItemEvent event) { Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); - boolean queueChanged = false; if(feed == null || feed.getItems() == null || adapter == null) { return; } @@ -628,7 +623,7 @@ public class ItemlistFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.fromCallable(() -> loadData()) + subscription = Observable.fromCallable(this::loadData) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { 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 eb947dc2b..b736688b9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java @@ -124,7 +124,7 @@ public class ItunesSearchFragment extends Fragment { } else { gridView.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); - rx.Observable.create((Observable.OnSubscribe) subscriber -> { + subscription = Observable.create((Observable.OnSubscribe) subscriber -> { OkHttpClient client = AntennapodHttpClient.getHttpClient(); Request.Builder httpReq = new Request.Builder() .url(podcast.feedUrl) @@ -233,7 +233,7 @@ public class ItunesSearchFragment extends Fragment { butRetry.setVisibility(View.GONE); txtvEmpty.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); - subscription = rx.Observable.create((Observable.OnSubscribe>) subscriber -> { + subscription = Observable.create((Observable.OnSubscribe>) subscriber -> { String lang = Locale.getDefault().getLanguage(); String url = "https://itunes.apple.com/" + lang + "/rss/toppodcasts/limit=25/explicit=true/json"; OkHttpClient client = AntennapodHttpClient.getHttpClient(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index c5b77fae2..f6cb71af5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -220,7 +220,7 @@ public class PlaybackHistoryFragment extends ListFragment { private FeedItemlistAdapter.ItemAccess itemAccess = new FeedItemlistAdapter.ItemAccess() { @Override public boolean isInQueue(FeedItem item) { - return (queue != null) ? queue.contains(item.getId()) : false; + return (queue != null) && queue.contains(item.getId()); } @Override @@ -255,7 +255,7 @@ public class PlaybackHistoryFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.fromCallable(() -> loadData()) + subscription = Observable.fromCallable(this::loadData) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index b3f6c3534..4bfc3c9da 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -230,9 +230,8 @@ public class QueueFragment extends Fragment { resetViewState(); } - private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = () -> { - return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); - }; + private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = + () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { @@ -415,7 +414,7 @@ public class QueueFragment extends Fragment { Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_read_label), Snackbar.LENGTH_LONG); snackbar.setAction(getString(R.string.undo), v -> { DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false); - if(false == isRead) { + if(!isRead) { DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId()); } }); @@ -424,12 +423,12 @@ public class QueueFragment extends Fragment { @Override public boolean isLongPressDragEnabled() { - return false == UserPreferences.isQueueLocked(); + return !UserPreferences.isQueueLocked(); } @Override public boolean isItemViewSwipeEnabled() { - return false == UserPreferences.isQueueLocked(); + return !UserPreferences.isQueueLocked(); } @Override @@ -474,6 +473,7 @@ public class QueueFragment extends Fragment { MainActivity activity = (MainActivity) getActivity(); recyclerAdapter = new QueueRecyclerAdapter(activity, itemAccess, new DefaultActionButtonCallback(activity), itemTouchHelper); + recyclerAdapter.setHasStableIds(true); recyclerView.setAdapter(recyclerAdapter); } if(queue == null || queue.size() == 0) { @@ -607,7 +607,7 @@ public class QueueFragment extends Fragment { txtvEmpty.setVisibility(View.GONE); progLoading.setVisibility(View.VISIBLE); } - subscription = Observable.fromCallable(() -> DBReader.getQueue()) + subscription = Observable.fromCallable(DBReader::getQueue) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(items -> { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java index dbd18163c..510909379 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java @@ -208,7 +208,7 @@ public class SearchFragment extends ListFragment { if (viewCreated && !itemsLoaded) { setListShown(false); } - subscription = Observable.fromCallable(() -> performSearch()) + subscription = Observable.fromCallable(this::performSearch) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { 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 204f36956..15e9c9943 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 @@ -14,7 +14,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; import android.widget.Button; import android.widget.GridView; import android.widget.ProgressBar; @@ -84,18 +83,9 @@ public abstract class PodcastListFragment extends Fragment { txtvError = (TextView) root.findViewById(R.id.txtvError); butRetry = (Button) root.findViewById(R.id.butRetry); - gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position)); - } - }); - butRetry.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - loadData(); - } - }); + gridView.setOnItemClickListener((parent, view, position, id) -> + onPodcastSelected((GpodnetPodcast) gridView.getAdapter().getItem(position))); + butRetry.setOnClickListener(v -> loadData()); loadData(); return root; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SuggestionListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SuggestionListFragment.java index 133bb0281..1b1b61efb 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SuggestionListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SuggestionListFragment.java @@ -1,13 +1,13 @@ package de.danoeh.antennapod.fragment.gpodnet; +import java.util.Collections; +import java.util.List; + import de.danoeh.antennapod.core.gpoddernet.GpodnetService; import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetPodcast; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; -import java.util.ArrayList; -import java.util.List; - /** * Displays suggestions from gpodder.net */ @@ -20,7 +20,7 @@ public class SuggestionListFragment extends PodcastListFragment { service.authenticate(GpodnetPreferences.getUsername(), GpodnetPreferences.getPassword()); return service.getSuggestions(SUGGESTIONS_COUNT); } else { - return new ArrayList(); + return Collections.emptyList(); } } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java index 338f02e61..d2c7f32dd 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java @@ -11,7 +11,6 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.AdapterView; import android.widget.TextView; import java.util.List; @@ -65,13 +64,10 @@ public class TagListFragment extends ListFragment { 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) { - GpodnetTag tag = (GpodnetTag) getListAdapter().getItem(position); - MainActivity activity = (MainActivity) getActivity(); - activity.loadChildFragment(TagFragment.newInstance(tag)); - } + getListView().setOnItemClickListener((parent, view1, position, id) -> { + GpodnetTag tag = (GpodnetTag) getListAdapter().getItem(position); + MainActivity activity = (MainActivity) getActivity(); + activity.loadChildFragment(TagFragment.newInstance(tag)); }); startLoadTask(); diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java index 58fe8afbf..c1f94acc5 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java @@ -41,7 +41,7 @@ public class FeedItemMenuHandler { * menu-object and call setVisibility(visibility) on the returned * MenuItem object. */ - abstract void setItemVisibility(int id, boolean visible); + void setItemVisibility(int id, boolean visible); } /** @@ -98,7 +98,7 @@ public class FeedItemMenuHandler { mi.setItemVisibility(R.id.share_download_url_item, false); mi.setItemVisibility(R.id.share_download_url_with_position_item, false); } - if(false == hasMedia || selectedItem.getMedia().getPosition() <= 0) { + if(!hasMedia || selectedItem.getMedia().getPosition() <= 0) { mi.setItemVisibility(R.id.share_link_with_position_item, false); mi.setItemVisibility(R.id.share_download_url_with_position_item, false); } @@ -113,7 +113,7 @@ public class FeedItemMenuHandler { mi.setItemVisibility(R.id.reset_position, false); } - if(false == UserPreferences.isEnableAutodownload()) { + if(!UserPreferences.isEnableAutodownload()) { mi.setItemVisibility(R.id.activate_auto_download, false); mi.setItemVisibility(R.id.deactivate_auto_download, false); } else if(selectedItem.getAutoDownload()) { @@ -224,7 +224,7 @@ public class FeedItemMenuHandler { context.startActivity(intent); } else { Toast.makeText(context, context.getString(R.string.download_error_malformed_url), - Toast.LENGTH_SHORT); + Toast.LENGTH_SHORT).show(); } break; case R.id.support_item: diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java index 830e9d419..ab7d0e7c6 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java @@ -63,10 +63,10 @@ public class FeedMenuHandler { final Feed selectedFeed) throws DownloadRequestException { switch (item.getItemId()) { case R.id.refresh_item: - DBTasks.refreshFeed(context, selectedFeed); + DBTasks.forceRefreshFeed(context, selectedFeed); break; case R.id.refresh_complete_item: - DBTasks.refreshCompleteFeed(context, selectedFeed); + DBTasks.forceRefreshCompleteFeed(context, selectedFeed); break; case R.id.filter_items: showFilterDialog(context, selectedFeed); @@ -92,7 +92,7 @@ public class FeedMenuHandler { context.startActivity(intent); } else { Toast.makeText(context, context.getString(R.string.download_error_malformed_url), - Toast.LENGTH_SHORT); + Toast.LENGTH_SHORT).show(); } break; case R.id.support_item: diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java index 0d2ff8a75..4c28b197d 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/MenuItemUtils.java @@ -39,6 +39,7 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue); queueLock.setIcon(ta.getDrawable(1)); } + ta.recycle(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/NavDrawerActivity.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/NavDrawerActivity.java index 6ceaaada4..c973990c9 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/NavDrawerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/NavDrawerActivity.java @@ -5,5 +5,5 @@ package de.danoeh.antennapod.menuhandler; */ public interface NavDrawerActivity { - public boolean isDrawerOpen(); + boolean isDrawerOpen(); } diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java index 785944768..116272578 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -1,12 +1,14 @@ package de.danoeh.antennapod.preferences; +import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.app.TimePickerDialog; +import android.content.ActivityNotFoundException; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.Uri; import android.net.wifi.WifiConfiguration; @@ -18,6 +20,7 @@ import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; +import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.text.Editable; @@ -47,15 +50,18 @@ import de.danoeh.antennapod.activity.DirectoryChooserActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.activity.PreferenceActivityGingerbread; +import de.danoeh.antennapod.activity.StatisticsActivity; import de.danoeh.antennapod.asynctask.OpmlExportWorker; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.service.GpodnetSyncService; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.flattr.FlattrUtils; import de.danoeh.antennapod.dialog.AuthenticationDialog; import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog; import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog; +import de.danoeh.antennapod.dialog.ProxyDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; /** @@ -71,20 +77,31 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; public static final String PREF_AUTO_FLATTR_PREFS = "prefAutoFlattrPrefs"; public static final String PREF_OPML_EXPORT = "prefOpmlExport"; + public static final String STATISTICS = "statistics"; public static final String PREF_ABOUT = "prefAbout"; public static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; public static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings"; public static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher"; public static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate"; public static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information"; + public static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync"; public static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout"; public static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname"; public static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify"; + public static final String PREF_PROXY = "prefProxy"; + public static final String PREF_KNOWN_ISSUES = "prefKnownIssues"; + public static final String PREF_FAQ = "prefFaq"; + public static final String PREF_SEND_CRASH_REPORT = "prefSendCrashReport"; private final PreferenceUI ui; private CheckBoxPreference[] selectedNetworks; + private static final String[] EXTERNAL_STORAGE_PERMISSIONS = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE }; + private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 41; + public PreferenceController(PreferenceUI ui) { this.ui = ui; PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext()) @@ -121,104 +138,93 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc // disable expanded notification option on unsupported android versions ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setEnabled(false); ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - Toast toast = Toast.makeText(activity, R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT); - toast.show(); - return true; - } + preference -> { + Toast toast = Toast.makeText(activity, + R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT); + toast.show(); + return true; } ); } - ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - FlattrUtils.revokeAccessToken(activity); - checkItemVisibility(); - return true; - } - + preference -> { + FlattrUtils.revokeAccessToken(activity); + checkItemVisibility(); + return true; } ); - ui.findPreference(PreferenceController.PREF_ABOUT).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - activity.startActivity(new Intent( - activity, AboutActivity.class)); - return true; - } - + preference -> { + activity.startActivity(new Intent(activity, AboutActivity.class)); + return true; + } + ); + ui.findPreference(PreferenceController.STATISTICS).setOnPreferenceClickListener( + preference -> { + activity.startActivity(new Intent(activity, StatisticsActivity.class)); + return true; } ); - ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - new OpmlExportWorker(activity) - .executeAsync(); - - return true; + preference -> { + new OpmlExportWorker(activity).executeAsync(); + return true; + } + ); + ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener( + preference -> { + if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT && + Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { + showChooseDataFolderDialog(); + } else { + int readPermission = ActivityCompat.checkSelfPermission( + activity, Manifest.permission.READ_EXTERNAL_STORAGE); + int writePermission = ActivityCompat.checkSelfPermission( + activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (readPermission == PackageManager.PERMISSION_GRANTED && + writePermission == PackageManager.PERMISSION_GRANTED) { + openDirectoryChooser(); + } else { + requestPermission(); + } } + return true; } ); ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR) .setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - if (Build.VERSION.SDK_INT >= 19) { - showChooseDataFolderDialog(); - } else { - Intent intent = new Intent(activity, DirectoryChooserActivity.class); - activity.startActivityForResult(intent, - DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); - } - return true; + preference -> { + if (Build.VERSION.SDK_INT >= 19) { + showChooseDataFolderDialog(); + } else { + Intent intent = new Intent(activity, DirectoryChooserActivity.class); + activity.startActivityForResult(intent, + DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); } + return true; } ); ui.findPreference(UserPreferences.PREF_THEME) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - Intent i = new Intent(activity, MainActivity.class); - i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK - | Intent.FLAG_ACTIVITY_NEW_TASK); - activity.finish(); - activity.startActivity(i); - return true; - } + (preference, newValue) -> { + Intent i = new Intent(activity, MainActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK + | Intent.FLAG_ACTIVITY_NEW_TASK); + activity.finish(); + activity.startActivity(i); + return true; } ); ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS) - .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showDrawerPreferencesDialog(); - return true; - } + .setOnPreferenceClickListener(preference -> { + showDrawerPreferencesDialog(); + return true; }); ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL) - .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showUpdateIntervalTimePreferencesDialog(); - return true; - } + .setOnPreferenceClickListener(preference -> { + showUpdateIntervalTimePreferencesDialog(); + return true; }); ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener( @@ -234,38 +240,30 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc }); ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - if (newValue instanceof Boolean) { - setSelectedNetworksEnabled((Boolean) newValue); - return true; - } else { - return false; - } + (preference, newValue) -> { + if (newValue instanceof Boolean) { + setSelectedNetworksEnabled((Boolean) newValue); + return true; + } else { + return false; } } ); ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - if (o instanceof String) { - try { - int value = Integer.valueOf((String) o); - if (1 <= value && value <= 50) { - setParallelDownloadsText(value); - return true; - } - } catch (NumberFormatException e) { - return false; + (preference, o) -> { + if (o instanceof String) { + try { + int value = Integer.parseInt((String) o); + if (1 <= value && value <= 50) { + setParallelDownloadsText(value); + return true; } + } catch (NumberFormatException e) { + return false; } - return false; } + return false; } ); // validate and set correct value: number of downloads between 1 and 50 (inclusive) @@ -283,7 +281,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc public void afterTextChanged(Editable s) { if (s.length() > 0) { try { - int value = Integer.valueOf(s.toString()); + int value = Integer.parseInt(s.toString()); if (value <= 0) { ev.setText("1"); } else if (value > 50) { @@ -298,103 +296,101 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc }); ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - if (o instanceof String) { - setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); - } - return true; + (preference, o) -> { + if (o instanceof String) { + setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); } + return true; } ); ui.findPreference(PreferenceController.PREF_PLAYBACK_SPEED_LAUNCHER) - .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - VariableSpeedDialog.showDialog(activity); - return true; - } + .setOnPreferenceClickListener(preference -> { + VariableSpeedDialog.showDialog(activity); + return true; }); - ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - AuthenticationDialog dialog = new AuthenticationDialog(activity, - R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(), - null) { - - @Override - protected void onConfirmed(String username, String password, boolean saveUsernamePassword) { - GpodnetPreferences.setPassword(password); - } - }; - dialog.show(); - return true; - } - }); - ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - GpodnetPreferences.logout(); - Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT); - toast.show(); - updateGpodnetPreferenceScreen(); - return true; - } - }); - ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - updateGpodnetPreferenceScreen(); - } + ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION) + .setOnPreferenceClickListener(preference -> { + AuthenticationDialog dialog = new AuthenticationDialog(activity, + R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(), + null) { + + @Override + protected void onConfirmed(String username, String password, boolean saveUsernamePassword) { + GpodnetPreferences.setPassword(password); + } + }; + dialog.show(); + return true; + }); + ui.findPreference(PreferenceController.PREF_GPODNET_SYNC). + setOnPreferenceClickListener(preference -> { + GpodnetSyncService.sendSyncIntent(ui.getActivity().getApplicationContext()); + Toast toast = Toast.makeText(ui.getActivity(), R.string.pref_gpodnet_sync_started, + Toast.LENGTH_SHORT); + toast.show(); + return true; + }); + ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener( + preference -> { + GpodnetPreferences.logout(); + Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT); + toast.show(); + updateGpodnetPreferenceScreen(); + return true; + }); + ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener( + preference -> { + GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(dialog -> updateGpodnetPreferenceScreen()); + return true; }); - return true; - } - }); - ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - AutoFlattrPreferenceDialog.newAutoFlattrPreferenceDialog(activity, - new AutoFlattrPreferenceDialog.AutoFlattrPreferenceDialogInterface() { - @Override - public void onCancelled() { + ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS) + .setOnPreferenceClickListener(preference -> { + AutoFlattrPreferenceDialog.newAutoFlattrPreferenceDialog(activity, + new AutoFlattrPreferenceDialog.AutoFlattrPreferenceDialogInterface() { + @Override + public void onCancelled() { - } + } - @Override - public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue) { - UserPreferences.setAutoFlattrSettings(autoFlattrEnabled, autoFlattrValue); - checkItemVisibility(); - } - }); - return true; - } - }); - ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE) - .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - if (o instanceof String) { - int newValue = Integer.valueOf((String) o) * 1024 * 1024; - if (newValue != UserPreferences.getImageCacheSize()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); - dialog.setTitle(android.R.string.dialog_alert_title); - dialog.setMessage(R.string.pref_restart_required); - dialog.setPositiveButton(android.R.string.ok, null); - dialog.show(); - } - return true; + @Override + public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue) { + UserPreferences.setAutoFlattrSettings(autoFlattrEnabled, autoFlattrValue); + checkItemVisibility(); } - return false; - } + }); + return true; + }); + ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE).setOnPreferenceChangeListener( + (preference, o) -> { + if (o instanceof String) { + int newValue = Integer.parseInt((String) o) * 1024 * 1024; + if (newValue != UserPreferences.getImageCacheSize()) { + AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); + dialog.setTitle(android.R.string.dialog_alert_title); + dialog.setMessage(R.string.pref_restart_required); + dialog.setPositiveButton(android.R.string.ok, null); + dialog.show(); } - ); - ui.findPreference("prefSendCrashReport").setOnPreferenceClickListener(preference -> { + return true; + } + return false; + } + ); + ui.findPreference(PREF_PROXY).setOnPreferenceClickListener(preference -> { + ProxyDialog dialog = new ProxyDialog(ui.getActivity()); + dialog.createDialog().show(); + return true; + }); + ui.findPreference(PREF_KNOWN_ISSUES).setOnPreferenceClickListener(preference -> { + openInBrowser("https://github.com/AntennaPod/AntennaPod/labels/bug"); + return true; + }); + ui.findPreference(PREF_FAQ).setOnPreferenceClickListener(preference -> { + openInBrowser("http://antennapod.org/faq.html"); + return true; + }); + ui.findPreference(PREF_SEND_CRASH_REPORT).setOnPreferenceClickListener(preference -> { Intent emailIntent = new Intent(Intent.ACTION_SEND); emailIntent.setType("text/plain"); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"Martin.Fietz@gmail.com"}); @@ -412,6 +408,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); } + private void openInBrowser(String url) { + try { + Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + ui.getActivity().startActivity(myIntent); + } catch (ActivityNotFoundException e) { + Toast.makeText(ui.getActivity(), R.string.pref_no_browser_found, Toast.LENGTH_LONG).show(); + Log.e(TAG, Log.getStackTraceString(e)); + } + } + public void onResume() { checkItemVisibility(); setUpdateIntervalText(); @@ -427,7 +433,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); - File path = new File(dir); + File path; + if(dir != null) { + path = new File(dir); + } else { + path = ui.getActivity().getExternalFilesDir(null); + } String message = null; final Context context= ui.getActivity().getApplicationContext(); if(!path.exists()) { @@ -456,7 +467,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc final boolean loggedIn = GpodnetPreferences.loggedIn(); ui.findPreference(PreferenceController.PREF_GPODNET_LOGIN).setEnabled(!loggedIn); ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setEnabled(loggedIn); + ui.findPreference(PreferenceController.PREF_GPODNET_SYNC).setEnabled(loggedIn); ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setEnabled(loggedIn); + if(loggedIn) { + String format = ui.getActivity().getString(R.string.pref_gpodnet_login_status); + String summary = String.format(format, GpodnetPreferences.getUsername(), + GpodnetPreferences.getDeviceID()); + ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setSummary(Html.fromHtml(summary)); + } else { + ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setSummary(null); + } ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setSummary(GpodnetPreferences.getHostname()); } @@ -547,7 +567,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(autoDownload); setSelectedNetworksEnabled(autoDownload && UserPreferences.isEnableAutodownloadWifiFilter()); - ui.findPreference("prefSendCrashReport").setEnabled(CrashReportWriter.getFile().exists()); + ui.findPreference(PREF_SEND_CRASH_REPORT).setEnabled(CrashReportWriter.getFile().exists()); if (Build.VERSION.SDK_INT >= 16) { ui.findPreference(UserPreferences.PREF_SONIC).setEnabled(true); @@ -628,35 +648,31 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc List prefValues = Arrays.asList(UserPreferences .getAutodownloadSelectedNetworks()); PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); - Preference.OnPreferenceClickListener clickListener = new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - if (preference instanceof CheckBoxPreference) { - String key = preference.getKey(); - ArrayList prefValuesList = new ArrayList( - Arrays.asList(UserPreferences - .getAutodownloadSelectedNetworks()) - ); - boolean newValue = ((CheckBoxPreference) preference) - .isChecked(); - Log.d(TAG, "Selected network " + key + ". New state: " + newValue); - - int index = prefValuesList.indexOf(key); - if (index >= 0 && newValue == false) { - // remove network - prefValuesList.remove(index); - } else if (index < 0 && newValue == true) { - prefValuesList.add(key); - } - - UserPreferences.setAutodownloadSelectedNetworks( - prefValuesList.toArray(new String[prefValuesList.size()]) - ); - return true; - } else { - return false; + Preference.OnPreferenceClickListener clickListener = preference -> { + if (preference instanceof CheckBoxPreference) { + String key = preference.getKey(); + List prefValuesList = new ArrayList<>( + Arrays.asList(UserPreferences + .getAutodownloadSelectedNetworks()) + ); + boolean newValue = ((CheckBoxPreference) preference) + .isChecked(); + Log.d(TAG, "Selected network " + key + ". New state: " + newValue); + + int index = prefValuesList.indexOf(key); + if (index >= 0 && !newValue) { + // remove network + prefValuesList.remove(index); + } else if (index < 0 && newValue) { + prefValuesList.add(key); } + + UserPreferences.setAutodownloadSelectedNetworks( + prefValuesList.toArray(new String[prefValuesList.size()]) + ); + return true; + } else { + return false; } }; // create preference for each known network. attach listener and set @@ -683,9 +699,9 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc if (selectedNetworks != null) { PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); - for (int i = 0; i < selectedNetworks.length; i++) { - if (selectedNetworks[i] != null) { - prefScreen.removePreference(selectedNetworks[i]); + for (CheckBoxPreference network : selectedNetworks) { + if (network != null) { + prefScreen.removePreference(network); } } } @@ -703,7 +719,6 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc checked[i] = true; } } - AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(R.string.drawer_preferences); builder.setMultiChoiceItems(navTitles, checked, (dialog, which, isChecked) -> { @@ -713,16 +728,26 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]); } }); - builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - UserPreferences.setHiddenDrawerItems(hiddenDrawerItems); - } + builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { + UserPreferences.setHiddenDrawerItems(hiddenDrawerItems); }); builder.setNegativeButton(R.string.cancel_label, null); builder.create().show(); } + // CHOOSE DATA FOLDER + + private void requestPermission() { + ActivityCompat.requestPermissions(ui.getActivity(), EXTERNAL_STORAGE_PERMISSIONS, + PERMISSION_REQUEST_EXTERNAL_STORAGE); + } + + private void openDirectoryChooser() { + Activity activity = ui.getActivity(); + Intent intent = new Intent(activity, DirectoryChooserActivity.class); + activity.startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); + } + private void showChooseDataFolderDialog() { Context context = ui.getActivity(); File dataFolder = UserPreferences.getDataFolder(null); @@ -786,6 +811,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc dialog.show(); } + // UPDATE TIME/INTERVAL DIALOG + private void showUpdateIntervalTimePreferencesDialog() { final Context context = ui.getActivity(); @@ -795,38 +822,34 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc builder.positiveText(R.string.pref_autoUpdateIntervallOrTime_Interval); builder.negativeText(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay); builder.neutralText(R.string.pref_autoUpdateIntervallOrTime_Disable); - builder.callback(new MaterialDialog.ButtonCallback() { - @Override - public void onPositive(MaterialDialog dialog) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval)); - final String[] values = context.getResources().getStringArray(R.array.update_intervall_values); - final String[] entries = getUpdateIntervalEntries(values); - long currInterval = UserPreferences.getUpdateInterval(); - int checkedItem = -1; - if(currInterval > 0) { - String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval)); - checkedItem = ArrayUtils.indexOf(values, currIntervalStr); - } - builder.setSingleChoiceItems(entries, checkedItem, (dialog1, which) -> { - int hours = Integer.valueOf(values[which]); - UserPreferences.setUpdateInterval(hours); - dialog1.dismiss(); - setUpdateIntervalText(); - }); - builder.setNegativeButton(context.getString(R.string.cancel_label), null); - builder.show(); + builder.onPositive((dialog, which) -> { + AlertDialog.Builder builder1 = new AlertDialog.Builder(context); + builder1.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval)); + final String[] values = context.getResources().getStringArray(R.array.update_intervall_values); + final String[] entries = getUpdateIntervalEntries(values); + long currInterval = UserPreferences.getUpdateInterval(); + int checkedItem = -1; + if(currInterval > 0) { + String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval)); + checkedItem = ArrayUtils.indexOf(values, currIntervalStr); } - - @Override - public void onNegative(MaterialDialog dialog) { - int hourOfDay = 7, minute = 0; - int[] updateTime = UserPreferences.getUpdateTimeOfDay(); - if (updateTime.length == 2) { - hourOfDay = updateTime[0]; - minute = updateTime[1]; - } - TimePickerDialog timePickerDialog = new TimePickerDialog(context, + builder1.setSingleChoiceItems(entries, checkedItem, (dialog1, which1) -> { + int hours = Integer.parseInt(values[which1]); + UserPreferences.setUpdateInterval(hours); + dialog1.dismiss(); + setUpdateIntervalText(); + }); + builder1.setNegativeButton(context.getString(R.string.cancel_label), null); + builder1.show(); + }); + builder.onNegative((dialog, which) -> { + int hourOfDay = 7, minute = 0; + int[] updateTime = UserPreferences.getUpdateTimeOfDay(); + if (updateTime.length == 2) { + hourOfDay = updateTime[0]; + minute = updateTime[1]; + } + TimePickerDialog timePickerDialog = new TimePickerDialog(context, (view, selectedHourOfDay, selectedMinute) -> { if (view.getTag() == null) { // onTimeSet() may get called twice! view.setTag("TAGGED"); @@ -834,17 +857,13 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc setUpdateIntervalText(); } }, hourOfDay, minute, DateFormat.is24HourFormat(context)); - timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay)); - timePickerDialog.show(); - } - - @Override - public void onNeutral(MaterialDialog dialog) { - UserPreferences.setUpdateInterval(0); - setUpdateIntervalText(); - } + timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay)); + timePickerDialog.show(); + }); + builder.onNeutral((dialog, which) -> { + UserPreferences.setUpdateInterval(0); + setUpdateIntervalText(); }); - builder.forceStacking(true); builder.show(); } diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java b/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java index 665ddc3b5..1075117dd 100644 --- a/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java +++ b/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java @@ -8,6 +8,7 @@ import android.net.NetworkInfo; import android.text.TextUtils; import android.util.Log; +import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.NetworkUtils; @@ -20,7 +21,8 @@ public class ConnectivityActionReceiver extends BroadcastReceiver { if (TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) { Log.d(TAG, "Received intent"); - if (NetworkUtils.autodownloadNetworkAvailable()) { + ClientConfig.initialize(context); + if (NetworkUtils.autodownloadNetworkAvailable()) { Log.d(TAG, "auto-dl network available, starting auto-download"); DBTasks.autodownloadUndownloadedItems(context); } else { // if new network is Wi-Fi, finish ongoing downloads, diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/PlayerWidget.java b/app/src/main/java/de/danoeh/antennapod/receiver/PlayerWidget.java index 7000827c6..f0d4014ed 100644 --- a/app/src/main/java/de/danoeh/antennapod/receiver/PlayerWidget.java +++ b/app/src/main/java/de/danoeh/antennapod/receiver/PlayerWidget.java @@ -1,5 +1,7 @@ package de.danoeh.antennapod.receiver; +import java.util.Arrays; + import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; @@ -44,14 +46,14 @@ public class PlayerWidget extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + appWidgetManager + "], appWidgetIds = [" + appWidgetIds + "]"); + Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + appWidgetManager + "], appWidgetIds = [" + Arrays.toString(appWidgetIds) + "]"); startUpdate(context); } @Override public void onDisabled(Context context) { super.onDisabled(context); - Log.d(TAG, "Widet disabled"); + Log.d(TAG, "Widget disabled"); setEnabled(context, false); stopUpdate(context); } diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java b/app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java index f050e031d..339a4f0f7 100644 --- a/app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java +++ b/app/src/main/java/de/danoeh/antennapod/receiver/PowerConnectionReceiver.java @@ -3,10 +3,9 @@ package de.danoeh.antennapod.receiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.BatteryManager; import android.util.Log; -import de.danoeh.antennapod.core.BuildConfig; +import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DownloadRequester; @@ -25,6 +24,7 @@ public class PowerConnectionReceiver extends BroadcastReceiver { Log.d(TAG, "charging intent: " + action); + ClientConfig.initialize(context); if (Intent.ACTION_POWER_CONNECTED.equals(action)) { Log.d(TAG, "charging, starting auto-download"); // we're plugged in, this is a great time to auto-download if everything else is diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java b/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java index ef6330f82..a373c5353 100644 --- a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java +++ b/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java @@ -8,10 +8,9 @@ import android.util.Log; import android.widget.Toast; import java.util.Arrays; -import java.util.Date; -import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.ClientConfig; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; @@ -28,29 +27,30 @@ public class SPAReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { - if (TextUtils.equals(intent.getAction(), ACTION_SP_APPS_QUERY_FEEDS_REPSONSE)) { - if (BuildConfig.DEBUG) Log.d(TAG, "Received SP_APPS_QUERY_RESPONSE"); - if (intent.hasExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA)) { - String[] feedUrls = intent.getStringArrayExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA); - if (feedUrls != null) { - if (BuildConfig.DEBUG) Log.d(TAG, "Received feeds list: " + Arrays.toString(feedUrls)); - for (String url : feedUrls) { - Feed f = new Feed(url, new Date(0)); - try { - DownloadRequester.getInstance().downloadFeed(context, f); - } catch (DownloadRequestException e) { - Log.e(TAG, "Error while trying to add feed " + url); - e.printStackTrace(); - } - } - Toast.makeText(context, R.string.sp_apps_importing_feeds_msg, Toast.LENGTH_LONG).show(); - - } else { - Log.e(TAG, "Received invalid SP_APPS_QUERY_REPSONSE: extra was null"); - } - } else { - Log.e(TAG, "Received invalid SP_APPS_QUERY_RESPONSE: Contains no extra"); + if (!TextUtils.equals(intent.getAction(), ACTION_SP_APPS_QUERY_FEEDS_REPSONSE)) { + return; + } + Log.d(TAG, "Received SP_APPS_QUERY_RESPONSE"); + if (!intent.hasExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA)) { + Log.e(TAG, "Received invalid SP_APPS_QUERY_RESPONSE: Contains no extra"); + return; + } + String[] feedUrls = intent.getStringArrayExtra(ACTION_SP_APPS_QUERY_FEEDS_REPSONSE_FEEDS_EXTRA); + if (feedUrls == null) { + Log.e(TAG, "Received invalid SP_APPS_QUERY_REPSONSE: extra was null"); + return; + } + Log.d(TAG, "Received feeds list: " + Arrays.toString(feedUrls)); + ClientConfig.initialize(context); + for (String url : feedUrls) { + Feed f = new Feed(url, null); + try { + DownloadRequester.getInstance().downloadFeed(context, f); + } catch (DownloadRequestException e) { + Log.e(TAG, "Error while trying to add feed " + url); + e.printStackTrace(); } } + Toast.makeText(context, R.string.sp_apps_importing_feeds_msg, Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java b/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java deleted file mode 100644 index bb0573e72..000000000 --- a/app/src/main/java/de/danoeh/antennapod/utils/TimeUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -package de.danoeh.antennapod.utils; - - -import android.content.Context; - -import java.util.Date; - -import de.danoeh.antennapod.R; - -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//http://stackoverflow.com/questions/13018550/time-since-ago-library-for-android-java - - -public class TimeUtils { - private static final int SECOND_MILLIS = 1000; - private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS; - private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS; - private static final int DAY_MILLIS = 24 * HOUR_MILLIS; - - - public static String getTimeAgo(long time, Context ctx) { - if (time < 1000000000000L) { - // if timestamp given in seconds, convert to millis - time *= 1000; - } - - long now = new Date().getTime(); - if (time > now || time <= 0) { - return null; - } - - final long diff = now - time; - if (diff < MINUTE_MILLIS) { - return ctx.getString(R.string.time_just_now); - } else if (diff < 2 * MINUTE_MILLIS) { - return ctx.getString(R.string.time_a_min_ago); - } else if (diff < 50 * MINUTE_MILLIS) { - return diff / MINUTE_MILLIS + ctx.getString(R.string.time_min_ago); - } else if (diff < 90 * MINUTE_MILLIS) { - return ctx.getString(R.string.time_an_hour_ago); - } else if (diff < 24 * HOUR_MILLIS) { - return diff / HOUR_MILLIS + ctx.getString(R.string.time_hours_ago); - } else if (diff < 48 * HOUR_MILLIS) { - return ctx.getString(R.string.time_yesterday); - } else { - return diff / DAY_MILLIS + ctx.getString(R.string.time_days_ago); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java index 7703554f9..67973a7ef 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java +++ b/app/src/main/java/de/danoeh/antennapod/view/SubscriptionViewItem.java @@ -24,7 +24,6 @@ public class SubscriptionViewItem extends RelativeLayout { private ImageView mImageView; private TextView mTextTime; - private TextView mUnreadCountText; private TextView mFeedTitle; private Context mContext; @@ -56,7 +55,6 @@ public class SubscriptionViewItem extends RelativeLayout { mTextTime = (TextView) view.findViewById(R.id.txtvTime); mFeedTitle = (TextView) view.findViewById(R.id.txtvTitle); mImageView = (ImageView) view.findViewById(R.id.imgvCover); - mUnreadCountText = (TextView) view.findViewById(R.id.unread_count_text); } public void setFeed(Feed feed) { @@ -78,12 +76,8 @@ public class SubscriptionViewItem extends RelativeLayout { }) .centerCrop() .into(mImageView); - // Removing the updated time. It could be the latest podcast updated time in the future. - //mTextTime.setText(TimeUtils.getTimeAgo(feed.getLastUpdate().getTime(), mContext)); - mTextTime.setVisibility(GONE); - // Could be the count of unread/ not played feed items - //mUnreadCountText.setText(String.valueOf(feed.getNumOfItems())); + mTextTime.setVisibility(GONE); } } -- cgit v1.2.3