diff options
-rw-r--r-- | res/menu/feeditem.xml | 3 | ||||
-rw-r--r-- | res/menu/mediaplayer.xml | 20 | ||||
-rw-r--r-- | res/values/ids.xml | 1 | ||||
-rw-r--r-- | res/values/strings.xml | 1 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/activity/MediaplayerActivity.java | 6 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/service/PlaybackService.java | 117 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java | 15 |
7 files changed, 116 insertions, 47 deletions
diff --git a/res/menu/feeditem.xml b/res/menu/feeditem.xml index a76f2c658..09b7fa6b0 100644 --- a/res/menu/feeditem.xml +++ b/res/menu/feeditem.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > - <item + <item android:id="@id/skip_episode_item" android:title="@string/skip_episode_label" android:showAsAction="collapseActionView"></item><item android:id="@+id/download_item" android:icon="?attr/av_download" android:showAsAction="ifRoom" @@ -67,5 +67,6 @@ android:showAsAction="collapseActionView" android:title="@string/support_label"> </item> + </menu>
\ No newline at end of file diff --git a/res/menu/mediaplayer.xml b/res/menu/mediaplayer.xml index 4f3a55114..2cde6d58a 100644 --- a/res/menu/mediaplayer.xml +++ b/res/menu/mediaplayer.xml @@ -1,7 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > - <item android:id="@+id/disable_sleeptimer_item" android:icon="?attr/device_access_time" android:title="@string/sleep_timer_label" android:showAsAction="always"></item><item android:id="@+id/set_sleeptimer_item" android:showAsAction="collapseActionView" android:title="@string/set_sleeptimer_label"></item><item + <item + android:id="@+id/disable_sleeptimer_item" + android:icon="?attr/device_access_time" + android:showAsAction="always" + android:title="@string/sleep_timer_label"> + </item> + <item + android:id="@+id/set_sleeptimer_item" + android:showAsAction="collapseActionView" + android:title="@string/set_sleeptimer_label"> + </item> + <item android:id="@+id/share_link_item" android:showAsAction="collapseActionView" android:title="@string/share_link_label"> @@ -19,7 +30,10 @@ android:title="@string/support_label" android:visible="false"> </item> - - + <item + android:id="@id/skip_episode_item" + android:showAsAction="collapseActionView" + android:title="@string/skip_episode_label" + android:visible="true"/> </menu>
\ No newline at end of file diff --git a/res/values/ids.xml b/res/values/ids.xml index 476969668..4d393e675 100644 --- a/res/values/ids.xml +++ b/res/values/ids.xml @@ -14,5 +14,6 @@ <item name="share_url_item" type="id"/> <item name="organize_queue_item" type="id"/> <item name="drag_handle" type="id"/> + <item name="skip_episode_item" type="id"/> </resources>
\ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 906d530d7..a1c9e336a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -70,6 +70,7 @@ <string name="support_label">Flattr this</string> <string name="enqueue_all_new">Enqueue all</string> <string name="download_all">Download all</string> + <string name="skip_episode_label">Skip episode</string> <!-- Download messages and labels --> <string name="download_successful">Download successful</string> diff --git a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java index c217a4628..10a879c06 100644 --- a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -227,7 +227,7 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity media != null && media.getWebsiteLink() != null); menu.findItem(R.id.visit_website_item).setVisible( media != null && media.getWebsiteLink() != null); - + menu.findItem(R.id.skip_episode_item).setVisible(media != null); boolean sleepTimerSet = controller.sleepTimerActive(); boolean sleepTimerNotSet = controller.sleepTimerNotActive(); menu.findItem(R.id.set_sleeptimer_item).setVisible(sleepTimerNotSet); @@ -303,6 +303,10 @@ public abstract class MediaplayerActivity extends SherlockFragmentActivity case R.id.share_link_item: ShareUtils.shareLink(this, media.getWebsiteLink()); break; + case R.id.skip_episode_item: + sendBroadcast(new Intent( + PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); + break; default: return false; diff --git a/src/de/danoeh/antennapod/service/PlaybackService.java b/src/de/danoeh/antennapod/service/PlaybackService.java index 82f0cb644..927413c4d 100644 --- a/src/de/danoeh/antennapod/service/PlaybackService.java +++ b/src/de/danoeh/antennapod/service/PlaybackService.java @@ -85,6 +85,12 @@ public class PlaybackService extends Service { */ public static final String ACTION_SHUTDOWN_PLAYBACK_SERVICE = "action.de.danoeh.antennapod.service.actionShutdownPlaybackService"; + /** + * If the PlaybackService receives this action, it will end playback of the + * current episode and load the next episode if there is one available. + * */ + public static final String ACTION_SKIP_CURRENT_EPISODE = "action.de.danoeh.antennapod.service.skipCurrentEpisode"; + /** Used in NOTIFICATION_TYPE_RELOAD. */ public static final int EXTRA_CODE_AUDIO = 1; public static final int EXTRA_CODE_VIDEO = 2; @@ -266,6 +272,7 @@ public class PlaybackService extends Service { ACTION_SHUTDOWN_PLAYBACK_SERVICE)); registerReceiver(audioBecomingNoisy, new IntentFilter( AudioManager.ACTION_AUDIO_BECOMING_NOISY)); + registerReceiver(skipCurrentEpisodeReceiver, new IntentFilter(ACTION_SKIP_CURRENT_EPISODE)); } @@ -296,6 +303,7 @@ public class PlaybackService extends Service { unregisterReceiver(headsetDisconnected); unregisterReceiver(shutdownReceiver); unregisterReceiver(audioBecomingNoisy); + unregisterReceiver(skipCurrentEpisodeReceiver); if (android.os.Build.VERSION.SDK_INT >= 14) { audioManager.unregisterRemoteControlClient(remoteControlClient); } @@ -460,25 +468,28 @@ public class PlaybackService extends Service { @Override protected void onPostExecute(Playable result) { - if (result != null) { - try { - if (shouldStream) { - player.setDataSource(media.getStreamUrl()); - setStatus(PlayerStatus.PREPARING); - player.prepareAsync(); - } else { - player.setDataSource(media - .getLocalMediaUrl()); - setStatus(PlayerStatus.PREPARING); - player.prepareAsync(); + if (status == PlayerStatus.INITIALIZING) { + if (result != null) { + try { + if (shouldStream) { + player.setDataSource(media + .getStreamUrl()); + setStatus(PlayerStatus.PREPARING); + player.prepareAsync(); + } else { + player.setDataSource(media + .getLocalMediaUrl()); + setStatus(PlayerStatus.PREPARING); + player.prepareAsync(); + } + } catch (IOException e) { + e.printStackTrace(); } - } catch (IOException e) { - e.printStackTrace(); + } else { + setStatus(PlayerStatus.ERROR); + sendBroadcast(new Intent( + ACTION_SHUTDOWN_PLAYBACK_SERVICE)); } - } else { - setStatus(PlayerStatus.ERROR); - sendBroadcast(new Intent( - ACTION_SHUTDOWN_PLAYBACK_SERVICE)); } } @@ -531,35 +542,45 @@ public class PlaybackService extends Service { @Override protected void onPostExecute(Playable result) { - if (result != null) { - playingVideo = false; - try { - if (shouldStream) { - player.setDataSource(media.getStreamUrl()); - } else if (media.localFileAvailable()) { - player.setDataSource(media - .getLocalMediaUrl()); + // check if state of service has changed. If it has + // changed, assume that loaded metadata is not needed + // anymore. + if (status == PlayerStatus.INITIALIZING) { + if (result != null) { + playingVideo = false; + try { + if (shouldStream) { + player.setDataSource(media + .getStreamUrl()); + } else if (media.localFileAvailable()) { + player.setDataSource(media + .getLocalMediaUrl()); + } + + if (prepareImmediately) { + setStatus(PlayerStatus.PREPARING); + player.prepareAsync(); + } else { + setStatus(PlayerStatus.INITIALIZED); + } + } catch (IOException e) { + e.printStackTrace(); + media = null; + setStatus(PlayerStatus.ERROR); + sendBroadcast(new Intent( + ACTION_SHUTDOWN_PLAYBACK_SERVICE)); } - - if (prepareImmediately) { - setStatus(PlayerStatus.PREPARING); - player.prepareAsync(); - } else { - setStatus(PlayerStatus.INITIALIZED); - } - } catch (IOException e) { - e.printStackTrace(); + } else { + Log.e(TAG, "InitTask could not load metadata"); media = null; setStatus(PlayerStatus.ERROR); sendBroadcast(new Intent( ACTION_SHUTDOWN_PLAYBACK_SERVICE)); } } else { - Log.e(TAG, "InitTask could not load metadata"); - media = null; - setStatus(PlayerStatus.ERROR); - sendBroadcast(new Intent( - ACTION_SHUTDOWN_PLAYBACK_SERVICE)); + if (AppConfig.DEBUG) + Log.d(TAG, + "Status of player has changed during initialization. Stopping init process."); } } @@ -688,7 +709,7 @@ public class PlaybackService extends Service { private void endPlayback(boolean playNextEpisode) { if (AppConfig.DEBUG) - Log.d(TAG, "Playback completed"); + Log.d(TAG, "Playback ended"); audioManager.abandonAudioFocus(audioFocusChangeListener); SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(getApplicationContext()); @@ -1214,6 +1235,22 @@ public class PlaybackService extends Service { }; + private BroadcastReceiver skipCurrentEpisodeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(ACTION_SKIP_CURRENT_EPISODE)) { + + if (AppConfig.DEBUG) + Log.d(TAG, "Received SKIP_CURRENT_EPISODE intent"); + if (media != null) { + setStatus(PlayerStatus.STOPPED); + player.reset(); + endPlayback(false); + } + } + } + }; + /** Periodically saves the position of the media file */ class PositionSaver implements Runnable { public static final int WAITING_INTERVALL = 5000; diff --git a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java index 9cdf8eec2..d1d0c6966 100644 --- a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java +++ b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java @@ -7,6 +7,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.asynctask.FlattrClickWorker; import de.danoeh.antennapod.feed.FeedItem; import de.danoeh.antennapod.feed.FeedManager; +import de.danoeh.antennapod.service.PlaybackService; import de.danoeh.antennapod.storage.DownloadRequestException; import de.danoeh.antennapod.storage.DownloadRequester; import de.danoeh.antennapod.util.ShareUtils; @@ -55,16 +56,22 @@ public class FeedItemMenuHandler { && requester.isDownloadingFile(selectedItem.getMedia()); boolean notLoadedAndNotLoading = hasMedia && (!downloaded) && (!downloading); + boolean isPlaying = hasMedia + && selectedItem.getState() == FeedItem.State.PLAYING; + FeedItem.State state = selectedItem.getState(); - if (!downloaded) { + if (!isPlaying) { + mi.setItemVisibility(R.id.skip_episode_item, false); + } + if (!downloaded || isPlaying) { mi.setItemVisibility(R.id.play_item, false); mi.setItemVisibility(R.id.remove_item, false); } if (!notLoadedAndNotLoading) { mi.setItemVisibility(R.id.download_item, false); } - if (!(notLoadedAndNotLoading | downloading)) { + if (!(notLoadedAndNotLoading | downloading | isPlaying)) { mi.setItemVisibility(R.id.stream_item, false); } if (!downloading) { @@ -104,6 +111,10 @@ public class FeedItemMenuHandler { DownloadRequester requester = DownloadRequester.getInstance(); FeedManager manager = FeedManager.getInstance(); switch (menuItemId) { + case R.id.skip_episode_item: + context.sendBroadcast(new Intent( + PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); + break; case R.id.download_item: manager.downloadFeedItem(context, selectedItem); break; |