summaryrefslogtreecommitdiff
path: root/src/de
diff options
context:
space:
mode:
Diffstat (limited to 'src/de')
-rw-r--r--src/de/danoeh/antennapod/activity/AudioplayerActivity.java965
-rw-r--r--src/de/danoeh/antennapod/activity/MediaplayerActivity.java16
-rw-r--r--src/de/danoeh/antennapod/activity/VideoplayerActivity.java544
-rw-r--r--src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java11
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlaybackService.java42
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java12
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlaybackServiceTaskManager.java17
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlayerStatus.java4
-rw-r--r--src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java8
-rw-r--r--src/de/danoeh/antennapod/util/playback/PlaybackController.java26
10 files changed, 853 insertions, 792 deletions
diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
index e883ffc92..90707a160 100644
--- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java
@@ -11,15 +11,10 @@ import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.Window;
import android.view.View.OnLongClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.ImageButton;
+import android.view.Window;
+import android.widget.*;
import android.widget.ImageView.ScaleType;
-import android.widget.ListView;
-import android.widget.TextView;
-
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.ChapterListAdapter;
@@ -35,496 +30,506 @@ import de.danoeh.antennapod.service.playback.PlaybackService;
import de.danoeh.antennapod.util.playback.ExternalMedia;
import de.danoeh.antennapod.util.playback.Playable;
-/** Activity for playing audio files. */
+/**
+ * Activity for playing audio files.
+ */
public class AudioplayerActivity extends MediaplayerActivity {
- private static final int POS_COVER = 0;
- private static final int POS_DESCR = 1;
- private static final int POS_CHAPTERS = 2;
- 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;
-
- private CoverFragment coverFragment;
- private ItemDescriptionFragment descriptionFragment;
- private ListFragment chapterFragment;
-
- private Fragment currentlyShownFragment;
- private int currentlyShownPosition = -1;
- /** Used if onResume was called without loadMediaInfo. */
- private int savedPosition = -1;
-
- private TextView txtvTitle;
- private TextView txtvFeed;
- private Button butPlaybackSpeed;
- private ImageButton butNavLeft;
- 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;
- chapterFragment = null;
- currentlyShownPosition = -1;
- detachedFragments = new Fragment[NUM_CONTENT_FRAGMENTS];
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- if (AppConfig.DEBUG)
- Log.d(TAG, "onStop");
-
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- super.onCreate(savedInstanceState);
- getSupportActionBar().setDisplayShowTitleEnabled(false);
- 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();
-
- savedPosition = currentlyShownPosition;
- }
-
- @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();
- if (getIntent().getAction() != null
- && getIntent().getAction().equals(Intent.ACTION_VIEW)) {
- Intent intent = getIntent();
- if (AppConfig.DEBUG)
- Log.d(TAG, "Received VIEW intent: "
- + intent.getData().getPath());
- ExternalMedia media = new ExternalMedia(intent.getData().getPath(),
- MediaType.AUDIO);
- Intent launchIntent = new Intent(this, PlaybackService.class);
- launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
- launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
- true);
- launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
- launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
- true);
- startService(launchIntent);
- }
- if (savedPosition != -1) {
- switchToFragment(savedPosition);
- }
-
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- setIntent(intent);
- }
-
- @Override
- protected void onAwaitingVideoSurface() {
- startActivity(new Intent(this, VideoplayerActivity.class));
- }
-
- @Override
- protected void postStatusMsg(int resId) {
- setSupportProgressBarIndeterminateVisibility(resId == R.string.player_preparing_msg
- || resId == R.string.player_seeking_msg
- || resId == R.string.player_buffering_msg);
- }
-
- @Override
- protected void clearStatusMsg() {
- setSupportProgressBarIndeterminateVisibility(false);
- }
-
- /**
- * Changes the currently displayed fragment.
- *
- * @param pos Must be POS_COVER, POS_DESCR, or POS_CHAPTERS
- * */
- private void switchToFragment(int pos) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Switching contentView to position " + pos);
- if (currentlyShownPosition != pos && controller != null) {
- Playable media = controller.getMedia();
- if (media != null) {
- FragmentTransaction ft = getSupportFragmentManager()
- .beginTransaction();
- if (currentlyShownFragment != null) {
- detachedFragments[currentlyShownPosition] = currentlyShownFragment;
- ft.detach(currentlyShownFragment);
- }
- switch (pos) {
- case POS_COVER:
- if (coverFragment == null) {
- Log.i(TAG, "Using new coverfragment");
- coverFragment = CoverFragment.newInstance(media);
- }
- currentlyShownFragment = coverFragment;
- break;
- case POS_DESCR:
- if (descriptionFragment == null) {
- descriptionFragment = ItemDescriptionFragment
- .newInstance(media, true);
- }
- currentlyShownFragment = descriptionFragment;
- break;
- case POS_CHAPTERS:
- if (chapterFragment == null) {
- chapterFragment = new ListFragment() {
-
- @Override
- public void onListItemClick(ListView l, View v,
- int position, long id) {
- super.onListItemClick(l, v, position, id);
- Chapter chapter = (Chapter) this
- .getListAdapter().getItem(position);
- controller.seekToChapter(chapter);
- }
-
- };
- chapterFragment.setListAdapter(new ChapterListAdapter(
- AudioplayerActivity.this, 0, media
- .getChapters(), media));
- }
- currentlyShownFragment = chapterFragment;
- break;
- }
- if (currentlyShownFragment != null) {
- currentlyShownPosition = pos;
- if (detachedFragments[pos] != null) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Reattaching fragment at position "
- + pos);
- ft.attach(detachedFragments[pos]);
- } else {
- ft.add(R.id.contentView, currentlyShownFragment);
- }
- ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
- ft.disallowAddToBackStack();
- ft.commit();
- updateNavButtonDrawable();
- }
- }
- }
- }
-
- private void updateNavButtonDrawable() {
- TypedArray drawables = obtainStyledAttributes(new int[] {
- R.attr.navigation_shownotes, R.attr.navigation_chapters });
- final Playable media = controller.getMedia();
- if (butNavLeft != null && butNavRight != null && media != null) {
- switch (currentlyShownPosition) {
- case POS_COVER:
- butNavLeft.setScaleType(ScaleType.CENTER);
- butNavLeft.setImageDrawable(drawables.getDrawable(0));
- butNavRight.setImageDrawable(drawables.getDrawable(1));
- break;
- case POS_DESCR:
- butNavLeft.setScaleType(ScaleType.CENTER_CROP);
- butNavLeft.post(new Runnable() {
-
- @Override
- public void run() {
- ImageLoader.getInstance().loadThumbnailBitmap(media,
- butNavLeft);
- }
- });
- butNavRight.setImageDrawable(drawables.getDrawable(1));
- break;
- case POS_CHAPTERS:
- butNavLeft.setScaleType(ScaleType.CENTER_CROP);
- butNavLeft.post(new Runnable() {
-
- @Override
- public void run() {
- ImageLoader.getInstance().loadThumbnailBitmap(media,
- butNavLeft);
- }
- });
- butNavRight.setImageDrawable(drawables.getDrawable(0));
- break;
- }
- }
- }
-
- @Override
- protected void setupGUI() {
- super.setupGUI();
- resetFragmentView();
- txtvTitle = (TextView) findViewById(R.id.txtvTitle);
- txtvFeed = (TextView) findViewById(R.id.txtvFeed);
- butNavLeft = (ImageButton) findViewById(R.id.butNavLeft);
- butNavRight = (ImageButton) findViewById(R.id.butNavRight);
- butPlaybackSpeed = (Button) findViewById(R.id.butPlaybackSpeed);
-
- butNavLeft.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (currentlyShownFragment == null
- || currentlyShownPosition == POS_DESCR) {
- switchToFragment(POS_COVER);
- } else if (currentlyShownPosition == POS_COVER) {
- switchToFragment(POS_DESCR);
- } else if (currentlyShownPosition == POS_CHAPTERS) {
- switchToFragment(POS_COVER);
- }
- }
- });
-
- butNavRight.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (currentlyShownPosition == POS_CHAPTERS) {
- switchToFragment(POS_DESCR);
- } else {
- switchToFragment(POS_CHAPTERS);
- }
- }
- });
-
- butPlaybackSpeed.setOnClickListener(new OnClickListener() {
+ private static final int POS_COVER = 0;
+ private static final int POS_DESCR = 1;
+ private static final int POS_CHAPTERS = 2;
+ 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;
+
+ private CoverFragment coverFragment;
+ private ItemDescriptionFragment descriptionFragment;
+ private ListFragment chapterFragment;
+
+ private Fragment currentlyShownFragment;
+ private int currentlyShownPosition = -1;
+ /**
+ * Used if onResume was called without loadMediaInfo.
+ */
+ private int savedPosition = -1;
+
+ private TextView txtvTitle;
+ private TextView txtvFeed;
+ private Button butPlaybackSpeed;
+ private ImageButton butNavLeft;
+ 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;
+ chapterFragment = null;
+ currentlyShownPosition = -1;
+ detachedFragments = new Fragment[NUM_CONTENT_FRAGMENTS];
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "onStop");
+
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ super.onCreate(savedInstanceState);
+ getSupportActionBar().setDisplayShowTitleEnabled(false);
+ 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();
+
+ savedPosition = currentlyShownPosition;
+ }
+
+ @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();
+ if (getIntent().getAction() != null
+ && getIntent().getAction().equals(Intent.ACTION_VIEW)) {
+ Intent intent = getIntent();
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Received VIEW intent: "
+ + intent.getData().getPath());
+ ExternalMedia media = new ExternalMedia(intent.getData().getPath(),
+ MediaType.AUDIO);
+ Intent launchIntent = new Intent(this, PlaybackService.class);
+ launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
+ launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
+ true);
+ launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
+ launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
+ true);
+ startService(launchIntent);
+ }
+ if (savedPosition != -1) {
+ switchToFragment(savedPosition);
+ }
+
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ setIntent(intent);
+ }
+
+ @Override
+ protected void onAwaitingVideoSurface() {
+ if (AppConfig.DEBUG) Log.d(TAG, "onAwaitingVideoSurface was called in audio player -> switching to video player");
+ startActivity(new Intent(this, VideoplayerActivity.class));
+ }
+
+ @Override
+ protected void postStatusMsg(int resId) {
+ setSupportProgressBarIndeterminateVisibility(resId == R.string.player_preparing_msg
+ || resId == R.string.player_seeking_msg
+ || resId == R.string.player_buffering_msg);
+ }
+
+ @Override
+ protected void clearStatusMsg() {
+ setSupportProgressBarIndeterminateVisibility(false);
+ }
+
+ /**
+ * Changes the currently displayed fragment.
+ *
+ * @param pos Must be POS_COVER, POS_DESCR, or POS_CHAPTERS
+ */
+ private void switchToFragment(int pos) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Switching contentView to position " + pos);
+ if (currentlyShownPosition != pos && controller != null) {
+ Playable media = controller.getMedia();
+ if (media != null) {
+ FragmentTransaction ft = getSupportFragmentManager()
+ .beginTransaction();
+ if (currentlyShownFragment != null) {
+ detachedFragments[currentlyShownPosition] = currentlyShownFragment;
+ ft.detach(currentlyShownFragment);
+ }
+ switch (pos) {
+ case POS_COVER:
+ if (coverFragment == null) {
+ Log.i(TAG, "Using new coverfragment");
+ coverFragment = CoverFragment.newInstance(media);
+ }
+ currentlyShownFragment = coverFragment;
+ break;
+ case POS_DESCR:
+ if (descriptionFragment == null) {
+ descriptionFragment = ItemDescriptionFragment
+ .newInstance(media, true);
+ }
+ currentlyShownFragment = descriptionFragment;
+ break;
+ case POS_CHAPTERS:
+ if (chapterFragment == null) {
+ chapterFragment = new ListFragment() {
+
+ @Override
+ public void onListItemClick(ListView l, View v,
+ int position, long id) {
+ super.onListItemClick(l, v, position, id);
+ Chapter chapter = (Chapter) this
+ .getListAdapter().getItem(position);
+ controller.seekToChapter(chapter);
+ }
+
+ };
+ chapterFragment.setListAdapter(new ChapterListAdapter(
+ AudioplayerActivity.this, 0, media
+ .getChapters(), media));
+ }
+ currentlyShownFragment = chapterFragment;
+ break;
+ }
+ if (currentlyShownFragment != null) {
+ currentlyShownPosition = pos;
+ if (detachedFragments[pos] != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Reattaching fragment at position "
+ + pos);
+ ft.attach(detachedFragments[pos]);
+ } else {
+ ft.add(R.id.contentView, currentlyShownFragment);
+ }
+ ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+ ft.disallowAddToBackStack();
+ ft.commit();
+ updateNavButtonDrawable();
+ }
+ }
+ }
+ }
+
+ private void updateNavButtonDrawable() {
+ TypedArray drawables = obtainStyledAttributes(new int[]{
+ R.attr.navigation_shownotes, R.attr.navigation_chapters});
+ final Playable media = controller.getMedia();
+ if (butNavLeft != null && butNavRight != null && media != null) {
+ switch (currentlyShownPosition) {
+ case POS_COVER:
+ butNavLeft.setScaleType(ScaleType.CENTER);
+ butNavLeft.setImageDrawable(drawables.getDrawable(0));
+ butNavRight.setImageDrawable(drawables.getDrawable(1));
+ break;
+ case POS_DESCR:
+ butNavLeft.setScaleType(ScaleType.CENTER_CROP);
+ butNavLeft.post(new Runnable() {
+
+ @Override
+ public void run() {
+ ImageLoader.getInstance().loadThumbnailBitmap(media,
+ butNavLeft);
+ }
+ });
+ butNavRight.setImageDrawable(drawables.getDrawable(1));
+ break;
+ case POS_CHAPTERS:
+ butNavLeft.setScaleType(ScaleType.CENTER_CROP);
+ butNavLeft.post(new Runnable() {
+
+ @Override
+ public void run() {
+ ImageLoader.getInstance().loadThumbnailBitmap(media,
+ butNavLeft);
+ }
+ });
+ butNavRight.setImageDrawable(drawables.getDrawable(0));
+ break;
+ }
+ }
+ }
+
+ @Override
+ protected void setupGUI() {
+ super.setupGUI();
+ resetFragmentView();
+ txtvTitle = (TextView) findViewById(R.id.txtvTitle);
+ txtvFeed = (TextView) findViewById(R.id.txtvFeed);
+ butNavLeft = (ImageButton) findViewById(R.id.butNavLeft);
+ butNavRight = (ImageButton) findViewById(R.id.butNavRight);
+ butPlaybackSpeed = (Button) findViewById(R.id.butPlaybackSpeed);
+
+ butNavLeft.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (currentlyShownFragment == null
+ || currentlyShownPosition == POS_DESCR) {
+ switchToFragment(POS_COVER);
+ } else if (currentlyShownPosition == POS_COVER) {
+ switchToFragment(POS_DESCR);
+ } else if (currentlyShownPosition == POS_CHAPTERS) {
+ switchToFragment(POS_COVER);
+ }
+ }
+ });
+
+ butNavRight.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (currentlyShownPosition == POS_CHAPTERS) {
+ switchToFragment(POS_DESCR);
+ } else {
+ switchToFragment(POS_CHAPTERS);
+ }
+ }
+ });
+
+ butPlaybackSpeed.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (controller != null && controller.canSetPlaybackSpeed()) {
- String[] availableSpeeds = UserPreferences
- .getPlaybackSpeedArray();
- String currentSpeed = UserPreferences.getPlaybackSpeed();
-
- // Provide initial value in case the speed list has changed
- // out from under us
- // and our current speed isn't in the new list
- String newSpeed;
- if (availableSpeeds.length > 0) {
- newSpeed = availableSpeeds[0];
+ String[] availableSpeeds = UserPreferences
+ .getPlaybackSpeedArray();
+ String currentSpeed = UserPreferences.getPlaybackSpeed();
+
+ // Provide initial value in case the speed list has changed
+ // out from under us
+ // and our current speed isn't in the new list
+ String newSpeed;
+ if (availableSpeeds.length > 0) {
+ newSpeed = availableSpeeds[0];
} else {
- newSpeed = "1.0";
+ newSpeed = "1.0";
}
- for (int i = 0; i < availableSpeeds.length; i++) {
- if (availableSpeeds[i].equals(currentSpeed)) {
- if (i == availableSpeeds.length - 1) {
- newSpeed = availableSpeeds[0];
- } else {
- newSpeed = availableSpeeds[i + 1];
- }
- break;
- }
- }
- UserPreferences.setPlaybackSpeed(newSpeed);
- controller.setPlaybackSpeed(Float.parseFloat(newSpeed));
+ for (int i = 0; i < availableSpeeds.length; i++) {
+ if (availableSpeeds[i].equals(currentSpeed)) {
+ if (i == availableSpeeds.length - 1) {
+ newSpeed = availableSpeeds[0];
+ } else {
+ newSpeed = availableSpeeds[i + 1];
+ }
+ break;
+ }
+ }
+ UserPreferences.setPlaybackSpeed(newSpeed);
+ controller.setPlaybackSpeed(Float.parseFloat(newSpeed));
}
}
});
- butPlaybackSpeed.setOnLongClickListener(new OnLongClickListener() {
+ butPlaybackSpeed.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
VariableSpeedDialog.showDialog(AudioplayerActivity.this);
return true;
}
});
- }
-
- @Override
- protected void onPlaybackSpeedChange() {
- super.onPlaybackSpeedChange();
- updateButPlaybackSpeed();
- }
-
- private void updateButPlaybackSpeed() {
- if (controller == null
- || (controller.getCurrentPlaybackSpeedMultiplier() == -1)) {
- butPlaybackSpeed.setVisibility(View.GONE);
- } else {
- butPlaybackSpeed.setVisibility(View.VISIBLE);
- butPlaybackSpeed.setText(UserPreferences.getPlaybackSpeed());
- }
- }
-
- @Override
- protected void onPositionObserverUpdate() {
- super.onPositionObserverUpdate();
- notifyMediaPositionChanged();
- }
-
- @Override
- protected void loadMediaInfo() {
- super.loadMediaInfo();
- final Playable media = controller.getMedia();
- if (media != null) {
- txtvTitle.setText(media.getEpisodeTitle());
- txtvFeed.setText(media.getFeedTitle());
- if (media.getChapters() != null) {
- butNavRight.setVisibility(View.VISIBLE);
- } else {
- butNavRight.setVisibility(View.GONE);
- }
-
- }
- if (currentlyShownPosition == -1) {
- if (!restoreFromPreferences()) {
- switchToFragment(POS_COVER);
- }
- }
- if (currentlyShownFragment instanceof AudioplayerContentFragment) {
- ((AudioplayerContentFragment) currentlyShownFragment)
- .onDataSetChanged(media);
- }
- updateButPlaybackSpeed();
- }
-
- public void notifyMediaPositionChanged() {
- if (chapterFragment != null) {
- ArrayAdapter<SimpleChapter> adapter = (ArrayAdapter<SimpleChapter>) chapterFragment
- .getListAdapter();
- adapter.notifyDataSetChanged();
- }
- }
-
- @Override
- protected void onReloadNotification(int notificationCode) {
- if (notificationCode == PlaybackService.EXTRA_CODE_VIDEO) {
- if (AppConfig.DEBUG)
- Log.d(TAG,
- "ReloadNotification received, switching to Videoplayer now");
- startActivity(new Intent(this, VideoplayerActivity.class));
-
- }
- }
-
- @Override
- protected void onBufferStart() {
- postStatusMsg(R.string.player_buffering_msg);
- }
-
- @Override
- protected void onBufferEnd() {
- clearStatusMsg();
- }
-
- public interface AudioplayerContentFragment {
- public void onDataSetChanged(Playable media);
- }
-
- @Override
- protected int getContentViewResourceId() {
- return R.layout.audioplayer_activity;
- }
+ }
+
+ @Override
+ protected void onPlaybackSpeedChange() {
+ super.onPlaybackSpeedChange();
+ updateButPlaybackSpeed();
+ }
+
+ private void updateButPlaybackSpeed() {
+ if (controller == null
+ || (controller.getCurrentPlaybackSpeedMultiplier() == -1)) {
+ butPlaybackSpeed.setVisibility(View.GONE);
+ } else {
+ butPlaybackSpeed.setVisibility(View.VISIBLE);
+ butPlaybackSpeed.setText(UserPreferences.getPlaybackSpeed());
+ }
+ }
+
+ @Override
+ protected void onPositionObserverUpdate() {
+ super.onPositionObserverUpdate();
+ notifyMediaPositionChanged();
+ }
+
+ @Override
+ protected boolean loadMediaInfo() {
+ if (!super.loadMediaInfo()) {
+ return false;
+ }
+ final Playable media = controller.getMedia();
+ if (media == null) {
+ return false;
+ }
+ txtvTitle.setText(media.getEpisodeTitle());
+ txtvFeed.setText(media.getFeedTitle());
+ if (media.getChapters() != null) {
+ butNavRight.setVisibility(View.VISIBLE);
+ } else {
+ butNavRight.setVisibility(View.GONE);
+ }
+
+
+ if (currentlyShownPosition == -1) {
+ if (!restoreFromPreferences()) {
+ switchToFragment(POS_COVER);
+ }
+ }
+ if (currentlyShownFragment instanceof AudioplayerContentFragment) {
+ ((AudioplayerContentFragment) currentlyShownFragment)
+ .onDataSetChanged(media);
+ }
+ updateButPlaybackSpeed();
+ return true;
+ }
+
+ public void notifyMediaPositionChanged() {
+ if (chapterFragment != null) {
+ ArrayAdapter<SimpleChapter> adapter = (ArrayAdapter<SimpleChapter>) chapterFragment
+ .getListAdapter();
+ adapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ protected void onReloadNotification(int notificationCode) {
+ if (notificationCode == PlaybackService.EXTRA_CODE_VIDEO) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "ReloadNotification received, switching to Videoplayer now");
+ startActivity(new Intent(this, VideoplayerActivity.class));
+
+ }
+ }
+
+ @Override
+ protected void onBufferStart() {
+ postStatusMsg(R.string.player_buffering_msg);
+ }
+
+ @Override
+ protected void onBufferEnd() {
+ clearStatusMsg();
+ }
+
+ public interface AudioplayerContentFragment {
+ public void onDataSetChanged(Playable media);
+ }
+
+ @Override
+ protected int getContentViewResourceId() {
+ return R.layout.audioplayer_activity;
+ }
}
diff --git a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
index eb2fb028a..201cccba3 100644
--- a/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -106,8 +106,8 @@ public abstract class MediaplayerActivity extends ActionBarActivity
}
@Override
- public void loadMediaInfo() {
- MediaplayerActivity.this.loadMediaInfo();
+ public boolean loadMediaInfo() {
+ return MediaplayerActivity.this.loadMediaInfo();
}
@Override
@@ -339,8 +339,9 @@ public abstract class MediaplayerActivity extends ActionBarActivity
}
/**
- * Called by 'handleStatus()' when the PlaybackService is in the
- * AWAITING_VIDEO_SURFACE state.
+ * Called by 'handleStatus()' when the PlaybackService is waiting for
+ * a video surface.
+ *
*/
protected abstract void onAwaitingVideoSurface();
@@ -380,7 +381,7 @@ public abstract class MediaplayerActivity extends ActionBarActivity
* to the PlaybackService to ensure that the activity has the right
* FeedMedia object.
*/
- protected void loadMediaInfo() {
+ protected boolean loadMediaInfo() {
if (AppConfig.DEBUG)
Log.d(TAG, "Loading media info");
Playable media = controller.getMedia();
@@ -395,7 +396,10 @@ public abstract class MediaplayerActivity extends ActionBarActivity
/ media.getDuration();
sbPosition.setProgress((int) (progress * sbPosition.getMax()));
}
- }
+ return true;
+ } else {
+ return false;
+ }
}
protected void setupGUI() {
diff --git a/src/de/danoeh/antennapod/activity/VideoplayerActivity.java b/src/de/danoeh/antennapod/activity/VideoplayerActivity.java
index bdc2a9033..19b7cbc04 100644
--- a/src/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/src/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -11,7 +11,6 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.VideoView;
-
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.feed.MediaType;
@@ -21,270 +20,283 @@ import de.danoeh.antennapod.service.playback.PlayerStatus;
import de.danoeh.antennapod.util.playback.ExternalMedia;
import de.danoeh.antennapod.util.playback.Playable;
-/** Activity for playing audio files. */
-public class VideoplayerActivity extends MediaplayerActivity implements
- SurfaceHolder.Callback {
- private static final String TAG = "VideoplayerActivity";
-
- /** True if video controls are currently visible. */
- private boolean videoControlsShowing = true;
- private boolean videoSurfaceCreated = false;
- private VideoControlsHider videoControlsToggler;
-
- private LinearLayout videoOverlay;
- private VideoView videoview;
- private ProgressBar progressIndicator;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
- setTheme(UserPreferences.getTheme());
-
- super.onCreate(savedInstanceState);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- if (videoControlsToggler != null) {
- videoControlsToggler.cancel(true);
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- if (getIntent().getAction() != null
- && getIntent().getAction().equals(Intent.ACTION_VIEW)) {
- Intent intent = getIntent();
- if (AppConfig.DEBUG)
- Log.d(TAG, "Received VIEW intent: "
- + intent.getData().getPath());
- ExternalMedia media = new ExternalMedia(intent.getData().getPath(),
- MediaType.VIDEO);
- Intent launchIntent = new Intent(this, PlaybackService.class);
- launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
- launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
- true);
- launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
- launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
- true);
- startService(launchIntent);
- }
- }
-
- @Override
- protected void loadMediaInfo() {
- super.loadMediaInfo();
- Playable media = controller.getMedia();
- if (media != null) {
- getSupportActionBar().setSubtitle(media.getEpisodeTitle());
- getSupportActionBar().setTitle(media.getFeedTitle());
- }
- }
-
- @Override
- protected void setupGUI() {
- super.setupGUI();
- videoOverlay = (LinearLayout) findViewById(R.id.overlay);
- videoview = (VideoView) findViewById(R.id.videoview);
- progressIndicator = (ProgressBar) findViewById(R.id.progressIndicator);
- videoview.getHolder().addCallback(this);
- videoview.setOnTouchListener(onVideoviewTouched);
-
- setupVideoControlsToggler();
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
-
- @Override
- protected void onAwaitingVideoSurface() {
- if (videoSurfaceCreated) {
- if (AppConfig.DEBUG)
- Log.d(TAG,
- "Videosurface already created, setting videosurface now");
- controller.setVideoSurface(videoview.getHolder());
- }
- }
-
- @Override
- protected void postStatusMsg(int resId) {
- if (resId == R.string.player_preparing_msg) {
- progressIndicator.setVisibility(View.VISIBLE);
- } else {
- progressIndicator.setVisibility(View.INVISIBLE);
- }
-
- }
-
- @Override
- protected void clearStatusMsg() {
- progressIndicator.setVisibility(View.INVISIBLE);
- }
-
- View.OnTouchListener onVideoviewTouched = new View.OnTouchListener() {
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- if (videoControlsToggler != null) {
- videoControlsToggler.cancel(true);
- }
- toggleVideoControlsVisibility();
- if (videoControlsShowing) {
- setupVideoControlsToggler();
- }
-
- return true;
- } else {
- return false;
- }
- }
- };
-
- @SuppressLint("NewApi")
- void setupVideoControlsToggler() {
- if (videoControlsToggler != null) {
- videoControlsToggler.cancel(true);
- }
- videoControlsToggler = new VideoControlsHider();
- if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
- videoControlsToggler
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } else {
- videoControlsToggler.execute();
- }
- }
-
- private void toggleVideoControlsVisibility() {
- if (videoControlsShowing) {
- getSupportActionBar().hide();
- hideVideoControls();
- } else {
- getSupportActionBar().show();
- showVideoControls();
- }
- videoControlsShowing = !videoControlsShowing;
- }
-
- /** Hides the videocontrols after a certain period of time. */
- public class VideoControlsHider extends AsyncTask<Void, Void, Void> {
- @Override
- protected void onCancelled() {
- videoControlsToggler = null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- videoControlsToggler = null;
- }
-
- private static final int WAITING_INTERVALL = 5000;
- private static final String TAG = "VideoControlsToggler";
-
- @Override
- protected void onProgressUpdate(Void... values) {
- if (videoControlsShowing) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Hiding video controls");
- getSupportActionBar().hide();
- hideVideoControls();
- videoControlsShowing = false;
- }
- }
-
- @Override
- protected Void doInBackground(Void... params) {
- try {
- Thread.sleep(WAITING_INTERVALL);
- } catch (InterruptedException e) {
- return null;
- }
- publishProgress();
- return null;
- }
-
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- holder.setFixedSize(width, height);
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Videoview holder created");
- videoSurfaceCreated = true;
- if (controller.getStatus() == PlayerStatus.AWAITING_VIDEO_SURFACE) {
- if (controller.serviceAvailable()) {
- controller.setVideoSurface(holder);
- } else {
- Log.e(TAG,
- "Could'nt attach surface to mediaplayer - reference to service was null");
- }
- }
-
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Videosurface was destroyed");
- videoSurfaceCreated = false;
- controller.notifyVideoSurfaceAbandoned();
- }
-
- @Override
- protected void onReloadNotification(int notificationCode) {
- if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) {
- if (AppConfig.DEBUG)
- Log.d(TAG,
- "ReloadNotification received, switching to Audioplayer now");
- startActivity(new Intent(this, AudioplayerActivity.class));
- }
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- super.onStartTrackingTouch(seekBar);
- if (videoControlsToggler != null) {
- videoControlsToggler.cancel(true);
- }
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- super.onStopTrackingTouch(seekBar);
- setupVideoControlsToggler();
- }
-
- @Override
- protected void onBufferStart() {
- progressIndicator.setVisibility(View.VISIBLE);
- }
-
- @Override
- protected void onBufferEnd() {
- progressIndicator.setVisibility(View.INVISIBLE);
- }
-
- private void showVideoControls() {
- videoOverlay.setVisibility(View.VISIBLE);
- videoOverlay.startAnimation(AnimationUtils.loadAnimation(this,
- R.anim.fade_in));
- }
-
- private void hideVideoControls() {
- videoOverlay.startAnimation(AnimationUtils.loadAnimation(this,
- R.anim.fade_out));
- videoOverlay.setVisibility(View.GONE);
- }
-
- @Override
- protected int getContentViewResourceId() {
- return R.layout.videoplayer_activity;
- }
+/**
+ * Activity for playing audio files.
+ */
+public class VideoplayerActivity extends MediaplayerActivity {
+ private static final String TAG = "VideoplayerActivity";
+
+ /**
+ * True if video controls are currently visible.
+ */
+ private boolean videoControlsShowing = true;
+ private boolean videoSurfaceCreated = false;
+ private VideoControlsHider videoControlsToggler;
+
+ private LinearLayout videoOverlay;
+ private VideoView videoview;
+ private ProgressBar progressIndicator;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
+ setTheme(UserPreferences.getTheme());
+
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (videoControlsToggler != null) {
+ videoControlsToggler.cancel(true);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (getIntent().getAction() != null
+ && getIntent().getAction().equals(Intent.ACTION_VIEW)) {
+ Intent intent = getIntent();
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Received VIEW intent: "
+ + intent.getData().getPath());
+ ExternalMedia media = new ExternalMedia(intent.getData().getPath(),
+ MediaType.VIDEO);
+ Intent launchIntent = new Intent(this, PlaybackService.class);
+ launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media);
+ launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED,
+ true);
+ launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, false);
+ launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY,
+ true);
+ startService(launchIntent);
+ }
+ }
+
+ @Override
+ protected boolean loadMediaInfo() {
+ if (!super.loadMediaInfo()) {
+ return false;
+ }
+ Playable media = controller.getMedia();
+ if (media != null) {
+ getSupportActionBar().setSubtitle(media.getEpisodeTitle());
+ getSupportActionBar().setTitle(media.getFeedTitle());
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void setupGUI() {
+ super.setupGUI();
+ videoOverlay = (LinearLayout) findViewById(R.id.overlay);
+ videoview = (VideoView) findViewById(R.id.videoview);
+ progressIndicator = (ProgressBar) findViewById(R.id.progressIndicator);
+ videoview.getHolder().addCallback(surfaceHolderCallback);
+ videoview.setOnTouchListener(onVideoviewTouched);
+
+ setupVideoControlsToggler();
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ }
+
+ @Override
+ protected void onAwaitingVideoSurface() {
+ if (videoSurfaceCreated) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "Videosurface already created, setting videosurface now");
+ controller.setVideoSurface(videoview.getHolder());
+ }
+ }
+
+ @Override
+ protected void postStatusMsg(int resId) {
+ if (resId == R.string.player_preparing_msg) {
+ progressIndicator.setVisibility(View.VISIBLE);
+ } else {
+ progressIndicator.setVisibility(View.INVISIBLE);
+ }
+
+ }
+
+ @Override
+ protected void clearStatusMsg() {
+ progressIndicator.setVisibility(View.INVISIBLE);
+ }
+
+ View.OnTouchListener onVideoviewTouched = new View.OnTouchListener() {
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (videoControlsToggler != null) {
+ videoControlsToggler.cancel(true);
+ }
+ toggleVideoControlsVisibility();
+ if (videoControlsShowing) {
+ setupVideoControlsToggler();
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+
+ @SuppressLint("NewApi")
+ void setupVideoControlsToggler() {
+ if (videoControlsToggler != null) {
+ videoControlsToggler.cancel(true);
+ }
+ videoControlsToggler = new VideoControlsHider();
+ if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
+ videoControlsToggler
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ } else {
+ videoControlsToggler.execute();
+ }
+ }
+
+ private void toggleVideoControlsVisibility() {
+ if (videoControlsShowing) {
+ getSupportActionBar().hide();
+ hideVideoControls();
+ } else {
+ getSupportActionBar().show();
+ showVideoControls();
+ }
+ videoControlsShowing = !videoControlsShowing;
+ }
+
+ /**
+ * Hides the videocontrols after a certain period of time.
+ */
+ public class VideoControlsHider extends AsyncTask<Void, Void, Void> {
+ @Override
+ protected void onCancelled() {
+ videoControlsToggler = null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ videoControlsToggler = null;
+ }
+
+ private static final int WAITING_INTERVALL = 5000;
+ private static final String TAG = "VideoControlsToggler";
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ if (videoControlsShowing) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Hiding video controls");
+ getSupportActionBar().hide();
+ hideVideoControls();
+ videoControlsShowing = false;
+ }
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+ Thread.sleep(WAITING_INTERVALL);
+ } catch (InterruptedException e) {
+ return null;
+ }
+ publishProgress();
+ return null;
+ }
+
+ }
+
+ private final SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width,
+ int height) {
+ holder.setFixedSize(width, height);
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Videoview holder created");
+ videoSurfaceCreated = true;
+ if (controller.getStatus() == PlayerStatus.PLAYING) {
+ if (controller.serviceAvailable()) {
+ controller.setVideoSurface(holder);
+ } else {
+ Log.e(TAG,
+ "Could'nt attach surface to mediaplayer - reference to service was null");
+ }
+ }
+
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Videosurface was destroyed");
+ videoSurfaceCreated = false;
+ controller.notifyVideoSurfaceAbandoned();
+ }
+ };
+
+
+ @Override
+ protected void onReloadNotification(int notificationCode) {
+ if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG,
+ "ReloadNotification received, switching to Audioplayer now");
+ startActivity(new Intent(this, AudioplayerActivity.class));
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ super.onStartTrackingTouch(seekBar);
+ if (videoControlsToggler != null) {
+ videoControlsToggler.cancel(true);
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ super.onStopTrackingTouch(seekBar);
+ setupVideoControlsToggler();
+ }
+
+ @Override
+ protected void onBufferStart() {
+ progressIndicator.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ protected void onBufferEnd() {
+ progressIndicator.setVisibility(View.INVISIBLE);
+ }
+
+ private void showVideoControls() {
+ videoOverlay.setVisibility(View.VISIBLE);
+ videoOverlay.startAnimation(AnimationUtils.loadAnimation(this,
+ R.anim.fade_in));
+ }
+
+ private void hideVideoControls() {
+ videoOverlay.startAnimation(AnimationUtils.loadAnimation(this,
+ R.anim.fade_out));
+ videoOverlay.setVisibility(View.GONE);
+ }
+
+ @Override
+ protected int getContentViewResourceId() {
+ return R.layout.videoplayer_activity;
+ }
}
diff --git a/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
index 7589726bf..56e6ee4b8 100644
--- a/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
+++ b/src/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java
@@ -137,10 +137,12 @@ public class ExternalPlayerFragment extends Fragment {
}
@Override
- public void loadMediaInfo() {
+ public boolean loadMediaInfo() {
ExternalPlayerFragment fragment = ExternalPlayerFragment.this;
if (fragment != null) {
- fragment.loadMediaInfo();
+ return fragment.loadMediaInfo();
+ } else {
+ return false;
}
}
@@ -209,7 +211,7 @@ public class ExternalPlayerFragment extends Fragment {
}
}
- private void loadMediaInfo() {
+ private boolean loadMediaInfo() {
if (AppConfig.DEBUG)
Log.d(TAG, "Loading media info");
if (controller.serviceAvailable()) {
@@ -230,13 +232,16 @@ public class ExternalPlayerFragment extends Fragment {
} else {
butPlay.setVisibility(View.VISIBLE);
}
+ return true;
} else {
Log.w(TAG,
"loadMediaInfo was called while the media object of playbackService was null!");
+ return false;
}
} else {
Log.w(TAG,
"loadMediaInfo was called while playbackService was null!");
+ return false;
}
}
diff --git a/src/de/danoeh/antennapod/service/playback/PlaybackService.java b/src/de/danoeh/antennapod/service/playback/PlaybackService.java
index 74e1c0c56..9ab1d1291 100644
--- a/src/de/danoeh/antennapod/service/playback/PlaybackService.java
+++ b/src/de/danoeh/antennapod/service/playback/PlaybackService.java
@@ -14,6 +14,7 @@ import android.media.RemoteControlClient;
import android.media.RemoteControlClient.MetadataEditor;
import android.os.AsyncTask;
import android.os.Binder;
+import android.os.Build;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
@@ -133,8 +134,6 @@ public class PlaybackService extends Service {
private final IBinder mBinder = new LocalBinder();
- private volatile List<FeedItem> queue;
-
public class LocalBinder extends Binder {
public PlaybackService getService() {
return PlaybackService.this;
@@ -322,6 +321,7 @@ public class PlaybackService extends Service {
}
public void notifyVideoSurfaceAbandoned() {
+ stopForeground(true);
mediaPlayer.resetVideoSurface();
}
@@ -352,6 +352,7 @@ public class PlaybackService extends Service {
private final PlaybackServiceMediaPlayer.PSMPCallback mediaPlayerCallback = new PlaybackServiceMediaPlayer.PSMPCallback() {
@Override
public void statusChanged(PlaybackServiceMediaPlayer.PSMPInfo newInfo) {
+ currentMediaType = mediaPlayer.getCurrentMediaType();
switch (newInfo.playerStatus) {
case PREPARED:
taskManager.startChapterLoader(newInfo.playable);
@@ -365,8 +366,8 @@ public class PlaybackService extends Service {
break;
case STOPPED:
- setCurrentlyPlayingMedia(PlaybackPreferences.NO_MEDIA_PLAYING);
- stopSelf();
+ //setCurrentlyPlayingMedia(PlaybackPreferences.NO_MEDIA_PLAYING);
+ //stopSelf();
break;
case PLAYING:
@@ -375,7 +376,6 @@ public class PlaybackService extends Service {
if (AppConfig.DEBUG)
Log.d(TAG, "Resuming/Starting playback");
- currentMediaType = mediaPlayer.getCurrentMediaType();
writePlaybackPreferences();
taskManager.startPositionSaver();
taskManager.startWidgetUpdater();
@@ -463,16 +463,19 @@ public class PlaybackService extends Service {
if (media instanceof FeedMedia) {
FeedItem item = ((FeedMedia) media).getItem();
DBWriter.markItemRead(PlaybackService.this, item, true, true);
- nextItem = DBTasks.getQueueSuccessorOfItem(this, item.getId(), queue);
- isInQueue = QueueAccess.ItemListAccess(queue).contains(((FeedMedia) media).getItem().getId());
+
+ try {
+ final List<FeedItem> queue = taskManager.getQueue();
+ isInQueue = QueueAccess.ItemListAccess(queue).contains(((FeedMedia) media).getItem().getId());
+ nextItem = DBTasks.getQueueSuccessorOfItem(this, item.getId(), queue);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ // isInQueue remains false
+ }
if (isInQueue) {
DBWriter.removeQueueItem(PlaybackService.this, item.getId(), true);
}
DBWriter.addItemToPlaybackHistory(PlaybackService.this, (FeedMedia) media);
- long autoDeleteMediaId = ((FeedComponent) media).getId();
- if (mediaPlayer.isStreaming()) {
- autoDeleteMediaId = -1;
- }
}
// Load next episode if previous episode was in the queue and if there
@@ -514,7 +517,7 @@ public class PlaybackService extends Service {
notificationCode);
} else {
sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_END, 0);
- stopSelf();
+ //stopSelf();
}
}
@@ -713,8 +716,6 @@ public class PlaybackService extends Service {
}
private void updateWidget() {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Sending widget update request");
PlaybackService.this.sendBroadcast(new Intent(
PlayerWidget.FORCE_WIDGET_UPDATE));
}
@@ -729,6 +730,10 @@ public class PlaybackService extends Service {
@SuppressLint("NewApi")
private RemoteControlClient setupRemoteControlClient() {
+ if (Build.VERSION.SDK_INT < 14) {
+ return null;
+ }
+
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(new ComponentName(getPackageName(),
MediaButtonReceiver.class.getName()));
@@ -806,6 +811,7 @@ public class PlaybackService extends Service {
i.putExtra("album", info.playable.getFeedTitle());
i.putExtra("track", info.playable.getEpisodeTitle());
i.putExtra("playing", isPlaying);
+ final List<FeedItem> queue = taskManager.getQueueIfLoaded();
if (queue != null) {
i.putExtra("ListSize", queue.size());
}
@@ -896,6 +902,10 @@ public class PlaybackService extends Service {
mediaPlayer.resume();
}
+ public void prepare() {
+ mediaPlayer.prepare();
+ }
+
public void pause(boolean abandonAudioFocus, boolean reinit) {
mediaPlayer.pause(abandonAudioFocus, reinit);
}
@@ -904,6 +914,10 @@ public class PlaybackService extends Service {
mediaPlayer.reinit();
}
+ public PlaybackServiceMediaPlayer.PSMPInfo getPSMPInfo() {
+ return mediaPlayer.getPSMPInfo();
+ }
+
public PlayerStatus getStatus() {
return mediaPlayer.getPSMPInfo().playerStatus;
}
diff --git a/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java b/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java
index f2440728f..1c92bd6e6 100644
--- a/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java
+++ b/src/de/danoeh/antennapod/service/playback/PlaybackServiceMediaPlayer.java
@@ -144,15 +144,16 @@ public class PlaybackServiceMediaPlayer {
return;
} else {
// stop playback of this episode
- setPlayerStatus(PlayerStatus.STOPPED, null);
if (playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PLAYING || playerStatus == PlayerStatus.PREPARED) {
mediaPlayer.stop();
}
+ setPlayerStatus(PlayerStatus.INDETERMINATE, null);
}
}
createMediaPlayer();
this.media = playable;
this.stream = stream;
+ this.mediaType = media.getMediaType();
PlaybackServiceMediaPlayer.this.startWhenPrepared.set(startWhenPrepared);
setPlayerStatus(PlayerStatus.INITIALIZING, media);
try {
@@ -372,8 +373,8 @@ public class PlaybackServiceMediaPlayer {
|| playerStatus == PlayerStatus.PAUSED
|| playerStatus == PlayerStatus.PREPARED) {
if (stream) {
- statusBeforeSeeking = playerStatus;
- setPlayerStatus(PlayerStatus.SEEKING, media);
+ // statusBeforeSeeking = playerStatus;
+ // setPlayerStatus(PlayerStatus.SEEKING, media);
}
mediaPlayer.seekTo(t);
@@ -505,9 +506,8 @@ public class PlaybackServiceMediaPlayer {
private void setSpeedSync(float speed) {
playerLock.lock();
if (media != null && media.getMediaType() == MediaType.AUDIO) {
- AudioPlayer audioPlayer = (AudioPlayer) mediaPlayer;
- if (audioPlayer.canSetSpeed()) {
- audioPlayer.setPlaybackSpeed((float) speed);
+ if (mediaPlayer.canSetSpeed()) {
+ mediaPlayer.setPlaybackSpeed((float) speed);
if (AppConfig.DEBUG)
Log.d(TAG, "Playback speed was set to " + speed);
callback.playbackSpeedChanged(speed);
diff --git a/src/de/danoeh/antennapod/service/playback/PlaybackServiceTaskManager.java b/src/de/danoeh/antennapod/service/playback/PlaybackServiceTaskManager.java
index a74ab0527..4060ab041 100644
--- a/src/de/danoeh/antennapod/service/playback/PlaybackServiceTaskManager.java
+++ b/src/de/danoeh/antennapod/service/playback/PlaybackServiceTaskManager.java
@@ -103,6 +103,23 @@ public class PlaybackServiceTaskManager {
}
/**
+ * Returns the queue if it is already loaded or null if it hasn't been loaded yet.
+ * In order to wait until the queue has been loaded, use getQueue()
+ */
+ public synchronized List<FeedItem> getQueueIfLoaded() {
+ if (queueFuture.isDone()) {
+ try {
+ return queueFuture.get();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns the queue or waits until the PSTM has loaded the queue from the database.
*/
public synchronized List<FeedItem> getQueue() throws InterruptedException {
diff --git a/src/de/danoeh/antennapod/service/playback/PlayerStatus.java b/src/de/danoeh/antennapod/service/playback/PlayerStatus.java
index fc0217081..3d2b4ad39 100644
--- a/src/de/danoeh/antennapod/service/playback/PlayerStatus.java
+++ b/src/de/danoeh/antennapod/service/playback/PlayerStatus.java
@@ -1,14 +1,14 @@
package de.danoeh.antennapod.service.playback;
public enum PlayerStatus {
+ INDETERMINATE, // player is currently changing its state, listeners should wait until the player has left this state.
ERROR,
PREPARING,
PAUSED,
PLAYING,
STOPPED,
PREPARED,
- SEEKING,
- AWAITING_VIDEO_SURFACE, // player has been initialized and the media type to be played is a video.
+ SEEKING,
INITIALIZING, // playback service is loading the Playable's metadata
INITIALIZED // playback service was started, data source of media player was set.
}
diff --git a/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java b/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java
index 494d58202..f4674d395 100644
--- a/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java
+++ b/src/de/danoeh/antennapod/service/playback/PlayerWidgetService.java
@@ -72,9 +72,11 @@ public class PlayerWidgetService extends Service {
}
private void updateViews() {
+ if (playbackService == null) {
+ return;
+ }
isUpdating = true;
- if (AppConfig.DEBUG)
- Log.d(TAG, "Updating widget views");
+
ComponentName playerWidget = new ComponentName(this, PlayerWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
RemoteViews views = new RemoteViews(getPackageName(),
@@ -101,8 +103,6 @@ public class PlayerWidgetService extends Service {
views.setOnClickPendingIntent(R.id.butPlay,
createMediaButtonIntent());
} else {
- if (AppConfig.DEBUG)
- Log.d(TAG, "No media playing. Displaying defaultt views");
views.setViewVisibility(R.id.txtvProgress, View.INVISIBLE);
views.setTextViewText(R.id.txtvTitle,
this.getString(R.string.no_media_playing_label));
diff --git a/src/de/danoeh/antennapod/util/playback/PlaybackController.java b/src/de/danoeh/antennapod/util/playback/PlaybackController.java
index 38f897262..07597c422 100644
--- a/src/de/danoeh/antennapod/util/playback/PlaybackController.java
+++ b/src/de/danoeh/antennapod/util/playback/PlaybackController.java
@@ -33,6 +33,7 @@ import de.danoeh.antennapod.feed.FeedMedia;
import de.danoeh.antennapod.feed.MediaType;
import de.danoeh.antennapod.preferences.PlaybackPreferences;
import de.danoeh.antennapod.service.playback.PlaybackService;
+import de.danoeh.antennapod.service.playback.PlaybackServiceMediaPlayer;
import de.danoeh.antennapod.service.playback.PlayerStatus;
import de.danoeh.antennapod.storage.DBTasks;
import de.danoeh.antennapod.util.Converter;
@@ -48,7 +49,7 @@ public abstract class PlaybackController {
public static final int DEFAULT_SEEK_DELTA = 30000;
public static final int INVALID_TIME = -1;
- private Activity activity;
+ private final Activity activity;
private PlaybackService playbackService;
private Playable media;
@@ -70,6 +71,8 @@ public abstract class PlaybackController {
private boolean reinitOnPause;
public PlaybackController(Activity activity, boolean reinitOnPause) {
+ if (activity == null)
+ throw new IllegalArgumentException("activity = null");
this.activity = activity;
this.reinitOnPause = reinitOnPause;
schedExecutor = new ScheduledThreadPoolExecutor(SCHED_EX_POOLSIZE,
@@ -298,7 +301,9 @@ public abstract class PlaybackController {
if (AppConfig.DEBUG)
Log.d(TAG, "Received statusUpdate Intent.");
if (isConnectedToPlaybackService()) {
- status = playbackService.getStatus();
+ PlaybackServiceMediaPlayer.PSMPInfo info = playbackService.getPSMPInfo();
+ status = info.playerStatus;
+ media = info.playable;
handleStatus();
} else {
Log.w(TAG,
@@ -422,6 +427,9 @@ public abstract class PlaybackController {
case PLAYING:
clearStatusMsg();
checkMediaInfoLoaded();
+ if (PlaybackService.getCurrentMediaType() == MediaType.VIDEO) {
+ onAwaitingVideoSurface();
+ }
setupPositionObserver();
updatePlayButtonAppearance(pauseResource);
break;
@@ -447,9 +455,6 @@ public abstract class PlaybackController {
case SEEKING:
postStatusMsg(R.string.player_seeking_msg);
break;
- case AWAITING_VIDEO_SURFACE:
- onAwaitingVideoSurface();
- break;
case INITIALIZED:
checkMediaInfoLoaded();
clearStatusMsg();
@@ -459,10 +464,7 @@ public abstract class PlaybackController {
}
private void checkMediaInfoLoaded() {
- if (!mediaInfoLoaded) {
- loadMediaInfo();
- }
- mediaInfoLoaded = true;
+ mediaInfoLoaded = (mediaInfoLoaded || loadMediaInfo());
}
private void updatePlayButtonAppearance(int resource) {
@@ -476,7 +478,7 @@ public abstract class PlaybackController {
public abstract void clearStatusMsg();
- public abstract void loadMediaInfo();
+ public abstract boolean loadMediaInfo();
public abstract void onAwaitingVideoSurface();
@@ -490,6 +492,7 @@ public abstract class PlaybackController {
if (playbackService != null) {
status = playbackService.getStatus();
media = playbackService.getPlayable();
+ /*
if (media == null) {
Log.w(TAG,
"PlaybackService has no media object. Trying to restore last played media.");
@@ -498,6 +501,7 @@ public abstract class PlaybackController {
activity.startService(serviceIntent);
}
}
+ */
onServiceQueried();
setupGUI();
@@ -570,7 +574,7 @@ public abstract class PlaybackController {
break;
case INITIALIZED:
playbackService.setStartWhenPrepared(true);
- playbackService.resume();
+ playbackService.prepare();
break;
}
} else {