summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/de/danoeh/antennapod/activity/AudioplayerActivity.java140
-rw-r--r--src/de/danoeh/antennapod/activity/ItemviewActivity.java4
-rw-r--r--src/de/danoeh/antennapod/activity/MediaplayerActivity.java12
-rw-r--r--src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java19
-rw-r--r--src/de/danoeh/antennapod/activity/VideoplayerActivity.java5
-rw-r--r--src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java29
-rw-r--r--src/de/danoeh/antennapod/feed/FeedManager.java42
-rw-r--r--src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java89
-rw-r--r--src/de/danoeh/antennapod/storage/DownloadRequester.java2
-rw-r--r--src/de/danoeh/antennapod/storage/PodDBAdapter.java39
-rw-r--r--src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java17
-rw-r--r--src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java3
-rw-r--r--src/de/danoeh/antennapod/util/playback/ExternalMedia.java9
13 files changed, 334 insertions, 76 deletions
diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
index 2809d638f..0e2c520fc 100644
--- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -1,6 +1,8 @@
package de.danoeh.antennapod.activity;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@@ -38,6 +40,9 @@ public class AudioplayerActivity extends MediaplayerActivity {
private static final int NUM_CONTENT_FRAGMENTS = 3;
final String TAG = "AudioplayerActivity";
+ private static final String PREFS = "AudioPlayerActivityPreferences";
+ private static final String PREF_KEY_SELECTED_FRAGMENT_POSITION = "selectedFragmentPosition";
+ private static final String PREF_PLAYABLE_ID = "playableId";
private Fragment[] detachedFragments;
@@ -54,6 +59,37 @@ public class AudioplayerActivity extends MediaplayerActivity {
private ImageButton butNavRight;
private void resetFragmentView() {
+ FragmentTransaction fT = getSupportFragmentManager().beginTransaction();
+
+ if (coverFragment != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Removing cover fragment");
+ fT.remove(coverFragment);
+ }
+ if (descriptionFragment != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Removing description fragment");
+ fT.remove(descriptionFragment);
+ }
+ if (chapterFragment != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Removing chapter fragment");
+ fT.remove(chapterFragment);
+ }
+ if (currentlyShownFragment != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Removing currently shown fragment");
+ fT.remove(currentlyShownFragment);
+ }
+ for (int i = 0; i < detachedFragments.length; i++) {
+ Fragment f = detachedFragments[i];
+ if (f != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Removing detached fragment");
+ fT.remove(f);
+ }
+ }
+ fT.commit();
currentlyShownFragment = null;
coverFragment = null;
descriptionFragment = null;
@@ -65,7 +101,8 @@ public class AudioplayerActivity extends MediaplayerActivity {
@Override
protected void onStop() {
super.onStop();
- resetFragmentView();
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "onStop");
}
@@ -77,6 +114,85 @@ public class AudioplayerActivity extends MediaplayerActivity {
detachedFragments = new Fragment[NUM_CONTENT_FRAGMENTS];
}
+ private void savePreferences() {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Saving preferences");
+ SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+ if (currentlyShownPosition >= 0 && controller != null
+ && controller.getMedia() != null) {
+ editor.putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION,
+ currentlyShownPosition);
+ editor.putString(PREF_PLAYABLE_ID, controller.getMedia()
+ .getIdentifier().toString());
+ } else {
+ editor.putInt(PREF_KEY_SELECTED_FRAGMENT_POSITION, -1);
+ editor.putString(PREF_PLAYABLE_ID, "");
+ }
+ editor.commit();
+
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ // super.onSaveInstanceState(outState); would cause crash
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "onSaveInstanceState");
+ }
+
+ @Override
+ protected void onPause() {
+ savePreferences();
+ resetFragmentView();
+ super.onPause();
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ restoreFromPreferences();
+ }
+
+ /**
+ * Tries to restore the selected fragment position from the Activity's
+ * preferences.
+ *
+ * @return true if restoreFromPrefernces changed the activity's state
+ * */
+ private boolean restoreFromPreferences() {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Restoring instance state");
+ SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
+ int savedPosition = prefs.getInt(PREF_KEY_SELECTED_FRAGMENT_POSITION,
+ -1);
+ String playableId = prefs.getString(PREF_PLAYABLE_ID, "");
+
+ if (savedPosition != -1
+ && controller != null
+ && controller.getMedia() != null
+ && controller.getMedia().getIdentifier().toString()
+ .equals(playableId)) {
+ switchToFragment(savedPosition);
+ return true;
+ } else if (controller == null || controller.getMedia() == null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "Couldn't restore from preferences: controller or media was null");
+ } else {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "Couldn't restore from preferences: savedPosition was -1 or saved identifier and playable identifier didn't match.\nsavedPosition: "
+ + savedPosition + ", id: " + playableId);
+
+ }
+ return false;
+ }
+
@Override
protected void onResume() {
super.onResume();
@@ -131,7 +247,7 @@ public class AudioplayerActivity extends MediaplayerActivity {
private void switchToFragment(int pos) {
if (AppConfig.DEBUG)
Log.d(TAG, "Switching contentView to position " + pos);
- if (currentlyShownPosition != pos) {
+ if (currentlyShownPosition != pos && controller != null) {
Playable media = controller.getMedia();
if (media != null) {
FragmentTransaction ft = getSupportFragmentManager()
@@ -151,7 +267,7 @@ public class AudioplayerActivity extends MediaplayerActivity {
case POS_DESCR:
if (descriptionFragment == null) {
descriptionFragment = ItemDescriptionFragment
- .newInstance(media);
+ .newInstance(media, true);
}
currentlyShownFragment = descriptionFragment;
break;
@@ -187,6 +303,7 @@ public class AudioplayerActivity extends MediaplayerActivity {
ft.add(R.id.contentView, currentlyShownFragment);
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+ ft.disallowAddToBackStack();
ft.commit();
updateNavButtonDrawable();
}
@@ -211,8 +328,8 @@ public class AudioplayerActivity extends MediaplayerActivity {
@Override
public void run() {
- ImageLoader.getInstance().loadThumbnailBitmap(
- media, butNavLeft);
+ ImageLoader.getInstance().loadThumbnailBitmap(media,
+ butNavLeft);
}
});
butNavRight.setImageDrawable(drawables.getDrawable(1));
@@ -223,8 +340,8 @@ public class AudioplayerActivity extends MediaplayerActivity {
@Override
public void run() {
- ImageLoader.getInstance().loadThumbnailBitmap(
- media, butNavLeft);
+ ImageLoader.getInstance().loadThumbnailBitmap(media,
+ butNavLeft);
}
});
butNavRight.setImageDrawable(drawables.getDrawable(0));
@@ -291,7 +408,9 @@ public class AudioplayerActivity extends MediaplayerActivity {
}
if (currentlyShownPosition == -1) {
- switchToFragment(POS_COVER);
+ if (!restoreFromPreferences()) {
+ switchToFragment(POS_COVER);
+ }
}
if (currentlyShownFragment instanceof AudioplayerContentFragment) {
((AudioplayerContentFragment) currentlyShownFragment)
@@ -333,4 +452,9 @@ public class AudioplayerActivity extends MediaplayerActivity {
public void onDataSetChanged(Playable media);
}
+ @Override
+ protected int getContentViewResourceId() {
+ return R.layout.audioplayer_activity;
+ }
+
}
diff --git a/src/de/danoeh/antennapod/activity/ItemviewActivity.java b/src/de/danoeh/antennapod/activity/ItemviewActivity.java
index 63dcb78f1..5ead667dc 100644
--- a/src/de/danoeh/antennapod/activity/ItemviewActivity.java
+++ b/src/de/danoeh/antennapod/activity/ItemviewActivity.java
@@ -99,7 +99,7 @@ public class ItemviewActivity extends SherlockFragmentActivity {
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
ItemDescriptionFragment fragment = ItemDescriptionFragment
- .newInstance(item);
+ .newInstance(item, false);
fragmentTransaction.replace(R.id.description_fragment, fragment);
fragmentTransaction.commit();
}
@@ -127,7 +127,7 @@ public class ItemviewActivity extends SherlockFragmentActivity {
DownloadRequestErrorDialogCreator.newRequestErrorDialog(this,
e.getMessage());
}
- invalidateOptionsMenu();
+ supportInvalidateOptionsMenu();
return true;
}
diff --git a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
index 6d27a82e0..16b03809a 100644
--- a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -3,7 +3,6 @@ package de.danoeh.antennapod.activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Bundle;
@@ -331,13 +330,6 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity
controller.init();
}
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- // ignore orientation change
-
- }
-
/**
* Called by 'handleStatus()' when the PlaybackService is in the
* AWAITING_VIDEO_SURFACE state.
@@ -399,7 +391,7 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity
}
protected void setupGUI() {
- setContentView(R.layout.mediaplayer_activity);
+ setContentView(getContentViewResourceId());
sbPosition = (SeekBar) findViewById(R.id.sbPosition);
txtvPosition = (TextView) findViewById(R.id.txtvPosition);
txtvLength = (TextView) findViewById(R.id.txtvLength);
@@ -421,6 +413,8 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity
}
+ protected abstract int getContentViewResourceId();
+
void handleError(int errorCode) {
final AlertDialog.Builder errorDialog = new AlertDialog.Builder(this);
errorDialog.setTitle(R.string.error_label);
diff --git a/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java b/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
index 65225a584..89001f7f5 100644
--- a/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
+++ b/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
@@ -72,10 +72,7 @@ public class OrganizeQueueActivity extends SherlockListActivity {
@Override
public void drop(int from, int to) {
FeedManager manager = FeedManager.getInstance();
- int offset = (manager.firstQueueItemIsPlaying()) ? 1 : 0;
-
- manager.moveQueueItem(OrganizeQueueActivity.this, from + offset, to
- + offset, false);
+ manager.moveQueueItem(OrganizeQueueActivity.this, from, to, false);
adapter.notifyDataSetChanged();
}
};
@@ -85,7 +82,6 @@ public class OrganizeQueueActivity extends SherlockListActivity {
@Override
public void remove(int which) {
FeedManager manager = FeedManager.getInstance();
-
manager.removeQueueItem(OrganizeQueueActivity.this,
(FeedItem) getListAdapter().getItem(which));
}
@@ -174,21 +170,12 @@ public class OrganizeQueueActivity extends SherlockListActivity {
@Override
public int getCount() {
int queueSize = manager.getQueueSize(true);
- if (manager.firstQueueItemIsPlaying()) {
- return queueSize - 1;
- } else {
- return queueSize;
- }
+ return queueSize;
}
@Override
public FeedItem getItem(int position) {
- if (manager.firstQueueItemIsPlaying() && position < getCount()) {
- return manager.getQueueItemAtIndex(position + 1, true);
- } else {
- return manager.getQueueItemAtIndex(position, true);
- }
-
+ return manager.getQueueItemAtIndex(position, true);
}
@Override
diff --git a/src/de/danoeh/antennapod/activity/VideoplayerActivity.java b/src/de/danoeh/antennapod/activity/VideoplayerActivity.java
index 2d9834a3e..b3567e417 100644
--- a/src/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -287,4 +287,9 @@ public class VideoplayerActivity extends MediaplayerActivity implements
videoOverlay.setVisibility(View.GONE);
}
+ @Override
+ protected int getContentViewResourceId() {
+ return R.layout.videoplayer_activity;
+ }
+
}
diff --git a/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java b/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
index 0e5ef2435..916e13469 100644
--- a/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/ExternalEpisodesListAdapter.java
@@ -166,7 +166,7 @@ public class ExternalEpisodesListAdapter extends BaseExpandableListAdapter {
holder.downloadStatus.setVisibility(View.INVISIBLE);
holder.lenSize.setVisibility(View.INVISIBLE);
}
-
+
holder.feedImage.setTag(item.getImageLoaderCacheKey());
ImageLoader.getInstance().loadThumbnailBitmap(
item,
@@ -209,7 +209,12 @@ public class ExternalEpisodesListAdapter extends BaseExpandableListAdapter {
@Override
public int getGroupCount() {
- return 2;
+ // Hide 'unread items' group if empty
+ if (manager.getUnreadItemsSize(true) > 0) {
+ return 2;
+ } else {
+ return 1;
+ }
}
@Override
@@ -226,20 +231,26 @@ public class ExternalEpisodesListAdapter extends BaseExpandableListAdapter {
TextView headerTitle = (TextView) convertView
.findViewById(R.id.txtvHeaderTitle);
ImageButton actionButton = (ImageButton) convertView
- .findViewById(R.id.butAction);
+ .findViewById(R.id.butAction);
+ TextView numItems = (TextView) convertView.findViewById(R.id.txtvNumItems);
+
String headerString = null;
+ int childrenCount = 0;
+
if (groupPosition == 0) {
headerString = context.getString(R.string.queue_label);
- if (manager.getQueueSize(true) > 0) {
- headerString += " (" + getChildrenCount(GROUP_POS_QUEUE) + ")";
- }
+ childrenCount = getChildrenCount(GROUP_POS_QUEUE);
} else {
headerString = context.getString(R.string.waiting_list_label);
- if (manager.getUnreadItemsSize(true) > 0) {
- headerString += " (" + getChildrenCount(GROUP_POS_UNREAD) + ")";
- }
+ childrenCount = getChildrenCount(GROUP_POS_UNREAD);
}
headerTitle.setText(headerString);
+ if (childrenCount <= 0) {
+ numItems.setVisibility(View.INVISIBLE);
+ } else {
+ numItems.setVisibility(View.VISIBLE);
+ numItems.setText(Integer.toString(childrenCount));
+ }
actionButton.setFocusable(false);
actionButton.setOnClickListener(new OnClickListener() {
diff --git a/src/de/danoeh/antennapod/feed/FeedManager.java b/src/de/danoeh/antennapod/feed/FeedManager.java
index c7f317b62..bdffdc667 100644
--- a/src/de/danoeh/antennapod/feed/FeedManager.java
+++ b/src/de/danoeh/antennapod/feed/FeedManager.java
@@ -7,6 +7,9 @@ import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.TreeSet;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
@@ -114,8 +117,8 @@ public class FeedManager {
/**
* Play FeedMedia and start the playback service + launch Mediaplayer
- * Activity. The FeedItem belonging to the media is moved to the top of the
- * queue.
+ * Activity. The FeedItem will be added at the top of the queue if it isn't
+ * in there yet.
*
* @param context
* for starting the playbackservice
@@ -153,9 +156,7 @@ public class FeedManager {
context.startActivity(PlaybackService.getPlayerActivityIntent(
context, media));
}
- if (queue.contains(media.getItem())) {
- moveQueueItem(context, queue.indexOf(media.getItem()), 0, true);
- } else {
+ if (!queue.contains(media.getItem())) {
addQueueItemAt(context, media.getItem(), 0, false);
}
} catch (MediaFileNotFoundException e) {
@@ -1627,6 +1628,10 @@ public class FeedManager {
if (AppConfig.DEBUG)
Log.d(TAG, "Extracting Queue");
Cursor cursor = adapter.getQueueCursor();
+
+ // Sort cursor results by ID with TreeMap
+ TreeMap<Integer, FeedItem> map = new TreeMap<Integer, FeedItem>();
+
if (cursor.moveToFirst()) {
do {
int index = cursor.getInt(PodDBAdapter.KEY_ID_INDEX);
@@ -1637,13 +1642,17 @@ public class FeedManager {
cursor.getLong(PodDBAdapter.KEY_FEEDITEM_INDEX),
feed);
if (item != null) {
- queue.add(index, item);
+ map.put(index, item);
}
}
-
} while (cursor.moveToNext());
}
cursor.close();
+
+ for (Map.Entry<Integer, FeedItem> entry : map.entrySet()) {
+ FeedItem item = entry.getValue();
+ queue.add(item);
+ }
}
/**
@@ -1786,18 +1795,23 @@ public class FeedManager {
}
/**
- * Returns true if the first item in the queue is currently being played or
- * false otherwise. If the queue is empty, this method will also return
- * false.
+ * Returns the index of the episode that is currently being played in the
+ * queue or -1 if the queue is empty or no episode in the queue is being
+ * played.
* */
- public boolean firstQueueItemIsPlaying() {
+ public int getQueuePlayingEpisodeIndex() {
FeedManager manager = FeedManager.getInstance();
int queueSize = manager.getQueueSize(true);
if (queueSize == 0) {
- return false;
+ return -1;
} else {
- FeedItem item = getQueueItemAtIndex(0, true);
- return item.getState() == FeedItem.State.PLAYING;
+ for (int x = 0; x < queueSize; x++) {
+ FeedItem item = getQueueItemAtIndex(x, true);
+ if (item.getState() == FeedItem.State.PLAYING) {
+ return x;
+ }
+ }
+ return -1;
}
}
diff --git a/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index 02b74a4e5..a1dfa51d4 100644
--- a/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -7,7 +7,9 @@ import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.TypedArray;
+import android.graphics.Picture;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -21,8 +23,10 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.webkit.WebChromeClient;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
+import android.webkit.WebView.PictureListener;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragment;
@@ -40,10 +44,16 @@ import de.danoeh.antennapod.util.playback.Playable;
public class ItemDescriptionFragment extends SherlockFragment {
private static final String TAG = "ItemDescriptionFragment";
+
+ private static final String PREF = "ItemDescriptionFragmentPrefs";
+ private static final String PREF_SCROLL_Y = "prefScrollY";
+ private static final String PREF_PLAYABLE_ID = "prefPlayableId";
+
private static final String ARG_PLAYABLE = "arg.playable";
private static final String ARG_FEED_ID = "arg.feedId";
private static final String ARG_FEED_ITEM_ID = "arg.feeditemId";
+ private static final String ARG_SAVE_STATE = "arg.saveState";
private WebView webvDescription;
private Playable media;
@@ -57,19 +67,29 @@ public class ItemDescriptionFragment extends SherlockFragment {
/** URL that was selected via long-press. */
private String selectedURL;
- public static ItemDescriptionFragment newInstance(Playable media) {
+ /**
+ * True if Fragment should save its state (e.g. scrolling position) in a
+ * shared preference.
+ */
+ private boolean saveState;
+
+ public static ItemDescriptionFragment newInstance(Playable media,
+ boolean saveState) {
ItemDescriptionFragment f = new ItemDescriptionFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_PLAYABLE, media);
+ args.putBoolean(ARG_SAVE_STATE, saveState);
f.setArguments(args);
return f;
}
- public static ItemDescriptionFragment newInstance(FeedItem item) {
+ public static ItemDescriptionFragment newInstance(FeedItem item,
+ boolean saveState) {
ItemDescriptionFragment f = new ItemDescriptionFragment();
Bundle args = new Bundle();
args.putLong(ARG_FEED_ID, item.getFeed().getId());
args.putLong(ARG_FEED_ITEM_ID, item.getId());
+ args.putBoolean(ARG_SAVE_STATE, saveState);
f.setArguments(args);
return f;
}
@@ -138,6 +158,7 @@ public class ItemDescriptionFragment extends SherlockFragment {
if (AppConfig.DEBUG)
Log.d(TAG, "Creating fragment");
Bundle args = getArguments();
+ saveState = args.getBoolean(ARG_SAVE_STATE, false);
if (args.containsKey(ARG_PLAYABLE)) {
media = args.getParcelable(ARG_PLAYABLE);
} else if (args.containsKey(ARG_FEED_ID)
@@ -244,6 +265,7 @@ public class ItemDescriptionFragment extends SherlockFragment {
}
};
+ @SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public boolean onContextItemSelected(MenuItem item) {
@@ -314,6 +336,7 @@ public class ItemDescriptionFragment extends SherlockFragment {
String data;
+ @SuppressWarnings("deprecation")
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
@@ -327,6 +350,16 @@ public class ItemDescriptionFragment extends SherlockFragment {
if (AppConfig.DEBUG)
Log.d(TAG, "Webview loaded");
webViewLoader = null;
+ webvDescription.setPictureListener(new PictureListener() {
+
+ @Override
+ @Deprecated
+ public void onNewPicture(WebView view, Picture picture) {
+ restoreFromPreference();
+
+ }
+ });
+
}
@Override
@@ -364,4 +397,56 @@ public class ItemDescriptionFragment extends SherlockFragment {
};
}
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ savePreference();
+ }
+
+ private void savePreference() {
+ if (saveState) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Saving preferences");
+ SharedPreferences prefs = getActivity().getSharedPreferences(PREF,
+ Activity.MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+ if (media != null && webvDescription != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "Saving scroll position: "
+ + webvDescription.getScrollY());
+ editor.putInt(PREF_SCROLL_Y, webvDescription.getScrollY());
+ editor.putString(PREF_PLAYABLE_ID, media.getIdentifier()
+ .toString());
+ } else {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "savePreferences was called while media or webview was null");
+ editor.putInt(PREF_SCROLL_Y, -1);
+ editor.putString(PREF_PLAYABLE_ID, "");
+ }
+ editor.commit();
+ }
+ }
+
+ private boolean restoreFromPreference() {
+ if (saveState) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Restoring from preferences");
+ SharedPreferences prefs = getActivity().getSharedPreferences(PREF,
+ Activity.MODE_PRIVATE);
+ String id = prefs.getString(PREF_PLAYABLE_ID, "");
+ int scrollY = prefs.getInt(PREF_SCROLL_Y, -1);
+ if (scrollY != -1 && media != null
+ && id.equals(media.getIdentifier().toString())
+ && webvDescription != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Restored scroll Position: " + scrollY);
+ webvDescription.scrollTo(webvDescription.getScrollX(), scrollY);
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/de/danoeh/antennapod/storage/DownloadRequester.java b/src/de/danoeh/antennapod/storage/DownloadRequester.java
index bebffe8f9..29bd764dd 100644
--- a/src/de/danoeh/antennapod/storage/DownloadRequester.java
+++ b/src/de/danoeh/antennapod/storage/DownloadRequester.java
@@ -113,7 +113,7 @@ public class DownloadRequester {
private boolean isFilenameAvailable(String path) {
for (String key : downloads.keySet()) {
FeedFile f = downloads.get(key);
- if (f.getFile_url().equals(path)) {
+ if (f.getFile_url() != null && f.getFile_url().equals(path)) {
if (AppConfig.DEBUG)
Log.d(TAG, path
+ " is already used by another requested download");
diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java
index f1842800b..420264840 100644
--- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java
+++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java
@@ -6,6 +6,7 @@ import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.database.DatabaseUtils;
import android.database.MergeCursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
@@ -212,7 +213,6 @@ public class PodDBAdapter {
public static final int IDX_FI_EXTRA_CONTENT_ENCODED = 2;
public static final int IDX_FI_EXTRA_FEED = 3;
-
public PodDBAdapter(Context c) {
this.context = c;
helper = new PodDBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -441,6 +441,7 @@ public class PodDBAdapter {
public void setQueue(List<FeedItem> queue) {
ContentValues values = new ContentValues();
+ db.beginTransaction();
db.delete(TABLE_NAME_QUEUE, null, null);
for (int i = 0; i < queue.size(); i++) {
FeedItem item = queue.get(i);
@@ -450,6 +451,8 @@ public class PodDBAdapter {
db.insertWithOnConflict(TABLE_NAME_QUEUE, null, values,
SQLiteDatabase.CONFLICT_REPLACE);
}
+ db.setTransactionSuccessful();
+ db.endTransaction();
}
public void removeFeedMedia(FeedMedia media) {
@@ -654,6 +657,18 @@ public class PodDBAdapter {
}
/**
+ * Uses DatabaseUtils to escape a search query and removes ' at the
+ * beginning and the end of the string returned by the escape method.
+ */
+ private String prepareSearchQuery(String query) {
+ StringBuilder builder = new StringBuilder();
+ DatabaseUtils.appendEscapedSQLString(builder, query);
+ builder.deleteCharAt(0);
+ builder.deleteCharAt(builder.length() - 1);
+ return builder.toString();
+ }
+
+ /**
* Searches for the given query in the description of all items or the items
* of a specified feed.
*
@@ -663,13 +678,15 @@ public class PodDBAdapter {
if (feed != null) {
// search items in specific feed
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_FEED
- + "=? AND " + KEY_DESCRIPTION + " LIKE '%" + query + "%'", new String[] {
- String.valueOf(feed.getId()) }, null, null, null);
+ + "=? AND " + KEY_DESCRIPTION + " LIKE '%"
+ + prepareSearchQuery(query) + "%'",
+ new String[] { String.valueOf(feed.getId()) }, null, null,
+ null);
} else {
// search through all items
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA,
- KEY_DESCRIPTION + " LIKE '%" + query + "%'", null, null,
- null, null);
+ KEY_DESCRIPTION + " LIKE '%" + prepareSearchQuery(query)
+ + "%'", null, null, null, null);
}
}
@@ -683,14 +700,16 @@ public class PodDBAdapter {
if (feed != null) {
// search items in specific feed
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA, KEY_FEED
- + "=? AND " + KEY_CONTENT_ENCODED + " LIKE '%" + query + "%'",
- new String[] { String.valueOf(feed.getId())}, null,
- null, null);
+ + "=? AND " + KEY_CONTENT_ENCODED + " LIKE '%"
+ + prepareSearchQuery(query) + "%'",
+ new String[] { String.valueOf(feed.getId()) }, null, null,
+ null);
} else {
// search through all items
return db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_EXTRA,
- KEY_CONTENT_ENCODED + " LIKE '%" + query + "%'", null,
- null, null, null);
+ KEY_CONTENT_ENCODED + " LIKE '%"
+ + prepareSearchQuery(query) + "%'", null, null,
+ null, null);
}
}
diff --git a/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java b/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java
index 522b16efe..1efaac359 100644
--- a/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java
+++ b/src/de/danoeh/antennapod/syndication/namespace/atom/NSAtom.java
@@ -42,6 +42,12 @@ public class NSAtom extends Namespace {
private static final String LINK_REL_PAYMENT = "payment";
private static final String LINK_REL_RELATED = "related";
private static final String LINK_REL_SELF = "self";
+ // type-values
+ private static final String LINK_TYPE_ATOM = "application/atom+xml";
+ private static final String LINK_TYPE_HTML = "text/html";
+ private static final String LINK_TYPE_XHTML = "application/xml+xhtml";
+
+ private static final String LINK_TYPE_RSS = "application/rss+xml";
/** Regexp to test whether an Element is a Text Element. */
private static final String isText = TITLE + "|" + CONTENT + "|" + "|"
@@ -85,7 +91,16 @@ public class NSAtom extends Namespace {
}
} else if (parent.getName().matches(isFeed)) {
if (rel == null || rel.equals(LINK_REL_ALTERNATE)) {
- state.getFeed().setLink(href);
+ String type = attributes.getValue(LINK_TYPE);
+ /*
+ * Use as link if a) no type-attribute is given and
+ * feed-object has no link yet b) type of link is
+ * LINK_TYPE_HTML or LINK_TYPE_XHTML
+ */
+ if ((type == null && state.getFeed().getLink() == null)
+ || (type != null && (type.equals(LINK_TYPE_HTML) || type.equals(LINK_TYPE_XHTML)))) {
+ state.getFeed().setLink(href);
+ }
} else if (rel.equals(LINK_REL_PAYMENT)) {
state.getFeed().setPaymentLink(href);
}
diff --git a/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java b/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java
index 6196d064d..30835434f 100644
--- a/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java
+++ b/src/de/danoeh/antennapod/syndication/util/SyndDateUtils.java
@@ -11,8 +11,7 @@ import android.util.Log;
public class SyndDateUtils {
private static final String TAG = "DateUtils";
- public static final String[] RFC822DATES = { "dd MMM yyyy HH:mm:ss Z",
- "dd MMM yy HH:mm:ss Z", };
+ public 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'";
diff --git a/src/de/danoeh/antennapod/util/playback/ExternalMedia.java b/src/de/danoeh/antennapod/util/playback/ExternalMedia.java
index 55a37413b..c0a92904b 100644
--- a/src/de/danoeh/antennapod/util/playback/ExternalMedia.java
+++ b/src/de/danoeh/antennapod/util/playback/ExternalMedia.java
@@ -69,6 +69,11 @@ public class ExternalMedia implements Playable {
e.printStackTrace();
throw new PlayableException(
"IllegalArgumentException when setting up MediaMetadataReceiver");
+ } catch (RuntimeException e) {
+ // http://code.google.com/p/android/issues/detail?id=39770
+ e.printStackTrace();
+ throw new PlayableException(
+ "RuntimeException when setting up MediaMetadataRetriever");
}
episodeTitle = mmr
.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
@@ -78,10 +83,10 @@ public class ExternalMedia implements Playable {
.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
ChapterUtils.loadChaptersFromFileUrl(this);
}
-
+
@Override
public void loadChapterMarks() {
-
+
}
@Override