diff options
Diffstat (limited to 'src/de/danoeh/antennapod')
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 |