summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/de/danoeh')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/AppConfig.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/PodcastApp.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/UpdateManager.java88
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java82
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java101
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java152
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java53
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java15
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java69
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java76
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java68
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/ApplicationCallbacksImpl.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java153
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java414
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java35
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java65
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java129
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java87
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java18
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java33
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java5
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java68
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java18
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java134
-rw-r--r--app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java2
46 files changed, 1493 insertions, 639 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/AppConfig.java b/app/src/main/java/de/danoeh/antennapod/AppConfig.java
deleted file mode 100644
index 24f13d4a3..000000000
--- a/app/src/main/java/de/danoeh/antennapod/AppConfig.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.danoeh.antennapod;
-
-public final class AppConfig {
- /** Should be used when setting User-Agent header for HTTP-requests. */
- public final static String USER_AGENT = "AntennaPod/0.9.9.4";
-
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
index 451094909..f47fe3944 100644
--- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
+++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
@@ -1,12 +1,14 @@
package de.danoeh.antennapod;
import android.app.Application;
+import android.content.Intent;
import android.content.res.Configuration;
-import de.danoeh.antennapod.core.asynctask.PicassoProvider;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.service.FeedMediaSizeService;
+import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.spa.SPAUtil;
/** Main application class. */
@@ -37,12 +39,15 @@ public class PodcastApp extends Application {
singleton = this;
LOGICAL_DENSITY = getResources().getDisplayMetrics().density;
- PicassoProvider.setupPicassoInstance(this);
- UserPreferences.createInstance(this);
- PlaybackPreferences.createInstance(this);
+ UpdateManager.init(this);
+ UserPreferences.init(this);
+ PlaybackPreferences.init(this);
+ NetworkUtils.init(this);
EventDistributor.getInstance();
SPAUtil.sendSPAppsQueryFeedsIntent(this);
+
+ startService(new Intent(this, FeedMediaSizeService.class));
}
public static float getLogicalDensity() {
diff --git a/app/src/main/java/de/danoeh/antennapod/UpdateManager.java b/app/src/main/java/de/danoeh/antennapod/UpdateManager.java
new file mode 100644
index 000000000..2f6bb1b50
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/UpdateManager.java
@@ -0,0 +1,88 @@
+package de.danoeh.antennapod;
+
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import java.io.File;
+import java.util.List;
+
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.FeedImage;
+import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
+
+/*
+ * This class's job is do perform maintenance tasks whenever the app has been updated
+ */
+public class UpdateManager {
+
+ public static final String TAG = UpdateManager.class.getSimpleName();
+
+ private static final String PREF_NAME = "app_version";
+ private static final String KEY_VERSION_CODE = "version_code";
+
+ private static int currentVersionCode;
+
+ private static Context context;
+ private static SharedPreferences prefs;
+
+ public static void init(Context context) {
+ UpdateManager.context = context;
+ prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+ PackageManager pm = context.getPackageManager();
+ try {
+ PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0);
+ currentVersionCode = info.versionCode;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Failed to obtain package info for package name: " + context.getPackageName(), e);
+ currentVersionCode = 0;
+ return;
+ }
+ final int oldVersionCode = getStoredVersionCode();
+ Log.d(TAG, "old: " + oldVersionCode + ", current: " + currentVersionCode);
+ if(oldVersionCode < currentVersionCode) {
+ onUpgrade(oldVersionCode, currentVersionCode);
+ setCurrentVersionCode();
+ }
+ }
+
+ public static int getStoredVersionCode() {
+ return prefs.getInt(KEY_VERSION_CODE, -1);
+ }
+
+ public static void setCurrentVersionCode() {
+ prefs.edit().putInt(KEY_VERSION_CODE, currentVersionCode).apply();
+ }
+
+ private static void onUpgrade(final int oldVersionCode, final int newVersionCode) {
+ if(oldVersionCode < 1030099) {
+ // delete the now obsolete image cache
+ // from now on, Glide will handle caching images
+ new Thread() {
+ public void run() {
+ List<Feed> feeds = DBReader.getFeedList(context);
+ for (Feed podcast : feeds) {
+ List<FeedItem> episodes = DBReader.getFeedItemList(context, podcast);
+ for (FeedItem episode : episodes) {
+ FeedImage image = episode.getImage();
+ if (image != null && image.isDownloaded() && image.getFile_url() != null) {
+ File imageFile = new File(image.getFile_url());
+ if (imageFile.exists()) {
+ imageFile.delete();
+ }
+ image.setFile_url(null); // calls setDownloaded(false)
+ DBWriter.setFeedImage(context, image);
+ }
+ }
+ }
+ }
+ }.start();
+ }
+ }
+
+}
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 b59f6ba35..294acd427 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.activity;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
@@ -13,6 +14,8 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@@ -24,21 +27,26 @@ import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.apache.commons.lang3.StringUtils;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.ChapterListAdapter;
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.feed.Chapter;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.feed.SimpleChapter;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
@@ -430,6 +438,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
drawerLayout.closeDrawer(navDrawer);
}
});
+ registerForContextMenu(navList);
drawerToggle.syncState();
findViewById(R.id.nav_settings).setOnClickListener(new View.OnClickListener() {
@@ -549,9 +558,13 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
}
txtvTitle.setText(media.getEpisodeTitle());
getSupportActionBar().setTitle("");
- Picasso.with(this)
+ Glide.with(this)
.load(media.getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(butShowCover);
setNavButtonVisibility();
@@ -634,6 +647,65 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
}
}
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ if(v.getId() != R.id.nav_list) {
+ return;
+ }
+ AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
+ int position = adapterInfo.position;
+ if(position < navAdapter.getSubscriptionOffset()) {
+ return;
+ }
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.nav_feed_context, menu);
+ Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ menu.setHeaderTitle(feed.getTitle());
+ // episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ if(menuInfo.targetView.getParent() instanceof ListView == false
+ || ((ListView)menuInfo.targetView.getParent()).getId() != R.id.nav_list) {
+ return false;
+ }
+ int position = menuInfo.position;
+ Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ switch(item.getItemId()) {
+ case R.id.mark_all_seen_item:
+ DBWriter.markFeedSeen(this, feed.getId());
+ return true;
+ case R.id.mark_all_read_item:
+ DBWriter.markFeedRead(this, feed.getId());
+ return true;
+ case R.id.remove_item:
+ final FeedRemover remover = new FeedRemover(this, feed) {
+ @Override
+ protected void onPostExecute(Void result) {
+ super.onPostExecute(result);
+ }
+ };
+ ConfirmationDialog conDialog = new ConfirmationDialog(this,
+ R.string.remove_feed_label,
+ R.string.feed_delete_confirmation_msg) {
+ @Override
+ public void onConfirmButtonPressed(
+ DialogInterface dialog) {
+ dialog.dismiss();
+ remover.executeAsync();
+ }
+ };
+ conDialog.createNewDialog().show();
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+
private DBReader.NavDrawerData navDrawerData;
private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask;
@@ -708,8 +780,8 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
}
@Override
- public int getNumberOfUnreadFeedItems(long feedId) {
- return (navDrawerData != null) ? navDrawerData.numUnreadFeedItems.get(feedId) : 0;
+ public int getFeedCounter(long feedId) {
+ return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
}
};
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
index 287ae3568..0993ed6d6 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
@@ -17,7 +17,8 @@ import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
@@ -36,6 +37,7 @@ import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
@@ -124,9 +126,13 @@ public class DefaultOnlineFeedViewActivity extends OnlineFeedViewActivity {
subscribeButton = (Button) header.findViewById(R.id.butSubscribe);
if (feed.getImage() != null && StringUtils.isNotBlank(feed.getImage().getDownload_url())) {
- Picasso.with(this)
+ Glide.with(this)
.load(feed.getImage().getDownload_url())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(cover);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
index 5f76a20a8..9cdaf2fc6 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedInfoActivity.java
@@ -2,6 +2,9 @@ package de.danoeh.antennapod.activity;
import android.content.ClipData;
import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
@@ -12,24 +15,31 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
+import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.joanzapata.android.iconify.Iconify;
-import com.squareup.picasso.Picasso;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedPreferences;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
+import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LangUtils;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
@@ -38,6 +48,7 @@ import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
*/
public class FeedInfoActivity extends ActionBarActivity {
private static final String TAG = "FeedInfoActivity";
+ private boolean autoDeleteChanged = false;
public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
@@ -52,6 +63,7 @@ public class FeedInfoActivity extends ActionBarActivity {
private EditText etxtUsername;
private EditText etxtPassword;
private CheckBox cbxAutoDownload;
+ private Spinner spnAutoDelete;
private final View.OnClickListener copyUrlToClipboard = new View.OnClickListener() {
@Override
@@ -89,6 +101,7 @@ public class FeedInfoActivity extends ActionBarActivity {
txtvAuthor = (TextView) findViewById(R.id.txtvAuthor);
txtvUrl = (TextView) findViewById(R.id.txtvUrl);
cbxAutoDownload = (CheckBox) findViewById(R.id.cbxAutoDownload);
+ spnAutoDelete = (Spinner) findViewById(R.id.spnAutoDelete);
etxtUsername = (EditText) findViewById(R.id.etxtUsername);
etxtPassword = (EditText) findViewById(R.id.etxtPassword);
@@ -108,13 +121,18 @@ public class FeedInfoActivity extends ActionBarActivity {
Log.d(TAG, "Language is " + feed.getLanguage());
Log.d(TAG, "Author is " + feed.getAuthor());
Log.d(TAG, "URL is " + feed.getDownload_url());
+ FeedPreferences prefs = feed.getPreferences();
imgvCover.post(new Runnable() {
@Override
public void run() {
- Picasso.with(FeedInfoActivity.this)
+ Glide.with(FeedInfoActivity.this)
.load(feed.getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(imgvCover);
}
});
@@ -133,17 +151,49 @@ public class FeedInfoActivity extends ActionBarActivity {
Iconify.addIcons(txtvUrl);
cbxAutoDownload.setEnabled(UserPreferences.isEnableAutodownload());
- cbxAutoDownload.setChecked(feed.getPreferences().getAutoDownload());
+ cbxAutoDownload.setChecked(prefs.getAutoDownload());
cbxAutoDownload.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
feed.getPreferences().setAutoDownload(checked);
feed.savePreferences(FeedInfoActivity.this);
+ ApplyToEpisodesDialog dialog = new ApplyToEpisodesDialog(FeedInfoActivity.this,
+ feed, checked);
+ dialog.createNewDialog().show();
}
});
+ spnAutoDelete.setOnItemSelectedListener(new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ FeedPreferences.AutoDeleteAction auto_delete_action;
+ switch (parent.getSelectedItemPosition()) {
+ case 0:
+ auto_delete_action = FeedPreferences.AutoDeleteAction.GLOBAL;
+ break;
+
+ case 1:
+ auto_delete_action = FeedPreferences.AutoDeleteAction.YES;
+ break;
+
+ case 2:
+ auto_delete_action = FeedPreferences.AutoDeleteAction.NO;
+ break;
+
+ default: // TODO - add exceptions here
+ return;
+ }
+ feed.getPreferences().setAutoDeleteAction(auto_delete_action);// p
+ autoDeleteChanged = true;
+ }
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Another interface callback
+ }
+ });
+ spnAutoDelete.setSelection(prefs.getAutoDeleteAction().ordinal());
- etxtUsername.setText(feed.getPreferences().getUsername());
- etxtPassword.setText(feed.getPreferences().getPassword());
+ etxtUsername.setText(prefs.getUsername());
+ etxtPassword.setText(prefs.getPassword());
etxtUsername.addTextChangedListener(authTextWatcher);
etxtPassword.addTextChangedListener(authTextWatcher);
@@ -181,13 +231,18 @@ public class FeedInfoActivity extends ActionBarActivity {
@Override
protected void onPause() {
super.onPause();
- if (feed != null && authInfoChanged) {
- Log.d(TAG, "Auth info changed, saving credentials");
+ if (feed != null) {
FeedPreferences prefs = feed.getPreferences();
- prefs.setUsername(etxtUsername.getText().toString());
- prefs.setPassword(etxtPassword.getText().toString());
- DBWriter.setFeedPreferences(this, prefs);
+ if (authInfoChanged) {
+ Log.d(TAG, "Auth info changed, saving credentials");
+ prefs.setUsername(etxtUsername.getText().toString());
+ prefs.setPassword(etxtPassword.getText().toString());
+ }
+ if (authInfoChanged || autoDeleteChanged) {
+ DBWriter.setFeedPreferences(this, prefs);
+ }
authInfoChanged = false;
+ autoDeleteChanged = false;
}
}
@@ -205,7 +260,8 @@ public class FeedInfoActivity extends ActionBarActivity {
menu.findItem(R.id.support_item).setVisible(
feed != null && feed.getPaymentLink() != null);
menu.findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
- menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null);
+ menu.findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null &&
+ IntentUtils.isCallable(this, new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
return true;
}
@@ -226,4 +282,25 @@ public class FeedInfoActivity extends ActionBarActivity {
return super.onOptionsItemSelected(item);
}
}
+
+ private class ApplyToEpisodesDialog extends ConfirmationDialog {
+
+ private final Feed feed;
+ private final boolean autoDownload;
+
+ public ApplyToEpisodesDialog(Context context, Feed feed, boolean autoDownload) {
+ super(context, R.string.auto_download_apply_to_items_title,
+ R.string.auto_download_apply_to_items_message);
+ this.feed = feed;
+ this.autoDownload = autoDownload;
+ setPositiveText(R.string.yes);
+ setNegativeText(R.string.no);
+ }
+
+ @Override
+ public void onConfirmButtonPressed(DialogInterface dialog) {
+ DBWriter.setFeedsItemsAutoDownload(context, feed, autoDownload);
+ }
+ }
+
}
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 254749cd6..7eee1558b 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -1,6 +1,7 @@
package de.danoeh.antennapod.activity;
import android.app.AlertDialog;
+import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -19,6 +20,8 @@ import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
@@ -31,11 +34,15 @@ import java.util.List;
import de.danoeh.antennapod.R;
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.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.QueueEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.AllEpisodesFragment;
@@ -92,9 +99,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
private ActionBarDrawerToggle drawerToggle;
- private CharSequence drawerTitle;
private CharSequence currentTitle;
+ private ProgressDialog pd;
+
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getNoTitleTheme());
@@ -107,7 +115,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
setSupportActionBar(toolbar);
getSupportActionBar().setElevation(3.0f);
- drawerTitle = currentTitle = getTitle();
+ currentTitle = getTitle();
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navList = (ListView) findViewById(R.id.nav_list);
@@ -136,6 +144,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
navList.setAdapter(navAdapter);
navList.setOnItemClickListener(navListClickListener);
navList.setOnItemLongClickListener(newListLongClickListener);
+ registerForContextMenu(navList);
navAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
@@ -161,9 +170,9 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
String lastFragment = getLastNavFragment();
if(ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) {
loadFragment(lastFragment, null);
+ } else {
+ loadFeedFragmentById(Integer.valueOf(lastFragment), null);
}
- // else: lastFragment contains feed id - drawer data is not loaded yet,
- // so loading is postponed until then
}
externalPlayerFragment = new ExternalPlayerFragment();
transaction.replace(R.id.playerFragment, externalPlayerFragment);
@@ -173,6 +182,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
private void saveLastNavFragment(String tag) {
+ Log.d(TAG, "saveLastNavFragment(tag: " + tag +")");
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
SharedPreferences.Editor edit = prefs.edit();
if(tag != null) {
@@ -185,7 +195,9 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
private String getLastNavFragment() {
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
- return prefs.getString(PREF_LAST_FRAGMENT_TAG, QueueFragment.TAG);
+ String lastFragment = prefs.getString(PREF_LAST_FRAGMENT_TAG, QueueFragment.TAG);
+ Log.d(TAG, "getLastNavFragment() -> " + lastFragment);
+ return lastFragment;
}
private void checkFirstLaunch() {
@@ -251,6 +263,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
public void loadFragment(int index, Bundle args) {
+ Log.d(TAG, "loadFragment(index: " + index + ", args: " + args +")");
if (index < navAdapter.getSubscriptionOffset()) {
String tag = navAdapter.getTags().get(index);
loadFragment(tag, args);
@@ -261,7 +274,7 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
public void loadFragment(final String tag, Bundle args) {
- Log.d(TAG, "loadFragment(\"" + tag + "\", " + args + ")");
+ Log.d(TAG, "loadFragment(tag: " + tag + ", args: " + args + ")");
Fragment fragment = null;
switch (tag) {
case QueueFragment.TAG:
@@ -297,32 +310,20 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
return;
}
Feed feed = itemAccess.getItem(relPos);
- long feedId = feed.getId();
+ loadFeedFragmentById(feed.getId(), args);
+ }
+
+ public void loadFeedFragmentById(long feedId, Bundle args) {
Fragment fragment = ItemlistFragment.newInstance(feedId);
if(args != null) {
fragment.setArguments(args);
}
- saveLastNavFragment(String.valueOf(feed.getId()));
+ saveLastNavFragment(String.valueOf(feedId));
currentTitle = "";
getSupportActionBar().setTitle(currentTitle);
loadFragment(fragment);
}
- public void loadFeedFragmentById(long feedId) {
- if (navDrawerData != null) {
- int relPos = -1;
- List<Feed> feeds = navDrawerData.feeds;
- for (int i = 0; relPos < 0 && i < feeds.size(); i++) {
- if (feeds.get(i).getId() == feedId) {
- relPos = i;
- }
- }
- if(relPos >= 0) {
- loadFeedFragmentByPosition(relPos, null);
- }
- }
- }
-
private void loadFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
// clear back stack
@@ -362,15 +363,19 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
private int getSelectedNavListIndex() {
- String lastFragment = getLastNavFragment();
- int tagIndex = navAdapter.getTags().indexOf(lastFragment);
+ String currentFragment = getLastNavFragment();
+ if(currentFragment == null) {
+ // should not happen, but better safe than sorry
+ return -1;
+ }
+ int tagIndex = navAdapter.getTags().indexOf(currentFragment);
if(tagIndex >= 0) {
return tagIndex;
- } else if(ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) {
+ } else if(ArrayUtils.contains(NAV_DRAWER_TAGS, currentFragment)) {
// the fragment was just hidden
return -1;
} else { // last fragment was not a list, but a feed
- long feedId = Long.parseLong(lastFragment);
+ long feedId = Long.parseLong(currentFragment);
if (navDrawerData != null) {
List<Feed> feeds = navDrawerData.feeds;
for (int i = 0; i < feeds.size(); i++) {
@@ -465,6 +470,9 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
cancelLoadTask();
EventDistributor.getInstance().unregister(contentUpdate);
EventBus.getDefault().unregister(this);
+ if(pd != null) {
+ pd.dismiss();
+ }
}
@Override
@@ -481,6 +489,67 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
}
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ if(v.getId() != R.id.nav_list) {
+ return;
+ }
+ AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
+ int position = adapterInfo.position;
+ if(position < navAdapter.getSubscriptionOffset()) {
+ return;
+ }
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.nav_feed_context, menu);
+ Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ menu.setHeaderTitle(feed.getTitle());
+ // episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ if(menuInfo.targetView.getParent() instanceof ListView == false
+ || ((ListView)menuInfo.targetView.getParent()).getId() != R.id.nav_list) {
+ return false;
+ }
+ final int position = menuInfo.position;
+ Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ switch(item.getItemId()) {
+ case R.id.mark_all_seen_item:
+ DBWriter.markFeedSeen(this, feed.getId());
+ return true;
+ case R.id.mark_all_read_item:
+ DBWriter.markFeedRead(this, feed.getId());
+ return true;
+ case R.id.remove_item:
+ final FeedRemover remover = new FeedRemover(this, feed) {
+ @Override
+ protected void onPostExecute(Void result) {
+ super.onPostExecute(result);
+ if(getSelectedNavListIndex() == position) {
+ loadFragment(NewEpisodesFragment.TAG, null);
+ }
+ }
+ };
+ ConfirmationDialog conDialog = new ConfirmationDialog(this,
+ R.string.remove_feed_label,
+ R.string.feed_delete_confirmation_msg) {
+ @Override
+ public void onConfirmButtonPressed(
+ DialogInterface dialog) {
+ dialog.dismiss();
+ remover.executeAsync();
+ }
+ };
+ conDialog.createNewDialog().show();
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
private DBReader.NavDrawerData navDrawerData;
private AsyncTask<Void, Void, DBReader.NavDrawerData> loadTask;
private int selectedNavListIndex = 0;
@@ -520,8 +589,8 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
}
@Override
- public int getNumberOfUnreadFeedItems(long feedId) {
- return (navDrawerData != null) ? navDrawerData.numUnreadFeedItems.get(feedId) : 0;
+ public int getFeedCounter(long feedId) {
+ return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
}
};
@@ -542,13 +611,6 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
navDrawerData = result;
navAdapter.notifyDataSetChanged();
- String lastFragment = getLastNavFragment();
- if(!ArrayUtils.contains(NAV_DRAWER_TAGS, lastFragment)) {
- long feedId = Long.valueOf(lastFragment);
- loadFeedFragmentById(feedId);
- saveLastNavFragment(null);
- }
-
if (handleIntent) {
handleNavIntent();
}
@@ -568,6 +630,24 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
loadData();
}
+ public void onEventMainThread(ProgressEvent event) {
+ Log.d(TAG, "onEvent(" + event + ")");
+ switch(event.action) {
+ case START:
+ pd = new ProgressDialog(this);
+ pd.setMessage(event.message);
+ pd.setIndeterminate(true);
+ pd.setCancelable(false);
+ pd.show();
+ break;
+ case END:
+ if(pd != null) {
+ pd.dismiss();
+ }
+ break;
+ }
+ }
+
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
index 0cd388b9d..b83e9bc15 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -278,6 +278,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
startActivity(intent);
return true;
} else if (media != null) {
+ FeedItem feedItem = ((FeedMedia) media).getItem();
switch (item.getItemId()) {
case R.id.disable_sleeptimer_item:
if (controller.serviceAvailable()) {
@@ -333,12 +334,20 @@ public abstract class MediaplayerActivity extends ActionBarActivity
break;
case R.id.support_item:
if (media instanceof FeedMedia) {
- FeedItem feedItem = ((FeedMedia) media).getItem();
DBTasks.flattrItemIfLoggedIn(this, feedItem);
}
break;
case R.id.share_link_item:
- ShareUtils.shareLink(this, media.getWebsiteLink());
+ ShareUtils.shareFeedItemLink(this, feedItem);
+ break;
+ case R.id.share_download_url_item:
+ ShareUtils.shareFeedItemDownloadLink(this, feedItem);
+ break;
+ case R.id.share_link_with_position_item:
+ ShareUtils.shareFeedItemLink(this, feedItem, true);
+ break;
+ case R.id.share_download_url_with_position_item:
+ ShareUtils.shareFeedItemDownloadLink(this, feedItem, true);
break;
case R.id.skip_episode_item:
sendBroadcast(new Intent(
@@ -471,7 +480,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
checked = i;
}
choices[i] = String.valueOf(values[i]) + " "
- + getString(R.string.time_unit_seconds);
+ + getString(R.string.time_seconds);
}
choice = values[checked];
AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
@@ -519,7 +528,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
checked = i;
}
choices[i] = String.valueOf(values[i]) + " "
- + getString(R.string.time_unit_seconds);
+ + getString(R.string.time_seconds);
}
choice = values[checked];
AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this);
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 2b1b13ae6..3ab384012 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -180,7 +180,7 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
url = URLChecker.prepareURL(url);
feed = new Feed(url, new Date(0));
if (username != null && password != null) {
- feed.setPreferences(new FeedPreferences(0, false, username, password));
+ feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, username, password));
}
String fileUrl = new File(getExternalCacheDir(),
FileNameGenerator.generateFileName(feed.getDownload_url())).toString();
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java
index feb3989bc..2ec987d1a 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportFromPathActivity.java
@@ -2,7 +2,6 @@ package de.danoeh.antennapod.activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
-import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
@@ -18,11 +17,10 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.util.List;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LangUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
@@ -72,38 +70,33 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
int nextOption = 1;
intentPickAction = new Intent(Intent.ACTION_PICK);
intentPickAction.setData(Uri.parse("file://"));
- List<ResolveInfo> intentActivities = getPackageManager()
- .queryIntentActivities(intentPickAction, CHOOSE_OPML_FILE);
- if(intentActivities.size() == 0) {
- intentPickAction.setData(null);
- intentActivities = getPackageManager()
- .queryIntentActivities(intentPickAction, CHOOSE_OPML_FILE);
- if(intentActivities.size() == 0) {
- txtvHeaderExplanation1.setVisibility(View.GONE);
- txtvExplanation1.setVisibility(View.GONE);
- findViewById(R.id.divider1).setVisibility(View.GONE);
- butChooseFilesystem.setVisibility(View.GONE);
- }
+
+ if(false == IntentUtils.isCallable(getApplicationContext(), intentPickAction)) {
+ intentPickAction.setData(null);
+ if(false == IntentUtils.isCallable(getApplicationContext(), intentPickAction)) {
+ txtvHeaderExplanation1.setVisibility(View.GONE);
+ txtvExplanation1.setVisibility(View.GONE);
+ findViewById(R.id.divider1).setVisibility(View.GONE);
+ butChooseFilesystem.setVisibility(View.GONE);
}
+ }
if(txtvExplanation1.getVisibility() == View.VISIBLE) {
- txtvHeaderExplanation1.setText("Option " + nextOption);
- nextOption++;
- }
+ txtvHeaderExplanation1.setText("Option " + nextOption);
+ nextOption++;
+ }
intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT);
intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE);
intentGetContentAction.setType("*/*");
- intentActivities = getPackageManager()
- .queryIntentActivities(intentGetContentAction, CHOOSE_OPML_FILE);
- if(intentActivities.size() == 0) {
- txtvHeaderExplanation2.setVisibility(View.GONE);
- txtvExplanation2.setVisibility(View.GONE);
- findViewById(R.id.divider2).setVisibility(View.GONE);
- butChooseExternal.setVisibility(View.GONE);
- } else {
- txtvHeaderExplanation2.setText("Option " + nextOption);
- nextOption++;
- }
+ if(false == IntentUtils.isCallable(getApplicationContext(), intentGetContentAction)) {
+ txtvHeaderExplanation2.setVisibility(View.GONE);
+ txtvExplanation2.setVisibility(View.GONE);
+ findViewById(R.id.divider2).setVisibility(View.GONE);
+ butChooseExternal.setVisibility(View.GONE);
+ } else {
+ txtvHeaderExplanation2.setText("Option " + nextOption);
+ nextOption++;
+ }
txtvHeaderExplanation3.setText("Option " + nextOption);
}
@@ -137,7 +130,7 @@ public class OpmlImportFromPathActivity extends OpmlImportBaseActivity {
try {
mReader = new InputStreamReader(new FileInputStream(file),
LangUtils.UTF_8);
- if (BuildConfig.DEBUG) Log.d(TAG, "Parsing " + file.toString());
+ Log.d(TAG, "Parsing " + file.toString());
startImport(mReader);
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found which really should be there");
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
index 3802de2a6..94970d833 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java
@@ -60,10 +60,13 @@ public class PreferenceActivity extends ActionBarActivity {
root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
setContentView(root);
- prefFragment = new MainFragment();
- getFragmentManager().beginTransaction().replace(R.id.content, prefFragment).commit();
+ // we need to create the PreferenceController before the MainFragment
+ // since the MainFragment depends on the preferenceController already being created
preferenceController = new PreferenceController(preferenceUI);
+
+ prefFragment = new MainFragment();
+ getFragmentManager().beginTransaction().replace(R.id.content, prefFragment).commit();
}
@Override
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 8e347a819..aca2b359a 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ActionButtonUtils.java
@@ -88,7 +88,7 @@ public class ActionButtonUtils {
butSecondary.setContentDescription(context.getString(labels[0]));
}
} else {
- if (item.isRead()) {
+ if (item.isPlayed()) {
butSecondary.setVisibility(View.INVISIBLE);
} else {
butSecondary.setVisibility(View.VISIBLE);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
index e22b31361..d3ee08546 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/AdapterUtils.java
@@ -36,18 +36,19 @@ public class AdapterUtils {
|| state == FeedItem.State.IN_PROGRESS) {
if (media.getDuration() > 0) {
episodeProgress.setVisibility(View.VISIBLE);
- episodeProgress
- .setProgress((int) (((double) media
+ episodeProgress.setProgress((int) (((double) media
.getPosition()) / media.getDuration() * 100));
- txtvPos.setText(Converter
- .getDurationStringLong(media.getDuration()
+ txtvPos.setText(Converter.getDurationStringLong(media.getDuration()
- media.getPosition()));
}
} else if (!media.isDownloaded()) {
- txtvPos.setText(Converter.byteToString(media.getSize()));
+ if(media.getSize() > 0) {
+ txtvPos.setText(Converter.byteToString(media.getSize()));
+ } else {
+ txtvPos.setText("");
+ }
} else {
- txtvPos.setText(Converter.getDurationStringLong(media
- .getDuration()));
+ txtvPos.setText(Converter.getDurationStringLong(media.getDuration()));
}
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java
index d96326053..4b6ee8f91 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesListAdapter.java
@@ -1,6 +1,8 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,11 +13,18 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.load.resource.drawable.GlideDrawable;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
+
+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.glide.ApGlideSettings;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
@@ -72,6 +81,7 @@ public class AllEpisodesListAdapter extends BaseAdapter {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.new_episodes_listitem,
parent, false);
+ holder.placeholder = (TextView) convertView.findViewById(R.id.txtvPlaceholder);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.pubDate = (TextView) convertView
.findViewById(R.id.txtvPublished);
@@ -82,16 +92,18 @@ public class AllEpisodesListAdapter extends BaseAdapter {
.findViewById(R.id.imgvInPlaylist);
holder.progress = (ProgressBar) convertView
.findViewById(R.id.pbar_progress);
- holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
+ holder.cover = (ImageView) convertView.findViewById(R.id.imgvCover);
holder.txtvDuration = (TextView) convertView.findViewById(R.id.txtvDuration);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
+ 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));
- if (showOnlyNewEpisodes || item.isRead() || false == itemAccess.isNew(item)) {
+ if (showOnlyNewEpisodes || false == item.isNew()) {
holder.statusUnread.setVisibility(View.INVISIBLE);
} else {
holder.statusUnread.setVisibility(View.VISIBLE);
@@ -141,14 +153,54 @@ public class AllEpisodesListAdapter extends BaseAdapter {
holder.butSecondary.setTag(item);
holder.butSecondary.setOnClickListener(secondaryActionListener);
- Picasso.with(context)
+ Glide.with(context)
.load(item.getImageUri())
- .fit()
- .into(holder.imageView);
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
+ .into(new CoverTarget(item.getFeed().getImageUri(), holder.placeholder, holder.cover));
return convertView;
}
+ private class CoverTarget extends GlideDrawableImageViewTarget {
+
+ private final WeakReference<Uri> fallback;
+ private final WeakReference<TextView> placeholder;
+ private final WeakReference<ImageView> cover;
+
+ public CoverTarget(Uri fallbackUri, TextView txtvPlaceholder, ImageView imgvCover) {
+ super(imgvCover);
+ fallback = new WeakReference<>(fallbackUri);
+ placeholder = new WeakReference<>(txtvPlaceholder);
+ cover = new WeakReference<>(imgvCover);
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ Uri fallbackUri = fallback.get();
+ TextView txtvPlaceholder = placeholder.get();
+ ImageView imgvCover = cover.get();
+ if(fallbackUri != null && txtvPlaceholder != null && imgvCover != null) {
+ Glide.with(context)
+ .load(fallbackUri)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
+ .into(new CoverTarget(null, txtvPlaceholder, imgvCover));
+ }
+ }
+
+ @Override
+ public void onResourceReady(GlideDrawable drawable, GlideAnimation anim) {
+ super.onResourceReady(drawable, anim);
+ TextView txtvPlaceholder = placeholder.get();
+ if(txtvPlaceholder != null) {
+ txtvPlaceholder.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+
private View.OnClickListener secondaryActionListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -159,11 +211,12 @@ public class AllEpisodesListAdapter extends BaseAdapter {
static class Holder {
+ TextView placeholder;
TextView title;
TextView pubDate;
View statusUnread;
ImageView queueStatus;
- ImageView imageView;
+ ImageView cover;
ProgressBar progress;
TextView txtvDuration;
ImageButton butSecondary;
@@ -179,7 +232,5 @@ public class AllEpisodesListAdapter extends BaseAdapter {
boolean isInQueue(FeedItem item);
- boolean isNew(FeedItem item);
-
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
index 223fe17f6..c3486f2f2 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DefaultActionButtonCallback.java
@@ -12,11 +12,8 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
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;
-import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
-import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -61,7 +58,7 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
if (!isDownloading && !media.isDownloaded()) {
LongList queueIds = DBReader.getQueueIDList(context);
- if (NetworkUtils.isDownloadAllowed(context) || userAllowedMobileDownloads()) {
+ if (NetworkUtils.isDownloadAllowed() || userAllowedMobileDownloads()) {
try {
DBTasks.downloadFeedItems(context, item);
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
@@ -95,21 +92,8 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
}
}
} else {
- if (!item.isRead()) {
+ if (!item.isPlayed()) {
DBWriter.markItemRead(context, item, true, true);
-
- if(GpodnetPreferences.loggedIn()) {
- // gpodder: send played action
- FeedMedia media = item.getMedia();
- GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, GpodnetEpisodeAction.Action.PLAY)
- .currentDeviceId()
- .currentTimestamp()
- .started(media.getDuration() / 1000)
- .position(media.getDuration() / 1000)
- .total(media.getDuration() / 1000)
- .build();
- GpodnetPreferences.enqueueEpisodeAction(action);
- }
}
}
}
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 f29cfdf2f..0eb15da8c 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -124,11 +124,15 @@ public class DownloadLogAdapter extends BaseAdapter {
ButtonHolder holder = (ButtonHolder) v.getTag();
if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
Feed feed = DBReader.getFeed(context, holder.id);
- feed.setLastUpdate(new Date(0)); // force refresh
- try {
- DBTasks.refreshFeed(context, feed);
- } catch (DownloadRequestException e) {
- e.printStackTrace();
+ if (feed != null) {
+ feed.setLastUpdate(new Date(0)); // force refresh
+ try {
+ DBTasks.refreshFeed(context, feed);
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ }
+ } else {
+ Log.wtf(TAG, "Could not find feed for feed id: " + holder.id);
}
} else if(holder.typeId == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
FeedMedia media = DBReader.getFeedMedia(context, holder.id);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java
index 15e0a7a33..2b1eccea5 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java
@@ -10,10 +10,12 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.util.Converter;
/**
@@ -88,9 +90,13 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
holder.butSecondary.setOnClickListener(secondaryActionListener);
- Picasso.with(context)
+ Glide.with(context)
.load(item.getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(holder.imageView);
return convertView;
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 b39e23d42..56e2bb1bd 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistAdapter.java
@@ -33,13 +33,17 @@ public class FeedItemlistAdapter extends BaseAdapter {
private final Context context;
private boolean showFeedtitle;
private int selectedItemIndex;
+ /** true if played items should be made partially transparent */
+ private boolean makePlayedItemsTransparent;
private final ActionButtonUtils actionButtonUtils;
public static final int SELECTION_NONE = -1;
public FeedItemlistAdapter(Context context,
ItemAccess itemAccess,
- ActionButtonCallback callback, boolean showFeedtitle) {
+ ActionButtonCallback callback,
+ boolean showFeedtitle,
+ boolean makePlayedItemsTransparent) {
super();
this.callback = callback;
this.context = context;
@@ -47,6 +51,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
this.showFeedtitle = showFeedtitle;
this.selectedItemIndex = SELECTION_NONE;
this.actionButtonUtils = new ActionButtonUtils(context);
+ this.makePlayedItemsTransparent = makePlayedItemsTransparent;
}
@Override
@@ -106,18 +111,18 @@ public class FeedItemlistAdapter extends BaseAdapter {
StringBuilder buffer = new StringBuilder(item.getTitle());
if (showFeedtitle) {
- buffer.append("(");
+ buffer.append(" (");
buffer.append(item.getFeed().getTitle());
buffer.append(")");
}
holder.title.setText(buffer.toString());
- if(false == item.isRead() && itemAccess.isNew(item)) {
+ if(item.isNew()) {
holder.statusUnread.setVisibility(View.VISIBLE);
} else {
holder.statusUnread.setVisibility(View.INVISIBLE);
}
- if(item.isRead()) {
+ if(item.isPlayed() && makePlayedItemsTransparent) {
ViewHelper.setAlpha(convertView, 0.5f);
} else {
ViewHelper.setAlpha(convertView, 1.0f);
@@ -180,7 +185,6 @@ public class FeedItemlistAdapter extends BaseAdapter {
convertView.setVisibility(View.GONE);
}
return convertView;
-
}
private final OnClickListener butActionListener = new OnClickListener() {
@@ -221,8 +225,6 @@ public class FeedItemlistAdapter extends BaseAdapter {
FeedItem getItem(int position);
- boolean isNew(FeedItem item);
-
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index 0d2d5cfa0..3c91cbbbb 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -15,7 +15,8 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.apache.commons.lang3.ArrayUtils;
@@ -27,6 +28,7 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.AllEpisodesFragment;
@@ -259,9 +261,13 @@ public class NavListAdapter extends BaseAdapter
holder = (FeedHolder) convertView.getTag();
}
- Picasso.with(context)
+ Glide.with(context)
.load(feed.getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(holder.image);
holder.title.setText(feed.getTitle());
@@ -276,10 +282,10 @@ public class NavListAdapter extends BaseAdapter
p.addRule(RelativeLayout.LEFT_OF, R.id.txtvCount);
holder.failure.setVisibility(View.GONE);
}
- int feedUnreadItems = itemAccess.getNumberOfUnreadFeedItems(feed.getId());
- if(feedUnreadItems > 0) {
+ int counter = itemAccess.getFeedCounter(feed.getId());
+ if(counter > 0) {
holder.count.setVisibility(View.VISIBLE);
- holder.count.setText(String.valueOf(feedUnreadItems));
+ holder.count.setText(String.valueOf(counter));
holder.count.setTypeface(holder.title.getTypeface());
} else {
holder.count.setVisibility(View.GONE);
@@ -306,7 +312,7 @@ public class NavListAdapter extends BaseAdapter
int getSelectedItemIndex();
int getQueueSize();
int getNumberOfNewItems();
- int getNumberOfUnreadFeedItems(long feedId);
+ int getFeedCounter(long feedId);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
index bba5a00a9..60c125fda 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueListAdapter.java
@@ -1,7 +1,10 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.text.format.DateUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -11,11 +14,18 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.load.resource.drawable.GlideDrawable;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
+
+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.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
@@ -25,6 +35,7 @@ import de.danoeh.antennapod.core.util.Converter;
*/
public class QueueListAdapter extends BaseAdapter {
+ private static final String TAG = QueueListAdapter.class.getSimpleName();
private final Context context;
private final ItemAccess itemAccess;
@@ -76,7 +87,8 @@ public class QueueListAdapter extends BaseAdapter {
convertView = inflater.inflate(R.layout.queue_listitem,
parent, false);
holder.dragHandle = (ImageView) convertView.findViewById(R.id.drag_handle);
- holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
+ holder.placeholder = (TextView) convertView.findViewById(R.id.txtvPlaceholder);
+ holder.cover = (ImageView) convertView.findViewById(R.id.imgvCover);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate);
holder.progressLeft = (TextView) convertView.findViewById(R.id.txtvProgressLeft);
@@ -86,7 +98,6 @@ public class QueueListAdapter extends BaseAdapter {
.findViewById(R.id.butSecondaryAction);
holder.progress = (ProgressBar) convertView
.findViewById(R.id.progressBar);
- holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
@@ -98,10 +109,11 @@ public class QueueListAdapter extends BaseAdapter {
holder.dragHandle.setVisibility(View.VISIBLE);
}
+ holder.placeholder.setText(item.getFeed().getTitle());
+
holder.title.setText(item.getTitle());
FeedMedia media = item.getMedia();
-
holder.title.setText(item.getTitle());
String pubDate = DateUtils.formatDateTime(context, item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL);
holder.pubDate.setText(pubDate.replace(" ", "\n"));
@@ -129,7 +141,11 @@ public class QueueListAdapter extends BaseAdapter {
holder.progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
}
} else {
- holder.progressLeft.setText(Converter.byteToString(media.getSize()));
+ if(media.getSize() > 0) {
+ holder.progressLeft.setText(Converter.byteToString(media.getSize()));
+ } else {
+ holder.progressLeft.setText("");
+ }
holder.progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
holder.progress.setVisibility(View.GONE);
}
@@ -140,14 +156,54 @@ public class QueueListAdapter extends BaseAdapter {
holder.butSecondary.setTag(item);
holder.butSecondary.setOnClickListener(secondaryActionListener);
- Picasso.with(context)
+ Glide.with(context)
.load(item.getImageUri())
- .fit()
- .into(holder.imageView);
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
+ .into(new CoverTarget(item.getFeed().getImageUri(), holder.placeholder, holder.cover));
return convertView;
}
+ private class CoverTarget extends GlideDrawableImageViewTarget {
+
+ private final WeakReference<Uri> fallback;
+ private final WeakReference<TextView> placeholder;
+ private final WeakReference<ImageView> cover;
+
+ public CoverTarget(Uri fallbackUri, TextView txtvPlaceholder, ImageView imgvCover) {
+ super(imgvCover);
+ fallback = new WeakReference<>(fallbackUri);
+ placeholder = new WeakReference<>(txtvPlaceholder);
+ cover = new WeakReference<>(imgvCover);
+ }
+
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ Uri fallbackUri = fallback.get();
+ TextView txtvPlaceholder = placeholder.get();
+ ImageView imgvCover = cover.get();
+ if(fallbackUri != null && txtvPlaceholder != null && imgvCover != null) {
+ Glide.with(context)
+ .load(fallbackUri)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
+ .into(new CoverTarget(null, txtvPlaceholder, imgvCover));
+ }
+ }
+
+ @Override
+ public void onResourceReady(GlideDrawable drawable, GlideAnimation anim) {
+ super.onResourceReady(drawable, anim);
+ TextView txtvPlaceholder = placeholder.get();
+ if(txtvPlaceholder != null) {
+ txtvPlaceholder.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+
private View.OnClickListener secondaryActionListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -156,10 +212,10 @@ public class QueueListAdapter extends BaseAdapter {
}
};
-
static class Holder {
ImageView dragHandle;
- ImageView imageView;
+ ImageView cover;
+ TextView placeholder;
TextView title;
TextView pubDate;
TextView progressLeft;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java
index cedce7903..83f5dcb4d 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SearchlistAdapter.java
@@ -8,13 +8,15 @@ import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
/**
* List adapter for search activity.
@@ -73,9 +75,13 @@ public class SearchlistAdapter extends BaseAdapter {
holder.title.setText(feed.getTitle());
holder.subtitle.setVisibility(View.GONE);
- Picasso.with(context)
+ Glide.with(context)
.load(feed.getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(holder.cover);
} else if (component.getClass() == FeedItem.class) {
@@ -86,9 +92,13 @@ public class SearchlistAdapter extends BaseAdapter {
holder.subtitle.setText(result.getSubtitle());
}
- Picasso.with(context)
+ Glide.with(context)
.load(item.getFeed().getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(holder.cover);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
index b85709c5e..743f9fc86 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
@@ -8,13 +8,15 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetPodcast;
/**
@@ -49,9 +51,13 @@ public class PodcastListAdapter extends ArrayAdapter<GpodnetPodcast> {
}
if (StringUtils.isNotBlank(podcast.getLogoUrl())) {
- Picasso.with(convertView.getContext())
+ Glide.with(convertView.getContext())
.load(podcast.getLogoUrl())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(holder.image);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
index 4fc2838b7..08ffdd197 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java
@@ -1,23 +1,18 @@
package de.danoeh.antennapod.adapter.itunes;
import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.AsyncTask;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+
import org.json.JSONException;
import org.json.JSONObject;
-import java.io.IOException;
import java.util.List;
import de.danoeh.antennapod.R;
@@ -46,55 +41,6 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
this.context = context;
}
- /**
- * Updates the given ImageView with the image in the given Podcast's imageUrl
- */
- class FetchImageTask extends AsyncTask<Void,Void,Bitmap>{
- /**
- * Current podcast
- */
- private final Podcast podcast;
-
- /**
- * ImageView to be updated
- */
- private final ImageView imageView;
-
- /**
- * Constructor
- *
- * @param podcast Podcast that has the image
- * @param imageView UI image to be updated
- */
- FetchImageTask(Podcast podcast, ImageView imageView){
- this.podcast = podcast;
- this.imageView = imageView;
- }
-
- //Get the image from the url
- @Override
- protected Bitmap doInBackground(Void... params) {
- HttpClient client = new DefaultHttpClient();
- HttpGet get = new HttpGet(podcast.imageUrl);
- try {
- HttpResponse response = client.execute(get);
- return BitmapFactory.decodeStream(response.getEntity().getContent());
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- //Set the background image for the podcast
- @Override
- protected void onPostExecute(Bitmap img) {
- super.onPostExecute(img);
- if(img!=null) {
- imageView.setImageBitmap(img);
- }
- }
- }
-
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//Current podcast
@@ -121,7 +67,13 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> {
viewHolder.titleView.setText(podcast.title);
//Update the empty imageView with the image from the feed
- new FetchImageTask(podcast,viewHolder.coverView).execute();
+ Glide.with(context)
+ .load(podcast.imageUrl)
+ .placeholder(R.color.light_gray)
+ .diskCacheStrategy(DiskCacheStrategy.NONE)
+ .fitCenter()
+ .dontAnimate()
+ .into(viewHolder.coverView);
//Feed the grid view
return view;
diff --git a/app/src/main/java/de/danoeh/antennapod/config/ApplicationCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/ApplicationCallbacksImpl.java
index 4d9be5d78..008aacfa5 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/ApplicationCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/ApplicationCallbacksImpl.java
@@ -8,7 +8,6 @@ import android.content.Intent;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.activity.StorageErrorActivity;
import de.danoeh.antennapod.core.ApplicationCallbacks;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
public class ApplicationCallbacksImpl implements ApplicationCallbacks {
@@ -22,8 +21,4 @@ public class ApplicationCallbacksImpl implements ApplicationCallbacks {
return new Intent(context, StorageErrorActivity.class);
}
- @Override
- public void setUpdateInterval(long updateInterval) {
- UserPreferences.restartUpdateAlarm(updateInterval, updateInterval);
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
index 10666aa36..932b9d22f 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
@@ -14,7 +14,6 @@ public class ClientConfigurator {
ClientConfig.downloadServiceCallbacks = new DownloadServiceCallbacksImpl();
ClientConfig.gpodnetCallbacks = new GpodnetCallbacksImpl();
ClientConfig.playbackServiceCallbacks = new PlaybackServiceCallbacksImpl();
- ClientConfig.storageCallbacks = new StorageCallbacksImpl();
ClientConfig.flattrCallbacks = new FlattrCallbacksImpl();
ClientConfig.dbTasksCallbacks = new DBTasksCallbacksImpl();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java
deleted file mode 100644
index 943e05690..000000000
--- a/app/src/main/java/de/danoeh/antennapod/config/StorageCallbacksImpl.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package de.danoeh.antennapod.config;
-
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.util.Log;
-
-import de.danoeh.antennapod.core.StorageCallbacks;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
-
-public class StorageCallbacksImpl implements StorageCallbacks {
-
- @Override
- public int getDatabaseVersion() {
- return 15;
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
- + newVersion + ".");
- if (oldVersion <= 1) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
- + PodDBAdapter.KEY_TYPE + " TEXT");
- }
- if (oldVersion <= 2) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
- + " ADD COLUMN " + PodDBAdapter.KEY_LINK + " TEXT");
- }
- if (oldVersion <= 3) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
- + " ADD COLUMN " + PodDBAdapter.KEY_ITEM_IDENTIFIER + " TEXT");
- }
- if (oldVersion <= 4) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
- + PodDBAdapter.KEY_FEED_IDENTIFIER + " TEXT");
- }
- if (oldVersion <= 5) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
- + " ADD COLUMN " + PodDBAdapter.KEY_REASON_DETAILED + " TEXT");
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
- + " ADD COLUMN " + PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE + " TEXT");
- }
- if (oldVersion <= 6) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
- + " ADD COLUMN " + PodDBAdapter.KEY_CHAPTER_TYPE + " INTEGER");
- }
- if (oldVersion <= 7) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
- + " ADD COLUMN " + PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE
- + " INTEGER");
- }
- if (oldVersion <= 8) {
- final int KEY_ID_POSITION = 0;
- final int KEY_MEDIA_POSITION = 1;
-
- // Add feeditem column to feedmedia table
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
- + " ADD COLUMN " + PodDBAdapter.KEY_FEEDITEM
- + " INTEGER");
- Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS,
- new String[]{PodDBAdapter.KEY_ID, PodDBAdapter.KEY_MEDIA}, "? > 0",
- new String[]{PodDBAdapter.KEY_MEDIA}, null, null, null);
- if (feeditemCursor.moveToFirst()) {
- db.beginTransaction();
- ContentValues contentValues = new ContentValues();
- do {
- long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION);
- contentValues.put(PodDBAdapter.KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION));
- db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, PodDBAdapter.KEY_ID + "=?", new String[]{String.valueOf(mediaId)});
- contentValues.clear();
- } while (feeditemCursor.moveToNext());
- db.setTransactionSuccessful();
- db.endTransaction();
- }
- feeditemCursor.close();
- }
- if (oldVersion <= 9) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD
- + " INTEGER DEFAULT 1");
- }
- if (oldVersion <= 10) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS
- + " INTEGER");
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
- + " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS
- + " INTEGER");
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
- + " ADD COLUMN " + PodDBAdapter.KEY_PLAYED_DURATION
- + " INTEGER");
- }
- if (oldVersion <= 11) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_USERNAME
- + " TEXT");
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_PASSWORD
- + " TEXT");
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
- + " ADD COLUMN " + PodDBAdapter.KEY_IMAGE
- + " INTEGER");
- }
- if (oldVersion <= 12) {
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_IS_PAGED + " INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_NEXT_PAGE_LINK + " TEXT");
- }
- if (oldVersion <= 13) {
- // remove duplicate rows in "Chapters" table that were created because of a bug.
- db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " +
- "(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)",
- PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
- PodDBAdapter.KEY_ID,
- PodDBAdapter.KEY_ID,
- PodDBAdapter.KEY_ID,
- PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
- PodDBAdapter.KEY_TITLE,
- PodDBAdapter.KEY_START,
- PodDBAdapter.KEY_FEEDITEM,
- PodDBAdapter.KEY_LINK,
- PodDBAdapter.KEY_CHAPTER_TYPE));
- }
- if(oldVersion <= 14) {
-
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
- + " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER");
- db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
- + " SET " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " = "
- + "(SELECT " + PodDBAdapter.KEY_AUTO_DOWNLOAD
- + " FROM " + PodDBAdapter.TABLE_NAME_FEEDS
- + " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID
- + " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")");
-
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT");
-
-
- db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
- + " ADD COLUMN " + PodDBAdapter.KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0");
-
- // create indexes
- db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED);
- db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE);
- db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM);
- db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM);
- db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
- }
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
new file mode 100644
index 000000000..8a4a4efbf
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -0,0 +1,414 @@
+package de.danoeh.antennapod.dialog;
+
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.app.Fragment;
+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.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.joanzapata.android.iconify.IconDrawable;
+import com.joanzapata.android.iconify.Iconify;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
+import de.danoeh.antennapod.core.feed.FeedItem;
+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.util.LongList;
+
+public class EpisodesApplyActionFragment extends Fragment {
+
+ public String TAG = "EpisodeActionFragment";
+
+ private ListView mListView;
+ private ArrayAdapter<String> mAdapter;
+
+ private Button btnAddToQueue;
+ private Button btnMarkAsPlayed;
+ private Button btnMarkAsUnplayed;
+ private Button btnDownload;
+ private Button btnDelete;
+
+ private final Map<Long,FeedItem> idMap;
+ private final List<FeedItem> episodes;
+ private final List<String> titles = new ArrayList();
+ private final LongList checkedIds = new LongList();
+
+ private MenuItem mSelectToggle;
+
+ private int textColor;
+
+ public EpisodesApplyActionFragment(List<FeedItem> episodes) {
+ this.episodes = episodes;
+ this.idMap = new HashMap<>(episodes.size());
+ for(FeedItem episode : episodes) {
+ this.idMap.put(episode.getId(), episode);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.episodes_apply_action_fragment, container, false);
+
+ mListView = (ListView) view.findViewById(android.R.id.list);
+ mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+ mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView<?> ListView, View view, int position, long rowId) {
+ long id = episodes.get(position).getId();
+ if (checkedIds.contains(id)) {
+ checkedIds.remove(id);
+ } else {
+ checkedIds.add(id);
+ }
+ refreshCheckboxes();
+ }
+ });
+
+ for(FeedItem episode : episodes) {
+ titles.add(episode.getTitle());
+ }
+
+ mAdapter = new ArrayAdapter<>(getActivity(),
+ android.R.layout.simple_list_item_multiple_choice, titles);
+ mListView.setAdapter(mAdapter);
+ checkAll();
+
+ btnAddToQueue = (Button) view.findViewById(R.id.btnAddToQueue);
+ btnAddToQueue.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ queueChecked();
+ }
+ });
+ btnMarkAsPlayed = (Button) view.findViewById(R.id.btnMarkAsPlayed);
+ btnMarkAsPlayed.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ markedCheckedPlayed();
+ }
+ });
+ btnMarkAsUnplayed = (Button) view.findViewById(R.id.btnMarkAsUnplayed);
+ btnMarkAsUnplayed.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ markedCheckedUnplayed();
+ }
+ });
+ btnDownload = (Button) view.findViewById(R.id.btnDownload);
+ btnDownload.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ downloadChecked();
+ }
+ });
+ btnDelete = (Button) view.findViewById(R.id.btnDelete);
+ btnDelete.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ deleteChecked();
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.episodes_apply_action_options, menu);
+
+ int[] attrs = { android.R.attr.textColor };
+ TypedArray ta = getActivity().obtainStyledAttributes(attrs);
+ textColor = ta.getColor(0, Color.GRAY);
+ ta.recycle();
+
+ menu.findItem(R.id.sort).setIcon(new IconDrawable(getActivity(),
+ Iconify.IconValue.fa_sort).color(textColor).actionBarSize());
+
+ mSelectToggle = menu.findItem(R.id.select_toggle);
+ mSelectToggle.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ if (checkedIds.size() == episodes.size()) {
+ checkNone();
+ } else {
+ checkAll();
+ }
+ return true;
+ }
+ });
+
+ menu.findItem(R.id.select_options).setIcon(new IconDrawable(getActivity(),
+ Iconify.IconValue.fa_caret_down).color(textColor).actionBarSize());
+ }
+
+ @Override
+ public void onPrepareOptionsMenu (Menu menu) {
+ Iconify.IconValue iVal;
+ if(checkedIds.size() == episodes.size()) {
+ iVal = Iconify.IconValue.fa_check_square_o;
+ } else if(checkedIds.size() == 0) {
+ iVal = Iconify.IconValue.fa_square_o;
+ } else {
+ iVal = Iconify.IconValue.fa_minus_square_o;
+ }
+ mSelectToggle.setIcon(new IconDrawable(getActivity(), iVal).color(textColor).actionBarSize());
+
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int resId = 0;
+ switch(item.getItemId()) {
+ case R.id.select_options:
+ return true;
+ case R.id.check_all:
+ checkAll();
+ resId = R.string.selected_all_label;
+ break;
+ case R.id.check_none:
+ checkNone();
+ resId = R.string.deselected_all_label;
+ break;
+ case R.id.check_played:
+ checkPlayed(true);
+ resId = R.string.selected_played_label;
+ break;
+ case R.id.check_unplayed:
+ checkPlayed(false);
+ resId = R.string.selected_unplayed_label;
+ break;
+ case R.id.check_downloaded:
+ checkDownloaded(true);
+ resId = R.string.selected_downloaded_label;
+ break;
+ case R.id.check_not_downloaded:
+ checkDownloaded(false);
+ resId = R.string.selected_not_downloaded_label;
+ break;
+ case R.id.sort_title_a_z:
+ sortByTitle(false);
+ return true;
+ case R.id.sort_title_z_a:
+ sortByTitle(true);
+ return true;
+ case R.id.sort_date_new_old:
+ sortByDate(true);
+ return true;
+ case R.id.sort_date_old_new:
+ sortByDate(false);
+ return true;
+ case R.id.sort_duration_long_short:
+ sortByDuration(true);
+ return true;
+ case R.id.sort_duration_short_long:
+ sortByDuration(false);
+ return true;
+ }
+ if(resId != 0) {
+ Toast.makeText(getActivity(), resId, Toast.LENGTH_SHORT).show();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void sortByTitle(final boolean reverse) {
+ Collections.sort(episodes, new Comparator<FeedItem>() {
+ @Override
+ public int compare(FeedItem lhs, FeedItem rhs) {
+ if (reverse) {
+ return -1 * lhs.getTitle().compareTo(rhs.getTitle());
+ } else {
+ return lhs.getTitle().compareTo(rhs.getTitle());
+ }
+ }
+ });
+ refreshTitles();
+ refreshCheckboxes();
+ }
+
+ private void sortByDate(final boolean reverse) {
+ Collections.sort(episodes, new Comparator<FeedItem>() {
+ @Override
+ public int compare(FeedItem lhs, FeedItem rhs) {
+ if (lhs.getPubDate() == null) {
+ return -1;
+ } else if (rhs.getPubDate() == null) {
+ return 1;
+ }
+ int code = lhs.getPubDate().compareTo(rhs.getPubDate());
+ if (reverse) {
+ return -1 * code;
+ } else {
+ return code;
+ }
+ }
+ });
+ refreshTitles();
+ refreshCheckboxes();
+ }
+
+ private void sortByDuration(final boolean reverse) {
+ Collections.sort(episodes, new Comparator<FeedItem>() {
+ @Override
+ public int compare(FeedItem lhs, FeedItem rhs) {
+ int ordering;
+ if (false == lhs.hasMedia()) {
+ ordering = 1;
+ } else if (false == rhs.hasMedia()) {
+ ordering = -1;
+ } else {
+ ordering = lhs.getMedia().getDuration() - rhs.getMedia().getDuration();
+ }
+ if(reverse) {
+ return -1 * ordering;
+ } else {
+ return ordering;
+ }
+ }
+ });
+ refreshTitles();
+ refreshCheckboxes();
+ }
+
+ private void checkAll() {
+ for (FeedItem episode : episodes) {
+ if(false == checkedIds.contains(episode.getId())) {
+ checkedIds.add(episode.getId());
+ }
+ }
+ refreshCheckboxes();
+ }
+
+ private void checkNone() {
+ checkedIds.clear();
+ refreshCheckboxes();
+ }
+
+ private void checkPlayed(boolean isPlayed) {
+ for (FeedItem episode : episodes) {
+ if(episode.isPlayed() == isPlayed) {
+ if(!checkedIds.contains(episode.getId())) {
+ checkedIds.add(episode.getId());
+ }
+ } else {
+ if(checkedIds.contains(episode.getId())) {
+ checkedIds.remove(episode.getId());
+ }
+ }
+ }
+ refreshCheckboxes();
+ }
+
+ private void checkDownloaded(boolean isDownloaded) {
+ for (FeedItem episode : episodes) {
+ if(episode.hasMedia() && episode.getMedia().isDownloaded() == isDownloaded) {
+ if(!checkedIds.contains(episode.getId())) {
+ checkedIds.add(episode.getId());
+ }
+ } else {
+ if(checkedIds.contains(episode.getId())) {
+ checkedIds.remove(episode.getId());
+ }
+ }
+ }
+ refreshCheckboxes();
+ }
+
+ private void refreshTitles() {
+ titles.clear();
+ for(FeedItem episode : episodes) {
+ titles.add(episode.getTitle());
+ }
+ mAdapter.notifyDataSetChanged();
+ }
+
+ private void refreshCheckboxes() {
+ for (int i = 0; i < episodes.size(); i++) {
+ FeedItem episode = episodes.get(i);
+ boolean checked = checkedIds.contains(episode.getId());
+ mListView.setItemChecked(i, checked);
+ }
+ ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity());
+ }
+
+ private void queueChecked() {
+ LongList orderedIds = new LongList();
+ for(FeedItem episode : episodes) {
+ if(checkedIds.contains(episode.getId())) {
+ orderedIds.add((episode.getId()));
+ }
+ }
+ DBWriter.addQueueItem(getActivity(), false, orderedIds.toArray());
+ close();
+ }
+
+ private void markedCheckedPlayed() {
+ DBWriter.markItemRead(getActivity(), true, checkedIds.toArray());
+ close();
+ }
+
+ private void markedCheckedUnplayed() {
+ DBWriter.markItemRead(getActivity(), false, checkedIds.toArray());
+ close();
+ }
+
+ private void downloadChecked() {
+ // download the check episodes in the same order as they are currently displayed
+ List<FeedItem> toDownload = new ArrayList<FeedItem>(checkedIds.size());
+ for(FeedItem episode : episodes) {
+ if(checkedIds.contains(episode.getId())) {
+ toDownload.add(episode);
+ }
+ }
+ try {
+ DBTasks.downloadFeedItems(getActivity(), toDownload.toArray(new FeedItem[0]));
+ } catch (DownloadRequestException e) {
+ e.printStackTrace();
+ DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());
+ }
+ close();
+ }
+
+ private void deleteChecked() {
+ for(long id : checkedIds.toArray()) {
+ FeedItem episode = idMap.get(id);
+ if(episode.hasMedia()) {
+ DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
+ }
+ }
+ close();
+ }
+
+ private void close() {
+ getActivity().getSupportFragmentManager().popBackStack();
+ }
+
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java
index 6561d501e..5c4d4c430 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java
@@ -39,9 +39,9 @@ public abstract class TimeDialog extends Dialog {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
- String[] spinnerContent = new String[]{context.getString(R.string.time_unit_seconds),
- context.getString(R.string.time_unit_minutes),
- context.getString(R.string.time_unit_hours)};
+ String[] spinnerContent = new String[]{context.getString(R.string.time_seconds),
+ context.getString(R.string.time_minutes),
+ context.getString(R.string.time_hours)};
setContentView(R.layout.time_dialog);
etxtTime = (EditText) findViewById(R.id.etxtTime);
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 ff5485251..b4c4f1822 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -30,8 +30,8 @@ import java.util.concurrent.atomic.AtomicReference;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
import de.danoeh.antennapod.adapter.AllEpisodesListAdapter;
+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.feed.EventDistributor;
@@ -72,10 +72,10 @@ public class AllEpisodesFragment extends Fragment {
private TextView txtvEmpty;
private ProgressBar progLoading;
private ContextMenu contextMenu;
+ private AdapterView.AdapterContextMenuInfo lastMenuInfo = null;
private List<FeedItem> episodes;
private LongList queuedItemsIds;
- private LongList newItemsIds;
private List<Downloader> downloaderList;
private boolean itemsLoaded = false;
@@ -341,12 +341,16 @@ public class AllEpisodesFragment extends Fragment {
}
contextMenu = menu;
- FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, true, queuedItemsIds);
+ lastMenuInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
+ FeedItemMenuHandler.onPrepareMenu(getActivity(), contextMenuInterface, item, true, queuedItemsIds);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ if(menuInfo == null) {
+ menuInfo = lastMenuInfo;
+ }
FeedItem selectedItem = itemAccess.getItem(menuInfo.position);
if (selectedItem == null) {
@@ -380,14 +384,7 @@ public class AllEpisodesFragment extends Fragment {
private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@Override
- public void onContentChanged() {
- if (listAdapter != null) {
- listAdapter.notifyDataSetChanged();
- }
- }
-
- @Override
- public void onDownloadDataAvailable(List<Downloader> downloaderList) {
+ public void onContentChanged(List<Downloader> downloaderList) {
AllEpisodesFragment.this.downloaderList = downloaderList;
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
@@ -434,18 +431,6 @@ public class AllEpisodesFragment extends Fragment {
return false;
}
}
-
- @Override
- public boolean isNew(FeedItem item) {
- if (itemsLoaded) {
- // should actually never be called in NewEpisodesFragment, but better safe than sorry
- return showOnlyNewEpisodes || newItemsIds.contains(item.getId());
- } else {
- return false;
- }
- }
-
-
};
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@@ -510,8 +495,7 @@ public class AllEpisodesFragment extends Fragment {
} else {
return new Object[]{
DBReader.getRecentlyPublishedEpisodes(context, RECENT_EPISODES_LIMIT),
- DBReader.getQueueIDList(context),
- DBReader.getNewItemIds(context)
+ DBReader.getQueueIDList(context)
};
}
} else {
@@ -528,7 +512,6 @@ public class AllEpisodesFragment extends Fragment {
if (lists != null) {
episodes = (List<FeedItem>) lists[0];
queuedItemsIds = (LongList) lists[1];
- newItemsIds = (LongList) lists[2];
itemsLoaded = true;
if (viewsCreated && activity.get() != null) {
onFragmentLoaded();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
index 3076f8136..a1667cce0 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java
@@ -10,12 +10,14 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.AudioplayerActivity;
import de.danoeh.antennapod.activity.AudioplayerActivity.AudioplayerContentFragment;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.util.playback.Playable;
/**
@@ -80,8 +82,12 @@ public class CoverFragment extends Fragment implements
public void run() {
Context c = getActivity();
if (c != null) {
- Picasso.with(c)
+ Glide.with(c)
.load(media.getImageUri())
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .dontAnimate()
.into(imgvCover);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
index fdb128f03..634c3c546 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
@@ -11,9 +11,11 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.playback.Playable;
@@ -55,7 +57,7 @@ public class ExternalPlayerFragment extends Fragment {
public void onClick(View v) {
Log.d(TAG, "layoutInfo was clicked");
- if (controller.getMedia() != null) {
+ if (controller != null && controller.getMedia() != null) {
startActivity(PlaybackService.getPlayerActivityIntent(
getActivity(), controller.getMedia()));
}
@@ -192,14 +194,18 @@ public class ExternalPlayerFragment extends Fragment {
private boolean loadMediaInfo() {
Log.d(TAG, "Loading media info");
- if (controller.serviceAvailable()) {
+ if (controller != null && controller.serviceAvailable()) {
Playable media = controller.getMedia();
if (media != null) {
txtvTitle.setText(media.getEpisodeTitle());
- Picasso.with(getActivity())
+ Glide.with(getActivity())
.load(media.getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(imgvCover);
fragmentLayout.setVisibility(View.VISIBLE);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index a7c6d62e6..9693e6886 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -25,12 +25,12 @@ import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
-import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.Converter;
+import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.ShownotesProvider;
import de.danoeh.antennapod.core.util.playback.Playable;
@@ -104,8 +104,7 @@ public class ItemDescriptionFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Creating view");
+ Log.d(TAG, "Creating view");
webvDescription = new WebView(getActivity());
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
if (Build.VERSION.SDK_INT >= 11
@@ -141,8 +140,7 @@ public class ItemDescriptionFragment extends Fragment {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Page finished");
+ Log.d(TAG, "Page finished");
// Restoring the scroll position might not always work
view.postDelayed(new Runnable() {
@@ -163,15 +161,13 @@ public class ItemDescriptionFragment extends Fragment {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Fragment attached");
+ Log.d(TAG, "Fragment attached");
}
@Override
public void onDetach() {
super.onDetach();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Fragment detached");
+ Log.d(TAG, "Fragment detached");
if (webViewLoader != null) {
webViewLoader.cancel(true);
}
@@ -180,8 +176,7 @@ public class ItemDescriptionFragment extends Fragment {
@Override
public void onDestroy() {
super.onDestroy();
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Fragment destroyed");
+ Log.d(TAG, "Fragment destroyed");
if (webViewLoader != null) {
webViewLoader.cancel(true);
}
@@ -195,8 +190,7 @@ public class ItemDescriptionFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Creating fragment");
+ Log.d(TAG, "Creating fragment");
Bundle args = getArguments();
saveState = args.getBoolean(ARG_SAVE_STATE, false);
highlightTimecodes = args.getBoolean(ARG_HIGHLIGHT_TIMECODES, false);
@@ -258,11 +252,7 @@ public class ItemDescriptionFragment extends Fragment {
WebView.HitTestResult r = webvDescription.getHitTestResult();
if (r != null
&& r.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Link of webview was long-pressed. Extra: "
- + r.getExtra()
- );
+ Log.d(TAG, "Link of webview was long-pressed. Extra: " + r.getExtra());
selectedURL = r.getExtra();
webvDescription.showContextMenu();
return true;
@@ -281,8 +271,10 @@ public class ItemDescriptionFragment extends Fragment {
switch (item.getItemId()) {
case R.id.open_in_browser_item:
Uri uri = Uri.parse(selectedURL);
- getActivity()
- .startActivity(new Intent(Intent.ACTION_VIEW, uri));
+ final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ if(IntentUtils.isCallable(getActivity(), intent)) {
+ getActivity().startActivity(intent);
+ }
break;
case R.id.share_url_item:
ShareUtils.shareLink(getActivity(), selectedURL);
@@ -331,8 +323,12 @@ public class ItemDescriptionFragment extends Fragment {
R.string.go_to_position_label);
menu.setHeaderTitle(Converter.getDurationStringLong(Timeline.getTimecodeLinkTime(selectedURL)));
} else {
- menu.add(Menu.NONE, R.id.open_in_browser_item, Menu.NONE,
- R.string.open_in_browser_label);
+ Uri uri = Uri.parse(selectedURL);
+ final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ if(IntentUtils.isCallable(getActivity(), intent)) {
+ menu.add(Menu.NONE, R.id.open_in_browser_item, Menu.NONE,
+ R.string.open_in_browser_label);
+ }
menu.add(Menu.NONE, R.id.copy_url_item, Menu.NONE,
R.string.copy_url_label);
menu.add(Menu.NONE, R.id.share_url_item, Menu.NONE,
@@ -358,8 +354,7 @@ public class ItemDescriptionFragment extends Fragment {
// /webvDescription.loadData(url, "text/html", "utf-8");
webvDescription.loadDataWithBaseURL(null, data, "text/html",
"utf-8", "about:blank");
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Webview loaded");
+ Log.d(TAG, "Webview loaded");
webViewLoader = null;
}
@@ -370,8 +365,7 @@ public class ItemDescriptionFragment extends Fragment {
@Override
protected Void doInBackground(Void... params) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Loading Webview");
+ Log.d(TAG, "Loading Webview");
try {
Activity activity = getActivity();
if (activity != null) {
@@ -397,24 +391,17 @@ public class ItemDescriptionFragment extends Fragment {
private void savePreference() {
if (saveState) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Saving preferences");
+ Log.d(TAG, "Saving preferences");
SharedPreferences prefs = getActivity().getSharedPreferences(PREF,
Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
if (media != null && webvDescription != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Saving scroll position: "
- + webvDescription.getScrollY()
- );
+ Log.d(TAG, "Saving scroll position: " + webvDescription.getScrollY());
editor.putInt(PREF_SCROLL_Y, webvDescription.getScrollY());
editor.putString(PREF_PLAYABLE_ID, media.getIdentifier()
.toString());
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "savePreferences was called while media or webview was null");
+ Log.d(TAG, "savePreferences was called while media or webview was null");
editor.putInt(PREF_SCROLL_Y, -1);
editor.putString(PREF_PLAYABLE_ID, "");
}
@@ -424,8 +411,7 @@ public class ItemDescriptionFragment extends Fragment {
private boolean restoreFromPreference() {
if (saveState) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Restoring from preferences");
+ Log.d(TAG, "Restoring from preferences");
Activity activity = getActivity();
if (activity != null) {
SharedPreferences prefs = activity.getSharedPreferences(
@@ -435,8 +421,7 @@ public class ItemDescriptionFragment extends Fragment {
if (scrollY != -1 && media != null
&& id.equals(media.getIdentifier().toString())
&& webvDescription != null) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Restored scroll Position: " + scrollY);
+ Log.d(TAG, "Restored scroll Position: " + scrollY);
webvDescription.scrollTo(webvDescription.getScrollX(),
scrollY);
return true;
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 51a1e2252..4edb7f36f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -1,7 +1,8 @@
package de.danoeh.antennapod.fragment;
import android.annotation.TargetApi;
-import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.net.Uri;
@@ -18,7 +19,9 @@ import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
+import android.view.ContextMenu;
import android.view.LayoutInflater;
+import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -32,7 +35,8 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
-import com.squareup.picasso.Picasso;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.List;
@@ -45,6 +49,7 @@ import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.QueueEvent;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -53,7 +58,9 @@ 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.Converter;
+import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LongList;
+import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.playback.Timeline;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.greenrobot.event.EventBus;
@@ -107,6 +114,11 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
private ImageButton butMore;
private PopupMenu popupMenu;
+ /**
+ * URL that was selected via long-press.
+ */
+ private String selectedURL;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -194,20 +206,19 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
webvDescription.getSettings().setLayoutAlgorithm(
WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webvDescription.getSettings().setLoadWithOverviewMode(true);
+ webvDescription.setOnLongClickListener(webViewLongClickListener);
webvDescription.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- try {
+ if(IntentUtils.isCallable(getActivity(), intent)) {
startActivity(intent);
- } catch (ActivityNotFoundException e) {
- e.printStackTrace();
- return true;
}
return true;
}
});
+ registerForContextMenu(webvDescription);
imgvCover = (ImageView) header.findViewById(R.id.imgvCover);
progbarDownload = (ProgressBar) header.findViewById(R.id.progbarDownload);
@@ -272,10 +283,10 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
popupMenu.getMenu().clear();
popupMenu.inflate(R.menu.feeditem_options);
if (item.hasMedia()) {
- FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue);
+ FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue);
} else {
// these are already available via button1 and button2
- FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue,
+ FeedItemMenuHandler.onPrepareMenu(getActivity(), popupMenuInterface, item, true, queue,
R.id.mark_read_item, R.id.visit_website_item);
}
popupMenu.show();
@@ -313,7 +324,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
private void onFragmentLoaded() {
- progbarLoading.setVisibility(View.GONE);
+ progbarLoading.setVisibility(View.INVISIBLE);
if (webviewData != null) {
webvDescription.loadDataWithBaseURL(null, webviewData, "text/html",
"utf-8", "about:blank");
@@ -327,10 +338,16 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
txtvTitle.setText(item.getTitle());
txtvPublished.setText(DateUtils.formatDateTime(getActivity(), item.getPubDate().getTime(), DateUtils.FORMAT_ABBREV_ALL));
- Picasso.with(getActivity()).load(item.getImageUri())
- .fit()
+ Glide.with(getActivity())
+ .load(item.getImageUri())
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(imgvCover);
- progbarDownload.setVisibility(View.GONE);
+
+ progbarDownload.setVisibility(View.INVISIBLE);
if (item.hasMedia() && downloaderList != null) {
for (Downloader downloader : downloaderList) {
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
@@ -346,7 +363,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
TypedArray drawables = getActivity().obtainStyledAttributes(new int[]{R.attr.navigation_accept,
R.attr.location_web_site});
- if (!item.isRead()) {
+ if (!item.isPlayed()) {
butAction1.setCompoundDrawablesWithIntrinsicBounds(drawables.getDrawable(0), null, null, null);
butAction1.setText(getActivity().getString(R.string.mark_read_label));
butAction1.setVisibility(View.VISIBLE);
@@ -398,6 +415,83 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
getLoaderManager().restartLoader(0, null, ItemFragment.this);
}
+ private View.OnLongClickListener webViewLongClickListener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ WebView.HitTestResult r = webvDescription.getHitTestResult();
+ if (r != null
+ && r.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
+ Log.d(TAG, "Link of webview was long-pressed. Extra: " + r.getExtra());
+ selectedURL = r.getExtra();
+ webvDescription.showContextMenu();
+ return true;
+ }
+ selectedURL = null;
+ return false;
+ }
+ };
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ boolean handled = selectedURL != null;
+ if (selectedURL != null) {
+ switch (item.getItemId()) {
+ case R.id.open_in_browser_item:
+ Uri uri = Uri.parse(selectedURL);
+ final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ if(IntentUtils.isCallable(getActivity(), intent)) {
+ getActivity().startActivity(intent);
+ }
+ break;
+ case R.id.share_url_item:
+ ShareUtils.shareLink(getActivity(), selectedURL);
+ break;
+ case R.id.copy_url_item:
+ if (android.os.Build.VERSION.SDK_INT >= 11) {
+ ClipData clipData = ClipData.newPlainText(selectedURL,
+ selectedURL);
+ android.content.ClipboardManager cm = (android.content.ClipboardManager) getActivity()
+ .getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setPrimaryClip(clipData);
+ } else {
+ android.text.ClipboardManager cm = (android.text.ClipboardManager) getActivity()
+ .getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setText(selectedURL);
+ }
+ Toast t = Toast.makeText(getActivity(),
+ R.string.copied_url_msg, Toast.LENGTH_SHORT);
+ t.show();
+ break;
+ default:
+ handled = false;
+ break;
+
+ }
+ selectedURL = null;
+ }
+ return handled;
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenu.ContextMenuInfo menuInfo) {
+ if (selectedURL != null) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ Uri uri = Uri.parse(selectedURL);
+ final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ if(IntentUtils.isCallable(getActivity(), intent)) {
+ menu.add(Menu.NONE, R.id.open_in_browser_item, Menu.NONE,
+ R.string.open_in_browser_label);
+ }
+ menu.add(Menu.NONE, R.id.copy_url_item, Menu.NONE,
+ R.string.copy_url_label);
+ menu.add(Menu.NONE, R.id.share_url_item, Menu.NONE,
+ R.string.share_url_label);
+ menu.setHeaderTitle(selectedURL);
+ }
+ }
+
@Override
public Loader<Pair<FeedItem,LongList>> onCreateLoader(int id, Bundle args) {
return new DBTaskLoader<Pair<FeedItem,LongList>>(getActivity()) {
@@ -445,14 +539,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba
private final DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@Override
- public void onContentChanged() {
- if (itemsLoaded && getActivity() != null) {
- updateAppearance();
- }
- }
-
- @Override
- public void onDownloadDataAvailable(List<Downloader> downloaderList) {
+ public void onContentChanged(List<Downloader> downloaderList) {
ItemFragment.this.downloaderList = downloaderList;
if (itemsLoaded && getActivity() != null) {
updateAppearance();
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 a9cbe8291..63ebf234e 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -4,13 +4,16 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.LightingColorFilter;
import android.os.AsyncTask;
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.view.MenuItemCompat;
-
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
@@ -29,8 +32,10 @@ import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.joanzapata.android.iconify.IconDrawable;
import com.joanzapata.android.iconify.Iconify;
-import com.squareup.picasso.Picasso;
import org.apache.commons.lang3.Validate;
@@ -43,7 +48,6 @@ 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.asynctask.PicassoProvider;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.EventDistributor;
@@ -53,6 +57,8 @@ 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.feed.QueueEvent;
+import de.danoeh.antennapod.core.glide.ApGlideSettings;
+import de.danoeh.antennapod.core.glide.FastBlurTransformation;
import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -61,6 +67,7 @@ import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
+import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
@@ -83,12 +90,11 @@ public class ItemlistFragment extends ListFragment {
protected FeedItemlistAdapter adapter;
private ContextMenu contextMenu;
+ private AdapterView.AdapterContextMenuInfo lastMenuInfo = null;
private long feedID;
private Feed feed;
private LongList queuedItemsIds;
- private LongList newItemsIds;
-
private boolean itemsLoaded = false;
private boolean viewsCreated = false;
@@ -155,6 +161,7 @@ public class ItemlistFragment extends ListFragment {
@Override
public void onResume() {
super.onResume();
+ Log.d(TAG, "onResume()");
updateProgressBarVisibility();
startItemLoader();
}
@@ -217,6 +224,18 @@ public class ItemlistFragment extends ListFragment {
return false;
}
});
+ if(feed == null || feed.getLink() == null) {
+ menu.findItem(R.id.share_link_item).setVisible(false);
+ menu.findItem(R.id.visit_website_item).setVisible(false);
+ }
+ int[] attrs = { android.R.attr.textColor };
+ TypedArray ta = getActivity().obtainStyledAttributes(attrs);
+ int textColor = ta.getColor(0, Color.GRAY);
+ ta.recycle();
+
+ menu.findItem(R.id.episode_actions).setIcon(new IconDrawable(getActivity(),
+ Iconify.IconValue.fa_gears).color(textColor).actionBarSize());
+
isUpdatingFeed = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
}
}
@@ -234,6 +253,10 @@ public class ItemlistFragment extends ListFragment {
try {
if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) {
switch (item.getItemId()) {
+ case R.id.episode_actions:
+ Fragment fragment = new EpisodesApplyActionFragment(feed.getItems());
+ ((MainActivity)getActivity()).loadChildFragment(fragment);
+ return true;
case R.id.remove_item:
final FeedRemover remover = new FeedRemover(
getActivity(), feed) {
@@ -302,12 +325,16 @@ public class ItemlistFragment extends ListFragment {
}
contextMenu = menu;
- FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, true, queuedItemsIds);
+ lastMenuInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
+ FeedItemMenuHandler.onPrepareMenu(getActivity(), contextMenuInterface, item, true, queuedItemsIds);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ if(menuInfo == null) {
+ menuInfo = lastMenuInfo;
+ }
// because of addHeaderView(), positions are increased by 1!
FeedItem selectedItem = itemAccess.getItem(menuInfo.position-1);
@@ -396,12 +423,15 @@ public class ItemlistFragment extends ListFragment {
private boolean insideOnFragmentLoaded = false;
private void onFragmentLoaded() {
+ if(!isVisible()) {
+ return;
+ }
insideOnFragmentLoaded = true;
if (adapter == null) {
setListAdapter(null);
setupHeaderView();
setupFooterView();
- adapter = new FeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(getActivity()), false);
+ adapter = new FeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(getActivity()), false, true);
setListAdapter(adapter);
downloadObserver = new DownloadObserver(getActivity(), new Handler(), downloadObserverCallback);
downloadObserver.onResume();
@@ -421,6 +451,10 @@ public class ItemlistFragment extends ListFragment {
}
private void refreshHeaderView() {
+ if (getListView() == null || feed == null) {
+ Log.e(TAG, "Unable to setup listview: listView = null or feed = null");
+ return;
+ }
if(feed.hasLastUpdateFailed()) {
txtvFailure.setVisibility(View.VISIBLE);
} else {
@@ -448,14 +482,7 @@ public class ItemlistFragment extends ListFragment {
private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@Override
- public void onContentChanged() {
- if (adapter != null) {
- adapter.notifyDataSetChanged();
- }
- }
-
- @Override
- public void onDownloadDataAvailable(List<Downloader> downloaderList) {
+ public void onContentChanged(List<Downloader> downloaderList) {
ItemlistFragment.this.downloaderList = downloaderList;
if (adapter != null) {
adapter.notifyDataSetChanged();
@@ -485,17 +512,26 @@ public class ItemlistFragment extends ListFragment {
txtvTitle.setText(feed.getTitle());
txtvAuthor.setText(feed.getAuthor());
- Picasso.with(getActivity())
+
+ // https://github.com/bumptech/glide/issues/529
+ imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
+
+ Glide.with(getActivity())
.load(feed.getImageUri())
.placeholder(R.color.image_readability_tint)
.error(R.color.image_readability_tint)
- .transform(PicassoProvider.blurTransformation)
- .resize(PicassoProvider.BLUR_IMAGE_SIZE, PicassoProvider.BLUR_IMAGE_SIZE)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .transform(new FastBlurTransformation(getActivity()))
+ .dontAnimate()
.into(imgvBackground);
- Picasso.with(getActivity())
+ Glide.with(getActivity())
.load(feed.getImageUri())
- .fit()
+ .placeholder(R.color.light_gray)
+ .error(R.color.light_gray)
+ .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
+ .fitCenter()
+ .dontAnimate()
.into(imgvCover);
butShowInfo.setOnClickListener(new View.OnClickListener() {
@@ -558,11 +594,6 @@ public class ItemlistFragment extends ListFragment {
}
@Override
- public boolean isNew(FeedItem item) {
- return (newItemsIds != null) && newItemsIds.contains(item.getId());
- }
-
- @Override
public int getItemDownloadProgressPercent(FeedItem item) {
if (downloaderList != null) {
for (Downloader downloader : downloaderList) {
@@ -599,13 +630,12 @@ public class ItemlistFragment extends ListFragment {
Context context = getActivity();
if (context != null) {
Feed feed = DBReader.getFeed(context, feedID);
- if(feed.getItemFilter() != null) {
+ if(feed != null && feed.getItemFilter() != null) {
FeedItemFilter filter = feed.getItemFilter();
feed.setItems(filter.filter(context, feed.getItems()));
}
LongList queuedItemsIds = DBReader.getQueueIDList(context);
- LongList newItemsIds = DBReader.getNewItemIds(context);
- return new Object[] { feed, queuedItemsIds, newItemsIds };
+ return new Object[] { feed, queuedItemsIds };
} else {
return null;
}
@@ -617,7 +647,6 @@ public class ItemlistFragment extends ListFragment {
if (res != null) {
feed = (Feed) res[0];
queuedItemsIds = (LongList) res[1];
- newItemsIds = res[2] == null ? null : (LongList) res[2];
itemsLoaded = true;
if (viewsCreated) {
onFragmentLoaded();
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
index 16789d694..edd4da7fe 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java
@@ -22,6 +22,8 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@@ -31,7 +33,7 @@ import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
import de.danoeh.antennapod.adapter.itunes.ItunesAdapter;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import static de.danoeh.antennapod.adapter.itunes.ItunesAdapter.*;
+import static de.danoeh.antennapod.adapter.itunes.ItunesAdapter.Podcast;
//Searches iTunes store for given string and displays results in a list
public class ItunesSearchFragment extends Fragment {
@@ -160,8 +162,18 @@ public class ItunesSearchFragment extends Fragment {
*
* @param query Search string
*/
- public SearchTask(String query){
- this.query = query;
+ public SearchTask(String query) {
+ String encodedQuery = null;
+ try {
+ encodedQuery = URLEncoder.encode(query, "UTF-8");
+ } catch(UnsupportedEncodingException e) {
+ // this won't ever be thrown
+ }
+ if(encodedQuery != null) {
+ this.query = encodedQuery;
+ } else {
+ this.query = query; // failsafe
+ }
}
//Get the podcast data
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 4bce3c7ba..9a25674b6 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -72,7 +72,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
Log.d(TAG, "remove(" + which + ")");
stopItemLoader();
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
- DBWriter.markItemRead(getActivity(), item.getId(), true);
+ DBWriter.markItemRead(getActivity(), true, item.getId());
undoBarController.showUndoBar(false,
getString(R.string.marked_as_read_label), new FeedItemUndoToken(item,
which)
@@ -88,7 +88,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
public void onUndo(FeedItemUndoToken token) {
if (token != null) {
long itemId = token.getFeedItemId();
- DBWriter.markItemRead(context, itemId, false);
+ DBWriter.markItemRead(context, false, itemId);
}
}
@Override
@@ -97,7 +97,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
long itemId = token.getFeedItemId();
FeedItem item = DBReader.getFeedItem(context, itemId);
FeedMedia media = item.getMedia();
- if(media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) {
+ if(media != null && media.hasAlmostEnded() && item.getFeed().getPreferences().getCurrentAutoDelete()) {
DBWriter.deleteFeedMediaOfItem(context, media.getId());
}
}
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 9099829d8..b094133d3 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -192,7 +192,10 @@ public class PlaybackHistoryFragment extends ListFragment {
private void onFragmentLoaded() {
if (adapter == null) {
- adapter = new FeedItemlistAdapter(getActivity(), itemAccess, new DefaultActionButtonCallback(activity.get()), true);
+ // played items shoudln't be transparent for this fragment since, *all* items
+ // in this fragment will, by definition, be played. So it serves no purpose and can make
+ // 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();
@@ -204,14 +207,7 @@ public class PlaybackHistoryFragment extends ListFragment {
private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@Override
- public void onContentChanged() {
- if (adapter != null) {
- adapter.notifyDataSetChanged();
- }
- }
-
- @Override
- public void onDownloadDataAvailable(List<Downloader> downloaderList) {
+ public void onContentChanged(List<Downloader> downloaderList) {
PlaybackHistoryFragment.this.downloaderList = downloaderList;
if (adapter != null) {
adapter.notifyDataSetChanged();
@@ -226,11 +222,6 @@ public class PlaybackHistoryFragment extends ListFragment {
}
@Override
- public boolean isNew(FeedItem item) {
- return false;
- }
-
- @Override
public int getItemDownloadProgressPercent(FeedItem item) {
if (downloaderList != null) {
for (Downloader downloader : downloaderList) {
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 d82c7b8f7..24c9fc425 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -47,6 +47,7 @@ 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.Converter;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.QueueSorter;
import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
@@ -66,12 +67,14 @@ public class QueueFragment extends Fragment {
EventDistributor.DOWNLOAD_QUEUED |
EventDistributor.PLAYER_STATUS_UPDATE;
+ private TextView infoBar;
private DragSortListView listView;
private QueueListAdapter listAdapter;
private TextView txtvEmpty;
private ProgressBar progLoading;
private ContextMenu contextMenu;
+ private AdapterView.AdapterContextMenuInfo lastMenuInfo = null;
private UndoBarController<FeedItemUndoToken> undoBarController;
@@ -325,16 +328,20 @@ public class QueueFragment extends Fragment {
}
contextMenu = menu;
+ lastMenuInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
LongList queueIds = new LongList(queue.size());
for(FeedItem queueItem : queue) {
queueIds.add(queueItem.getId());
}
- FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, true, queueIds);
+ FeedItemMenuHandler.onPrepareMenu(getActivity(), contextMenuInterface, item, true, queueIds);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ if(menuInfo == null) {
+ menuInfo = lastMenuInfo;
+ }
FeedItem selectedItem = itemAccess.getItem(menuInfo.position);
if (selectedItem == null) {
@@ -358,6 +365,7 @@ public class QueueFragment extends Fragment {
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.queue_label);
View root = inflater.inflate(R.layout.queue_fragment, container, false);
+ infoBar = (TextView) root.findViewById(R.id.info_bar);
listView = (DragSortListView) root.findViewById(android.R.id.list);
txtvEmpty = (TextView) root.findViewById(android.R.id.empty);
progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
@@ -426,7 +434,7 @@ public class QueueFragment extends Fragment {
long itemId = token.getFeedItemId();
FeedItem item = DBReader.getFeedItem(context, itemId);
FeedMedia media = item.getMedia();
- if(media != null && media.hasAlmostEnded() && UserPreferences.isAutoDelete()) {
+ if(media != null && media.hasAlmostEnded() && item.getFeed().getPreferences().getCurrentAutoDelete()) {
DBWriter.deleteFeedMediaOfItem(context, media.getId());
}
}
@@ -464,18 +472,25 @@ public class QueueFragment extends Fragment {
// we need to refresh the options menu because it sometimes
// needs data that may have just been loaded.
getActivity().supportInvalidateOptionsMenu();
- }
- private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
- @Override
- public void onContentChanged() {
- if (listAdapter != null && !blockDownloadObserverUpdate) {
- listAdapter.notifyDataSetChanged();
+ // refresh information bar
+ String info = queue.size() + getString(R.string.episodes_suffix);
+ if(queue.size() > 0) {
+ long duration = 0;
+ for(FeedItem item : queue) {
+ if(item.getMedia() != null) {
+ duration += item.getMedia().getDuration();
+ }
}
+ info += " \u2022 ";
+ info += Converter.getDurationStringLocalized(getActivity(), duration);
}
+ infoBar.setText(info);
+ }
+ private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
@Override
- public void onDownloadDataAvailable(List<Downloader> downloaderList) {
+ public void onContentChanged(List<Downloader> downloaderList) {
QueueFragment.this.downloaderList = downloaderList;
if (listAdapter != null && !blockDownloadObserverUpdate) {
listAdapter.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 b1b61f74b..eb4d18328 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
@@ -3,6 +3,7 @@ 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;
import android.widget.ListView;
import android.widget.Toast;
@@ -24,7 +25,7 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
* Displays all running downloads and provides actions to cancel them
*/
public class RunningDownloadsFragment extends ListFragment {
- private static final String TAG = "RunningDownloadsFragment";
+ private static final String TAG = "RunningDownloadsFrag";
private DownloadObserver downloadObserver;
private List<Downloader> downloaderList;
@@ -53,12 +54,8 @@ public class RunningDownloadsFragment extends ListFragment {
downloadObserver = new DownloadObserver(getActivity(), new Handler(), new DownloadObserver.Callback() {
@Override
- public void onContentChanged() {
- downloadlistAdapter.notifyDataSetChanged();
- }
-
- @Override
- public void onDownloadDataAvailable(List<Downloader> downloaderList) {
+ public void onContentChanged(List<Downloader> downloaderList) {
+ Log.d(TAG, "onContentChanged: downloaderList.size() == " + downloaderList.size());
RunningDownloadsFragment.this.downloaderList = downloaderList;
downloadlistAdapter.notifyDataSetChanged();
}
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 fc6225409..975493ce9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java
@@ -120,7 +120,7 @@ public class SearchFragment extends ListFragment {
SearchResult result = (SearchResult) l.getAdapter().getItem(position);
FeedComponent comp = result.getComponent();
if (comp.getClass() == Feed.class) {
- ((MainActivity) getActivity()).loadFeedFragmentById(comp.getId());
+ ((MainActivity) getActivity()).loadFeedFragmentById(comp.getId(), null);
} else {
if (comp.getClass() == FeedItem.class) {
FeedItem item = (FeedItem) comp;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
index 6139a4901..623c6faa7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
@@ -62,7 +62,10 @@ public abstract class PodcastListFragment extends Fragment {
@Override
public boolean onQueryTextSubmit(String s) {
sv.clearFocus();
- ((MainActivity) getActivity()).loadChildFragment(SearchListFragment.newInstance(s));
+ MainActivity activity = (MainActivity)getActivity();
+ if (activity != null) {
+ activity.loadChildFragment(SearchListFragment.newInstance(s));
+ }
return true;
}
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 fe1a09149..3e2fdf24f 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
+import android.widget.Toast;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
@@ -16,7 +17,7 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService;
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.IntentUtils;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.ShareUtils;
@@ -56,7 +57,7 @@ public class FeedItemMenuHandler {
* @param queueAccess Used for testing if the queue contains the selected item
* @return Returns true if selectedItem is not null.
*/
- public static boolean onPrepareMenu(MenuInterface mi, FeedItem selectedItem,
+ public static boolean onPrepareMenu(Context context, MenuInterface mi, FeedItem selectedItem,
boolean showExtendedMenu, LongList queueAccess) {
if (selectedItem == null) {
return false;
@@ -84,8 +85,19 @@ public class FeedItemMenuHandler {
if (!(!isInQueue && selectedItem.getMedia() != null)) {
mi.setItemVisibility(R.id.add_to_queue_item, false);
}
+
if (!showExtendedMenu || selectedItem.getLink() == null) {
+ mi.setItemVisibility(R.id.visit_website_item, false);
mi.setItemVisibility(R.id.share_link_item, false);
+ mi.setItemVisibility(R.id.share_link_with_position_item, false);
+ }
+ if (!showExtendedMenu || !hasMedia || selectedItem.getMedia().getDownload_url() == null) {
+ mi.setItemVisibility(R.id.share_download_url_item, false);
+ mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
+ }
+ if(false == hasMedia || selectedItem.getMedia().getPosition() <= 0) {
+ mi.setItemVisibility(R.id.share_link_with_position_item, false);
+ mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
}
if (!(state == FeedItem.State.UNREAD || state == FeedItem.State.IN_PROGRESS)) {
@@ -108,10 +120,6 @@ public class FeedItemMenuHandler {
mi.setItemVisibility(R.id.deactivate_auto_download, false);
}
- if (!showExtendedMenu || selectedItem.getLink() == null) {
- mi.setItemVisibility(R.id.visit_website_item, false);
- }
-
if (selectedItem.getPaymentLink() == null || !selectedItem.getFlattrStatus().flattrable()) {
mi.setItemVisibility(R.id.support_item, false);
}
@@ -125,21 +133,19 @@ public class FeedItemMenuHandler {
* @param excludeIds Menu item that should be excluded
* @return true if selectedItem is not null.
*/
- public static boolean onPrepareMenu(MenuInterface mi,
- FeedItem selectedItem, boolean showExtendedMenu, LongList queueAccess, int... excludeIds) {
- boolean rc = onPrepareMenu(mi, selectedItem, showExtendedMenu, queueAccess);
+ public static boolean onPrepareMenu(Context context, MenuInterface mi, FeedItem selectedItem,
+ boolean showExtendedMenu, LongList queueAccess, int... excludeIds) {
+ boolean rc = onPrepareMenu(context, mi, selectedItem, showExtendedMenu, queueAccess);
if (rc && excludeIds != null) {
for (int id : excludeIds) {
mi.setItemVisibility(id, false);
}
}
-
return rc;
}
public static boolean onMenuItemClicked(Context context, int menuItemId,
FeedItem selectedItem) throws DownloadRequestException {
- DownloadRequester requester = DownloadRequester.getInstance();
switch (menuItemId) {
case R.id.skip_episode_item:
context.sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
@@ -148,22 +154,25 @@ public class FeedItemMenuHandler {
DBWriter.deleteFeedMediaOfItem(context, selectedItem.getMedia().getId());
break;
case R.id.mark_read_item:
- selectedItem.setRead(true);
+ selectedItem.setPlayed(true);
DBWriter.markItemRead(context, selectedItem, true, false);
if(GpodnetPreferences.loggedIn()) {
FeedMedia media = selectedItem.getMedia();
- GpodnetEpisodeAction actionPlay = new GpodnetEpisodeAction.Builder(selectedItem, Action.PLAY)
- .currentDeviceId()
- .currentTimestamp()
- .started(media.getDuration() / 1000)
- .position(media.getDuration() / 1000)
- .total(media.getDuration() / 1000)
- .build();
- GpodnetPreferences.enqueueEpisodeAction(actionPlay);
+ // not all items have media, Gpodder only cares about those that do
+ if (media != null) {
+ GpodnetEpisodeAction actionPlay = new GpodnetEpisodeAction.Builder(selectedItem, Action.PLAY)
+ .currentDeviceId()
+ .currentTimestamp()
+ .started(media.getDuration() / 1000)
+ .position(media.getDuration() / 1000)
+ .total(media.getDuration() / 1000)
+ .build();
+ GpodnetPreferences.enqueueEpisodeAction(actionPlay);
+ }
}
break;
case R.id.mark_unread_item:
- selectedItem.setRead(false);
+ selectedItem.setPlayed(false);
DBWriter.markItemRead(context, selectedItem, false, false);
if(GpodnetPreferences.loggedIn()) {
GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(selectedItem, Action.NEW)
@@ -198,7 +207,13 @@ public class FeedItemMenuHandler {
break;
case R.id.visit_website_item:
Uri uri = Uri.parse(selectedItem.getLink());
- context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ if(IntentUtils.isCallable(context, intent)) {
+ context.startActivity(intent);
+ } else {
+ Toast.makeText(context, context.getString(R.string.download_error_malformed_url),
+ Toast.LENGTH_SHORT);
+ }
break;
case R.id.support_item:
DBTasks.flattrItemIfLoggedIn(context, selectedItem);
@@ -206,6 +221,15 @@ public class FeedItemMenuHandler {
case R.id.share_link_item:
ShareUtils.shareFeedItemLink(context, selectedItem);
break;
+ case R.id.share_download_url_item:
+ ShareUtils.shareFeedItemDownloadLink(context, selectedItem);
+ break;
+ case R.id.share_link_with_position_item:
+ ShareUtils.shareFeedItemLink(context, selectedItem, true);
+ break;
+ case R.id.share_download_url_with_position_item:
+ ShareUtils.shareFeedItemDownloadLink(context, selectedItem, true);
+ break;
default:
Log.d(TAG, "Unknown menuItemId: " + menuItemId);
return false;
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
index 7bd8fedc9..3df59724d 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
@@ -9,6 +9,7 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
@@ -20,6 +21,7 @@ import de.danoeh.antennapod.core.feed.Feed;
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.util.IntentUtils;
import de.danoeh.antennapod.core.util.ShareUtils;
/**
@@ -39,11 +41,11 @@ public class FeedMenuHandler {
}
Log.d(TAG, "Preparing options menu");
- menu.findItem(R.id.mark_all_read_item).setVisible(selectedFeed.hasNewItems());
- if (selectedFeed.getPaymentLink() != null && selectedFeed.getFlattrStatus().flattrable())
+ if (selectedFeed.getPaymentLink() != null && selectedFeed.getFlattrStatus().flattrable()) {
menu.findItem(R.id.support_item).setVisible(true);
- else
+ } else {
menu.findItem(R.id.support_item).setVisible(false);
+ }
menu.findItem(R.id.refresh_complete_item).setVisible(selectedFeed.isPaged());
@@ -83,7 +85,13 @@ public class FeedMenuHandler {
break;
case R.id.visit_website_item:
Uri uri = Uri.parse(selectedFeed.getLink());
- context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ if(IntentUtils.isCallable(context, intent)) {
+ context.startActivity(intent);
+ } else {
+ Toast.makeText(context, context.getString(R.string.download_error_malformed_url),
+ Toast.LENGTH_SHORT);
+ }
break;
case R.id.support_item:
DBTasks.flattrFeedIfLoggedIn(context, selectedFeed);
@@ -91,7 +99,7 @@ public class FeedMenuHandler {
case R.id.share_link_item:
ShareUtils.shareFeedlink(context, selectedFeed);
break;
- case R.id.share_source_item:
+ case R.id.share_download_url_item:
ShareUtils.shareFeedDownloadLink(context, selectedFeed);
break;
default:
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 f387b7524..39edfe582 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.preferences;
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -16,8 +17,10 @@ import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.text.Editable;
import android.text.TextWatcher;
+import android.text.format.DateFormat;
import android.util.Log;
import android.widget.EditText;
+import android.widget.TimePicker;
import android.widget.Toast;
import java.io.File;
@@ -33,12 +36,9 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.activity.PreferenceActivityGingerbread;
import de.danoeh.antennapod.asynctask.OpmlExportWorker;
-import de.danoeh.antennapod.core.asynctask.FlattrClickWorker;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
-import de.danoeh.antennapod.core.util.flattr.SimpleFlattrThing;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog;
import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog;
@@ -49,7 +49,6 @@ import de.danoeh.antennapod.dialog.VariableSpeedDialog;
*/
public class PreferenceController {
private static final String TAG = "PreferenceController";
- public static final String PREF_FLATTR_THIS_APP = "prefFlattrThisApp";
public static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings";
public static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate";
public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess";
@@ -105,23 +104,6 @@ public class PreferenceController {
);
}
- ui.findPreference(PreferenceController.PREF_FLATTR_THIS_APP).setOnPreferenceClickListener(
- new Preference.OnPreferenceClickListener() {
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- new FlattrClickWorker(activity,
- new SimpleFlattrThing(activity.getString(R.string.app_name),
- FlattrUtils.APP_URL,
- new FlattrStatus(FlattrStatus.STATUS_QUEUE)
- )
- ).executeAsync();
-
- return true;
- }
- }
- );
-
ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@@ -200,6 +182,15 @@ public class PreferenceController {
}
});
+ ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL)
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ showUpdateIntervalTimePreferencesDialog();
+ return true;
+ }
+ });
+
ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL)
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
@@ -345,14 +336,33 @@ public class PreferenceController {
@Override
public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue) {
- UserPreferences.setAutoFlattrSettings(activity, autoFlattrEnabled, autoFlattrValue);
+ UserPreferences.setAutoFlattrSettings(autoFlattrEnabled, autoFlattrValue);
checkItemVisibility();
}
});
return true;
}
});
- buildUpdateIntervalPreference();
+ ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE)
+ .setOnPreferenceChangeListener(
+ new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object o) {
+ if (o instanceof String) {
+ int newValue = Integer.valueOf((String) o) * 1024 * 1024;
+ if(newValue != UserPreferences.getImageCacheSize()) {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity());
+ dialog.setTitle(android.R.string.dialog_alert_title);
+ dialog.setMessage(R.string.pref_restart_required);
+ dialog.setPositiveButton(android.R.string.ok, null);
+ dialog.show();
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+ );
buildSmartMarkAsPlayedPreference();
buildAutodownloadSelectedNetworsPreference();
setSelectedNetworksEnabled(UserPreferences
@@ -385,12 +395,8 @@ public class PreferenceController {
ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setSummary(GpodnetPreferences.getHostname());
}
- private void buildUpdateIntervalPreference() {
+ private String[] getUpdateIntervalEntries(final String[] values) {
final Resources res = ui.getActivity().getResources();
-
- ListPreference pref = (ListPreference) ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL);
- String[] values = res.getStringArray(
- R.array.update_intervall_values);
String[] entries = new String[values.length];
for (int x = 0; x < values.length; x++) {
Integer v = Integer.parseInt(values[x]);
@@ -399,19 +405,15 @@ public class PreferenceController {
entries[x] = res.getString(R.string.pref_update_interval_hours_manual);
break;
case 1:
- entries[x] = v
- + " "
- + res.getString(R.string.pref_update_interval_hours_singular);
+ entries[x] = v + " " + res.getString(R.string.pref_update_interval_hours_singular);
break;
default:
- entries[x] = v + " "
- + res.getString(R.string.pref_update_interval_hours_plural);
+ entries[x] = v + " " + res.getString(R.string.pref_update_interval_hours_plural);
break;
}
}
- pref.setEntries(entries);
-
+ return entries;
}
private void buildSmartMarkAsPlayedPreference() {
@@ -426,7 +428,7 @@ public class PreferenceController {
entries[x] = res.getString(R.string.pref_smart_mark_as_played_disabled);
} else {
Integer v = Integer.parseInt(values[x]);
- entries[x] = v + " " + res.getString(R.string.time_unit_seconds);
+ entries[x] = res.getQuantityString(R.plurals.time_seconds_quantified, v);
}
}
pref.setEntries(entries);
@@ -529,9 +531,7 @@ public class PreferenceController {
}
UserPreferences.setAutodownloadSelectedNetworks(
- activity, prefValuesList
- .toArray(new String[prefValuesList
- .size()])
+ prefValuesList.toArray(new String[prefValuesList.size()])
);
return true;
} else {
@@ -606,7 +606,63 @@ public class PreferenceController {
builder.create().show();
}
+ private void showUpdateIntervalTimePreferencesDialog() {
+ final Context context = ui.getActivity();
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.pref_autoUpdateIntervallOrTime_title);
+ builder.setMessage(R.string.pref_autoUpdateIntervallOrTime_message);
+ builder.setNegativeButton(R.string.pref_autoUpdateIntervallOrTime_Disable, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ UserPreferences.setUpdateInterval(0);
+ }
+ });
+ builder.setNeutralButton(R.string.pref_autoUpdateIntervallOrTime_Interval, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
+ final String[] values = context.getResources().getStringArray(R.array.update_intervall_values);
+ final String[] entries = getUpdateIntervalEntries(values);
+ builder.setSingleChoiceItems(entries, -1, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int hours = Integer.valueOf(values[which]);
+ UserPreferences.setUpdateInterval(hours);
+ dialog.dismiss();
+ }
+ });
+ builder.setNegativeButton(context.getString(R.string.cancel_label), null);
+ builder.show();
+ }
+ });
+ builder.setPositiveButton(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ int hourOfDay = 7, minute = 0;
+ int[] updateTime = UserPreferences.getUpdateTimeOfDay();
+ if (updateTime.length == 2) {
+ hourOfDay = updateTime[0];
+ minute = updateTime[1];
+ }
+ TimePickerDialog timePickerDialog = new TimePickerDialog(context, new TimePickerDialog.OnTimeSetListener() {
+ @Override
+ public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+ if (view.getTag() == null) { // onTimeSet() may get called twice!
+ view.setTag("TAGGED");
+ UserPreferences.setUpdateTimeOfDay(hourOfDay, minute);
+ }
+ }
+ }, hourOfDay, minute, DateFormat.is24HourFormat(context));
+ timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay));
+ timePickerDialog.show();
+ }
+ }
+ );
+ builder.show();
+ }
public static interface PreferenceUI {
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 f55a7603f..2615ec5c8 100644
--- a/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java
+++ b/app/src/main/java/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java
@@ -9,24 +9,20 @@ import android.util.Log;
import org.apache.commons.lang3.StringUtils;
-import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.NetworkUtils;
public class ConnectivityActionReceiver extends BroadcastReceiver {
- private static final String TAG = "ConnectivityActionReceiver";
+ private static final String TAG = "ConnectivityActionRecvr";
@Override
public void onReceive(final Context context, Intent intent) {
if (StringUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Received intent");
+ Log.d(TAG, "Received intent");
- if (NetworkUtils.autodownloadNetworkAvailable(context)) {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "auto-dl network available, starting auto-download");
+ if (NetworkUtils.autodownloadNetworkAvailable()) {
+ Log.d(TAG, "auto-dl network available, starting auto-download");
DBTasks.autodownloadUndownloadedItems(context);
} else { // if new network is Wi-Fi, finish ongoing downloads,
// otherwise cancel all downloads
@@ -34,12 +30,9 @@ public class ConnectivityActionReceiver extends BroadcastReceiver {
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null || ni.getType() != ConnectivityManager.TYPE_WIFI) {
- if (BuildConfig.DEBUG)
- Log.i(TAG,
- "Device is no longer connected to Wi-Fi. Cancelling ongoing downloads");
+ Log.i(TAG, "Device is no longer connected to Wi-Fi. Cancelling ongoing downloads");
DownloadRequester.getInstance().cancelAllDownloads(context);
}
-
}
}
}
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 1fe9e2cf9..990b3bd54 100644
--- a/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java
+++ b/app/src/main/java/de/danoeh/antennapod/service/PlayerWidgetService.java
@@ -62,7 +62,7 @@ public class PlayerWidgetService extends Service {
DBWriter.markItemRead(this, item, true, false);
DBWriter.removeQueueItem(this, item, false);
DBWriter.addItemToPlaybackHistory(this, media);
- if (UserPreferences.isAutoDelete()) {
+ if (item.getFeed().getPreferences().getCurrentAutoDelete()) {
Log.d(TAG, "Delete " + media.toString());
DBWriter.deleteFeedMediaOfItem(this, media.getId());
}