summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/de/danoeh/antennapod/activity/AudioplayerActivity.java6
-rw-r--r--src/de/danoeh/antennapod/activity/MainActivity.java6
-rw-r--r--src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java5
-rw-r--r--src/de/danoeh/antennapod/activity/PreferenceActivity.java1
-rw-r--r--src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java6
-rw-r--r--src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java7
-rw-r--r--src/de/danoeh/antennapod/asynctask/BitmapDecodeWorkerTask.java54
-rw-r--r--src/de/danoeh/antennapod/asynctask/ImageLoader.java77
-rw-r--r--src/de/danoeh/antennapod/feed/FeedImage.java40
-rw-r--r--src/de/danoeh/antennapod/feed/FeedItem.java42
-rw-r--r--src/de/danoeh/antennapod/feed/FeedMedia.java44
-rw-r--r--src/de/danoeh/antennapod/fragment/CoverFragment.java2
-rw-r--r--src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java2
-rw-r--r--src/de/danoeh/antennapod/fragment/ItemlistFragment.java2
-rw-r--r--src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java1
-rw-r--r--src/de/danoeh/antennapod/preferences/PlaybackPreferences.java2
-rw-r--r--src/de/danoeh/antennapod/preferences/UserPreferences.java1
-rw-r--r--src/de/danoeh/antennapod/receiver/AlarmUpdateReceiver.java4
-rw-r--r--src/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java8
-rw-r--r--src/de/danoeh/antennapod/service/PlaybackService.java13
-rw-r--r--src/de/danoeh/antennapod/service/download/APRedirectHandler.java2
-rw-r--r--src/de/danoeh/antennapod/service/download/DownloadService.java1
-rw-r--r--src/de/danoeh/antennapod/service/download/HttpDownloader.java1
-rw-r--r--src/de/danoeh/antennapod/util/BitmapDecoder.java27
-rw-r--r--src/de/danoeh/antennapod/util/NetworkUtils.java4
-rw-r--r--src/de/danoeh/antennapod/util/playback/ExternalMedia.java57
-rw-r--r--src/de/danoeh/antennapod/util/playback/Playable.java75
27 files changed, 311 insertions, 179 deletions
diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
index adabb3bdb..2809d638f 100644
--- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.activity;
-import java.io.File;
-
import android.content.Intent;
import android.content.res.TypedArray;
import android.os.Bundle;
@@ -214,7 +212,7 @@ public class AudioplayerActivity extends MediaplayerActivity {
@Override
public void run() {
ImageLoader.getInstance().loadThumbnailBitmap(
- media.getImageFileUrl(), butNavLeft);
+ media, butNavLeft);
}
});
butNavRight.setImageDrawable(drawables.getDrawable(1));
@@ -226,7 +224,7 @@ public class AudioplayerActivity extends MediaplayerActivity {
@Override
public void run() {
ImageLoader.getInstance().loadThumbnailBitmap(
- media.getImageFileUrl(), butNavLeft);
+ media, butNavLeft);
}
});
butNavRight.setImageDrawable(drawables.getDrawable(0));
diff --git a/src/de/danoeh/antennapod/activity/MainActivity.java b/src/de/danoeh/antennapod/activity/MainActivity.java
index 2bca3ac6b..410617b23 100644
--- a/src/de/danoeh/antennapod/activity/MainActivity.java
+++ b/src/de/danoeh/antennapod/activity/MainActivity.java
@@ -4,26 +4,20 @@ import java.util.ArrayList;
import android.content.Context;
import android.content.Intent;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.util.Log;
-import android.view.View;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
-import com.actionbarsherlock.app.ActionBar.TabListener;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
-import com.viewpagerindicator.TabPageIndicator;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
diff --git a/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java b/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
index 50780844d..65225a584 100644
--- a/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
+++ b/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
@@ -155,10 +155,9 @@ public class OrganizeQueueActivity extends SherlockListActivity {
holder.title.setText(item.getTitle());
holder.feedTitle.setText(item.getFeed().getTitle());
- holder.feedImage.setTag((item.getFeed().getImage() != null) ? item
- .getFeed().getImage().getFile_url() : null);
+ holder.feedImage.setTag(item.getImageLoaderCacheKey());
ImageLoader.getInstance().loadThumbnailBitmap(
- item.getFeed().getImage(),
+ item,
holder.feedImage,
(int) convertView.getResources().getDimension(
R.dimen.thumbnail_length));
diff --git a/src/de/danoeh/antennapod/activity/PreferenceActivity.java b/src/de/danoeh/antennapod/activity/PreferenceActivity.java
index 6bad316a6..8b3f2539a 100644
--- a/src/de/danoeh/antennapod/activity/PreferenceActivity.java
+++ b/src/de/danoeh/antennapod/activity/PreferenceActivity.java
@@ -7,7 +7,6 @@ import java.util.List;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.res.Resources.Theme;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
diff --git a/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java b/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java
index 5e8dca005..b603bb54f 100644
--- a/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java
@@ -8,20 +8,14 @@ import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.View.OnClickListener;
import android.widget.Adapter;
import android.widget.BaseAdapter;
-import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.adapter.InternalFeedItemlistAdapter.Holder;
import de.danoeh.antennapod.feed.FeedItem;
-import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.feed.MediaType;
-import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.util.Converter;
-import de.danoeh.antennapod.util.ThemeUtils;
public class DefaultFeedItemlistAdapter extends BaseAdapter {
diff --git a/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
index 5005b25b4..0e5ef2435 100644
--- a/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
@@ -166,11 +166,10 @@ public class ExternalEpisodesListAdapter extends BaseExpandableListAdapter {
holder.downloadStatus.setVisibility(View.INVISIBLE);
holder.lenSize.setVisibility(View.INVISIBLE);
}
-
- holder.feedImage.setTag((item.getFeed().getImage() != null) ? item
- .getFeed().getImage().getFile_url() : null);
+
+ holder.feedImage.setTag(item.getImageLoaderCacheKey());
ImageLoader.getInstance().loadThumbnailBitmap(
- item.getFeed().getImage(),
+ item,
holder.feedImage,
(int) convertView.getResources().getDimension(
R.dimen.thumbnail_length));
diff --git a/src/de/danoeh/antennapod/asynctask/BitmapDecodeWorkerTask.java b/src/de/danoeh/antennapod/asynctask/BitmapDecodeWorkerTask.java
index 810a17165..4380bc6ea 100644
--- a/src/de/danoeh/antennapod/asynctask/BitmapDecodeWorkerTask.java
+++ b/src/de/danoeh/antennapod/asynctask/BitmapDecodeWorkerTask.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.asynctask;
-import java.io.File;
-
import android.content.res.TypedArray;
import android.graphics.BitmapFactory;
import android.os.Handler;
@@ -9,6 +7,7 @@ import android.util.Log;
import android.widget.ImageView;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.asynctask.ImageLoader.ImageWorkerTaskResource;
import de.danoeh.antennapod.util.BitmapDecoder;
public class BitmapDecodeWorkerTask extends Thread {
@@ -22,18 +21,18 @@ public class BitmapDecodeWorkerTask extends Thread {
private ImageView target;
protected CachedBitmap cBitmap;
- protected String fileUrl;
+ protected ImageLoader.ImageWorkerTaskResource imageResource;
private Handler handler;
private final int defaultCoverResource;
public BitmapDecodeWorkerTask(Handler handler, ImageView target,
- String fileUrl, int length, int imageType) {
+ ImageWorkerTaskResource imageResource, int length, int imageType) {
super();
this.handler = handler;
this.target = target;
- this.fileUrl = fileUrl;
+ this.imageResource = imageResource;
this.PREFERRED_LENGTH = length;
this.imageType = imageType;
TypedArray res = target.getContext().obtainStyledAttributes(
@@ -47,7 +46,8 @@ public class BitmapDecodeWorkerTask extends Thread {
* before the bitmap was decoded
*/
protected boolean tagsMatching(ImageView target) {
- return target.getTag() == null || target.getTag() == fileUrl;
+ return target.getTag() == null
+ || target.getTag() == imageResource.getImageLoaderCacheKey();
}
protected void onPostExecute() {
@@ -62,31 +62,19 @@ public class BitmapDecodeWorkerTask extends Thread {
@Override
public void run() {
- File f = null;
- if (fileUrl != null) {
- f = new File(fileUrl);
- }
- if (fileUrl != null && f.exists()) {
- cBitmap = new CachedBitmap(BitmapDecoder.decodeBitmap(
- PREFERRED_LENGTH, fileUrl), PREFERRED_LENGTH);
- if (cBitmap.getBitmap() != null) {
- storeBitmapInCache(cBitmap);
- } else {
- Log.w(TAG, "Could not load bitmap. Using default image.");
- cBitmap = new CachedBitmap(BitmapFactory.decodeResource(
- target.getResources(), defaultCoverResource),
- PREFERRED_LENGTH);
- }
- if (AppConfig.DEBUG)
- Log.d(TAG, "Finished loading bitmaps");
+ cBitmap = new CachedBitmap(BitmapDecoder.decodeBitmapFromWorkerTaskResource(
+ PREFERRED_LENGTH, imageResource), PREFERRED_LENGTH);
+ if (cBitmap.getBitmap() != null) {
+ storeBitmapInCache(cBitmap);
} else {
- if (fileUrl == null) {
- Log.w(TAG, "File URL is null");
- } else {
- Log.w(TAG, "File does not exist anymore.");
- }
- onInvalidFileUrl();
+ Log.w(TAG, "Could not load bitmap. Using default image.");
+ cBitmap = new CachedBitmap(BitmapFactory.decodeResource(
+ target.getResources(), defaultCoverResource),
+ PREFERRED_LENGTH);
}
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Finished loading bitmaps");
+
endBackgroundTask();
}
@@ -101,8 +89,7 @@ public class BitmapDecodeWorkerTask extends Thread {
});
}
- protected void onInvalidFileUrl() {
- Log.e(TAG, "FeedImage has no valid file url. Using default image");
+ protected void onInvalidStream() {
cBitmap = new CachedBitmap(BitmapFactory.decodeResource(
target.getResources(), defaultCoverResource), PREFERRED_LENGTH);
}
@@ -110,9 +97,10 @@ public class BitmapDecodeWorkerTask extends Thread {
protected void storeBitmapInCache(CachedBitmap cb) {
ImageLoader loader = ImageLoader.getInstance();
if (imageType == ImageLoader.IMAGE_TYPE_COVER) {
- loader.addBitmapToCoverCache(fileUrl, cb);
+ loader.addBitmapToCoverCache(imageResource.getImageLoaderCacheKey(), cb);
} else if (imageType == ImageLoader.IMAGE_TYPE_THUMBNAIL) {
- loader.addBitmapToThumbnailCache(fileUrl, cb);
+ loader.addBitmapToThumbnailCache(imageResource.getImageLoaderCacheKey(), cb);
}
}
+
}
diff --git a/src/de/danoeh/antennapod/asynctask/ImageLoader.java b/src/de/danoeh/antennapod/asynctask/ImageLoader.java
index d0f20d621..fb807f469 100644
--- a/src/de/danoeh/antennapod/asynctask/ImageLoader.java
+++ b/src/de/danoeh/antennapod/asynctask/ImageLoader.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.asynctask;
+import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
@@ -15,7 +16,6 @@ import android.widget.ImageView;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.feed.FeedImage;
/** Caches and loads FeedImage bitmaps in the background */
public class ImageLoader {
@@ -90,18 +90,8 @@ public class ImageLoader {
* ImageView's size has already been set or inside a Runnable which is
* posted to the ImageView's message queue.
*/
- public void loadCoverBitmap(String fileUrl, ImageView target) {
- loadCoverBitmap(fileUrl, target, target.getHeight());
- }
-
- public void loadCoverBitmap(FeedImage image, ImageView target) {
- loadCoverBitmap((image != null) ? image.getFile_url() : null, target,
- target.getHeight());
- }
-
- public void loadCoverBitmap(FeedImage image, ImageView target, int length) {
- loadCoverBitmap((image != null) ? image.getFile_url() : null, target,
- length);
+ public void loadCoverBitmap(ImageWorkerTaskResource source, ImageView target) {
+ loadCoverBitmap(source, target, target.getHeight());
}
/**
@@ -110,18 +100,19 @@ public class ImageLoader {
* ImageView's size has already been set or inside a Runnable which is
* posted to the ImageView's message queue.
*/
- public void loadCoverBitmap(String fileUrl, ImageView target, int length) {
+ public void loadCoverBitmap(ImageWorkerTaskResource source,
+ ImageView target, int length) {
final int defaultCoverResource = getDefaultCoverResource(target
.getContext());
- if (fileUrl != null) {
- CachedBitmap cBitmap = getBitmapFromCoverCache(fileUrl);
+ if (source != null && source.getImageLoaderCacheKey() != null) {
+ CachedBitmap cBitmap = getBitmapFromCoverCache(source.getImageLoaderCacheKey());
if (cBitmap != null && cBitmap.getLength() >= length) {
target.setImageBitmap(cBitmap.getBitmap());
} else {
target.setImageResource(defaultCoverResource);
BitmapDecodeWorkerTask worker = new BitmapDecodeWorkerTask(
- handler, target, fileUrl, length, IMAGE_TYPE_COVER);
+ handler, target, source, length, IMAGE_TYPE_COVER);
executor.submit(worker);
}
} else {
@@ -135,19 +126,9 @@ public class ImageLoader {
* called if the ImageView's size has already been set or inside a Runnable
* which is posted to the ImageView's message queue.
*/
- public void loadThumbnailBitmap(String fileUrl, ImageView target) {
- loadThumbnailBitmap(fileUrl, target, target.getHeight());
- }
-
- public void loadThumbnailBitmap(FeedImage image, ImageView target) {
- loadThumbnailBitmap((image != null) ? image.getFile_url() : null,
- target, target.getHeight());
- }
-
- public void loadThumbnailBitmap(FeedImage image, ImageView target,
- int length) {
- loadThumbnailBitmap((image != null) ? image.getFile_url() : null,
- target, length);
+ public void loadThumbnailBitmap(ImageWorkerTaskResource source,
+ ImageView target) {
+ loadThumbnailBitmap(source, target, target.getHeight());
}
/**
@@ -156,18 +137,19 @@ public class ImageLoader {
* called if the ImageView's size has already been set or inside a Runnable
* which is posted to the ImageView's message queue.
*/
- public void loadThumbnailBitmap(String fileUrl, ImageView target, int length) {
+ public void loadThumbnailBitmap(ImageWorkerTaskResource source,
+ ImageView target, int length) {
final int defaultCoverResource = getDefaultCoverResource(target
.getContext());
- if (fileUrl != null) {
- CachedBitmap cBitmap = getBitmapFromThumbnailCache(fileUrl);
+ if (source != null && source.getImageLoaderCacheKey() != null) {
+ CachedBitmap cBitmap = getBitmapFromThumbnailCache(source.getImageLoaderCacheKey());
if (cBitmap != null && cBitmap.getLength() >= length) {
target.setImageBitmap(cBitmap.getBitmap());
} else {
target.setImageResource(defaultCoverResource);
BitmapDecodeWorkerTask worker = new BitmapDecodeWorkerTask(
- handler, target, fileUrl, length, IMAGE_TYPE_THUMBNAIL);
+ handler, target, source, length, IMAGE_TYPE_THUMBNAIL);
executor.submit(worker);
}
} else {
@@ -220,4 +202,31 @@ public class ImageLoader {
return defaultCoverResource;
}
+ /**
+ * Used by the BitmapDecodeWorker task to retrieve the source of the bitmap.
+ */
+ public interface ImageWorkerTaskResource {
+ /**
+ * Opens a new InputStream that can be decoded as a bitmap by the
+ * BitmapFactory.
+ */
+ public InputStream openImageInputStream();
+
+ /**
+ * Returns an InputStream that points to the beginning of the image
+ * resource. Implementations can either create a new InputStream or
+ * reset the existing one, depending on their implementation of
+ * openInputStream. If a new InputStream is returned, the one given as a
+ * parameter MUST be closed.
+ * @param input The input stream that was returned by openImageInputStream()
+ * */
+ public InputStream reopenImageInputStream(InputStream input);
+
+ /**
+ * Returns a string that identifies the image resource. Example: file
+ * path of an image
+ */
+ public String getImageLoaderCacheKey();
+ }
+
}
diff --git a/src/de/danoeh/antennapod/feed/FeedImage.java b/src/de/danoeh/antennapod/feed/FeedImage.java
index 8e3824560..09595f5eb 100644
--- a/src/de/danoeh/antennapod/feed/FeedImage.java
+++ b/src/de/danoeh/antennapod/feed/FeedImage.java
@@ -1,6 +1,18 @@
package de.danoeh.antennapod.feed;
-public class FeedImage extends FeedFile {
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+
+import de.danoeh.antennapod.asynctask.ImageLoader;
+
+;
+
+public class FeedImage extends FeedFile implements
+ ImageLoader.ImageWorkerTaskResource {
public static final int FEEDFILETYPE_FEEDIMAGE = 1;
protected String title;
@@ -53,4 +65,30 @@ public class FeedImage extends FeedFile {
this.feed = feed;
}
+ @Override
+ public InputStream openImageInputStream() {
+ if (file_url != null) {
+ File file = new File(file_url);
+ if (file.exists()) {
+ try {
+ return new FileInputStream(file_url);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getImageLoaderCacheKey() {
+ return file_url;
+ }
+
+ @Override
+ public InputStream reopenImageInputStream(InputStream input) {
+ IOUtils.closeQuietly(input);
+ return openImageInputStream();
+ }
+
}
diff --git a/src/de/danoeh/antennapod/feed/FeedItem.java b/src/de/danoeh/antennapod/feed/FeedItem.java
index 87cea0a1e..0df384b60 100644
--- a/src/de/danoeh/antennapod/feed/FeedItem.java
+++ b/src/de/danoeh/antennapod/feed/FeedItem.java
@@ -1,10 +1,11 @@
package de.danoeh.antennapod.feed;
+import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.Date;
import java.util.List;
-import de.danoeh.antennapod.preferences.PlaybackPreferences;
+import de.danoeh.antennapod.asynctask.ImageLoader;
/**
* Data Object for a XML message
@@ -12,7 +13,8 @@ import de.danoeh.antennapod.preferences.PlaybackPreferences;
* @author daniel
*
*/
-public class FeedItem extends FeedComponent {
+public class FeedItem extends FeedComponent implements
+ ImageLoader.ImageWorkerTaskResource {
/** The id/guid that can be found in the rss/atom feed. Might not be set. */
private String itemIdentifier;
@@ -241,4 +243,40 @@ public class FeedItem extends FeedComponent {
}
return (isRead() ? State.READ : State.NEW);
}
+
+ @Override
+ public InputStream openImageInputStream() {
+ InputStream out = null;
+ if (hasMedia()) {
+ out = media.openImageInputStream();
+ }
+ if (out == null && feed.getImage() != null) {
+ out = feed.getImage().openImageInputStream();
+ }
+ return out;
+ }
+
+ @Override
+ public InputStream reopenImageInputStream(InputStream input) {
+ InputStream out = null;
+ if (hasMedia()) {
+ out = media.reopenImageInputStream(input);
+ }
+ if (out == null && feed.getImage() != null) {
+ out = feed.getImage().reopenImageInputStream(input);
+ }
+ return out;
+ }
+
+ @Override
+ public String getImageLoaderCacheKey() {
+ String out = null;
+ if (hasMedia()) {
+ out = media.getImageLoaderCacheKey();
+ }
+ if (out == null && feed.getImage() != null) {
+ out = feed.getImage().getImageLoaderCacheKey();
+ }
+ return out;
+ }
}
diff --git a/src/de/danoeh/antennapod/feed/FeedMedia.java b/src/de/danoeh/antennapod/feed/FeedMedia.java
index fd3d2ebb0..4096c6cca 100644
--- a/src/de/danoeh/antennapod/feed/FeedMedia.java
+++ b/src/de/danoeh/antennapod/feed/FeedMedia.java
@@ -1,5 +1,7 @@
package de.danoeh.antennapod.feed;
+import java.io.FileInputStream;
+import java.io.InputStream;
import java.util.Date;
import java.util.List;
@@ -226,15 +228,6 @@ public class FeedMedia extends FeedFile implements Playable {
}
@Override
- public String getImageFileUrl() {
- if (getItem().getFeed().getImage() != null) {
- return getItem().getFeed().getImage().getFile_url();
- } else {
- return null;
- }
- }
-
- @Override
public Object getIdentifier() {
return id;
}
@@ -329,4 +322,37 @@ public class FeedMedia extends FeedFile implements Playable {
return new FeedMedia[size];
}
};
+
+ @Override
+ public InputStream openImageInputStream() {
+ InputStream out = new Playable.DefaultPlayableImageLoader(this)
+ .openImageInputStream();
+ if (out == null) {
+ if (item.getFeed().getImage() != null) {
+ return item.getFeed().getImage().openImageInputStream();
+ }
+ }
+ return out;
+ }
+
+ @Override
+ public String getImageLoaderCacheKey() {
+ String out = new Playable.DefaultPlayableImageLoader(this).getImageLoaderCacheKey();
+ if (out == null) {
+ if (item.getFeed().getImage() != null) {
+ return item.getFeed().getImage().getImageLoaderCacheKey();
+ }
+ }
+ return out;
+ }
+
+ @Override
+ public InputStream reopenImageInputStream(InputStream input) {
+ if (input instanceof FileInputStream) {
+ return item.getFeed().getImage().reopenImageInputStream(input);
+ } else {
+ return new Playable.DefaultPlayableImageLoader(this)
+ .reopenImageInputStream(input);
+ }
+ }
}
diff --git a/src/de/danoeh/antennapod/fragment/CoverFragment.java b/src/de/danoeh/antennapod/fragment/CoverFragment.java
index c477ea2b8..6be76f515 100644
--- a/src/de/danoeh/antennapod/fragment/CoverFragment.java
+++ b/src/de/danoeh/antennapod/fragment/CoverFragment.java
@@ -65,7 +65,7 @@ public class CoverFragment extends SherlockFragment implements
@Override
public void run() {
ImageLoader.getInstance().loadCoverBitmap(
- media.getImageFileUrl(), imgvCover);
+ media, imgvCover);
}
});
} else {
diff --git a/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
index 1b7d77193..a50e820b6 100644
--- a/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
@@ -209,7 +209,7 @@ public class ExternalPlayerFragment extends SherlockFragment {
if (media != null) {
txtvTitle.setText(media.getEpisodeTitle());
ImageLoader.getInstance().loadThumbnailBitmap(
- media.getImageFileUrl(),
+ media,
imgvCover,
(int) getActivity().getResources().getDimension(
R.dimen.external_player_height));
diff --git a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java
index 484a1f9f6..6265694f6 100644
--- a/src/de/danoeh/antennapod/fragment/ItemlistFragment.java
+++ b/src/de/danoeh/antennapod/fragment/ItemlistFragment.java
@@ -17,8 +17,8 @@ import com.actionbarsherlock.app.SherlockListFragment;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.ItemviewActivity;
-import de.danoeh.antennapod.adapter.DefaultFeedItemlistAdapter;
import de.danoeh.antennapod.adapter.ActionButtonCallback;
+import de.danoeh.antennapod.adapter.DefaultFeedItemlistAdapter;
import de.danoeh.antennapod.adapter.InternalFeedItemlistAdapter;
import de.danoeh.antennapod.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.feed.EventDistributor;
diff --git a/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
index 637b6121b..b471d5303 100644
--- a/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/src/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -4,7 +4,6 @@ import android.os.Bundle;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.adapter.DefaultFeedItemlistAdapter;
-import de.danoeh.antennapod.adapter.InternalFeedItemlistAdapter;
import de.danoeh.antennapod.feed.EventDistributor;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedManager;
diff --git a/src/de/danoeh/antennapod/preferences/PlaybackPreferences.java b/src/de/danoeh/antennapod/preferences/PlaybackPreferences.java
index c6a431541..9ae0f8f2f 100644
--- a/src/de/danoeh/antennapod/preferences/PlaybackPreferences.java
+++ b/src/de/danoeh/antennapod/preferences/PlaybackPreferences.java
@@ -5,8 +5,6 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
-import de.danoeh.antennapod.feed.FeedManager;
-import de.danoeh.antennapod.feed.FeedMedia;
/**
* Provides access to preferences set by the playback service. A private
diff --git a/src/de/danoeh/antennapod/preferences/UserPreferences.java b/src/de/danoeh/antennapod/preferences/UserPreferences.java
index 5b7c9d84f..489f9f02d 100644
--- a/src/de/danoeh/antennapod/preferences/UserPreferences.java
+++ b/src/de/danoeh/antennapod/preferences/UserPreferences.java
@@ -2,7 +2,6 @@ package de.danoeh.antennapod.preferences;
import java.io.File;
import java.io.IOException;
-import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
diff --git a/src/de/danoeh/antennapod/receiver/AlarmUpdateReceiver.java b/src/de/danoeh/antennapod/receiver/AlarmUpdateReceiver.java
index 05914a0e1..63a03b9e6 100644
--- a/src/de/danoeh/antennapod/receiver/AlarmUpdateReceiver.java
+++ b/src/de/danoeh/antennapod/receiver/AlarmUpdateReceiver.java
@@ -1,11 +1,11 @@
package de.danoeh.antennapod.receiver;
-import de.danoeh.antennapod.AppConfig;
-import de.danoeh.antennapod.preferences.UserPreferences;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
+import de.danoeh.antennapod.AppConfig;
+import de.danoeh.antennapod.preferences.UserPreferences;
/** Listens for events that make it necessary to reset the update alarm. */
public class AlarmUpdateReceiver extends BroadcastReceiver {
diff --git a/src/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java b/src/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java
index 5c898384a..b58527130 100644
--- a/src/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java
+++ b/src/de/danoeh/antennapod/receiver/ConnectivityActionReceiver.java
@@ -1,15 +1,15 @@
package de.danoeh.antennapod.receiver;
-import de.danoeh.antennapod.AppConfig;
-import de.danoeh.antennapod.feed.FeedManager;
-import de.danoeh.antennapod.storage.DownloadRequester;
-import de.danoeh.antennapod.util.NetworkUtils;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
+import de.danoeh.antennapod.AppConfig;
+import de.danoeh.antennapod.feed.FeedManager;
+import de.danoeh.antennapod.storage.DownloadRequester;
+import de.danoeh.antennapod.util.NetworkUtils;
public class ConnectivityActionReceiver extends BroadcastReceiver {
private static final String TAG = "ConnectivityActionReceiver";
diff --git a/src/de/danoeh/antennapod/service/PlaybackService.java b/src/de/danoeh/antennapod/service/PlaybackService.java
index 811b02535..8ff115077 100644
--- a/src/de/danoeh/antennapod/service/PlaybackService.java
+++ b/src/de/danoeh/antennapod/service/PlaybackService.java
@@ -41,7 +41,6 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.AudioplayerActivity;
import de.danoeh.antennapod.activity.VideoplayerActivity;
import de.danoeh.antennapod.feed.Chapter;
-import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedComponent;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedManager;
@@ -730,8 +729,7 @@ public class PlaybackService extends Service {
prepareImmediately = startWhenPrepared = true;
} else {
if (AppConfig.DEBUG)
- Log.d(TAG,
- "No more episodes available to play");
+ Log.d(TAG, "No more episodes available to play");
media = null;
prepareImmediately = startWhenPrepared = false;
stopForeground(true);
@@ -752,7 +750,8 @@ public class PlaybackService extends Service {
if (media != null) {
resetVideoSurface();
refreshRemoteControlClientState();
- sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, notificationCode);
+ sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD,
+ notificationCode);
} else {
sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_END, 0);
stopSelf();
@@ -958,12 +957,12 @@ public class PlaybackService extends Service {
Bitmap icon = null;
if (android.os.Build.VERSION.SDK_INT >= 11) {
- if (media != null && media.getImageFileUrl() != null) {
+ if (media != null && media != null) {
int iconSize = getResources().getDimensionPixelSize(
android.R.dimen.notification_large_icon_width);
- icon = BitmapDecoder.decodeBitmap(iconSize,
- media.getImageFileUrl());
+ icon = BitmapDecoder.decodeBitmapFromWorkerTaskResource(iconSize, media);
}
+
}
if (icon == null) {
icon = BitmapFactory.decodeResource(getResources(),
diff --git a/src/de/danoeh/antennapod/service/download/APRedirectHandler.java b/src/de/danoeh/antennapod/service/download/APRedirectHandler.java
index 9416ef9d7..8a31c9390 100644
--- a/src/de/danoeh/antennapod/service/download/APRedirectHandler.java
+++ b/src/de/danoeh/antennapod/service/download/APRedirectHandler.java
@@ -7,8 +7,8 @@ import org.apache.http.HttpResponse;
import org.apache.http.impl.client.DefaultRedirectHandler;
import org.apache.http.protocol.HttpContext;
-import de.danoeh.antennapod.AppConfig;
import android.util.Log;
+import de.danoeh.antennapod.AppConfig;
public class APRedirectHandler extends DefaultRedirectHandler {
// Identifier for logger
diff --git a/src/de/danoeh/antennapod/service/download/DownloadService.java b/src/de/danoeh/antennapod/service/download/DownloadService.java
index 272b1bf59..e1230e170 100644
--- a/src/de/danoeh/antennapod/service/download/DownloadService.java
+++ b/src/de/danoeh/antennapod/service/download/DownloadService.java
@@ -58,7 +58,6 @@ import de.danoeh.antennapod.feed.FeedImage;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.feed.FeedMedia;
-import de.danoeh.antennapod.preferences.UserPreferences;
import de.danoeh.antennapod.storage.DownloadRequestException;
import de.danoeh.antennapod.storage.DownloadRequester;
import de.danoeh.antennapod.syndication.handler.FeedHandler;
diff --git a/src/de/danoeh/antennapod/service/download/HttpDownloader.java b/src/de/danoeh/antennapod/service/download/HttpDownloader.java
index 07998be0b..f8f26f6fd 100644
--- a/src/de/danoeh/antennapod/service/download/HttpDownloader.java
+++ b/src/de/danoeh/antennapod/service/download/HttpDownloader.java
@@ -27,7 +27,6 @@ import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.asynctask.DownloadStatus;
-import de.danoeh.antennapod.service.download.APRedirectHandler;
import de.danoeh.antennapod.util.DownloadError;
import de.danoeh.antennapod.util.StorageUtils;
diff --git a/src/de/danoeh/antennapod/util/BitmapDecoder.java b/src/de/danoeh/antennapod/util/BitmapDecoder.java
index e9ef2ad01..e9423c3f7 100644
--- a/src/de/danoeh/antennapod/util/BitmapDecoder.java
+++ b/src/de/danoeh/antennapod/util/BitmapDecoder.java
@@ -1,11 +1,15 @@
package de.danoeh.antennapod.util;
-import java.io.File;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Rect;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;
+import de.danoeh.antennapod.asynctask.ImageLoader;
public class BitmapDecoder {
private static final String TAG = "BitmapDecoder";
@@ -18,11 +22,13 @@ public class BitmapDecoder {
return sampleSize;
}
- public static Bitmap decodeBitmap(int preferredLength, String fileUrl) {
- if (fileUrl != null && new File(fileUrl).exists()) {
+ public static Bitmap decodeBitmapFromWorkerTaskResource(int preferredLength,
+ ImageLoader.ImageWorkerTaskResource source) {
+ InputStream input = source.openImageInputStream();
+ if (input != null) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(fileUrl, options);
+ BitmapFactory.decodeStream(input, new Rect(), options);
int srcWidth = options.outWidth;
int srcHeight = options.outHeight;
int length = Math.max(srcWidth, srcHeight);
@@ -32,17 +38,14 @@ public class BitmapDecoder {
options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
-
- Bitmap decodedBitmap = BitmapFactory.decodeFile(fileUrl, options);
+ Bitmap decodedBitmap = BitmapFactory.decodeStream(source.reopenImageInputStream(input),
+ null, options);
if (decodedBitmap == null) {
- Log.i(TAG,
- "Bitmap could not be decoded in custom sample size. Trying default sample size (path was "
- + fileUrl + ")");
- decodedBitmap = BitmapFactory.decodeFile(fileUrl);
+ decodedBitmap = BitmapFactory.decodeStream(source.reopenImageInputStream(input));
}
+ IOUtils.closeQuietly(input);
return decodedBitmap;
- } else {
- return null;
}
+ return null;
}
}
diff --git a/src/de/danoeh/antennapod/util/NetworkUtils.java b/src/de/danoeh/antennapod/util/NetworkUtils.java
index 6064f3f91..de7b854cc 100644
--- a/src/de/danoeh/antennapod/util/NetworkUtils.java
+++ b/src/de/danoeh/antennapod/util/NetworkUtils.java
@@ -3,14 +3,14 @@ package de.danoeh.antennapod.util;
import java.util.Arrays;
import java.util.List;
-import de.danoeh.antennapod.AppConfig;
-import de.danoeh.antennapod.preferences.UserPreferences;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
+import de.danoeh.antennapod.AppConfig;
+import de.danoeh.antennapod.preferences.UserPreferences;
public class NetworkUtils {
private static final String TAG = "NetworkUtils";
diff --git a/src/de/danoeh/antennapod/util/playback/ExternalMedia.java b/src/de/danoeh/antennapod/util/playback/ExternalMedia.java
index 4574f088e..46f3dfcd8 100644
--- a/src/de/danoeh/antennapod/util/playback/ExternalMedia.java
+++ b/src/de/danoeh/antennapod/util/playback/ExternalMedia.java
@@ -1,24 +1,16 @@
package de.danoeh.antennapod.util.playback;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.io.InputStream;
import java.util.List;
-import org.apache.commons.io.IOUtils;
-
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.media.MediaMetadataRetriever;
import android.os.Parcel;
import android.os.Parcelable;
-import de.danoeh.antennapod.PodcastApp;
import de.danoeh.antennapod.feed.Chapter;
import de.danoeh.antennapod.feed.MediaType;
import de.danoeh.antennapod.util.ChapterUtils;
-import de.danoeh.antennapod.util.FileNameGenerator;
/** Represents a media file that is stored on the local storage device. */
public class ExternalMedia implements Playable {
@@ -35,7 +27,6 @@ public class ExternalMedia implements Playable {
private String shownotes;
private MediaType mediaType = MediaType.AUDIO;
private List<Chapter> chapters;
- private String imageUrl;
private int duration;
private int position;
@@ -71,12 +62,15 @@ public class ExternalMedia implements Playable {
@Override
public void loadMetadata() throws PlayableException {
+ final String tmpFileName = "tmpExternalMediaimage";
+
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
try {
- mmr.setDataSource(source);
+ mmr.setDataSource(source);
} catch (IllegalArgumentException e) {
e.printStackTrace();
- throw new PlayableException("IllegalArgumentException when setting up MediaMetadataReceiver");
+ throw new PlayableException(
+ "IllegalArgumentException when setting up MediaMetadataReceiver");
}
episodeTitle = mmr
.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
@@ -85,24 +79,6 @@ public class ExternalMedia implements Playable {
duration = Integer.parseInt(mmr
.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
ChapterUtils.loadChaptersFromFileUrl(this);
- byte[] imgData = mmr.getEmbeddedPicture();
- File cacheDir = PodcastApp.getInstance().getExternalCacheDir();
- if (cacheDir != null) {
- OutputStream out = null;
- try {
- File tmpFile = File.createTempFile(
- FileNameGenerator.generateFileName(source) + "-img",
- null, cacheDir);
- out = new BufferedOutputStream(new FileOutputStream(tmpFile));
- IOUtils.write(imgData, out);
- imageUrl = tmpFile.getAbsolutePath();
- } catch (IOException e) {
- e.printStackTrace();
- throw new PlayableException("IOException during loadMetadata()");
- } finally {
- IOUtils.closeQuietly(out);
- }
- }
}
@Override
@@ -136,11 +112,6 @@ public class ExternalMedia implements Playable {
}
@Override
- public String getImageFileUrl() {
- return imageUrl;
- }
-
- @Override
public Object getIdentifier() {
return source;
}
@@ -235,4 +206,20 @@ public class ExternalMedia implements Playable {
}
};
+ @Override
+ public InputStream openImageInputStream() {
+ return new Playable.DefaultPlayableImageLoader(this)
+ .openImageInputStream();
+ }
+
+ @Override
+ public String getImageLoaderCacheKey() {
+ return new Playable.DefaultPlayableImageLoader(this).getImageLoaderCacheKey();
+ }
+
+ @Override
+ public InputStream reopenImageInputStream(InputStream input) {
+ return new Playable.DefaultPlayableImageLoader(this).reopenImageInputStream(input);
+ }
+
}
diff --git a/src/de/danoeh/antennapod/util/playback/Playable.java b/src/de/danoeh/antennapod/util/playback/Playable.java
index bf38b9518..ae87d5903 100644
--- a/src/de/danoeh/antennapod/util/playback/Playable.java
+++ b/src/de/danoeh/antennapod/util/playback/Playable.java
@@ -1,10 +1,16 @@
package de.danoeh.antennapod.util.playback;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.util.List;
+import org.apache.commons.io.IOUtils;
+
import android.content.SharedPreferences;
+import android.media.MediaMetadataRetriever;
import android.os.Parcelable;
import android.util.Log;
+import de.danoeh.antennapod.asynctask.ImageLoader;
import de.danoeh.antennapod.feed.Chapter;
import de.danoeh.antennapod.feed.Feed;
import de.danoeh.antennapod.feed.FeedManager;
@@ -12,7 +18,8 @@ import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.feed.MediaType;
/** Interface for objects that can be played by the PlaybackService. */
-public interface Playable extends Parcelable {
+public interface Playable extends Parcelable,
+ ImageLoader.ImageWorkerTaskResource {
/**
* Save information about the playable in a preference so that it can be
@@ -52,9 +59,6 @@ public interface Playable extends Parcelable {
/** Returns the title of the feed this Playable belongs to. */
public String getFeedTitle();
- /** Returns a file url to an image or null if no such image exists. */
- public String getImageFileUrl();
-
/**
* Returns a unique identifier, for example a file url or an ID from a
* database.
@@ -194,4 +198,67 @@ public interface Playable extends Parcelable {
public static interface ShownoteLoaderCallback {
void onShownotesLoaded(String shownotes);
}
+
+ /** Uses local file as image resource if it is available. */
+ public static class DefaultPlayableImageLoader implements
+ ImageLoader.ImageWorkerTaskResource {
+ private Playable playable;
+
+ public DefaultPlayableImageLoader(Playable playable) {
+ if (playable == null) {
+ throw new IllegalArgumentException("Playable must not be null");
+ }
+ this.playable = playable;
+ }
+
+ @Override
+ public InputStream openImageInputStream() {
+ if (playable.localFileAvailable()
+ && playable.getLocalMediaUrl() != null) {
+ MediaMetadataRetriever mmr = new MediaMetadataRetriever();
+ try {
+ mmr.setDataSource(playable.getLocalMediaUrl());
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ return null;
+ }
+ byte[] imgData = mmr.getEmbeddedPicture();
+ if (imgData != null) {
+ return new PublicByteArrayInputStream(imgData);
+
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getImageLoaderCacheKey() {
+ return playable.getLocalMediaUrl();
+ }
+
+ @Override
+ public InputStream reopenImageInputStream(InputStream input) {
+ if (input instanceof PublicByteArrayInputStream) {
+ IOUtils.closeQuietly(input);
+ byte[] imgData = ((PublicByteArrayInputStream) input).getByteArray();
+ if (imgData != null) {
+ ByteArrayInputStream out = new ByteArrayInputStream(imgData);
+ return out;
+ }
+
+ }
+ return null;
+ }
+
+ private static class PublicByteArrayInputStream extends
+ ByteArrayInputStream {
+ public PublicByteArrayInputStream(byte[] buf) {
+ super(buf);
+ }
+
+ public byte[] getByteArray() {
+ return buf;
+ }
+ }
+ }
}