summaryrefslogtreecommitdiff
path: root/src/de/danoeh/antennapod
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2014-10-09 21:29:30 +0200
committerdaniel oeh <daniel.oeh@gmail.com>2014-10-09 21:29:30 +0200
commitbaa7d5f11283cb7668d45b561af5d38f0ccb9632 (patch)
tree21cb976e8f2a948dae44bc014fb2c6ed62f81157 /src/de/danoeh/antennapod
parenta8bf235017d5896c0691ad056727dafc72c63596 (diff)
parent4d622cb27ab54dc081d81285128b9c70f8dd37ac (diff)
downloadAntennaPod-baa7d5f11283cb7668d45b561af5d38f0ccb9632.zip
Merge branch 'develop'0.9.9.4
Diffstat (limited to 'src/de/danoeh/antennapod')
-rw-r--r--src/de/danoeh/antennapod/AppConfig.java2
-rw-r--r--src/de/danoeh/antennapod/activity/AudioplayerActivity.java3
-rw-r--r--src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java5
-rw-r--r--src/de/danoeh/antennapod/activity/FeedInfoActivity.java1
-rw-r--r--src/de/danoeh/antennapod/activity/MediaplayerActivity.java14
-rw-r--r--src/de/danoeh/antennapod/activity/PreferenceActivity.java23
-rw-r--r--src/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java6
-rw-r--r--src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java2
-rw-r--r--src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java2
-rw-r--r--src/de/danoeh/antennapod/adapter/NavListAdapter.java5
-rw-r--r--src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java4
-rw-r--r--src/de/danoeh/antennapod/adapter/QueueListAdapter.java5
-rw-r--r--src/de/danoeh/antennapod/adapter/SearchlistAdapter.java6
-rw-r--r--src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java14
-rw-r--r--src/de/danoeh/antennapod/asynctask/PicassoImageResource.java12
-rw-r--r--src/de/danoeh/antennapod/asynctask/PicassoProvider.java13
-rw-r--r--src/de/danoeh/antennapod/dialog/FeedItemDialog.java6
-rw-r--r--src/de/danoeh/antennapod/feed/FeedComponent.java82
-rw-r--r--src/de/danoeh/antennapod/feed/FeedMedia.java18
-rw-r--r--src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java3
-rw-r--r--src/de/danoeh/antennapod/fragment/ItemlistFragment.java3
-rw-r--r--src/de/danoeh/antennapod/fragment/SearchFragment.java2
-rw-r--r--src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java8
-rw-r--r--src/de/danoeh/antennapod/preferences/UserPreferences.java32
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlaybackService.java62
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java2
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java27
-rw-r--r--src/de/danoeh/antennapod/storage/DownloadRequester.java42
-rw-r--r--src/de/danoeh/antennapod/syndication/namespace/NSSimpleChapters.java21
-rw-r--r--src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java254
-rw-r--r--src/de/danoeh/antennapod/util/ChapterUtils.java469
-rw-r--r--src/de/danoeh/antennapod/util/URLChecker.java21
-rw-r--r--src/de/danoeh/antennapod/util/flattr/FlattrUtils.java4
33 files changed, 691 insertions, 482 deletions
diff --git a/src/de/danoeh/antennapod/AppConfig.java b/src/de/danoeh/antennapod/AppConfig.java
index 7a75e3a18..24f13d4a3 100644
--- a/src/de/danoeh/antennapod/AppConfig.java
+++ b/src/de/danoeh/antennapod/AppConfig.java
@@ -2,6 +2,6 @@ package de.danoeh.antennapod;
public final class AppConfig {
/** Should be used when setting User-Agent header for HTTP-requests. */
- public final static String USER_AGENT = "AntennaPod/0.9.9.3";
+ public final static String USER_AGENT = "AntennaPod/0.9.9.4";
}
diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
index 50f5d8f2e..18d27ddda 100644
--- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -343,7 +343,6 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
} else {
ft.add(R.id.contentView, currentlyShownFragment);
}
- ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.disallowAddToBackStack();
ft.commit();
updateNavButtonDrawable();
@@ -383,6 +382,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
public void run() {
PicassoProvider.getMediaMetadataPicassoInstance(AudioplayerActivity.this)
.load(media.getImageUri())
+ .fit()
.into(butNavLeft);
}
});
@@ -399,6 +399,7 @@ public class AudioplayerActivity extends MediaplayerActivity implements ItemDesc
public void run() {
PicassoProvider.getMediaMetadataPicassoInstance(AudioplayerActivity.this)
.load(media.getImageUri())
+ .fit()
.into(butNavLeft);
}
diff --git a/src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java b/src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
index 86b278bf0..e8bc75293 100644
--- a/src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
+++ b/src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
@@ -122,11 +122,10 @@ public class DefaultOnlineFeedViewActivity extends OnlineFeedViewActivity {
subscribeButton = (Button) header.findViewById(R.id.butSubscribe);
- if (feed.getImage() != null) {
- int imageSize = (int) getResources().getDimension(R.dimen.thumbnail_length);
+ if (feed.getImage() != null && StringUtils.isNoneBlank(feed.getImage().getDownload_url())) {
PicassoProvider.getDefaultPicassoInstance(this)
.load(feed.getImage().getDownload_url())
- .resize(imageSize, imageSize)
+ .fit()
.into(cover);
}
diff --git a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java
index b46bc7546..5cf187eb6 100644
--- a/src/de/danoeh/antennapod/activity/FeedInfoActivity.java
+++ b/src/de/danoeh/antennapod/activity/FeedInfoActivity.java
@@ -80,6 +80,7 @@ public class FeedInfoActivity extends ActionBarActivity {
public void run() {
PicassoProvider.getDefaultPicassoInstance(FeedInfoActivity.this)
.load(feed.getImageUri())
+ .fit()
.into(imgvCover);
}
});
diff --git a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
index 13e7b8a82..2e5372b60 100644
--- a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -502,18 +502,24 @@ public abstract class MediaplayerActivity extends ActionBarActivity
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
- prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser,
- txtvPosition);
+ if (controller != null) {
+ prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser,
+ txtvPosition);
+ }
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
- controller.onSeekBarStartTrackingTouch(seekBar);
+ if (controller != null) {
+ controller.onSeekBarStartTrackingTouch(seekBar);
+ }
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
- controller.onSeekBarStopTrackingTouch(seekBar, prog);
+ if (controller != null) {
+ controller.onSeekBarStopTrackingTouch(seekBar, prog);
+ }
}
}
diff --git a/src/de/danoeh/antennapod/activity/PreferenceActivity.java b/src/de/danoeh/antennapod/activity/PreferenceActivity.java
index cd6731c02..a21985bb8 100644
--- a/src/de/danoeh/antennapod/activity/PreferenceActivity.java
+++ b/src/de/danoeh/antennapod/activity/PreferenceActivity.java
@@ -9,6 +9,7 @@ import android.content.res.Resources.Theme;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
+import android.os.Build;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
@@ -60,6 +61,9 @@ public class PreferenceActivity extends android.preference.PreferenceActivity {
private static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
private static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
+ private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
+ private static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify";
+
private CheckBoxPreference[] selectedNetworks;
@SuppressLint("NewApi")
@@ -77,6 +81,23 @@ public class PreferenceActivity extends android.preference.PreferenceActivity {
}
addPreferencesFromResource(R.xml.preferences);
+
+ if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
+ // disable expanded notification option on unsupported android versions
+ findPreference(PREF_EXPANDED_NOTIFICATION).setEnabled(false);
+ findPreference(PREF_EXPANDED_NOTIFICATION).setOnPreferenceClickListener(
+ new OnPreferenceClickListener() {
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Toast toast = Toast.makeText(PreferenceActivity.this, R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT);
+ toast.show();
+ return true;
+ }
+ }
+ );
+ }
+
findPreference(PREF_FLATTR_THIS_APP).setOnPreferenceClickListener(
new OnPreferenceClickListener() {
@@ -272,8 +293,6 @@ public class PreferenceActivity extends android.preference.PreferenceActivity {
buildAutodownloadSelectedNetworsPreference();
setSelectedNetworksEnabled(UserPreferences
.isEnableAutodownloadWifiFilter());
-
-
}
private void updateGpodnetPreferenceScreen() {
diff --git a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
index cb6dc41cf..6a60f65fe 100644
--- a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
+++ b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
@@ -270,8 +270,10 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity {
@Override
public void onClick(View v) {
final int position = spinnerDevices.getSelectedItemPosition();
- selectedDevice = devices.get().get(position);
- advance();
+ if (position != AdapterView.INVALID_POSITION) {
+ selectedDevice = devices.get().get(position);
+ advance();
+ }
}
});
}
diff --git a/src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java
index 641a1368d..ef5af67de 100644
--- a/src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/DownloadedEpisodesListAdapter.java
@@ -89,7 +89,7 @@ public class DownloadedEpisodesListAdapter extends BaseAdapter {
PicassoProvider.getMediaMetadataPicassoInstance(context)
.load(item.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(holder.imageView);
return convertView;
diff --git a/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
index 56c3e1ca6..3f666eb8b 100644
--- a/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
@@ -176,7 +176,7 @@ public class ExternalEpisodesListAdapter extends BaseExpandableListAdapter {
PicassoProvider.getMediaMetadataPicassoInstance(context)
.load(item.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(holder.feedImage);
holder.butAction.setFocusable(false);
diff --git a/src/de/danoeh/antennapod/adapter/NavListAdapter.java b/src/de/danoeh/antennapod/adapter/NavListAdapter.java
index ed85c8836..ef8e8ce07 100644
--- a/src/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -32,8 +32,6 @@ public class NavListAdapter extends BaseAdapter {
private ItemAccess itemAccess;
private Context context;
- private final int imageSize;
-
public NavListAdapter(ItemAccess itemAccess, Context context) {
this.itemAccess = itemAccess;
this.context = context;
@@ -43,7 +41,6 @@ public class NavListAdapter extends BaseAdapter {
drawables = new Drawable[]{ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2),
ta.getDrawable(3), ta.getDrawable(4)};
ta.recycle();
- this.imageSize = (int) context.getResources().getDimension(R.dimen.thumbnail_length_navlist);
}
@Override
@@ -195,7 +192,7 @@ public class NavListAdapter extends BaseAdapter {
PicassoProvider.getDefaultPicassoInstance(context)
.load(feed.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(holder.image);
return convertView;
diff --git a/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java
index 4370de14d..8abe49133 100644
--- a/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/NewEpisodesListAdapter.java
@@ -27,7 +27,6 @@ public class NewEpisodesListAdapter extends BaseAdapter {
private final ItemAccess itemAccess;
private final ActionButtonCallback actionButtonCallback;
private final ActionButtonUtils actionButtonUtils;
- private final int imageSize;
public NewEpisodesListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) {
super();
@@ -35,7 +34,6 @@ public class NewEpisodesListAdapter extends BaseAdapter {
this.itemAccess = itemAccess;
this.actionButtonUtils = new ActionButtonUtils(context);
this.actionButtonCallback = actionButtonCallback;
- this.imageSize = (int) context.getResources().getDimension(R.dimen.thumbnail_length_itemlist);
}
@Override
@@ -133,7 +131,7 @@ public class NewEpisodesListAdapter extends BaseAdapter {
PicassoProvider.getMediaMetadataPicassoInstance(context)
.load(item.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(holder.imageView);
return convertView;
diff --git a/src/de/danoeh/antennapod/adapter/QueueListAdapter.java b/src/de/danoeh/antennapod/adapter/QueueListAdapter.java
index c670089b9..ebe519592 100644
--- a/src/de/danoeh/antennapod/adapter/QueueListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/QueueListAdapter.java
@@ -22,7 +22,6 @@ public class QueueListAdapter extends BaseAdapter {
private final ActionButtonCallback actionButtonCallback;
private final ActionButtonUtils actionButtonUtils;
- private final int imageSize;
public QueueListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) {
super();
@@ -30,8 +29,6 @@ public class QueueListAdapter extends BaseAdapter {
this.itemAccess = itemAccess;
this.actionButtonUtils = new ActionButtonUtils(context);
this.actionButtonCallback = actionButtonCallback;
- this.imageSize = (int) context.getResources().getDimension(R.dimen.thumbnail_length_queue_item);
-
}
@Override
@@ -97,7 +94,7 @@ public class QueueListAdapter extends BaseAdapter {
PicassoProvider.getMediaMetadataPicassoInstance(context)
.load(item.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(holder.imageView);
return convertView;
diff --git a/src/de/danoeh/antennapod/adapter/SearchlistAdapter.java b/src/de/danoeh/antennapod/adapter/SearchlistAdapter.java
index 6b1fefaad..2314c2269 100644
--- a/src/de/danoeh/antennapod/adapter/SearchlistAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/SearchlistAdapter.java
@@ -23,12 +23,10 @@ public class SearchlistAdapter extends BaseAdapter {
private final Context context;
private final ItemAccess itemAccess;
- private final int imageSize;
public SearchlistAdapter(Context context, ItemAccess itemAccess) {
this.context = context;
this.itemAccess = itemAccess;
- this.imageSize = (int) context.getResources().getDimension(R.dimen.thumbnail_length);
}
@Override
@@ -76,7 +74,7 @@ public class SearchlistAdapter extends BaseAdapter {
PicassoProvider.getDefaultPicassoInstance(context)
.load(feed.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(holder.cover);
} else if (component.getClass() == FeedItem.class) {
@@ -89,7 +87,7 @@ public class SearchlistAdapter extends BaseAdapter {
PicassoProvider.getDefaultPicassoInstance(context)
.load(item.getFeed().getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(holder.cover);
}
diff --git a/src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java b/src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
index dcad2d524..aeb1fc53a 100644
--- a/src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/gpodnet/PodcastListAdapter.java
@@ -8,6 +8,8 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
+import org.apache.commons.lang3.StringUtils;
+
import java.util.List;
import de.danoeh.antennapod.R;
@@ -18,11 +20,9 @@ import de.danoeh.antennapod.gpoddernet.model.GpodnetPodcast;
* Adapter for displaying a list of GPodnetPodcast-Objects.
*/
public class PodcastListAdapter extends ArrayAdapter<GpodnetPodcast> {
- private final int thumbnailLength;
public PodcastListAdapter(Context context, int resource, List<GpodnetPodcast> objects) {
super(context, resource, objects);
- thumbnailLength = (int) context.getResources().getDimension(R.dimen.thumbnail_length);
}
@Override
@@ -50,10 +50,12 @@ public class PodcastListAdapter extends ArrayAdapter<GpodnetPodcast> {
holder.title.setText(podcast.getTitle());
holder.description.setText(podcast.getDescription());
- PicassoProvider.getDefaultPicassoInstance(convertView.getContext())
- .load(podcast.getLogoUrl())
- .resize(thumbnailLength, thumbnailLength)
- .into(holder.image);
+ if (StringUtils.isNoneBlank(podcast.getLogoUrl())) {
+ PicassoProvider.getDefaultPicassoInstance(convertView.getContext())
+ .load(podcast.getLogoUrl())
+ .fit()
+ .into(holder.image);
+ }
return convertView;
}
diff --git a/src/de/danoeh/antennapod/asynctask/PicassoImageResource.java b/src/de/danoeh/antennapod/asynctask/PicassoImageResource.java
index 84179cfcb..26f9d9278 100644
--- a/src/de/danoeh/antennapod/asynctask/PicassoImageResource.java
+++ b/src/de/danoeh/antennapod/asynctask/PicassoImageResource.java
@@ -18,8 +18,20 @@ public interface PicassoImageResource {
*/
public static final String SCHEME_MEDIA = "media";
+
+ /**
+ * Parameter key for an encoded fallback Uri. This Uri MUST point to a local image file
+ */
+ public static final String PARAM_FALLBACK = "fallback";
+
/**
* Returns a Uri to the image or null if no image is available.
+ * <p/>
+ * The Uri can either be an HTTP-URL, a URL pointing to a local image file or
+ * a non-image file (see SCHEME_MEDIA for more details).
+ * <p/>
+ * The Uri can also have an optional fallback-URL if loading the default URL
+ * failed (see PARAM_FALLBACK).
*/
public Uri getImageUri();
}
diff --git a/src/de/danoeh/antennapod/asynctask/PicassoProvider.java b/src/de/danoeh/antennapod/asynctask/PicassoProvider.java
index 9ecf87023..849725630 100644
--- a/src/de/danoeh/antennapod/asynctask/PicassoProvider.java
+++ b/src/de/danoeh/antennapod/asynctask/PicassoProvider.java
@@ -127,14 +127,25 @@ public class PicassoProvider {
mmr.setDataSource(uri.getPath());
byte[] data = mmr.getEmbeddedPicture();
mmr.release();
+
if (data != null) {
return new Response(new ByteArrayInputStream(data), true, data.length);
} else {
+
+ // check for fallback Uri
+ String fallbackParam = uri.getQueryParameter(PicassoImageResource.PARAM_FALLBACK);
+
+ if (fallbackParam != null) {
+ String fallback = Uri.decode(Uri.parse(fallbackParam).getPath());
+ if (fallback != null) {
+ File imageFile = new File(fallback);
+ return new Response(new BufferedInputStream(new FileInputStream(imageFile)), true, imageFile.length());
+ }
+ }
return null;
}
}
}
-
return okHttpDownloader.load(uri, b);
}
}
diff --git a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java
index 7384463de..4cd6a379e 100644
--- a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java
+++ b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java
@@ -11,6 +11,7 @@ import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.widget.PopupMenu;
+import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.MenuItem;
@@ -115,6 +116,11 @@ public class FeedItemDialog extends Dialog {
popupMenu = new PopupMenu(getContext(), butMore);
webvDescription.setWebViewClient(new WebViewClient());
+
+ if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448
+ txtvTitle.setEllipsize(TextUtils.TruncateAt.END);
+ }
+
txtvTitle.setText(item.getTitle());
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
diff --git a/src/de/danoeh/antennapod/feed/FeedComponent.java b/src/de/danoeh/antennapod/feed/FeedComponent.java
index 66a2f9cc5..48b243770 100644
--- a/src/de/danoeh/antennapod/feed/FeedComponent.java
+++ b/src/de/danoeh/antennapod/feed/FeedComponent.java
@@ -2,43 +2,43 @@ package de.danoeh.antennapod.feed;
/**
* Represents every possible component of a feed
- * @author daniel
*
+ * @author daniel
*/
public abstract class FeedComponent {
- protected long id;
-
- public FeedComponent() {
- super();
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- /**
- * Update this FeedComponent's attributes with the attributes from another
- * FeedComponent. This method should only update attributes which where read from
- * the feed.
- */
- public void updateFromOther(FeedComponent other) {
- }
-
- /**
- * Compare's this FeedComponent's attribute values with another FeedComponent's
- * attribute values. This method will only compare attributes which were
- * read from the feed.
- *
- * @return true if attribute values are different, false otherwise
- */
- public boolean compareWithOther(FeedComponent other) {
- return false;
- }
+ protected long id;
+
+ public FeedComponent() {
+ super();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ /**
+ * Update this FeedComponent's attributes with the attributes from another
+ * FeedComponent. This method should only update attributes which where read from
+ * the feed.
+ */
+ public void updateFromOther(FeedComponent other) {
+ }
+
+ /**
+ * Compare's this FeedComponent's attribute values with another FeedComponent's
+ * attribute values. This method will only compare attributes which were
+ * read from the feed.
+ *
+ * @return true if attribute values are different, false otherwise
+ */
+ public boolean compareWithOther(FeedComponent other) {
+ return false;
+ }
/**
@@ -47,4 +47,20 @@ public abstract class FeedComponent {
*/
public abstract String getHumanReadableIdentifier();
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ FeedComponent that = (FeedComponent) o;
+
+ if (id != that.id) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) (id ^ (id >>> 32));
+ }
} \ No newline at end of file
diff --git a/src/de/danoeh/antennapod/feed/FeedMedia.java b/src/de/danoeh/antennapod/feed/FeedMedia.java
index f555654d0..9298ebe8a 100644
--- a/src/de/danoeh/antennapod/feed/FeedMedia.java
+++ b/src/de/danoeh/antennapod/feed/FeedMedia.java
@@ -386,9 +386,23 @@ public class FeedMedia extends FeedFile implements Playable {
@Override
public Uri getImageUri() {
+ final Uri feedImgUri = getFeedImageUri();
+
if (localFileAvailable()) {
- return new Uri.Builder().scheme(SCHEME_MEDIA).encodedPath(getLocalMediaUrl()).build();
- } else if (item != null && item.getFeed() != null) {
+ Uri.Builder builder = new Uri.Builder();
+ builder.scheme(SCHEME_MEDIA)
+ .encodedPath(getLocalMediaUrl());
+ if (feedImgUri != null) {
+ builder.appendQueryParameter(PARAM_FALLBACK, feedImgUri.toString());
+ }
+ return builder.build();
+ } else {
+ return feedImgUri;
+ }
+ }
+
+ private Uri getFeedImageUri() {
+ if (item != null && item.getFeed() != null) {
return item.getFeed().getImageUri();
} else {
return null;
diff --git a/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
index 77587194b..985673dd3 100644
--- a/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
@@ -207,10 +207,9 @@ public class ExternalPlayerFragment extends Fragment {
if (media != null) {
txtvTitle.setText(media.getEpisodeTitle());
- int imageSize = (int) getResources().getDimension(R.dimen.external_player_height);
PicassoProvider.getMediaMetadataPicassoInstance(getActivity())
.load(media.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(imgvCover);
fragmentLayout.setVisibility(View.VISIBLE);
diff --git a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java
index 5ef914f6c..909774467 100644
--- a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -350,10 +350,9 @@ public class ItemlistFragment extends ListFragment {
txtvTitle.setText(feed.getTitle());
txtvAuthor.setText(feed.getAuthor());
- int imageSize = (int) getResources().getDimension(R.dimen.thumbnail_length_onlinefeedview);
PicassoProvider.getDefaultPicassoInstance(getActivity())
.load(feed.getImageUri())
- .resize(imageSize, imageSize)
+ .fit()
.into(imgvCover);
if (feed.getLink() == null) {
diff --git a/src/de/danoeh/antennapod/fragment/SearchFragment.java b/src/de/danoeh/antennapod/fragment/SearchFragment.java
index b3ade4d70..b1411cf0a 100644
--- a/src/de/danoeh/antennapod/fragment/SearchFragment.java
+++ b/src/de/danoeh/antennapod/fragment/SearchFragment.java
@@ -160,7 +160,7 @@ public class SearchFragment extends ListFragment {
private final EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
@Override
public void update(EventDistributor eventDistributor, Integer arg) {
- if ((arg & (EventDistributor.DOWNLOAD_QUEUED)) != 0) {
+ if ((arg & (EventDistributor.DOWNLOAD_QUEUED)) != 0 && feedItemDialog != null) {
feedItemDialog.updateMenuAppearance();
}
if ((arg & (EventDistributor.UNREAD_ITEMS_UPDATE
diff --git a/src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
index 2289862aa..a7e1033df 100644
--- a/src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
+++ b/src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.fragment.gpodnet;
+import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -43,8 +44,11 @@ public class TagListFragment extends ListFragment {
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
- sv.clearFocus();
- ((MainActivity) getActivity()).loadChildFragment(SearchListFragment.newInstance(s));
+ Activity activity = getActivity();
+ if (activity != null) {
+ sv.clearFocus();
+ ((MainActivity) activity).loadChildFragment(SearchListFragment.newInstance(s));
+ }
return true;
}
diff --git a/src/de/danoeh/antennapod/preferences/UserPreferences.java b/src/de/danoeh/antennapod/preferences/UserPreferences.java
index 2020ddfae..73a4a1a14 100644
--- a/src/de/danoeh/antennapod/preferences/UserPreferences.java
+++ b/src/de/danoeh/antennapod/preferences/UserPreferences.java
@@ -6,6 +6,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
import android.util.Log;
import org.apache.commons.lang3.StringUtils;
@@ -53,6 +54,8 @@ public class UserPreferences implements
private static final String PREF_PLAYBACK_SPEED_ARRAY = "prefPlaybackSpeedArray";
public static final String PREF_PAUSE_PLAYBACK_FOR_FOCUS_LOSS = "prefPauseForFocusLoss";
private static final String PREF_SEEK_DELTA_SECS = "prefSeekDeltaSecs";
+ private static final String PREF_EXPANDED_NOTIFICATION = "prefExpandNotify";
+ private static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify";
// TODO: Make this value configurable
private static final float PREF_AUTO_FLATTR_PLAYED_DURATION_THRESHOLD_DEFAULT = 0.8f;
@@ -82,6 +85,8 @@ public class UserPreferences implements
private boolean pauseForFocusLoss;
private int seekDeltaSecs;
private boolean isFreshInstall;
+ private int notifyPriority;
+ private boolean persistNotify;
private UserPreferences(Context context) {
this.context = context;
@@ -138,6 +143,13 @@ public class UserPreferences implements
PREF_PLAYBACK_SPEED_ARRAY, null));
pauseForFocusLoss = sp.getBoolean(PREF_PAUSE_PLAYBACK_FOR_FOCUS_LOSS, false);
seekDeltaSecs = Integer.valueOf(sp.getString(PREF_SEEK_DELTA_SECS, "30"));
+ if (sp.getBoolean(PREF_EXPANDED_NOTIFICATION, false)) {
+ notifyPriority = NotificationCompat.PRIORITY_MAX;
+ }
+ else {
+ notifyPriority = NotificationCompat.PRIORITY_DEFAULT;
+ }
+ persistNotify = sp.getBoolean(PREF_PERSISTENT_NOTIFICATION, false);
}
private int readThemeValue(String valueFromPrefs) {
@@ -243,6 +255,17 @@ public class UserPreferences implements
return instance.autoFlattr;
}
+ public static int getNotifyPriority() {
+ instanceAvailable();
+ return instance.notifyPriority;
+ }
+
+ public static boolean isPersistNotify() {
+ instanceAvailable();
+ return instance.persistNotify;
+ }
+
+
/**
* Returns the time after which an episode should be auto-flattr'd in percent of the episode's
* duration.
@@ -366,6 +389,15 @@ public class UserPreferences implements
} else if (key.equals(PREF_AUTO_FLATTR_PLAYED_DURATION_THRESHOLD)) {
autoFlattrPlayedDurationThreshold = sp.getFloat(PREF_AUTO_FLATTR_PLAYED_DURATION_THRESHOLD,
PREF_AUTO_FLATTR_PLAYED_DURATION_THRESHOLD_DEFAULT);
+ } else if (key.equals(PREF_EXPANDED_NOTIFICATION)) {
+ if (sp.getBoolean(PREF_EXPANDED_NOTIFICATION, false)) {
+ notifyPriority = NotificationCompat.PRIORITY_MAX;
+ }
+ else {
+ notifyPriority = NotificationCompat.PRIORITY_DEFAULT;
+ }
+ } else if (key.equals(PREF_PERSISTENT_NOTIFICATION)) {
+ persistNotify = sp.getBoolean(PREF_PERSISTENT_NOTIFICATION, false);
}
}
diff --git a/src/de/danoeh/antennapod/service/playback/PlaybackService.java b/src/de/danoeh/antennapod/service/playback/PlaybackService.java
index 59d7ddbb9..6c292c08a 100644
--- a/src/de/danoeh/antennapod/service/playback/PlaybackService.java
+++ b/src/de/danoeh/antennapod/service/playback/PlaybackService.java
@@ -297,7 +297,12 @@ public class PlaybackService extends Service {
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (status == PlayerStatus.PLAYING) {
- mediaPlayer.pause(true, true);
+ if (UserPreferences.isPersistNotify()) {
+ mediaPlayer.pause(false, true);
+ }
+ else {
+ mediaPlayer.pause(true, true);
+ }
} else if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
mediaPlayer.resume();
} else if (status == PlayerStatus.PREPARING) {
@@ -317,7 +322,12 @@ public class PlaybackService extends Service {
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (status == PlayerStatus.PLAYING) {
+ if (UserPreferences.isPersistNotify()) {
+ mediaPlayer.pause(false, true);
+ }
+ else {
mediaPlayer.pause(true, true);
+ }
}
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
@@ -328,6 +338,12 @@ public class PlaybackService extends Service {
case KeyEvent.KEYCODE_MEDIA_REWIND:
mediaPlayer.seekDelta(-UserPreferences.getSeekDeltaMs());
break;
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ if (status == PlayerStatus.PLAYING) {
+ mediaPlayer.pause(true, true);
+ }
+ stopForeground(true); // gets rid of persistent notification
+ break;
default:
if (info.playable != null && info.playerStatus == PlayerStatus.PLAYING) { // only notify the user about an unknown key event if it is actually doing something
String message = String.format(getResources().getString(R.string.unknown_media_key), keycode);
@@ -401,7 +417,13 @@ public class PlaybackService extends Service {
taskManager.cancelPositionSaver();
saveCurrentPosition(false, 0);
taskManager.cancelWidgetUpdater();
- stopForeground(true);
+ if (UserPreferences.isPersistNotify() && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ // do not remove notification on pause based on user pref and whether android version supports expanded notifications
+ }
+ else {
+ // remove notifcation on pause
+ stopForeground(true);
+ }
break;
case STOPPED:
@@ -713,7 +735,7 @@ public class PlaybackService extends Service {
String contentTitle = info.playable.getEpisodeTitle();
Notification notification = null;
if (android.os.Build.VERSION.SDK_INT >= 16) {
- Intent pauseButtonIntent = new Intent(
+ Intent pauseButtonIntent = new Intent( // pause button intent
PlaybackService.this, PlaybackService.class);
pauseButtonIntent.putExtra(
MediaButtonReceiver.EXTRA_KEYCODE,
@@ -722,6 +744,24 @@ public class PlaybackService extends Service {
.getService(PlaybackService.this, 0,
pauseButtonIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
+ Intent playButtonIntent = new Intent( // play button intent
+ PlaybackService.this, PlaybackService.class);
+ playButtonIntent.putExtra(
+ MediaButtonReceiver.EXTRA_KEYCODE,
+ KeyEvent.KEYCODE_MEDIA_PLAY);
+ PendingIntent playButtonPendingIntent = PendingIntent
+ .getService(PlaybackService.this, 1,
+ playButtonIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ Intent stopButtonIntent = new Intent( // stop button intent
+ PlaybackService.this, PlaybackService.class);
+ stopButtonIntent.putExtra(
+ MediaButtonReceiver.EXTRA_KEYCODE,
+ KeyEvent.KEYCODE_MEDIA_STOP);
+ PendingIntent stopButtonPendingIntent = PendingIntent
+ .getService(PlaybackService.this, 2,
+ stopButtonIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder notificationBuilder = new Notification.Builder(
PlaybackService.this)
.setContentTitle(contentTitle)
@@ -730,9 +770,16 @@ public class PlaybackService extends Service {
.setContentIntent(pIntent)
.setLargeIcon(icon)
.setSmallIcon(R.drawable.ic_stat_antenna)
- .addAction(android.R.drawable.ic_media_pause,
+ .setPriority(UserPreferences.getNotifyPriority()) // set notification priority
+ .addAction(android.R.drawable.ic_media_play, //play action
+ getString(R.string.play_label),
+ playButtonPendingIntent)
+ .addAction(android.R.drawable.ic_media_pause, //pause action
getString(R.string.pause_label),
- pauseButtonPendingIntent);
+ pauseButtonPendingIntent)
+ .addAction(android.R.drawable.ic_menu_close_clear_cancel, // stop action
+ getString(R.string.stop_label),
+ stopButtonPendingIntent);
notification = notificationBuilder.build();
} else {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
@@ -949,7 +996,12 @@ public class PlaybackService extends Service {
*/
private void pauseIfPauseOnDisconnect() {
if (UserPreferences.isPauseOnHeadsetDisconnect()) {
+ if (UserPreferences.isPersistNotify()) {
+ mediaPlayer.pause(false, true);
+ }
+ else {
mediaPlayer.pause(true, true);
+ }
}
}
diff --git a/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java b/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java
index 49f20012d..9978fff3c 100644
--- a/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java
+++ b/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java
@@ -747,8 +747,8 @@ public class PlaybackServiceMediaPlayer {
pause(false, false);
pausedBecauseOfTransientAudiofocusLoss = true;
}
- playerLock.unlock();
}
+ playerLock.unlock();
}
});
}
diff --git a/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java b/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java
index 71bc40c2a..ec28724ed 100644
--- a/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java
+++ b/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java
@@ -24,6 +24,10 @@ public class PlayerWidgetService extends Service {
private static final String TAG = "PlayerWidgetService";
private PlaybackService playbackService;
+
+ /** Controls write access to playbackservice reference */
+ private Object psLock;
+
/** True while service is updating the widget */
private volatile boolean isUpdating;
@@ -36,6 +40,7 @@ public class PlayerWidgetService extends Service {
if (BuildConfig.DEBUG)
Log.d(TAG, "Service created");
isUpdating = false;
+ psLock = new Object();
}
@Override
@@ -148,16 +153,20 @@ public class PlayerWidgetService extends Service {
public void onServiceConnected(ComponentName className, IBinder service) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Connection to service established");
- playbackService = ((PlaybackService.LocalBinder) service)
- .getService();
- startViewUpdaterIfNotRunning();
+ synchronized (psLock) {
+ playbackService = ((PlaybackService.LocalBinder) service)
+ .getService();
+ startViewUpdaterIfNotRunning();
+ }
}
@Override
public void onServiceDisconnected(ComponentName name) {
- playbackService = null;
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Disconnected from service");
+ synchronized (psLock) {
+ playbackService = null;
+ if (BuildConfig.DEBUG)
+ Log.d(TAG, "Disconnected from service");
+ }
}
};
@@ -169,7 +178,7 @@ public class PlayerWidgetService extends Service {
}
}
- static class ViewUpdater extends Thread {
+ class ViewUpdater extends Thread {
private static final String THREAD_NAME = "ViewUpdater";
private PlayerWidgetService service;
@@ -182,7 +191,9 @@ public class PlayerWidgetService extends Service {
@Override
public void run() {
- service.updateViews();
+ synchronized (psLock) {
+ service.updateViews();
+ }
}
}
diff --git a/src/de/danoeh/antennapod/storage/DownloadRequester.java b/src/de/danoeh/antennapod/storage/DownloadRequester.java
index d305c572b..0eae52137 100644
--- a/src/de/danoeh/antennapod/storage/DownloadRequester.java
+++ b/src/de/danoeh/antennapod/storage/DownloadRequester.java
@@ -34,7 +34,7 @@ public class DownloadRequester {
private static DownloadRequester downloader;
- Map<String, DownloadRequest> downloads;
+ private Map<String, DownloadRequest> downloads;
private DownloadRequester() {
downloads = new ConcurrentHashMap<String, DownloadRequest>();
@@ -57,7 +57,7 @@ public class DownloadRequester {
* call will return false.
* @return True if the download request was accepted, false otherwise.
*/
- public boolean download(Context context, DownloadRequest request) {
+ public synchronized boolean download(Context context, DownloadRequest request) {
Validate.notNull(context);
Validate.notNull(request);
@@ -145,7 +145,7 @@ public class DownloadRequester {
return true;
}
- public void downloadFeed(Context context, Feed feed)
+ public synchronized void downloadFeed(Context context, Feed feed)
throws DownloadRequestException {
if (feedFileValid(feed)) {
String username = (feed.getPreferences() != null) ? feed.getPreferences().getUsername() : null;
@@ -156,7 +156,7 @@ public class DownloadRequester {
}
}
- public void downloadImage(Context context, FeedImage image)
+ public synchronized void downloadImage(Context context, FeedImage image)
throws DownloadRequestException {
if (feedFileValid(image)) {
download(context, image, new File(getImagefilePath(context),
@@ -164,7 +164,7 @@ public class DownloadRequester {
}
}
- public void downloadMedia(Context context, FeedMedia feedmedia)
+ public synchronized void downloadMedia(Context context, FeedMedia feedmedia)
throws DownloadRequestException {
if (feedFileValid(feedmedia)) {
Feed feed = feedmedia.getItem().getFeed();
@@ -210,14 +210,14 @@ public class DownloadRequester {
/**
* Cancels a running download.
*/
- public void cancelDownload(final Context context, final FeedFile f) {
+ public synchronized void cancelDownload(final Context context, final FeedFile f) {
cancelDownload(context, f.getDownload_url());
}
/**
* Cancels a running download.
*/
- public void cancelDownload(final Context context, final String downloadUrl) {
+ public synchronized void cancelDownload(final Context context, final String downloadUrl) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Cancelling download with url " + downloadUrl);
Intent cancelIntent = new Intent(DownloadService.ACTION_CANCEL_DOWNLOAD);
@@ -228,7 +228,7 @@ public class DownloadRequester {
/**
* Cancels all running downloads
*/
- public void cancelAllDownloads(Context context) {
+ public synchronized void cancelAllDownloads(Context context) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Cancelling all running downloads");
context.sendBroadcast(new Intent(
@@ -238,7 +238,7 @@ public class DownloadRequester {
/**
* Returns true if there is at least one Feed in the downloads queue.
*/
- public boolean isDownloadingFeeds() {
+ public synchronized boolean isDownloadingFeeds() {
for (DownloadRequest r : downloads.values()) {
if (r.getFeedfileType() == Feed.FEEDFILETYPE_FEED) {
return true;
@@ -250,32 +250,32 @@ public class DownloadRequester {
/**
* Checks if feedfile is in the downloads list
*/
- public boolean isDownloadingFile(FeedFile item) {
+ public synchronized boolean isDownloadingFile(FeedFile item) {
if (item.getDownload_url() != null) {
return downloads.containsKey(item.getDownload_url());
}
return false;
}
- public DownloadRequest getDownload(String downloadUrl) {
+ public synchronized DownloadRequest getDownload(String downloadUrl) {
return downloads.get(downloadUrl);
}
/**
* Checks if feedfile with the given download url is in the downloads list
*/
- public boolean isDownloadingFile(String downloadUrl) {
+ public synchronized boolean isDownloadingFile(String downloadUrl) {
return downloads.get(downloadUrl) != null;
}
- public boolean hasNoDownloads() {
+ public synchronized boolean hasNoDownloads() {
return downloads.isEmpty();
}
/**
* Remove an object from the downloads-list of the requester.
*/
- public void removeDownload(DownloadRequest r) {
+ public synchronized void removeDownload(DownloadRequest r) {
if (downloads.remove(r.getSource()) == null) {
Log.e(TAG,
"Could not remove object with url " + r.getSource());
@@ -285,17 +285,17 @@ public class DownloadRequester {
/**
* Get the number of uncompleted Downloads
*/
- public int getNumberOfDownloads() {
+ public synchronized int getNumberOfDownloads() {
return downloads.size();
}
- public String getFeedfilePath(Context context)
+ public synchronized String getFeedfilePath(Context context)
throws DownloadRequestException {
return getExternalFilesDirOrThrowException(context, FEED_DOWNLOADPATH)
.toString() + "/";
}
- public String getFeedfileName(Feed feed) {
+ public synchronized String getFeedfileName(Feed feed) {
String filename = feed.getDownload_url();
if (feed.getTitle() != null && !feed.getTitle().isEmpty()) {
filename = feed.getTitle();
@@ -303,13 +303,13 @@ public class DownloadRequester {
return "feed-" + FileNameGenerator.generateFileName(filename);
}
- public String getImagefilePath(Context context)
+ public synchronized String getImagefilePath(Context context)
throws DownloadRequestException {
return getExternalFilesDirOrThrowException(context, IMAGE_DOWNLOADPATH)
.toString() + "/";
}
- public String getImagefileName(FeedImage image) {
+ public synchronized String getImagefileName(FeedImage image) {
String filename = image.getDownload_url();
if (image.getOwner() != null && image.getOwner().getHumanReadableIdentifier() != null) {
filename = image.getOwner().getHumanReadableIdentifier();
@@ -317,7 +317,7 @@ public class DownloadRequester {
return "image-" + FileNameGenerator.generateFileName(filename);
}
- public String getMediafilePath(Context context, FeedMedia media)
+ public synchronized String getMediafilePath(Context context, FeedMedia media)
throws DownloadRequestException {
File externalStorage = getExternalFilesDirOrThrowException(
context,
@@ -338,7 +338,7 @@ public class DownloadRequester {
return result;
}
- public String getMediafilename(FeedMedia media) {
+ private String getMediafilename(FeedMedia media) {
String filename;
String titleBaseFilename = "";
diff --git a/src/de/danoeh/antennapod/syndication/namespace/NSSimpleChapters.java b/src/de/danoeh/antennapod/syndication/namespace/NSSimpleChapters.java
index 3f983ee88..b45793b6b 100644
--- a/src/de/danoeh/antennapod/syndication/namespace/NSSimpleChapters.java
+++ b/src/de/danoeh/antennapod/syndication/namespace/NSSimpleChapters.java
@@ -1,5 +1,8 @@
package de.danoeh.antennapod.syndication.namespace;
+import android.util.Log;
+
+import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.feed.Chapter;
import de.danoeh.antennapod.feed.SimpleChapter;
import de.danoeh.antennapod.syndication.handler.HandlerState;
@@ -9,6 +12,8 @@ import org.xml.sax.Attributes;
import java.util.ArrayList;
public class NSSimpleChapters extends Namespace {
+ private static final String TAG = "NSSimpleChapters";
+
public static final String NSTAG = "psc|sc";
public static final String NSURI = "http://podlove.org/simple-chapters";
@@ -24,12 +29,16 @@ public class NSSimpleChapters extends Namespace {
if (localName.equals(CHAPTERS)) {
state.getCurrentItem().setChapters(new ArrayList<Chapter>());
} else if (localName.equals(CHAPTER)) {
- state.getCurrentItem()
- .getChapters()
- .add(new SimpleChapter(SyndDateUtils
- .parseTimeString(attributes.getValue(START)),
- attributes.getValue(TITLE), state.getCurrentItem(),
- attributes.getValue(HREF)));
+ try {
+ state.getCurrentItem()
+ .getChapters()
+ .add(new SimpleChapter(SyndDateUtils
+ .parseTimeString(attributes.getValue(START)),
+ attributes.getValue(TITLE), state.getCurrentItem(),
+ attributes.getValue(HREF)));
+ } catch (NumberFormatException e) {
+ if (BuildConfig.DEBUG) Log.w(TAG, "Unable to read chapter", e);
+ }
}
return new SyndElement(localName, this);
diff --git a/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java b/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java
index 3138f087a..56687ac2e 100644
--- a/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java
+++ b/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java
@@ -7,130 +7,138 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
-/** Parses several date formats. */
+/**
+ * Parses several date formats.
+ */
public class SyndDateUtils {
- private static final String TAG = "DateUtils";
-
- private static final String[] RFC822DATES = { "dd MMM yy HH:mm:ss Z", };
-
- /** RFC 3339 date format for UTC dates. */
- public static final String RFC3339UTC = "yyyy-MM-dd'T'HH:mm:ss'Z'";
-
- /** RFC 3339 date format for localtime dates with offset. */
- public static final String RFC3339LOCAL = "yyyy-MM-dd'T'HH:mm:ssZ";
-
- private static ThreadLocal<SimpleDateFormat> RFC822Formatter = new ThreadLocal<SimpleDateFormat>() {
- @Override
- protected SimpleDateFormat initialValue() {
- return new SimpleDateFormat(RFC822DATES[0], Locale.US);
- }
-
- };
-
- private static ThreadLocal<SimpleDateFormat> RFC3339Formatter = new ThreadLocal<SimpleDateFormat>() {
- @Override
- protected SimpleDateFormat initialValue() {
- return new SimpleDateFormat(RFC3339UTC, Locale.US);
- }
-
- };
-
- public static Date parseRFC822Date(String date) {
- Date result = null;
- if (date.contains("PDT")) {
- date = date.replace("PDT", "PST8PDT");
- }
- if (date.contains(",")) {
- // Remove day of the week
- date = date.substring(date.indexOf(",") + 1).trim();
- }
- SimpleDateFormat format = RFC822Formatter.get();
- for (int i = 0; i < RFC822DATES.length; i++) {
- try {
- format.applyPattern(RFC822DATES[i]);
- result = format.parse(date);
- break;
- } catch (ParseException e) {
- e.printStackTrace();
- }
- }
- if (result == null) {
- Log.e(TAG, "Unable to parse feed date correctly");
- }
-
- return result;
- }
-
- public static Date parseRFC3339Date(String date) {
- Date result = null;
- SimpleDateFormat format = RFC3339Formatter.get();
- boolean isLocal = date.endsWith("Z");
- if (date.contains(".")) {
- // remove secfrac
- int fracIndex = date.indexOf(".");
- String first = date.substring(0, fracIndex);
- String second = null;
- if (isLocal) {
- second = date.substring(date.length() - 1);
- } else {
- if (date.contains("+")) {
- second = date.substring(date.indexOf("+"));
- } else {
- second = date.substring(date.indexOf("-"));
- }
- }
-
- date = first + second;
- }
- if (isLocal) {
- try {
- result = format.parse(date);
- } catch (ParseException e) {
- e.printStackTrace();
- }
- } else {
- format.applyPattern(RFC3339LOCAL);
- // remove last colon
- StringBuffer buf = new StringBuffer(date.length() - 1);
- int colonIdx = date.lastIndexOf(':');
- for (int x = 0; x < date.length(); x++) {
- if (x != colonIdx)
- buf.append(date.charAt(x));
- }
- String bufStr = buf.toString();
- try {
- result = format.parse(bufStr);
- } catch (ParseException e) {
- e.printStackTrace();
- Log.e(TAG, "Unable to parse date");
- } finally {
- format.applyPattern(RFC3339UTC);
- }
-
- }
-
- return result;
-
- }
-
- /**
- * Takes a string of the form [HH:]MM:SS[.mmm] and converts it to
- * milliseconds.
- */
- public static long parseTimeString(final String time) {
- String[] parts = time.split(":");
- long result = 0;
- int idx = 0;
- if (parts.length == 3) {
- // string has hours
- result += Integer.valueOf(parts[idx]) * 3600000L;
- idx++;
- }
- result += Integer.valueOf(parts[idx]) * 60000L;
- idx++;
- result += (Float.valueOf(parts[idx])) * 1000L;
- return result;
- }
+ private static final String TAG = "DateUtils";
+
+ private static final String[] RFC822DATES = {"dd MMM yy HH:mm:ss Z",};
+
+ /**
+ * RFC 3339 date format for UTC dates.
+ */
+ public static final String RFC3339UTC = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+
+ /**
+ * RFC 3339 date format for localtime dates with offset.
+ */
+ public static final String RFC3339LOCAL = "yyyy-MM-dd'T'HH:mm:ssZ";
+
+ private static ThreadLocal<SimpleDateFormat> RFC822Formatter = new ThreadLocal<SimpleDateFormat>() {
+ @Override
+ protected SimpleDateFormat initialValue() {
+ return new SimpleDateFormat(RFC822DATES[0], Locale.US);
+ }
+
+ };
+
+ private static ThreadLocal<SimpleDateFormat> RFC3339Formatter = new ThreadLocal<SimpleDateFormat>() {
+ @Override
+ protected SimpleDateFormat initialValue() {
+ return new SimpleDateFormat(RFC3339UTC, Locale.US);
+ }
+
+ };
+
+ public static Date parseRFC822Date(String date) {
+ Date result = null;
+ if (date.contains("PDT")) {
+ date = date.replace("PDT", "PST8PDT");
+ }
+ if (date.contains(",")) {
+ // Remove day of the week
+ date = date.substring(date.indexOf(",") + 1).trim();
+ }
+ SimpleDateFormat format = RFC822Formatter.get();
+ for (int i = 0; i < RFC822DATES.length; i++) {
+ try {
+ format.applyPattern(RFC822DATES[i]);
+ result = format.parse(date);
+ break;
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+ if (result == null) {
+ Log.e(TAG, "Unable to parse feed date correctly");
+ }
+
+ return result;
+ }
+
+ public static Date parseRFC3339Date(String date) {
+ Date result = null;
+ SimpleDateFormat format = RFC3339Formatter.get();
+ boolean isLocal = date.endsWith("Z");
+ if (date.contains(".")) {
+ // remove secfrac
+ int fracIndex = date.indexOf(".");
+ String first = date.substring(0, fracIndex);
+ String second = null;
+ if (isLocal) {
+ second = date.substring(date.length() - 1);
+ } else {
+ if (date.contains("+")) {
+ second = date.substring(date.indexOf("+"));
+ } else {
+ second = date.substring(date.indexOf("-"));
+ }
+ }
+
+ date = first + second;
+ }
+ if (isLocal) {
+ try {
+ result = format.parse(date);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ } else {
+ format.applyPattern(RFC3339LOCAL);
+ // remove last colon
+ StringBuffer buf = new StringBuffer(date.length() - 1);
+ int colonIdx = date.lastIndexOf(':');
+ for (int x = 0; x < date.length(); x++) {
+ if (x != colonIdx)
+ buf.append(date.charAt(x));
+ }
+ String bufStr = buf.toString();
+ try {
+ result = format.parse(bufStr);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ Log.e(TAG, "Unable to parse date");
+ } finally {
+ format.applyPattern(RFC3339UTC);
+ }
+
+ }
+
+ return result;
+
+ }
+
+ /**
+ * Takes a string of the form [HH:]MM:SS[.mmm] and converts it to
+ * milliseconds.
+ *
+ * @throws java.lang.NumberFormatException if the number segments contain invalid numbers.
+ */
+ public static long parseTimeString(final String time) {
+ String[] parts = time.split(":");
+ long result = 0;
+ int idx = 0;
+ if (parts.length == 3) {
+ // string has hours
+ result += Integer.valueOf(parts[idx]) * 3600000L;
+ idx++;
+ }
+ result += Integer.valueOf(parts[idx]) * 60000L;
+ idx++;
+ result += (Float.valueOf(parts[idx])) * 1000L;
+ return result;
+ }
public static String formatRFC822Date(Date date) {
SimpleDateFormat format = RFC822Formatter.get();
diff --git a/src/de/danoeh/antennapod/util/ChapterUtils.java b/src/de/danoeh/antennapod/util/ChapterUtils.java
index 9e1c50674..2d9022eed 100644
--- a/src/de/danoeh/antennapod/util/ChapterUtils.java
+++ b/src/de/danoeh/antennapod/util/ChapterUtils.java
@@ -1,6 +1,20 @@
package de.danoeh.antennapod.util;
import android.util.Log;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.feed.Chapter;
import de.danoeh.antennapod.util.comparator.ChapterStartTimeComparator;
@@ -9,253 +23,252 @@ import de.danoeh.antennapod.util.id3reader.ID3ReaderException;
import de.danoeh.antennapod.util.playback.Playable;
import de.danoeh.antennapod.util.vorbiscommentreader.VorbisCommentChapterReader;
import de.danoeh.antennapod.util.vorbiscommentreader.VorbisCommentReaderException;
-import org.apache.commons.io.IOUtils;
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.List;
-
-/** Utility class for getting chapter data from media files. */
+/**
+ * Utility class for getting chapter data from media files.
+ */
public class ChapterUtils {
- private static final String TAG = "ChapterUtils";
+ private static final String TAG = "ChapterUtils";
- private ChapterUtils() {
- }
+ private ChapterUtils() {
+ }
- /**
- * Uses the download URL of a media object of a feeditem to read its ID3
- * chapters.
- */
- public static void readID3ChaptersFromPlayableStreamUrl(Playable p) {
- if (p != null && p.getStreamUrl() != null) {
+ /**
+ * Uses the download URL of a media object of a feeditem to read its ID3
+ * chapters.
+ */
+ public static void readID3ChaptersFromPlayableStreamUrl(Playable p) {
+ if (p != null && p.getStreamUrl() != null) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Reading id3 chapters from item " + p.getEpisodeTitle());
- InputStream in = null;
- try {
- URL url = new URL(p.getStreamUrl());
- ChapterReader reader = new ChapterReader();
+ InputStream in = null;
+ try {
+ URL url = new URL(p.getStreamUrl());
+ ChapterReader reader = new ChapterReader();
- in = url.openStream();
- reader.readInputStream(in);
- List<Chapter> chapters = reader.getChapters();
+ in = url.openStream();
+ reader.readInputStream(in);
+ List<Chapter> chapters = reader.getChapters();
- if (chapters != null) {
- Collections
- .sort(chapters, new ChapterStartTimeComparator());
- processChapters(chapters, p);
- if (chaptersValid(chapters)) {
- p.setChapters(chapters);
- Log.i(TAG, "Chapters loaded");
- } else {
- Log.e(TAG, "Chapter data was invalid");
- }
- } else {
- Log.i(TAG, "ChapterReader could not find any ID3 chapters");
- }
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ID3ReaderException e) {
- e.printStackTrace();
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- } else {
- Log.e(TAG,
- "Unable to read ID3 chapters: media or download URL was null");
- }
- }
+ if (chapters != null) {
+ Collections
+ .sort(chapters, new ChapterStartTimeComparator());
+ processChapters(chapters, p);
+ if (chaptersValid(chapters)) {
+ p.setChapters(chapters);
+ Log.i(TAG, "Chapters loaded");
+ } else {
+ Log.e(TAG, "Chapter data was invalid");
+ }
+ } else {
+ Log.i(TAG, "ChapterReader could not find any ID3 chapters");
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ID3ReaderException e) {
+ e.printStackTrace();
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } else {
+ Log.e(TAG,
+ "Unable to read ID3 chapters: media or download URL was null");
+ }
+ }
- /**
- * Uses the file URL of a media object of a feeditem to read its ID3
- * chapters.
- */
- public static void readID3ChaptersFromPlayableFileUrl(Playable p) {
- if (p != null && p.localFileAvailable() && p.getLocalMediaUrl() != null) {
+ /**
+ * Uses the file URL of a media object of a feeditem to read its ID3
+ * chapters.
+ */
+ public static void readID3ChaptersFromPlayableFileUrl(Playable p) {
+ if (p != null && p.localFileAvailable() && p.getLocalMediaUrl() != null) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Reading id3 chapters from item " + p.getEpisodeTitle());
- File source = new File(p.getLocalMediaUrl());
- if (source.exists()) {
- ChapterReader reader = new ChapterReader();
- InputStream in = null;
+ File source = new File(p.getLocalMediaUrl());
+ if (source.exists()) {
+ ChapterReader reader = new ChapterReader();
+ InputStream in = null;
+
+ try {
+ in = new BufferedInputStream(new FileInputStream(source));
+ reader.readInputStream(in);
+ List<Chapter> chapters = reader.getChapters();
- try {
- in = new BufferedInputStream(new FileInputStream(source));
- reader.readInputStream(in);
- List<Chapter> chapters = reader.getChapters();
+ if (chapters != null) {
+ Collections.sort(chapters,
+ new ChapterStartTimeComparator());
+ processChapters(chapters, p);
+ if (chaptersValid(chapters)) {
+ p.setChapters(chapters);
+ Log.i(TAG, "Chapters loaded");
+ } else {
+ Log.e(TAG, "Chapter data was invalid");
+ }
+ } else {
+ Log.i(TAG,
+ "ChapterReader could not find any ID3 chapters");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ID3ReaderException e) {
+ e.printStackTrace();
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } else {
+ Log.e(TAG, "Unable to read id3 chapters: Source doesn't exist");
+ }
+ }
+ }
- if (chapters != null) {
- Collections.sort(chapters,
- new ChapterStartTimeComparator());
- processChapters(chapters, p);
- if (chaptersValid(chapters)) {
- p.setChapters(chapters);
- Log.i(TAG, "Chapters loaded");
- } else {
- Log.e(TAG, "Chapter data was invalid");
- }
- } else {
- Log.i(TAG,
- "ChapterReader could not find any ID3 chapters");
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ID3ReaderException e) {
- e.printStackTrace();
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- } else {
- Log.e(TAG, "Unable to read id3 chapters: Source doesn't exist");
- }
- }
- }
+ public static void readOggChaptersFromPlayableStreamUrl(Playable media) {
+ if (media != null && media.streamAvailable()) {
+ InputStream input = null;
+ try {
+ URL url = new URL(media.getStreamUrl());
+ input = url.openStream();
+ if (input != null) {
+ readOggChaptersFromInputStream(media, input);
+ }
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(input);
+ }
+ }
+ }
- public static void readOggChaptersFromPlayableStreamUrl(Playable media) {
- if (media != null && media.streamAvailable()) {
- InputStream input = null;
- try {
- URL url = new URL(media.getStreamUrl());
- input = url.openStream();
- if (input != null) {
- readOggChaptersFromInputStream(media, input);
- }
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- IOUtils.closeQuietly(input);
- }
- }
- }
+ public static void readOggChaptersFromPlayableFileUrl(Playable media) {
+ if (media != null && media.getLocalMediaUrl() != null) {
+ File source = new File(media.getLocalMediaUrl());
+ if (source.exists()) {
+ InputStream input = null;
+ try {
+ input = new BufferedInputStream(new FileInputStream(source));
+ readOggChaptersFromInputStream(media, input);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(input);
+ }
+ }
+ }
+ }
- public static void readOggChaptersFromPlayableFileUrl(Playable media) {
- if (media != null && media.getLocalMediaUrl() != null) {
- File source = new File(media.getLocalMediaUrl());
- if (source.exists()) {
- InputStream input = null;
- try {
- input = new BufferedInputStream(new FileInputStream(source));
- readOggChaptersFromInputStream(media, input);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } finally {
- IOUtils.closeQuietly(input);
- }
- }
- }
- }
+ private static void readOggChaptersFromInputStream(Playable p,
+ InputStream input) {
+ if (BuildConfig.DEBUG)
+ Log.d(TAG,
+ "Trying to read chapters from item with title "
+ + p.getEpisodeTitle());
+ try {
+ VorbisCommentChapterReader reader = new VorbisCommentChapterReader();
+ reader.readInputStream(input);
+ List<Chapter> chapters = reader.getChapters();
+ if (chapters != null) {
+ Collections.sort(chapters, new ChapterStartTimeComparator());
+ processChapters(chapters, p);
+ if (chaptersValid(chapters)) {
+ p.setChapters(chapters);
+ Log.i(TAG, "Chapters loaded");
+ } else {
+ Log.e(TAG, "Chapter data was invalid");
+ }
+ } else {
+ Log.i(TAG,
+ "ChapterReader could not find any Ogg vorbis chapters");
+ }
+ } catch (VorbisCommentReaderException e) {
+ e.printStackTrace();
+ }
+ }
- private static void readOggChaptersFromInputStream(Playable p,
- InputStream input) {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Trying to read chapters from item with title "
- + p.getEpisodeTitle());
- try {
- VorbisCommentChapterReader reader = new VorbisCommentChapterReader();
- reader.readInputStream(input);
- List<Chapter> chapters = reader.getChapters();
- if (chapters != null) {
- Collections.sort(chapters, new ChapterStartTimeComparator());
- processChapters(chapters, p);
- if (chaptersValid(chapters)) {
- p.setChapters(chapters);
- Log.i(TAG, "Chapters loaded");
- } else {
- Log.e(TAG, "Chapter data was invalid");
- }
- } else {
- Log.i(TAG,
- "ChapterReader could not find any Ogg vorbis chapters");
- }
- } catch (VorbisCommentReaderException e) {
- e.printStackTrace();
- }
- }
+ /**
+ * Makes sure that chapter does a title and an item attribute.
+ */
+ private static void processChapters(List<Chapter> chapters, Playable p) {
+ for (int i = 0; i < chapters.size(); i++) {
+ Chapter c = chapters.get(i);
+ if (c.getTitle() == null) {
+ c.setTitle(Integer.toString(i));
+ }
+ }
+ }
- /** Makes sure that chapter does a title and an item attribute. */
- private static void processChapters(List<Chapter> chapters, Playable p) {
- for (int i = 0; i < chapters.size(); i++) {
- Chapter c = chapters.get(i);
- if (c.getTitle() == null) {
- c.setTitle(Integer.toString(i));
- }
- }
- }
+ private static boolean chaptersValid(List<Chapter> chapters) {
+ if (chapters.isEmpty()) {
+ return false;
+ }
+ for (Chapter c : chapters) {
+ if (c.getTitle() == null) {
+ return false;
+ }
+ if (c.getStart() < 0) {
+ return false;
+ }
+ }
+ return true;
+ }
- private static boolean chaptersValid(List<Chapter> chapters) {
- if (chapters.isEmpty()) {
- return false;
- }
- for (Chapter c : chapters) {
- if (c.getTitle() == null) {
- return false;
- }
- if (c.getStart() < 0) {
- return false;
- }
- }
- return true;
- }
+ /**
+ * Calls getCurrentChapter with current position.
+ */
+ public static Chapter getCurrentChapter(Playable media) {
+ if (media.getChapters() != null) {
+ List<Chapter> chapters = media.getChapters();
+ Chapter current = null;
+ if (chapters != null) {
+ current = chapters.get(0);
+ for (Chapter sc : chapters) {
+ if (sc.getStart() > media.getPosition()) {
+ break;
+ } else {
+ current = sc;
+ }
+ }
+ }
+ return current;
+ } else {
+ return null;
+ }
+ }
- /** Calls getCurrentChapter with current position. */
- public static Chapter getCurrentChapter(Playable media) {
- if (media.getChapters() != null) {
- List<Chapter> chapters = media.getChapters();
- Chapter current = null;
- if (chapters != null) {
- current = chapters.get(0);
- for (Chapter sc : chapters) {
- if (sc.getStart() > media.getPosition()) {
- break;
- } else {
- current = sc;
- }
- }
- }
- return current;
- } else {
- return null;
- }
- }
+ public static void loadChaptersFromStreamUrl(Playable media) {
+ if (BuildConfig.DEBUG)
+ Log.d(TAG, "Starting chapterLoader thread");
+ ChapterUtils.readID3ChaptersFromPlayableStreamUrl(media);
+ if (media.getChapters() == null) {
+ ChapterUtils.readOggChaptersFromPlayableStreamUrl(media);
+ }
- public static void loadChaptersFromStreamUrl(Playable media) {
- if (BuildConfig.DEBUG)
- Log.d(TAG, "Starting chapterLoader thread");
- ChapterUtils.readID3ChaptersFromPlayableStreamUrl(media);
- if (media.getChapters() == null) {
- ChapterUtils.readOggChaptersFromPlayableStreamUrl(media);
- }
+ if (BuildConfig.DEBUG)
+ Log.d(TAG, "ChapterLoaderThread has finished");
+ }
- if (BuildConfig.DEBUG)
- Log.d(TAG, "ChapterLoaderThread has finished");
- }
-
- public static void loadChaptersFromFileUrl(Playable media) {
- if (media.localFileAvailable()) {
- ChapterUtils.readID3ChaptersFromPlayableFileUrl(media);
- if (media.getChapters() == null) {
- ChapterUtils.readOggChaptersFromPlayableFileUrl(media);
- }
- } else {
- Log.e(TAG, "Could not load chapters from file url: local file not available");
- }
- }
+ public static void loadChaptersFromFileUrl(Playable media) {
+ if (media.localFileAvailable()) {
+ ChapterUtils.readID3ChaptersFromPlayableFileUrl(media);
+ if (media.getChapters() == null) {
+ ChapterUtils.readOggChaptersFromPlayableFileUrl(media);
+ }
+ } else {
+ Log.e(TAG, "Could not load chapters from file url: local file not available");
+ }
+ }
}
diff --git a/src/de/danoeh/antennapod/util/URLChecker.java b/src/de/danoeh/antennapod/util/URLChecker.java
index 9997daaf7..2352adddf 100644
--- a/src/de/danoeh/antennapod/util/URLChecker.java
+++ b/src/de/danoeh/antennapod/util/URLChecker.java
@@ -22,6 +22,8 @@ public final class URLChecker {
*/
private static final String TAG = "URLChecker";
+ private static final String AP_SUBSCRIBE = "antennapod-subscribe://";
+
/**
* Checks if URL is valid and modifies it if necessary.
*
@@ -29,23 +31,24 @@ public final class URLChecker {
* @return The prepared url
*/
public static String prepareURL(String url) {
- StringBuilder builder = new StringBuilder();
url = StringUtils.trim(url);
if (url.startsWith("feed://")) {
if (BuildConfig.DEBUG) Log.d(TAG, "Replacing feed:// with http://");
- url = url.replaceFirst("feed://", "http://");
+ return url.replaceFirst("feed://", "http://");
} else if (url.startsWith("pcast://")) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Replacing pcast:// with http://");
- url = url.replaceFirst("pcast://", "http://");
+ if (BuildConfig.DEBUG) Log.d(TAG, "Removing pcast://");
+ return prepareURL(StringUtils.removeStart(url, "pcast://"));
} else if (url.startsWith("itpc")) {
if (BuildConfig.DEBUG) Log.d(TAG, "Replacing itpc:// with http://");
- url = url.replaceFirst("itpc://", "http://");
+ return url.replaceFirst("itpc://", "http://");
+ } else if (url.startsWith(AP_SUBSCRIBE)) {
+ if (BuildConfig.DEBUG) Log.d(TAG, "Removing antennapod-subscribe://");
+ return prepareURL(StringUtils.removeStart(url, AP_SUBSCRIBE));
} else if (!(url.startsWith("http://") || url.startsWith("https://"))) {
if (BuildConfig.DEBUG) Log.d(TAG, "Adding http:// at the beginning of the URL");
- builder.append("http://");
+ return "http://" + url;
+ } else {
+ return url;
}
- builder.append(url);
-
- return builder.toString();
}
}
diff --git a/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java b/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java
index 1ff3437c0..96d3bbedd 100644
--- a/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java
+++ b/src/de/danoeh/antennapod/util/flattr/FlattrUtils.java
@@ -90,7 +90,7 @@ public class FlattrUtils {
*/
public static boolean hasAPICredentials() {
return StringUtils.isNotEmpty(BuildConfig.FLATTR_APP_KEY)
- && StringUtils.isNoneEmpty(BuildConfig.FLATTR_APP_SECRET);
+ && StringUtils.isNotEmpty(BuildConfig.FLATTR_APP_SECRET);
}
public static boolean hasToken() {
@@ -133,7 +133,7 @@ public class FlattrUtils {
throws FlattrException {
if (hasToken()) {
FlattrService fs = FlattrServiceCreator.getService(retrieveToken());
- fs.click(url);
+ fs.flattr(url);
} else {
Log.e(TAG, "clickUrl was called with null access token");
}