diff options
author | Tom Hennen <TomHennen@users.noreply.github.com> | 2015-12-10 21:08:49 -0500 |
---|---|---|
committer | Tom Hennen <TomHennen@users.noreply.github.com> | 2015-12-10 21:08:49 -0500 |
commit | e021e78c81c3f162b9a60ed2f3ce4c43a2e0613a (patch) | |
tree | 9e7bed559c8d83eedd09d8e1cb4df707ef892121 /app/src/main/java | |
parent | 212bef11414cda7af816cbb6753710c9561841a1 (diff) | |
parent | c0f15653d4d986e83167402807db27e0b8a121ed (diff) | |
download | AntennaPod-e021e78c81c3f162b9a60ed2f3ce4c43a2e0613a.zip |
Merge pull request #1457 from AntennaPod/develop1.4.1.4
1.4.1 now in production
Diffstat (limited to 'app/src/main/java')
31 files changed, 855 insertions, 552 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java b/app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java new file mode 100644 index 000000000..17942a93c --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java @@ -0,0 +1,49 @@ +package de.danoeh.antennapod; + +import android.os.Build; +import android.util.Log; + +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +import de.danoeh.antennapod.core.preferences.UserPreferences; + +public class CrashReportWriter implements Thread.UncaughtExceptionHandler { + + private static final String TAG = "CrashReportWriter"; + + private final Thread.UncaughtExceptionHandler defaultHandler; + + public CrashReportWriter() { + defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + } + + public static File getFile() { + return new File(UserPreferences.getDataFolder(null), "crash-report.log"); + } + + @Override + public void uncaughtException(Thread thread, Throwable ex) { + File path = getFile(); + PrintWriter out = null; + try { + out = new PrintWriter(new FileWriter(path)); + out.println("[ Environment ]"); + out.println("Android version: " + Build.VERSION.RELEASE); + out.println("AntennaPod version: " + BuildConfig.VERSION_NAME); + out.println("Phone model: " + Build.MODEL); + out.println(); + out.println("[ StackTrace ]"); + ex.printStackTrace(out); + } catch (IOException e) { + Log.e(TAG, Log.getStackTraceString(e)); + } finally { + IOUtils.closeQuietly(out); + } + defaultHandler.uncaughtException(thread, ex); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java index 83bc9afb2..835f43f40 100644 --- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java +++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod; import android.app.Application; -import android.content.res.Configuration; import android.os.Build; import android.os.StrictMode; @@ -27,10 +26,6 @@ public class PodcastApp extends Application { } } - private static final String TAG = "PodcastApp"; - - private static float LOGICAL_DENSITY; - private static PodcastApp singleton; public static PodcastApp getInstance() { @@ -41,6 +36,8 @@ public class PodcastApp extends Application { public void onCreate() { super.onCreate(); + Thread.setDefaultUncaughtExceptionHandler(new CrashReportWriter()); + if(BuildConfig.DEBUG) { StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() @@ -57,7 +54,6 @@ public class PodcastApp extends Application { } singleton = this; - LOGICAL_DENSITY = getResources().getDisplayMetrics().density; PodDBAdapter.init(this); UpdateManager.init(this); @@ -68,15 +64,6 @@ public class PodcastApp extends Application { Iconify.with(new FontAwesomeModule()); SPAUtil.sendSPAppsQueryFeedsIntent(this); - } - - public static float getLogicalDensity() { - return LOGICAL_DENSITY; - } - - public boolean isLargeScreen() { - return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE - || (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; + } - } } 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 b87870c69..220724af4 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java @@ -13,6 +13,7 @@ import android.support.v4.app.ListFragment; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.widget.Toolbar; +import android.text.TextUtils; import android.util.Log; import android.view.ContextMenu; import android.view.Gravity; @@ -35,7 +36,6 @@ import android.widget.TextView; import com.bumptech.glide.Glide; import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.ChapterListAdapter; @@ -246,7 +246,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc @Override protected void onResume() { super.onResume(); - if (StringUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { + if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { Intent intent = getIntent(); Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath()); ExternalMedia media = new ExternalMedia(intent.getData().getPath(), @@ -772,7 +772,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc private DBReader.NavDrawerData navDrawerData; private void loadData() { - subscription = Observable.defer(() -> Observable.just(DBReader.getNavDrawerData())) + subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { 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 6915c817b..211b895d0 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -8,6 +8,7 @@ import android.content.SharedPreferences; import android.content.res.Configuration; import android.database.DataSetObserver; import android.media.AudioManager; +import android.media.Rating; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; @@ -41,10 +42,9 @@ import de.danoeh.antennapod.adapter.NavListAdapter; import de.danoeh.antennapod.core.asynctask.FeedRemover; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.event.ProgressEvent; +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.event.QueueEvent; -import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; @@ -54,6 +54,7 @@ import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.dialog.RatingDialog; import de.danoeh.antennapod.fragment.AddFeedFragment; import de.danoeh.antennapod.fragment.DownloadsFragment; import de.danoeh.antennapod.fragment.EpisodesFragment; @@ -76,9 +77,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity private static final String TAG = "MainActivity"; - private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED - | EventDistributor.DOWNLOAD_QUEUED - | EventDistributor.FEED_LIST_UPDATE + private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE | EventDistributor.UNREAD_ITEMS_UPDATE; public static final String PREF_NAME = "MainActivityPrefs"; @@ -452,6 +451,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity super.onStart(); EventDistributor.getInstance().register(contentUpdate); EventBus.getDefault().register(this); + RatingDialog.init(this); } @Override @@ -469,8 +469,8 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity (intent.hasExtra(EXTRA_NAV_INDEX) || intent.hasExtra(EXTRA_FRAGMENT_TAG))) { handleNavIntent(); } - loadData(); + RatingDialog.check(); } @Override @@ -639,7 +639,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity }; private void loadData() { - subscription = Observable.defer(() -> Observable.just(DBReader.getNavDrawerData())) + subscription = Observable.fromCallable(() -> DBReader.getNavDrawerData()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { 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 c67d65a9d..8c2b7f838 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -9,6 +9,7 @@ import android.os.Looper; import android.support.v4.app.NavUtils; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AlertDialog; +import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; @@ -41,6 +42,7 @@ import java.util.Map; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.FeedItemlistDescriptionAdapter; import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; +import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; @@ -63,6 +65,7 @@ import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.URLChecker; import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer; import de.danoeh.antennapod.dialog.AuthenticationDialog; +import de.greenrobot.event.EventBus; import rx.Observable; import rx.Subscriber; import rx.Subscription; @@ -86,7 +89,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity { // Optional argument: specify a title for the actionbar. public static final String ARG_TITLE = "title"; - private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | EventDistributor.DOWNLOAD_QUEUED | EventDistributor.FEED_LIST_UPDATE; + private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE; public static final int RESULT_ERROR = 2; @@ -105,11 +108,16 @@ public class OnlineFeedViewActivity extends ActionBarActivity { private Subscription parser; private Subscription updater; + public void onEventMainThread(DownloadEvent event) { + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + setSubscribeButtonState(feed); + } + private EventDistributor.EventListener listener = new EventDistributor.EventListener() { @Override public void update(EventDistributor eventDistributor, Integer arg) { if ((arg & EventDistributor.FEED_LIST_UPDATE) != 0) { - updater = Observable.defer(() -> Observable.just(DBReader.getFeedList())) + updater = Observable.fromCallable(() -> DBReader.getFeedList()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(feeds -> { @@ -138,9 +146,9 @@ public class OnlineFeedViewActivity extends ActionBarActivity { final String feedUrl; if (getIntent().hasExtra(ARG_FEEDURL)) { feedUrl = getIntent().getStringExtra(ARG_FEEDURL); - } else if (StringUtils.equals(getIntent().getAction(), Intent.ACTION_SEND) - || StringUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { - feedUrl = (StringUtils.equals(getIntent().getAction(), Intent.ACTION_SEND)) + } else if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND) + || TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { + feedUrl = (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND)) ? getIntent().getStringExtra(Intent.EXTRA_TEXT) : getIntent().getDataString(); getSupportActionBar().setTitle(R.string.add_new_feed_label); } else { @@ -180,7 +188,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity { super.onResume(); isPaused = false; EventDistributor.getInstance().register(listener); - + EventBus.getDefault().register(this); } @Override @@ -188,6 +196,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity { super.onPause(); isPaused = true; EventDistributor.getInstance().unregister(listener); + EventBus.getDefault().unregister(this); } @Override @@ -314,7 +323,7 @@ public class OnlineFeedViewActivity extends ActionBarActivity { subscriber.onNext(result); } catch (UnsupportedFeedtypeException e) { Log.d(TAG, "Unsupported feed type detected"); - if (StringUtils.equalsIgnoreCase("html", e.getRootElement())) { + if (TextUtils.equals("html", e.getRootElement().toLowerCase())) { showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url()); } else { subscriber.onError(e); 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 173bec6b2..7f975b3c8 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java @@ -6,10 +6,9 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; +import android.text.TextUtils; import android.util.Log; -import org.apache.commons.lang3.StringUtils; - import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -57,7 +56,7 @@ public class StorageErrorActivity extends ActionBarActivity { @Override public void onReceive(Context context, Intent intent) { - if (StringUtils.equals(intent.getAction(), Intent.ACTION_MEDIA_MOUNTED)) { + 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"); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java index 74cf6af60..1a8f0a67a 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java @@ -7,14 +7,10 @@ import android.widget.ImageButton; import org.apache.commons.lang3.Validate; -import java.lang.ref.WeakReference; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DownloadRequester; -import de.danoeh.antennapod.core.util.LongList; /** * Utility methods for the action button that is displayed on the right hand side @@ -51,7 +47,7 @@ public class ActionButtonUtils { * Sets the displayed bitmap and content description of the given * action button so that it matches the state of the FeedItem. */ - public void configureActionButton(ImageButton butSecondary, FeedItem item) { + public void configureActionButton(ImageButton butSecondary, FeedItem item, boolean isInQueue) { Validate.isTrue(butSecondary != null && item != null, "butSecondary or item was null"); final FeedMedia media = item.getMedia(); @@ -66,9 +62,8 @@ public class ActionButtonUtils { butSecondary.setContentDescription(context.getString(labels[1])); } else { // item is not downloaded and not being downloaded - LongList queueIds = DBReader.getQueueIDList(); if(DefaultActionButtonCallback.userAllowedMobileDownloads() || - !DefaultActionButtonCallback.userChoseAddToQueue() || queueIds.contains(item.getId())) { + !DefaultActionButtonCallback.userChoseAddToQueue() || isInQueue) { butSecondary.setVisibility(View.VISIBLE); butSecondary.setImageDrawable(drawables.getDrawable(2)); butSecondary.setContentDescription(context.getString(labels[2])); 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 b35ff0aa9..f120aa1d5 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java @@ -1,22 +1,21 @@ package de.danoeh.antennapod.adapter; -import android.content.Context; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.text.format.DateUtils; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; -import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; @@ -34,7 +33,7 @@ import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.glide.ApGlideSettings; -import de.danoeh.antennapod.core.storage.DownloadRequestException; +import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.NetworkUtils; @@ -48,27 +47,34 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR private static final String TAG = AllEpisodesRecycleAdapter.class.getSimpleName(); - private final Context context; + private final WeakReference<MainActivity> mainActivityRef; private final ItemAccess itemAccess; private final ActionButtonCallback actionButtonCallback; private final ActionButtonUtils actionButtonUtils; private final boolean showOnlyNewEpisodes; - private final WeakReference<MainActivity> mainActivityRef; private int position = -1; - public AllEpisodesRecycleAdapter(Context context, - MainActivity mainActivity, + private final int playingBackGroundColor; + private final int normalBackGroundColor; + + public AllEpisodesRecycleAdapter(MainActivity mainActivity, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback, boolean showOnlyNewEpisodes) { super(); this.mainActivityRef = new WeakReference<>(mainActivity); - this.context = context; this.itemAccess = itemAccess; - this.actionButtonUtils = new ActionButtonUtils(context); + this.actionButtonUtils = new ActionButtonUtils(mainActivity); this.actionButtonCallback = actionButtonCallback; this.showOnlyNewEpisodes = showOnlyNewEpisodes; + + if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { + playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_dark); + } else { + playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_light); + } + normalBackGroundColor = mainActivity.getResources().getColor(android.R.color.transparent); } @Override @@ -76,6 +82,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.new_episodes_listitem, parent, false); Holder holder = new Holder(view); + holder.container = (FrameLayout) view.findViewById(R.id.container); holder.placeholder = (TextView) view.findViewById(R.id.txtvPlaceholder); holder.title = (TextView) view.findViewById(R.id.txtvTitle); holder.pubDate = (TextView) view @@ -111,7 +118,8 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR holder.placeholder.setVisibility(View.VISIBLE); holder.placeholder.setText(item.getFeed().getTitle()); holder.title.setText(item.getTitle()); - holder.pubDate.setText(DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL)); + holder.pubDate.setText(DateUtils.formatDateTime(mainActivityRef.get(), + item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL)); if (showOnlyNewEpisodes || false == item.isNew()) { holder.statusUnread.setVisibility(View.INVISIBLE); } else { @@ -161,23 +169,29 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR holder.progress.setVisibility(View.GONE); } + if(media.isCurrentlyPlaying()) { + holder.container.setBackgroundColor(playingBackGroundColor); + } else { + holder.container.setBackgroundColor(normalBackGroundColor); + } } else { holder.progress.setVisibility(View.GONE); holder.txtvDuration.setVisibility(View.GONE); } - if (itemAccess.isInQueue(item)) { + boolean isInQueue = itemAccess.isInQueue(item); + if (isInQueue) { holder.queueStatus.setVisibility(View.VISIBLE); } else { holder.queueStatus.setVisibility(View.INVISIBLE); } - actionButtonUtils.configureActionButton(holder.butSecondary, item); + actionButtonUtils.configureActionButton(holder.butSecondary, item, isInQueue); holder.butSecondary.setFocusable(false); holder.butSecondary.setTag(item); holder.butSecondary.setOnClickListener(secondaryActionListener); - Glide.with(context) + Glide.with(mainActivityRef.get()) .load(item.getImageUri()) .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) .fitCenter() @@ -224,7 +238,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR TextView txtvPlaceholder = placeholder.get(); ImageView imgvCover = cover.get(); if(fallbackUri != null && txtvPlaceholder != null && imgvCover != null) { - Glide.with(context) + Glide.with(mainActivityRef.get()) .load(fallbackUri) .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) .fitCenter() @@ -255,6 +269,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR implements View.OnClickListener, View.OnCreateContextMenuListener, ItemTouchHelperViewHolder { + FrameLayout container; TextView placeholder; TextView title; TextView pubDate; 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 4ccff39af..9d7a509cf 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java @@ -7,11 +7,11 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; -import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.joanzapata.iconify.Iconify; +import com.joanzapata.iconify.widget.IconButton; import java.util.Date; @@ -50,7 +50,7 @@ public class DownloadLogAdapter extends BaseAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.downloadlog_item, parent, false); holder.icon = (TextView) convertView.findViewById(R.id.txtvIcon); - holder.retry = (Button) convertView.findViewById(R.id.btnRetry); + holder.retry = (IconButton) convertView.findViewById(R.id.btnRetry); holder.date = (TextView) convertView.findViewById(R.id.txtvDate); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); holder.type = (TextView) convertView.findViewById(R.id.txtvType); @@ -96,8 +96,6 @@ public class DownloadLogAdapter extends BaseAdapter { if(status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE && !newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) { holder.retry.setVisibility(View.VISIBLE); - holder.retry.setText("{fa-repeat}"); - Iconify.addIcons(holder.retry); holder.retry.setOnClickListener(clickListener); ButtonHolder btnHolder; if(holder.retry.getTag() != null) { @@ -161,7 +159,7 @@ public class DownloadLogAdapter extends BaseAdapter { static class Holder { TextView icon; - Button retry; + IconButton retry; TextView title; TextView type; TextView date; 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 507d1adbc..1972e675e 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java @@ -11,6 +11,7 @@ import android.widget.Adapter; import android.widget.BaseAdapter; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; @@ -39,6 +40,9 @@ public class FeedItemlistAdapter extends BaseAdapter { public static final int SELECTION_NONE = -1; + private final int playingBackGroundColor; + private final int normalBackGroundColor; + public FeedItemlistAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback callback, @@ -52,6 +56,9 @@ public class FeedItemlistAdapter extends BaseAdapter { this.selectedItemIndex = SELECTION_NONE; this.actionButtonUtils = new ActionButtonUtils(context); this.makePlayedItemsTransparent = makePlayedItemsTransparent; + + playingBackGroundColor = context.getResources().getColor(R.color.highlight_light); + normalBackGroundColor = context.getResources().getColor(android.R.color.transparent); } @Override @@ -80,6 +87,8 @@ public class FeedItemlistAdapter extends BaseAdapter { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.feeditemlist_item, parent, false); + holder.container = (LinearLayout) convertView + .findViewById(R.id.container); holder.title = (TextView) convertView .findViewById(R.id.txtvItemname); holder.lenSize = (TextView) convertView @@ -174,9 +183,18 @@ public class FeedItemlistAdapter extends BaseAdapter { holder.type.setImageBitmap(null); holder.type.setVisibility(View.GONE); } + + if(media.isCurrentlyPlaying()) { + if(media.isCurrentlyPlaying()) { + holder.container.setBackgroundColor(playingBackGroundColor); + } else { + holder.container.setBackgroundColor(normalBackGroundColor); + } + } } - actionButtonUtils.configureActionButton(holder.butAction, item); + boolean isInQueue = itemAccess.isInQueue(item); + actionButtonUtils.configureActionButton(holder.butAction, item, isInQueue); holder.butAction.setFocusable(false); holder.butAction.setTag(item); holder.butAction.setOnClickListener(butActionListener); @@ -196,6 +214,7 @@ public class FeedItemlistAdapter extends BaseAdapter { }; static class Holder { + LinearLayout container; TextView title; TextView published; TextView lenSize; 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 8593e0dde..3e4dd4deb 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java @@ -4,19 +4,18 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.support.annotation.Nullable; import android.support.v4.view.MotionEventCompat; -import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.text.format.DateUtils; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; -import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ProgressBar; @@ -37,7 +36,6 @@ import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.LongList; @@ -62,6 +60,9 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap private FeedItem selectedItem; + private final int playingBackGroundColor; + private final int normalBackGroundColor; + public QueueRecyclerAdapter(MainActivity mainActivity, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback, @@ -73,6 +74,13 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap this.actionButtonCallback = actionButtonCallback; this.itemTouchHelper = itemTouchHelper; locked = UserPreferences.isQueueLocked(); + + if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { + playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_dark); + } else { + playingBackGroundColor = mainActivity.getResources().getColor(R.color.highlight_light); + } + normalBackGroundColor = mainActivity.getResources().getColor(android.R.color.transparent); } public void setLocked(boolean locked) { @@ -108,6 +116,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap View.OnCreateContextMenuListener, ItemTouchHelperViewHolder { + private final FrameLayout container; private final ImageView dragHandle; private final TextView placeholder; private final ImageView cover; @@ -122,6 +131,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap public ViewHolder(View v) { super(v); + container = (FrameLayout) v.findViewById(R.id.container); dragHandle = (ImageView) v.findViewById(R.id.drag_handle); placeholder = (TextView) v.findViewById(R.id.txtvPlaceholder); cover = (ImageView) v.findViewById(R.id.imgvCover); @@ -249,9 +259,15 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap progressRight.setText(Converter.getDurationStringLong(media.getDuration())); progressBar.setVisibility(View.GONE); } + + if(media.isCurrentlyPlaying()) { + container.setBackgroundColor(playingBackGroundColor); + } else { + container.setBackgroundColor(normalBackGroundColor); + } } - actionButtonUtils.configureActionButton(butSecondary, item); + actionButtonUtils.configureActionButton(butSecondary, item, true); butSecondary.setFocusable(false); butSecondary.setTag(item); butSecondary.setOnClickListener(secondaryActionListener); @@ -264,7 +280,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap .into(new CoverTarget(item.getFeed().getImageUri(), placeholder, cover)); } - } 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 3940eb8b6..5c24c2822 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlExportWorker.java @@ -49,7 +49,7 @@ public class OpmlExportWorker extends AsyncTask<Void, Void, Void> { OpmlWriter opmlWriter = new OpmlWriter(); if (output == null) { output = new File( - UserPreferences.getDataFolder(context, EXPORT_DIR), + UserPreferences.getDataFolder(EXPORT_DIR), DEFAULT_OUTPUT_NAME); if (output.exists()) { Log.w(TAG, "Overwriting previously exported file."); 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 c5b6ddb65..e867540e4 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java @@ -11,7 +11,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; @@ -23,7 +22,6 @@ import com.joanzapata.iconify.fonts.FontAwesomeIcons; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,9 +56,15 @@ public class EpisodesApplyActionFragment extends Fragment { private int textColor; - public EpisodesApplyActionFragment(List<FeedItem> episodes) { - this.episodes = episodes; - this.idMap = new HashMap<>(episodes.size()); + public EpisodesApplyActionFragment() { + this.episodes = new ArrayList<>(); + this.idMap = new HashMap<>(); + } + + public void setEpisodes(List<FeedItem> episodes) { + this.episodes.clear(); + this.episodes.addAll(episodes); + this.idMap.clear(); for(FeedItem episode : episodes) { this.idMap.put(episode.getId(), episode); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java new file mode 100644 index 000000000..ed0db92a4 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/RatingDialog.java @@ -0,0 +1,136 @@ +package de.danoeh.antennapod.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.support.annotation.Nullable; +import android.util.Log; + +import com.afollestad.materialdialogs.MaterialDialog; + +import java.lang.ref.WeakReference; +import java.util.concurrent.TimeUnit; + +import de.danoeh.antennapod.R; + +public class RatingDialog { + + private static final String TAG = RatingDialog.class.getSimpleName(); + private static final int AFTER_DAYS = 7; + + private static WeakReference<Context> mContext; + private static SharedPreferences mPreferences; + private static Dialog mDialog; + + private static final String PREFS_NAME = "RatingPrefs"; + private static final String KEY_RATED = "KEY_WAS_RATED"; + private static final String KEY_FIRST_START_DATE = "KEY_FIRST_HIT_DATE"; + + public static void init(Context context) { + mContext = new WeakReference<>(context); + mPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + + long firstDate = mPreferences.getLong(KEY_FIRST_START_DATE, 0); + if (firstDate == 0) { + resetStartDate(); + } + } + + public static void check() { + if (mDialog != null && mDialog.isShowing()) { + return; + } + if (shouldShow()) { + try { + mDialog = createDialog(); + if (mDialog != null) { + mDialog.show(); + } + } catch (Exception e) { + Log.e(TAG, Log.getStackTraceString(e)); + } + } + } + + public static void rateNow() { + Context context = mContext.get(); + if(context == null) { + return; + } + final String appPackage = "de.danoeh.antennapod"; + final Uri uri = Uri.parse("https://play.google.com/store/apps/details?id=" + appPackage); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + saveRated(); + } + + public static boolean rated() { + return mPreferences.getBoolean(KEY_RATED, false); + } + + public static void saveRated() { + mPreferences + .edit() + .putBoolean(KEY_RATED, true) + .apply(); + } + + private static void resetStartDate() { + mPreferences + .edit() + .putLong(KEY_FIRST_START_DATE, System.currentTimeMillis()) + .apply(); + } + + private static boolean shouldShow() { + if (rated()) { + return false; + } + + long now = System.currentTimeMillis(); + 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; + } + } + + @Nullable + private static MaterialDialog createDialog() { + Context context = mContext.get(); + if(context == null) { + return null; + } + MaterialDialog dialog = 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(); + } + }) + .cancelListener(dialog1 -> resetStartDate()) + .build(); + return dialog; + } +} 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 cdd6bc265..37be8f020 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -5,7 +5,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; -import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.LinearLayoutManager; @@ -30,8 +29,10 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.AllEpisodesRecycleAdapter; import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; -import de.danoeh.antennapod.core.asynctask.DownloadObserver; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; +import de.danoeh.antennapod.core.event.DownloadEvent; +import de.danoeh.antennapod.core.event.DownloaderUpdate; +import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; @@ -43,8 +44,10 @@ import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; +import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; +import de.greenrobot.event.EventBus; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; @@ -57,9 +60,7 @@ public class AllEpisodesFragment extends Fragment { public static final String TAG = "AllEpisodesFragment"; - private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | - EventDistributor.FEED_LIST_UPDATE | - EventDistributor.DOWNLOAD_QUEUED | + private static final int EVENTS = EventDistributor.FEED_LIST_UPDATE | EventDistributor.UNREAD_ITEMS_UPDATE | EventDistributor.PLAYER_STATUS_UPDATE; @@ -80,8 +81,6 @@ public class AllEpisodesFragment extends Fragment { private AtomicReference<MainActivity> activity = new AtomicReference<MainActivity>(); - private DownloadObserver downloadObserver = null; - private boolean isUpdatingFeeds; protected Subscription subscription; @@ -101,10 +100,6 @@ public class AllEpisodesFragment extends Fragment { super.onStart(); EventDistributor.getInstance().register(contentUpdate); this.activity.set((MainActivity) getActivity()); - if (downloadObserver != null) { - downloadObserver.setActivity(getActivity()); - downloadObserver.onResume(); - } if (viewsCreated && itemsLoaded) { onFragmentLoaded(); } @@ -113,6 +108,7 @@ public class AllEpisodesFragment extends Fragment { @Override public void onResume() { super.onResume(); + EventBus.getDefault().registerSticky(this); loadItems(); registerForContextMenu(recyclerView); } @@ -120,6 +116,7 @@ public class AllEpisodesFragment extends Fragment { @Override public void onPause() { super.onPause(); + EventBus.getDefault().unregister(this); saveScrollPosition(); unregisterForContextMenu(recyclerView); } @@ -180,9 +177,6 @@ public class AllEpisodesFragment extends Fragment { listAdapter = null; activity.set(null); viewsCreated = false; - if (downloadObserver != null) { - downloadObserver.onPause(); - } } @@ -267,9 +261,13 @@ public class AllEpisodesFragment extends Fragment { @Override public boolean onContextItemSelected(MenuItem item) { + Log.d(TAG, "onContextItemSelected() called with: " + "item = [" + item + "]"); if(!isVisible()) { return false; } + if(item.getItemId() == R.id.share_item) { + return true; // avoids that the position is reset when we need it in the submenu + } int pos = listAdapter.getPosition(); if(pos < 0) { return false; @@ -327,11 +325,10 @@ public class AllEpisodesFragment extends Fragment { private void onFragmentLoaded() { if (listAdapter == null) { - listAdapter = new AllEpisodesRecycleAdapter(activity.get(), activity.get(), itemAccess, - new DefaultActionButtonCallback(activity.get()), showOnlyNewEpisodes()); + MainActivity mainActivity = activity.get(); + listAdapter = new AllEpisodesRecycleAdapter(mainActivity, itemAccess, + new DefaultActionButtonCallback(mainActivity), showOnlyNewEpisodes()); recyclerView.setAdapter(listAdapter); - downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback); - downloadObserver.onResume(); } listAdapter.notifyDataSetChanged(); restoreScrollPosition(); @@ -339,21 +336,11 @@ public class AllEpisodesFragment extends Fragment { updateShowOnlyEpisodesListViewState(); } - private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { - @Override - public void onContentChanged(List<Downloader> downloaderList) { - AllEpisodesFragment.this.downloaderList = downloaderList; - if (listAdapter != null) { - listAdapter.notifyDataSetChanged(); - } - } - }; - protected AllEpisodesRecycleAdapter.ItemAccess itemAccess = new AllEpisodesRecycleAdapter.ItemAccess() { @Override public int getCount() { - if (itemsLoaded) { + if (episodes != null) { return episodes.size(); } return 0; @@ -361,7 +348,7 @@ public class AllEpisodesFragment extends Fragment { @Override public FeedItem getItem(int position) { - if (itemsLoaded) { + if (episodes != null && position < episodes.size()) { return episodes.get(position); } return null; @@ -389,6 +376,39 @@ public class AllEpisodesFragment extends Fragment { } }; + public void onEventMainThread(FeedItemEvent event) { + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + if(episodes == null || listAdapter == null) { + return; + } + for(int i=0, size = event.items.size(); i < size; i++) { + FeedItem item = event.items.get(i); + int pos = FeedItemUtil.indexOfItemWithId(episodes, item.getId()); + if(pos >= 0) { + episodes.remove(pos); + episodes.add(pos, item); + listAdapter.notifyItemChanged(pos); + } + } + } + + + public void onEventMainThread(DownloadEvent event) { + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + DownloaderUpdate update = event.update; + downloaderList = update.downloaders; + if(update.feedIds.length > 0) { + if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { + getActivity().supportInvalidateOptionsMenu(); + } + } + if(update.mediaIds.length > 0) { + if(listAdapter != null) { + listAdapter.notifyDataSetChanged(); + } + } + } + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { @Override public void update(EventDistributor eventDistributor, Integer arg) { @@ -412,7 +432,7 @@ public class AllEpisodesFragment extends Fragment { recyclerView.setVisibility(View.GONE); progLoading.setVisibility(View.VISIBLE); } - subscription = Observable.defer(() -> Observable.just(loadData())) + subscription = Observable.fromCallable(() -> loadData()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { 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 c5b582d3a..a5568b16e 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -156,7 +156,7 @@ public class CompletedDownloadsFragment extends ListFragment { if (!itemsLoaded && viewCreated) { setListShown(false); } - subscription = Observable.defer(() -> Observable.just(DBReader.getDownloadedItems())) + subscription = Observable.fromCallable(() -> DBReader.getDownloadedItems()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { 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 669c6ac49..90cacd2e4 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java @@ -147,7 +147,7 @@ public class DownloadLogFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.defer(() -> Observable.just(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/FavoriteEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java index 532516dda..65305df3d 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java @@ -17,7 +17,6 @@ import de.danoeh.antennapod.core.event.FavoritesEvent; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; -import de.greenrobot.event.EventBus; /** @@ -38,23 +37,11 @@ public class FavoriteEpisodesFragment extends AllEpisodesFragment { protected String getPrefName() { return PREF_NAME; } public void onEvent(FavoritesEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); + Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); loadItems(); } @Override - public void onStart() { - super.onStart(); - EventBus.getDefault().register(this); - } - - @Override - public void onStop() { - super.onStop(); - EventBus.getDefault().unregister(this); - } - - @Override protected void resetViewState() { super.resetViewState(); } 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 dc9f9740d..10d56d5cf 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -8,7 +8,6 @@ import android.content.res.TypedArray; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.Handler; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.util.Pair; @@ -35,12 +34,16 @@ import android.widget.Toast; import com.bumptech.glide.Glide; +import org.apache.commons.lang3.ArrayUtils; + import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; -import de.danoeh.antennapod.core.asynctask.DownloadObserver; +import de.danoeh.antennapod.core.event.DownloadEvent; +import de.danoeh.antennapod.core.event.DownloaderUpdate; +import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.FeedItem; @@ -72,9 +75,7 @@ public class ItemFragment extends Fragment { private static final String TAG = "ItemFragment"; - private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | - EventDistributor.DOWNLOAD_QUEUED | - EventDistributor.UNREAD_ITEMS_UPDATE; + private static final int EVENTS = EventDistributor.UNREAD_ITEMS_UPDATE; private static final String ARG_FEEDITEM = "feeditem"; @@ -97,7 +98,6 @@ public class ItemFragment extends Fragment { private FeedItem item; private LongList queue; private String webviewData; - private DownloadObserver downloadObserver; private List<Downloader> downloaderList; private ViewGroup root; @@ -263,11 +263,7 @@ public class ItemFragment extends Fragment { public void onResume() { super.onResume(); EventDistributor.getInstance().register(contentUpdate); - EventBus.getDefault().register(this); - if (downloadObserver != null) { - downloadObserver.setActivity(getActivity()); - downloadObserver.onResume(); - } + EventBus.getDefault().registerSticky(this); if(itemsLoaded) { updateAppearance(); } @@ -294,9 +290,6 @@ public class ItemFragment extends Fragment { } private void resetViewState() { - if (downloadObserver != null) { - downloadObserver.onPause(); - } Toolbar toolbar = ((MainActivity) getActivity()).getToolbar(); toolbar.removeView(header); } @@ -319,8 +312,6 @@ public class ItemFragment extends Fragment { "utf-8", "about:blank"); } updateAppearance(); - downloadObserver = new DownloadObserver(getActivity(), new Handler(), downloadObserverCallback); - downloadObserver.onResume(); } private void updateAppearance() { @@ -486,27 +477,41 @@ public class ItemFragment extends Fragment { public void onEventMainThread(QueueEvent event) { if(event.contains(itemID)) { - updateAppearance(); + load(); } } + public void onEventMainThread(FeedItemEvent event) { + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + for(FeedItem item : event.items) { + if(itemID == item.getId()) { + load(); + return; + } + } + } - private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { - @Override - public void update(EventDistributor eventDistributor, Integer arg) { - if ((arg & EVENTS) != 0) { + public void onEventMainThread(DownloadEvent event) { + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + DownloaderUpdate update = event.update; + downloaderList = update.downloaders; + if(item == null || item.getMedia() == null) { + return; + } + long mediaId = item.getMedia().getId(); + if(ArrayUtils.contains(update.mediaIds, mediaId)) { + if (itemsLoaded && getActivity() != null) { updateAppearance(); } } - }; + } - private final DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { @Override - public void onContentChanged(List<Downloader> downloaderList) { - ItemFragment.this.downloaderList = downloaderList; - if (itemsLoaded && getActivity() != null) { - updateAppearance(); + public void update(EventDistributor eventDistributor, Integer arg) { + if ((arg & EVENTS) != 0) { + load(); } } }; @@ -515,7 +520,7 @@ public class ItemFragment extends Fragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.defer(() -> Observable.just(loadInBackground())) + subscription = Observable.fromCallable(() -> 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 ba3dfc2af..09d2f5676 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -9,7 +9,6 @@ import android.graphics.Color; import android.graphics.LightingColorFilter; import android.os.Build; import android.os.Bundle; -import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v4.app.ListFragment; import android.support.v4.util.Pair; @@ -46,17 +45,19 @@ import de.danoeh.antennapod.activity.FeedInfoActivity; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.FeedItemlistAdapter; -import de.danoeh.antennapod.core.asynctask.DownloadObserver; import de.danoeh.antennapod.core.asynctask.FeedRemover; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; +import de.danoeh.antennapod.core.event.DownloadEvent; +import de.danoeh.antennapod.core.event.DownloaderUpdate; +import de.danoeh.antennapod.core.event.FeedItemEvent; +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.FeedEvent; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItemFilter; import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.FastBlurTransformation; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -66,6 +67,7 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; +import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil; import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment; @@ -85,9 +87,7 @@ import rx.schedulers.Schedulers; public class ItemlistFragment extends ListFragment { private static final String TAG = "ItemlistFragment"; - private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED - | EventDistributor.DOWNLOAD_QUEUED - | EventDistributor.UNREAD_ITEMS_UPDATE + private static final int EVENTS = EventDistributor.UNREAD_ITEMS_UPDATE | EventDistributor.PLAYER_STATUS_UPDATE; public static final String EXTRA_SELECTED_FEEDITEM = "extra.de.danoeh.antennapod.activity.selected_feeditem"; @@ -104,7 +104,6 @@ public class ItemlistFragment extends ListFragment { private boolean itemsLoaded = false; private boolean viewsCreated = false; - private DownloadObserver downloadObserver; private List<Downloader> downloaderList; private MoreContentListFooterUtil listFooter; @@ -147,11 +146,7 @@ public class ItemlistFragment extends ListFragment { public void onStart() { super.onStart(); EventDistributor.getInstance().register(contentUpdate); - EventBus.getDefault().register(this); - if (downloadObserver != null) { - downloadObserver.setActivity(getActivity()); - downloadObserver.onResume(); - } + EventBus.getDefault().registerSticky(this); if (viewsCreated && itemsLoaded) { onFragmentLoaded(); } @@ -193,9 +188,6 @@ public class ItemlistFragment extends ListFragment { adapter = null; viewsCreated = false; listFooter = null; - if (downloadObserver != null) { - downloadObserver.onPause(); - } } private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() { @@ -265,7 +257,8 @@ public class ItemlistFragment extends ListFragment { if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) { switch (item.getItemId()) { case R.id.episode_actions: - Fragment fragment = new EpisodesApplyActionFragment(feed.getItems()); + EpisodesApplyActionFragment fragment = new EpisodesApplyActionFragment(); + fragment.setEpisodes(feed.getItems()); ((MainActivity)getActivity()).loadChildFragment(fragment); return true; case R.id.remove_item: @@ -394,29 +387,54 @@ public class ItemlistFragment extends ListFragment { } public void onEvent(QueueEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); + Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); loadItems(); } public void onEvent(FeedEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); + Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); if(event.feedId == feedID) { loadItems(); } } + 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; + } + for(FeedItem item : event.items) { + int pos = FeedItemUtil.indexOfItemWithId(feed.getItems(), item.getId()); + if(pos >= 0) { + loadItems(); + return; + } + } + } + + public void onEventMainThread(DownloadEvent event) { + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + DownloaderUpdate update = event.update; + downloaderList = update.downloaders; + if(update.feedIds.length > 0) { + updateProgressBarVisibility(); + } + if(update.mediaIds.length > 0) { + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + } + private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() { @Override public void update(EventDistributor eventDistributor, Integer arg) { if ((EVENTS & arg) != 0) { Log.d(TAG, "Received contentUpdate Intent. arg " + arg); - if ((EventDistributor.DOWNLOAD_QUEUED & arg) != 0) { - updateProgressBarVisibility(); - } else { - loadItems(); - updateProgressBarVisibility(); - } + loadItems(); + updateProgressBarVisibility(); } } }; @@ -444,8 +462,6 @@ public class ItemlistFragment extends ListFragment { setupFooterView(); adapter = new FeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(getActivity()), false, true); setListAdapter(adapter); - downloadObserver = new DownloadObserver(getActivity(), new Handler(), downloadObserverCallback); - downloadObserver.onResume(); } refreshHeaderView(); setListShown(true); @@ -485,22 +501,10 @@ public class ItemlistFragment extends ListFragment { txtvInformation.setVisibility(View.GONE); } } else { - txtvInformation.setVisibility(View.GONE); } } - - private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { - @Override - public void onContentChanged(List<Downloader> downloaderList) { - ItemlistFragment.this.downloaderList = downloaderList; - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - } - }; - private void setupHeaderView() { if (getListView() == null || feed == null) { Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null"); @@ -624,7 +628,7 @@ public class ItemlistFragment extends ListFragment { subscription.unsubscribe(); } - subscription = Observable.defer(() -> Observable.just(loadData())) + subscription = Observable.fromCallable(() -> loadData()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java index d684c064c..b996e1cb3 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java @@ -14,14 +14,12 @@ import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.AllEpisodesRecycleAdapter; -import de.danoeh.antennapod.adapter.QueueRecyclerAdapter; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; -import de.greenrobot.event.EventBus; /** @@ -42,23 +40,11 @@ public class NewEpisodesFragment extends AllEpisodesFragment { protected String getPrefName() { return PREF_NAME; } public void onEvent(QueueEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); + Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); loadItems(); } @Override - public void onStart() { - super.onStart(); - EventBus.getDefault().register(this); - } - - @Override - public void onStop() { - super.onStop(); - EventBus.getDefault().unregister(this); - } - - @Override protected void resetViewState() { super.resetViewState(); } 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 d7ffa3e23..b47a197c3 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -3,7 +3,6 @@ package de.danoeh.antennapod.fragment; import android.app.Activity; import android.content.res.TypedArray; import android.os.Bundle; -import android.os.Handler; import android.support.v4.app.ListFragment; import android.support.v4.util.Pair; import android.support.v4.view.MenuItemCompat; @@ -21,7 +20,8 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.FeedItemlistAdapter; -import de.danoeh.antennapod.core.asynctask.DownloadObserver; +import de.danoeh.antennapod.core.event.DownloadEvent; +import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; @@ -52,12 +52,20 @@ public class PlaybackHistoryFragment extends ListFragment { private AtomicReference<Activity> activity = new AtomicReference<Activity>(); - private DownloadObserver downloadObserver; private List<Downloader> downloaderList; private Subscription subscription; @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + this.activity.set(activity); + if (viewsCreated && itemsLoaded) { + onFragmentLoaded(); + } + } + + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); @@ -65,8 +73,26 @@ public class PlaybackHistoryFragment extends ListFragment { } @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + // add padding + final ListView lv = getListView(); + lv.setClipToPadding(false); + final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding); + lv.setPadding(0, vertPadding, 0, vertPadding); + + viewsCreated = true; + if (itemsLoaded) { + onFragmentLoaded(); + } + } + + + @Override public void onResume() { super.onResume(); + EventBus.getDefault().registerSticky(this); loadItems(); } @@ -74,14 +100,18 @@ public class PlaybackHistoryFragment extends ListFragment { public void onStart() { super.onStart(); EventDistributor.getInstance().register(contentUpdate); - EventBus.getDefault().register(this); + } + + @Override + public void onPause() { + super.onPause(); + EventBus.getDefault().unregister(this); } @Override public void onStop() { super.onStop(); EventDistributor.getInstance().unregister(contentUpdate); - EventBus.getDefault().unregister(this); if(subscription != null) { subscription.unsubscribe(); } @@ -97,41 +127,18 @@ public class PlaybackHistoryFragment extends ListFragment { } @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - this.activity.set(activity); - if (downloadObserver != null) { - downloadObserver.setActivity(activity); - downloadObserver.onResume(); - } - if (viewsCreated && itemsLoaded) { - onFragmentLoaded(); - } - } - - @Override public void onDestroyView() { super.onDestroyView(); adapter = null; viewsCreated = false; - if (downloadObserver != null) { - downloadObserver.onPause(); - } } - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - // add padding - final ListView lv = getListView(); - lv.setClipToPadding(false); - final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding); - lv.setPadding(0, vertPadding, 0, vertPadding); - - viewsCreated = true; - if (itemsLoaded) { - onFragmentLoaded(); + public void onEvent(DownloadEvent event) { + Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); + DownloaderUpdate update = event.update; + downloaderList = update.downloaders; + if (adapter != null) { + adapter.notifyDataSetChanged(); } } @@ -205,24 +212,12 @@ public class PlaybackHistoryFragment extends ListFragment { // it harder to read. adapter = new FeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(activity.get()), true, false); setListAdapter(adapter); - downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback); - downloadObserver.onResume(); } setListShown(true); adapter.notifyDataSetChanged(); getActivity().supportInvalidateOptionsMenu(); } - private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { - @Override - public void onContentChanged(List<Downloader> downloaderList) { - PlaybackHistoryFragment.this.downloaderList = downloaderList; - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - } - }; - private FeedItemlistAdapter.ItemAccess itemAccess = new FeedItemlistAdapter.ItemAccess() { @Override public boolean isInQueue(FeedItem item) { @@ -257,7 +252,7 @@ public class PlaybackHistoryFragment extends ListFragment { if(subscription != null) { subscription.unsubscribe(); } - subscription = Observable.defer(() -> Observable.just(loadData())) + subscription = Observable.fromCallable(() -> 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 bfac7a347..46bbfd13c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; -import android.os.Handler; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; import android.support.v4.view.MenuItemCompat; @@ -31,8 +30,9 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; import de.danoeh.antennapod.adapter.QueueRecyclerAdapter; -import de.danoeh.antennapod.core.asynctask.DownloadObserver; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; +import de.danoeh.antennapod.core.event.DownloadEvent; +import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.event.FeedItemEvent; import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.feed.EventDistributor; @@ -67,7 +67,6 @@ public class QueueFragment extends Fragment { public static final String TAG = "QueueFragment"; private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED | - EventDistributor.DOWNLOAD_QUEUED | EventDistributor.PLAYER_STATUS_UPDATE; private TextView infoBar; @@ -85,13 +84,6 @@ public class QueueFragment extends Fragment { private static final String PREF_SCROLL_POSITION = "scroll_position"; private static final String PREF_SCROLL_OFFSET = "scroll_offset"; - private DownloadObserver downloadObserver = null; - - /** - * Download observer updates won't result in an upate of the list adapter if this is true. - */ - private boolean blockDownloadObserverUpdate = false; - private Subscription subscription; private LinearLayoutManager layoutManager; private ItemTouchHelper itemTouchHelper; @@ -107,12 +99,8 @@ public class QueueFragment extends Fragment { @Override public void onStart() { super.onStart(); - if (downloadObserver != null) { - downloadObserver.setActivity(getActivity()); - downloadObserver.onResume(); - } if (queue != null) { - onFragmentLoaded(); + onFragmentLoaded(true); } } @@ -120,9 +108,9 @@ public class QueueFragment extends Fragment { public void onResume() { super.onResume(); recyclerView.setAdapter(recyclerAdapter); - loadItems(); + loadItems(true); EventDistributor.getInstance().register(contentUpdate); - EventBus.getDefault().register(this); + EventBus.getDefault().registerSticky(this); } @Override @@ -137,7 +125,10 @@ public class QueueFragment extends Fragment { } public void onEventMainThread(QueueEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + if(queue == null || recyclerAdapter == null) { + return; + } switch(event.action) { case ADDED: queue.add(event.position, event.item); @@ -162,21 +153,17 @@ public class QueueFragment extends Fragment { recyclerAdapter.notifyDataSetChanged(); break; case MOVED: - int from = FeedItemUtil.indexOfItemWithId(queue, event.item.getId()); - int to = event.position; - if(from != to) { - queue.add(to, queue.remove(from)); - recyclerAdapter.notifyItemMoved(from, to); - } else { - // QueueFragment itself sent the event and already moved the item - } - break; + return; } - onFragmentLoaded(); + saveScrollPosition(); + onFragmentLoaded(false); } public void onEventMainThread(FeedItemEvent event) { - Log.d(TAG, "onEvent(" + event + ")"); + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + if(queue == null || recyclerAdapter == null) { + return; + } for(int i=0, size = event.items.size(); i < size; i++) { FeedItem item = event.items.get(i); int pos = FeedItemUtil.indexOfItemWithId(queue, item.getId()); @@ -188,6 +175,21 @@ public class QueueFragment extends Fragment { } } + public void onEventMainThread(DownloadEvent event) { + Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); + DownloaderUpdate update = event.update; + downloaderList = update.downloaders; + if (update.feedIds.length > 0) { + if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { + getActivity().supportInvalidateOptionsMenu(); + } + } else if (update.mediaIds.length > 0) { + if (recyclerAdapter != null) { + recyclerAdapter.notifyDataSetChanged(); + } + } + } + private void saveScrollPosition() { int firstItem = layoutManager.findFirstVisibleItemPosition(); View firstItemView = layoutManager.findViewByPosition(firstItem); @@ -211,20 +213,11 @@ public class QueueFragment extends Fragment { float offset = prefs.getFloat(PREF_SCROLL_OFFSET, 0.0f); if (position > 0 || offset > 0) { layoutManager.scrollToPositionWithOffset(position, (int) offset); - // restore once, then forget - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(PREF_SCROLL_POSITION, 0); - editor.putFloat(PREF_SCROLL_OFFSET, 0.0f); - editor.commit(); } } private void resetViewState() { recyclerAdapter = null; - blockDownloadObserverUpdate = false; - if (downloadObserver != null) { - downloadObserver.onPause(); - } } @Override @@ -327,6 +320,7 @@ public class QueueFragment extends Fragment { @Override public boolean onContextItemSelected(MenuItem item) { + Log.d(TAG, "onContextItemSelected() called with: " + "item = [" + item + "]"); if(!isVisible()) { return false; } @@ -336,12 +330,27 @@ public class QueueFragment extends Fragment { return super.onContextItemSelected(item); } - try { - return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem); - } catch (DownloadRequestException e) { - e.printStackTrace(); - Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show(); - return true; + switch(item.getItemId()) { + case R.id.move_to_top_item: + int position = FeedItemUtil.indexOfItemWithId(queue, selectedItem.getId()); + queue.add(0, queue.remove(position)); + recyclerAdapter.notifyItemMoved(position, 0); + DBWriter.moveQueueItemToTop(selectedItem.getId(), true); + return true; + case R.id.move_to_bottom_item: + position = FeedItemUtil.indexOfItemWithId(queue, selectedItem.getId()); + queue.add(queue.size()-1, queue.remove(position)); + recyclerAdapter.notifyItemMoved(position, queue.size()-1); + DBWriter.moveQueueItemToBottom(selectedItem.getId(), true); + return true; + default: + try { + return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem); + } catch (DownloadRequestException e) { + e.printStackTrace(); + Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show(); + return true; + } } } @@ -442,14 +451,12 @@ public class QueueFragment extends Fragment { return root; } - private void onFragmentLoaded() { + private void onFragmentLoaded(final boolean restoreScrollPosition) { if (recyclerAdapter == null) { MainActivity activity = (MainActivity) getActivity(); recyclerAdapter = new QueueRecyclerAdapter(activity, itemAccess, new DefaultActionButtonCallback(activity), itemTouchHelper); recyclerView.setAdapter(recyclerAdapter); - downloadObserver = new DownloadObserver(activity, new Handler(), downloadObserverCallback); - downloadObserver.onResume(); } if(queue == null || queue.size() == 0) { recyclerView.setVisibility(View.GONE); @@ -459,7 +466,9 @@ public class QueueFragment extends Fragment { recyclerView.setVisibility(View.VISIBLE); } - restoreScrollPosition(); + if (restoreScrollPosition) { + restoreScrollPosition(); + } // we need to refresh the options menu because it sometimes // needs data that may have just been loaded. @@ -483,16 +492,6 @@ public class QueueFragment extends Fragment { infoBar.setText(info); } - private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() { - @Override - public void onContentChanged(List<Downloader> downloaderList) { - QueueFragment.this.downloaderList = downloaderList; - if (recyclerAdapter != null && !blockDownloadObserverUpdate) { - recyclerAdapter.notifyDataSetChanged(); - } - } - }; - private QueueRecyclerAdapter.ItemAccess itemAccess = new QueueRecyclerAdapter.ItemAccess() { @Override public int getCount() { @@ -501,7 +500,10 @@ public class QueueFragment extends Fragment { @Override public FeedItem getItem(int position) { - return queue != null ? queue.get(position) : null; + if(queue != null && position < queue.size()) { + return queue.get(position); + } + return null; } @Override @@ -554,7 +556,8 @@ public class QueueFragment extends Fragment { @Override public void update(EventDistributor eventDistributor, Integer arg) { if ((arg & EVENTS) != 0) { - loadItems(); + Log.d(TAG, "arg: " + arg); + loadItems(false); if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { getActivity().supportInvalidateOptionsMenu(); } @@ -562,7 +565,8 @@ public class QueueFragment extends Fragment { } }; - private void loadItems() { + private void loadItems(final boolean restoreScrollPosition) { + Log.d(TAG, "loadItems()"); if(subscription != null) { subscription.unsubscribe(); } @@ -571,14 +575,14 @@ public class QueueFragment extends Fragment { txtvEmpty.setVisibility(View.GONE); progLoading.setVisibility(View.VISIBLE); } - subscription = Observable.defer(() -> Observable.just(DBReader.getQueue())) + subscription = Observable.fromCallable(() -> DBReader.getQueue()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(items -> { if(items != null) { progLoading.setVisibility(View.GONE); queue = items; - onFragmentLoaded(); + onFragmentLoaded(restoreScrollPosition); if(recyclerAdapter != null) { recyclerAdapter.notifyDataSetChanged(); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java index 544bdfc43..d81d18640 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.fragment; import android.os.Bundle; -import android.os.Handler; import android.support.v4.app.ListFragment; import android.util.Log; import android.view.View; @@ -12,7 +11,8 @@ import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.adapter.DownloadlistAdapter; -import de.danoeh.antennapod.core.asynctask.DownloadObserver; +import de.danoeh.antennapod.core.event.DownloadEvent; +import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadRequest; @@ -20,25 +20,18 @@ import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequester; +import de.greenrobot.event.EventBus; /** * Displays all running downloads and provides actions to cancel them */ public class RunningDownloadsFragment extends ListFragment { + private static final String TAG = "RunningDownloadsFrag"; - private DownloadObserver downloadObserver; + private DownloadlistAdapter adapter; private List<Downloader> downloaderList; - - @Override - public void onDetach() { - super.onDetach(); - if (downloadObserver != null) { - downloadObserver.onPause(); - } - } - @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -49,20 +42,39 @@ public class RunningDownloadsFragment extends ListFragment { final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding); lv.setPadding(0, vertPadding, 0, vertPadding); - final DownloadlistAdapter downloadlistAdapter = new DownloadlistAdapter(getActivity(), itemAccess); - setListAdapter(downloadlistAdapter); + adapter = new DownloadlistAdapter(getActivity(), itemAccess); + setListAdapter(adapter); + } - downloadObserver = new DownloadObserver(getActivity(), new Handler(), new DownloadObserver.Callback() { - @Override - public void onContentChanged(List<Downloader> downloaderList) { - Log.d(TAG, "onContentChanged: downloaderList.size() == " + downloaderList.size()); - RunningDownloadsFragment.this.downloaderList = downloaderList; - downloadlistAdapter.notifyDataSetChanged(); - } - }); - downloadObserver.onResume(); + @Override + public void onResume() { + super.onResume(); + EventBus.getDefault().registerSticky(this); } + @Override + public void onPause() { + super.onPause(); + EventBus.getDefault().unregister(this); + } + + @Override + public void onDestroy() { + super.onDestroy(); + setListAdapter(null); + adapter = null; + } + + public void onEvent(DownloadEvent event) { + Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]"); + DownloaderUpdate update = event.update; + downloaderList = update.downloaders; + if (adapter != null) { + adapter.notifyDataSetChanged(); + } + } + + private DownloadlistAdapter.ItemAccess itemAccess = new DownloadlistAdapter.ItemAccess() { @Override public int getCount() { 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 edd8cdd1a..43354ad28 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java @@ -204,7 +204,7 @@ public class SearchFragment extends ListFragment { if (viewCreated && !itemsLoaded) { setListShown(false); } - subscription = Observable.defer(() -> Observable.just(performSearch())) + subscription = Observable.fromCallable(() -> performSearch()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { 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 3fa1048c0..0197cc88c 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java @@ -186,11 +186,6 @@ public class FeedItemMenuHandler { GpodnetPreferences.enqueueEpisodeAction(actionNew); } break; - case R.id.move_to_top_item: - DBWriter.moveQueueItemToTop(selectedItem.getId(), true); - return true; - case R.id.move_to_bottom_item: - DBWriter.moveQueueItemToBottom(selectedItem.getId(), true); case R.id.add_to_queue_item: DBWriter.addQueueItem(context, selectedItem); break; 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 73d7da0f2..94f5d822e 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -8,6 +8,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; +import android.net.Uri; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Build; @@ -34,6 +35,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import de.danoeh.antennapod.CrashReportWriter; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.AboutActivity; import de.danoeh.antennapod.activity.DirectoryChooserActivity; @@ -169,7 +171,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - if(Build.VERSION.SDK_INT >= 19) { + if (Build.VERSION.SDK_INT >= 19) { showChooseDataFolderDialog(); } else { Intent intent = new Intent(activity, DirectoryChooserActivity.class); @@ -254,7 +256,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc setParallelDownloadsText(value); return true; } - } catch(NumberFormatException e) { + } catch (NumberFormatException e) { return false; } } @@ -263,17 +265,19 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } ); // validate and set correct value: number of downloads between 1 and 50 (inclusive) - final EditText ev = ((EditTextPreference)ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)).getEditText(); + final EditText ev = ((EditTextPreference) ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)).getEditText(); ev.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } @Override public void afterTextChanged(Editable s) { - if(s.length() > 0) { + if (s.length() > 0) { try { int value = Integer.valueOf(s.toString()); if (value <= 0) { @@ -281,7 +285,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } else if (value > 50) { ev.setText("50"); } - } catch(NumberFormatException e) { + } catch (NumberFormatException e) { ev.setText("6"); } ev.setSelection(ev.getText().length()); @@ -386,11 +390,23 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } } ); + ui.findPreference("prefSendCrashReport").setOnPreferenceClickListener(preference -> { + Intent emailIntent = new Intent(Intent.ACTION_SEND); + emailIntent.setType("text/plain"); + String to[] = { "Martin.Fietz@gmail.com" }; + emailIntent .putExtra(Intent.EXTRA_EMAIL, to); + // the attachment + emailIntent .putExtra(Intent.EXTRA_STREAM, Uri.fromFile(CrashReportWriter.getFile())); + // the mail subject + emailIntent .putExtra(Intent.EXTRA_SUBJECT, "AntennaPod Crash Report"); + String intentTitle = ui.getActivity().getString(R.string.send_email); + ui.getActivity().startActivity(Intent.createChooser(emailIntent, intentTitle)); + return true; + }); buildEpisodeCleanupPreference(); buildSmartMarkAsPlayedPreference(); buildAutodownloadSelectedNetworsPreference(); - setSelectedNetworksEnabled(UserPreferences - .isEnableAutodownloadWifiFilter()); + setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); } public void onResume() { @@ -527,6 +543,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY) .setEnabled(UserPreferences.isEnableAutodownload()); + ui.findPreference("prefSendCrashReport").setEnabled(CrashReportWriter.getFile().exists()); + if (Build.VERSION.SDK_INT >= 16) { ui.findPreference(UserPreferences.PREF_SONIC).setEnabled(true); } else { @@ -558,7 +576,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } private void setDataFolderText() { - File f = UserPreferences.getDataFolder(ui.getActivity(), null); + File f = UserPreferences.getDataFolder(null); if (f != null) { ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR) .setSummary(f.getAbsolutePath()); @@ -677,7 +695,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc private void showChooseDataFolderDialog() { Context context = ui.getActivity(); - String dataFolder = UserPreferences.getDataFolder(context, null).getAbsolutePath(); + String dataFolder = UserPreferences.getDataFolder(null).getAbsolutePath(); int selectedIndex = -1; File[] mediaDirs = ContextCompat.getExternalFilesDirs(context, null); String[] folders = new String[mediaDirs.length]; 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 2615ec5c8..665ddc3b5 100644 --- a/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java +++ b/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java @@ -5,10 +5,9 @@ import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.text.TextUtils; import android.util.Log; -import org.apache.commons.lang3.StringUtils; - import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.NetworkUtils; @@ -18,7 +17,7 @@ public class ConnectivityActionReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, Intent intent) { - if (StringUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) { + if (TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) { Log.d(TAG, "Received intent"); if (NetworkUtils.autodownloadNetworkAvailable()) { 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 7ab386edf..7000827c6 100644 --- a/app/src/main/java/de/danoeh/antennapod/receiver/PlayerWidget.java +++ b/app/src/main/java/de/danoeh/antennapod/receiver/PlayerWidget.java @@ -4,46 +4,75 @@ import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.text.TextUtils; import android.util.Log; -import org.apache.commons.lang3.StringUtils; - -import de.danoeh.antennapod.core.BuildConfig; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.service.PlayerWidgetService; public class PlayerWidget extends AppWidgetProvider { - private static final String TAG = "PlayerWidget"; + private static final String TAG = "PlayerWidget"; + private static final String PREFS_NAME = "PlayerWidgetPrefs"; + private static final String KEY_ENABLED = "WidgetEnabled"; + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "onReceive"); + super.onReceive(context, intent); + // don't do anything if we're not enabled + if (!isEnabled(context)) { + return; + } + + // these come from the PlaybackService when things should get updated + if (TextUtils.equals(intent.getAction(), PlaybackService.FORCE_WIDGET_UPDATE)) { + startUpdate(context); + } else if (TextUtils.equals(intent.getAction(), PlaybackService.STOP_WIDGET_UPDATE)) { + stopUpdate(context); + } + } + + @Override + public void onEnabled(Context context) { + super.onEnabled(context); + Log.d(TAG, "Widget enabled"); + setEnabled(context, true); + startUpdate(context); + } @Override - public void onReceive(Context context, Intent intent) { - if (StringUtils.equals(intent.getAction(), PlaybackService.FORCE_WIDGET_UPDATE)) { - startUpdate(context); - } else if (StringUtils.equals(intent.getAction(), PlaybackService.STOP_WIDGET_UPDATE)) { - stopUpdate(context); - } - - } - - @Override - public void onEnabled(Context context) { - super.onEnabled(context); - if (BuildConfig.DEBUG) - Log.d(TAG, "Widget enabled"); - } - - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, - int[] appWidgetIds) { - startUpdate(context); - } - - private void startUpdate(Context context) { - context.startService(new Intent(context, PlayerWidgetService.class)); - } - - private void stopUpdate(Context context) { - context.stopService(new Intent(context, PlayerWidgetService.class)); - } + public void onUpdate(Context context, AppWidgetManager appWidgetManager, + int[] appWidgetIds) { + Log.d(TAG, "onUpdate() called with: " + "context = [" + context + "], appWidgetManager = [" + appWidgetManager + "], appWidgetIds = [" + appWidgetIds + "]"); + startUpdate(context); + } + + @Override + public void onDisabled(Context context) { + super.onDisabled(context); + Log.d(TAG, "Widet disabled"); + setEnabled(context, false); + stopUpdate(context); + } + + private void startUpdate(Context context) { + Log.d(TAG, "startUpdate() called with: " + "context = [" + context + "]"); + context.startService(new Intent(context, PlayerWidgetService.class)); + } + + private void stopUpdate(Context context) { + Log.d(TAG, "stopUpdate() called with: " + "context = [" + context + "]"); + context.stopService(new Intent(context, PlayerWidgetService.class)); + } + + private boolean isEnabled(Context context) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getBoolean(KEY_ENABLED, false); + } + private void setEnabled(Context context, boolean enabled) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + prefs.edit().putBoolean(KEY_ENABLED, enabled).apply(); + } } 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 d15108bfe..ef6330f82 100644 --- a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java +++ b/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java @@ -3,11 +3,10 @@ package de.danoeh.antennapod.receiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.text.TextUtils; import android.util.Log; import android.widget.Toast; -import org.apache.commons.lang3.StringUtils; - import java.util.Arrays; import java.util.Date; @@ -29,7 +28,7 @@ public class SPAReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { - if (StringUtils.equals(intent.getAction(), ACTION_SP_APPS_QUERY_FEEDS_REPSONSE)) { + 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); diff --git a/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java b/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java index d7a049a32..d61a189c2 100644 --- a/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java +++ b/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java @@ -14,6 +14,7 @@ import android.view.View; import android.widget.RemoteViews; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; @@ -22,197 +23,220 @@ import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.playback.Playable; +import de.danoeh.antennapod.fragment.QueueFragment; import de.danoeh.antennapod.receiver.PlayerWidget; -/** Updates the state of the player widget */ +/** + * Updates the state of the player widget + */ public class PlayerWidgetService extends Service { - private static final String TAG = "PlayerWidgetService"; + private static final String TAG = "PlayerWidgetService"; - private PlaybackService playbackService; + private PlaybackService playbackService; - /** Controls write access to playbackservice reference */ + /** + * Controls write access to playbackservice reference + */ private Object psLock; - /** True while service is updating the widget */ - private volatile boolean isUpdating; + /** + * True while service is updating the widget + */ + private volatile boolean isUpdating; - public PlayerWidgetService() { - } + public PlayerWidgetService() { + } - @Override - public void onCreate() { - super.onCreate(); - Log.d(TAG, "Service created"); - isUpdating = false; + @Override + public void onCreate() { + super.onCreate(); + Log.d(TAG, "Service created"); + isUpdating = false; psLock = new Object(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - Log.d(TAG, "Service is about to be destroyed"); - if (playbackService != null) { - Playable playable = playbackService.getPlayable(); - if (playable != null && playable instanceof FeedMedia) { - FeedMedia media = (FeedMedia) playable; - if (media.hasAlmostEnded()) { - Log.d(TAG, "smart mark as read"); - FeedItem item = media.getItem(); - DBWriter.markItemPlayed(item, FeedItem.PLAYED, false); - DBWriter.removeQueueItem(this, item, false); - DBWriter.addItemToPlaybackHistory(media); - if (item.getFeed().getPreferences().getCurrentAutoDelete()) { - Log.d(TAG, "Delete " + media.toString()); - DBWriter.deleteFeedMediaOfItem(this, media.getId()); - } - } - } - } - - try { - unbindService(mConnection); - } catch (IllegalArgumentException e) { - Log.w(TAG, "IllegalArgumentException when trying to unbind service"); - } - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (!isUpdating) { - if (playbackService == null && PlaybackService.isRunning) { - bindService(new Intent(this, PlaybackService.class), - mConnection, 0); - } else { - startViewUpdaterIfNotRunning(); - } - } else { - Log.d(TAG, "Service was called while updating. Ignoring update request"); - } - return Service.START_NOT_STICKY; - } - - private void updateViews() { - if (playbackService == null) { - return; + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d(TAG, "Service is about to be destroyed"); + if (playbackService != null) { + Playable playable = playbackService.getPlayable(); + if (playable != null && playable instanceof FeedMedia) { + FeedMedia media = (FeedMedia) playable; + if (media.hasAlmostEnded()) { + Log.d(TAG, "smart mark as read"); + FeedItem item = media.getItem(); + DBWriter.markItemPlayed(item, FeedItem.PLAYED, false); + DBWriter.removeQueueItem(this, item, false); + DBWriter.addItemToPlaybackHistory(media); + if (item.getFeed().getPreferences().getCurrentAutoDelete()) { + Log.d(TAG, "Delete " + media.toString()); + DBWriter.deleteFeedMediaOfItem(this, media.getId()); + } + } + } + } + + try { + unbindService(mConnection); + } catch (IllegalArgumentException e) { + Log.w(TAG, "IllegalArgumentException when trying to unbind service"); + } + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (!isUpdating) { + if (playbackService == null && PlaybackService.isRunning) { + bindService(new Intent(this, PlaybackService.class), + mConnection, 0); + } else { + startViewUpdaterIfNotRunning(); + } + } else { + Log.d(TAG, "Service was called while updating. Ignoring update request"); } - isUpdating = true; - - ComponentName playerWidget = new ComponentName(this, PlayerWidget.class); - AppWidgetManager manager = AppWidgetManager.getInstance(this); - RemoteViews views = new RemoteViews(getPackageName(), - R.layout.player_widget); - PendingIntent startMediaplayer = PendingIntent.getActivity(this, 0, - PlaybackService.getPlayerActivityIntent(this), 0); - - views.setOnClickPendingIntent(R.id.layout_left, startMediaplayer); - final Playable media = playbackService.getPlayable(); - if (playbackService != null && media != null) { - PlayerStatus status = playbackService.getStatus(); - - views.setTextViewText(R.id.txtvTitle, media.getEpisodeTitle()); - - String progressString = getProgressString(media); - if (progressString != null) { - views.setTextViewText(R.id.txtvProgress, progressString); - } - - if (status == PlayerStatus.PLAYING) { - views.setImageViewResource(R.id.butPlay, R.drawable.ic_pause_white_24dp); - if (Build.VERSION.SDK_INT >= 15) { - views.setContentDescription(R.id.butPlay, getString(R.string.pause_label)); + return Service.START_NOT_STICKY; + } + + private void updateViews() { + isUpdating = true; + + ComponentName playerWidget = new ComponentName(this, PlayerWidget.class); + AppWidgetManager manager = AppWidgetManager.getInstance(this); + RemoteViews views = new RemoteViews(getPackageName(), + R.layout.player_widget); + PendingIntent startMediaplayer = PendingIntent.getActivity(this, 0, + PlaybackService.getPlayerActivityIntent(this), 0); + + Intent startApp = new Intent(getBaseContext(), MainActivity.class); + startApp.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startApp.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, QueueFragment.TAG); + PendingIntent startAppPending = PendingIntent.getActivity(getBaseContext(), 0, startApp, PendingIntent.FLAG_UPDATE_CURRENT); + + boolean nothingPlaying = false; + if (playbackService != null) { + final Playable media = playbackService.getPlayable(); + if (media != null) { + PlayerStatus status = playbackService.getStatus(); + views.setOnClickPendingIntent(R.id.layout_left, startMediaplayer); + + views.setTextViewText(R.id.txtvTitle, media.getEpisodeTitle()); + + String progressString = getProgressString(media); + if (progressString != null) { + views.setViewVisibility(R.id.txtvProgress, View.VISIBLE); + views.setTextViewText(R.id.txtvProgress, progressString); } - } else { - views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp); - if (Build.VERSION.SDK_INT >= 15) { - views.setContentDescription(R.id.butPlay, getString(R.string.play_label)); + + if (status == PlayerStatus.PLAYING) { + views.setImageViewResource(R.id.butPlay, R.drawable.ic_pause_white_24dp); + if (Build.VERSION.SDK_INT >= 15) { + views.setContentDescription(R.id.butPlay, getString(R.string.pause_label)); + } + } else { + views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp); + if (Build.VERSION.SDK_INT >= 15) { + views.setContentDescription(R.id.butPlay, getString(R.string.play_label)); + } } - } - views.setOnClickPendingIntent(R.id.butPlay, - createMediaButtonIntent()); - } else { - views.setViewVisibility(R.id.txtvProgress, View.INVISIBLE); - views.setTextViewText(R.id.txtvTitle, - this.getString(R.string.no_media_playing_label)); - views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp); - - } - - manager.updateAppWidget(playerWidget, views); - isUpdating = false; - } - - /** Creates an intent which fakes a mediabutton press */ - private PendingIntent createMediaButtonIntent() { - KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, - KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE); - Intent startingIntent = new Intent( - MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER); - startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); - - return PendingIntent.getBroadcast(this, 0, startingIntent, 0); - } - - private String getProgressString(Playable media) { - int position = media.getPosition(); - int duration = media.getDuration(); - if (position > 0 && duration > 0) { - return Converter.getDurationStringLong(position) + " / " - + Converter.getDurationStringLong(duration); - } else { - return null; - } - } - - private ServiceConnection mConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Connection to service established"); + views.setOnClickPendingIntent(R.id.butPlay, + createMediaButtonIntent()); + } else { + nothingPlaying = true; + } + } else { + nothingPlaying = true; + } + + if (nothingPlaying) { + // start the app if they click anything + views.setOnClickPendingIntent(R.id.layout_left, startAppPending); + views.setOnClickPendingIntent(R.id.butPlay, startAppPending); + views.setViewVisibility(R.id.txtvProgress, View.INVISIBLE); + views.setTextViewText(R.id.txtvTitle, + this.getString(R.string.no_media_playing_label)); + views.setImageViewResource(R.id.butPlay, R.drawable.ic_play_arrow_white_24dp); + } + + manager.updateAppWidget(playerWidget, views); + isUpdating = false; + } + + /** + * Creates an intent which fakes a mediabutton press + */ + private PendingIntent createMediaButtonIntent() { + KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, + KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE); + Intent startingIntent = new Intent( + MediaButtonReceiver.NOTIFY_BUTTON_RECEIVER); + startingIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); + + return PendingIntent.getBroadcast(this, 0, startingIntent, 0); + } + + private String getProgressString(Playable media) { + int position = media.getPosition(); + int duration = media.getDuration(); + if (position > 0 && duration > 0) { + return Converter.getDurationStringLong(position) + " / " + + Converter.getDurationStringLong(duration); + } else { + return null; + } + } + + private ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + Log.d(TAG, "Connection to service established"); synchronized (psLock) { playbackService = ((PlaybackService.LocalBinder) service) .getService(); startViewUpdaterIfNotRunning(); } - } + } - @Override - public void onServiceDisconnected(ComponentName name) { + @Override + public void onServiceDisconnected(ComponentName name) { synchronized (psLock) { playbackService = null; Log.d(TAG, "Disconnected from service"); } - } + } - }; + }; - private void startViewUpdaterIfNotRunning() { - if (!isUpdating) { - ViewUpdater updateThread = new ViewUpdater(this); - updateThread.start(); - } - } + private void startViewUpdaterIfNotRunning() { + if (!isUpdating) { + ViewUpdater updateThread = new ViewUpdater(this); + updateThread.start(); + } + } - class ViewUpdater extends Thread { - private static final String THREAD_NAME = "ViewUpdater"; - private PlayerWidgetService service; + class ViewUpdater extends Thread { + private static final String THREAD_NAME = "ViewUpdater"; + private PlayerWidgetService service; - public ViewUpdater(PlayerWidgetService service) { - super(); - setName(THREAD_NAME); - this.service = service; + public ViewUpdater(PlayerWidgetService service) { + super(); + setName(THREAD_NAME); + this.service = service; - } + } - @Override - public void run() { + @Override + public void run() { synchronized (psLock) { service.updateViews(); } - } + } - } + } } |