Adapted remaining classes to new playback service model

This commit is contained in:
daniel oeh 2013-12-29 01:27:18 +01:00
parent e05a5c265b
commit b864927709
11 changed files with 776 additions and 716 deletions

View File

@ -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;
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";
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 Fragment[] detachedFragments;
private CoverFragment coverFragment;
private ItemDescriptionFragment descriptionFragment;
private ListFragment chapterFragment;
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 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 TextView txtvTitle;
private TextView txtvFeed;
private Button butPlaybackSpeed;
private ImageButton butNavLeft;
private ImageButton butNavRight;
private void resetFragmentView() {
FragmentTransaction fT = getSupportFragmentManager().beginTransaction();
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];
}
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 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];
}
@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();
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;
}
savedPosition = currentlyShownPosition;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@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 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 onPause() {
savePreferences();
resetFragmentView();
super.onPause();
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
restoreFromPreferences();
}
@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, "");
/**
* 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);
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;
}
}
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 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 onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
protected void onAwaitingVideoSurface() {
startActivity(new Intent(this, VideoplayerActivity.class));
}
@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 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);
}
@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() {
/**
* 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);
}
@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();
}
}
}
}
};
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() {
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(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
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);
@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() {
butNavLeft.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];
} else {
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));
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);
}
}
});
butPlaybackSpeed.setOnLongClickListener(new OnLongClickListener() {
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];
} else {
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));
}
}
});
butPlaybackSpeed.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
VariableSpeedDialog.showDialog(AudioplayerActivity.this);
return true;
}
});
}
}
@Override
protected void onPlaybackSpeedChange() {
super.onPlaybackSpeedChange();
updateButPlaybackSpeed();
}
@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());
}
}
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 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);
}
@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();
}
public void notifyMediaPositionChanged() {
if (chapterFragment != null) {
ArrayAdapter<SimpleChapter> adapter = (ArrayAdapter<SimpleChapter>) chapterFragment
.getListAdapter();
adapter.notifyDataSetChanged();
}
}
if (currentlyShownPosition == -1) {
if (!restoreFromPreferences()) {
switchToFragment(POS_COVER);
}
}
if (currentlyShownFragment instanceof AudioplayerContentFragment) {
((AudioplayerContentFragment) currentlyShownFragment)
.onDataSetChanged(media);
}
updateButPlaybackSpeed();
return true;
}
@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));
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();
}
@Override
protected void onBufferStart() {
postStatusMsg(R.string.player_buffering_msg);
}
public interface AudioplayerContentFragment {
public void onDataSetChanged(Playable media);
}
@Override
protected void onBufferEnd() {
clearStatusMsg();
}
@Override
protected int getContentViewResourceId() {
return R.layout.audioplayer_activity;
}
public interface AudioplayerContentFragment {
public void onDataSetChanged(Playable media);
}
@Override
protected int getContentViewResourceId() {
return R.layout.audioplayer_activity;
}
}

View File

@ -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() {

View File

@ -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";
/**
* 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;
/**
* 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;
private LinearLayout videoOverlay;
private VideoView videoview;
private ProgressBar progressIndicator;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setTheme(UserPreferences.getTheme());
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setTheme(UserPreferences.getTheme());
super.onCreate(savedInstanceState);
}
super.onCreate(savedInstanceState);
}
@Override
protected void onPause() {
super.onPause();
if (videoControlsToggler != null) {
videoControlsToggler.cancel(true);
}
}
@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 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 boolean loadMediaInfo() {
if (!super.loadMediaInfo()) {
return false;
}
Playable media = controller.getMedia();
if (media != null) {
getSupportActionBar().setSubtitle(media.getEpisodeTitle());
getSupportActionBar().setTitle(media.getFeedTitle());
return true;
}
@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);
return false;
}
setupVideoControlsToggler();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@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);
@Override
protected void onAwaitingVideoSurface() {
if (videoSurfaceCreated) {
if (AppConfig.DEBUG)
Log.d(TAG,
"Videosurface already created, setting videosurface now");
controller.setVideoSurface(videoview.getHolder());
}
}
setupVideoControlsToggler();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@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 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
protected void clearStatusMsg() {
progressIndicator.setVisibility(View.INVISIBLE);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (videoControlsToggler != null) {
videoControlsToggler.cancel(true);
}
toggleVideoControlsVisibility();
if (videoControlsShowing) {
setupVideoControlsToggler();
}
View.OnTouchListener onVideoviewTouched = new View.OnTouchListener() {
return true;
} else {
return false;
}
}
};
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (videoControlsToggler != null) {
videoControlsToggler.cancel(true);
}
toggleVideoControlsVisibility();
if (videoControlsShowing) {
setupVideoControlsToggler();
}
@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();
}
}
return true;
} else {
return false;
}
}
};
private void toggleVideoControlsVisibility() {
if (videoControlsShowing) {
getSupportActionBar().hide();
hideVideoControls();
} else {
getSupportActionBar().show();
showVideoControls();
}
videoControlsShowing = !videoControlsShowing;
}
@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();
}
}
/** Hides the videocontrols after a certain period of time. */
public class VideoControlsHider extends AsyncTask<Void, Void, Void> {
@Override
protected void onCancelled() {
videoControlsToggler = null;
}
private void toggleVideoControlsVisibility() {
if (videoControlsShowing) {
getSupportActionBar().hide();
hideVideoControls();
} else {
getSupportActionBar().show();
showVideoControls();
}
videoControlsShowing = !videoControlsShowing;
}
@Override
protected void onPostExecute(Void result) {
videoControlsToggler = null;
}
/**
* Hides the videocontrols after a certain period of time.
*/
public class VideoControlsHider extends AsyncTask<Void, Void, Void> {
@Override
protected void onCancelled() {
videoControlsToggler = null;
}
private static final int WAITING_INTERVALL = 5000;
private static final String TAG = "VideoControlsToggler";
@Override
protected void onPostExecute(Void result) {
videoControlsToggler = null;
}
@Override
protected void onProgressUpdate(Void... values) {
if (videoControlsShowing) {
if (AppConfig.DEBUG)
Log.d(TAG, "Hiding video controls");
getSupportActionBar().hide();
hideVideoControls();
videoControlsShowing = false;
}
}
private static final int WAITING_INTERVALL = 5000;
private static final String TAG = "VideoControlsToggler";
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(WAITING_INTERVALL);
} catch (InterruptedException e) {
return null;
}
publishProgress();
return null;
}
@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");
}
}
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 surfaceDestroyed(SurfaceHolder holder) {
if (AppConfig.DEBUG)
Log.d(TAG, "Videosurface was destroyed");
videoSurfaceCreated = false;
controller.notifyVideoSurfaceAbandoned();
}
};
@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 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
protected void onBufferStart() {
progressIndicator.setVisibility(View.VISIBLE);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
super.onStartTrackingTouch(seekBar);
if (videoControlsToggler != null) {
videoControlsToggler.cancel(true);
}
}
@Override
protected void onBufferEnd() {
progressIndicator.setVisibility(View.INVISIBLE);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
super.onStopTrackingTouch(seekBar);
setupVideoControlsToggler();
}
private void showVideoControls() {
videoOverlay.setVisibility(View.VISIBLE);
videoOverlay.startAnimation(AnimationUtils.loadAnimation(this,
R.anim.fade_in));
}
@Override
protected void onBufferStart() {
progressIndicator.setVisibility(View.VISIBLE);
}
private void hideVideoControls() {
videoOverlay.startAnimation(AnimationUtils.loadAnimation(this,
R.anim.fade_out));
videoOverlay.setVisibility(View.GONE);
}
@Override
protected void onBufferEnd() {
progressIndicator.setVisibility(View.INVISIBLE);
}
@Override
protected int getContentViewResourceId() {
return R.layout.videoplayer_activity;
}
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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -102,6 +102,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.
*/

View File

@ -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.
}

View File

@ -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));

View File

@ -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 {

View File

@ -82,7 +82,6 @@ public class PlaybackServiceMediaPlayerTest extends InstrumentationTestCase {
case INITIALIZED:
case INITIALIZING:
case SEEKING:
case AWAITING_VIDEO_SURFACE:
assertNotNull(info.playable);
break;
case STOPPED: