问题
We are trying to use a VideoView to play a video in an Android Activiy.
I've read the MediaPlayer documentation and studied its state diagram.
We get a Media Player error if we call this method:
MediaPlayer.setLooping()
from this listener method:
MediaPlayer.OnPreparedListener.onPrepared()
The error message from LogCat:
error (-38, 0)
Note:
We have tested on two physical devices and this only happens on our Motorola Xoom.
If I comment out this line: mp.setLooping(false);
everything works fine on the Xoom.
(see code below)
According to the documentation, setLooping()
can be called from the following Media Player states:
- Idle
- Initialized
- Stopped
- Prepared
- Started
- Paused
- PlaybackCompleted
Although the documentation also includes this seemingly contradictory statement:
It is a programming error to invoke methods such as getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare() or prepareAsync() in the Idle state...
Question 1:
Why can't we call setLooping()
from onPrepared()
?
Question 2:
Shouldn't the VideoView be handling the preparation of the underlying MediaPlayer?
Question 3:
Shouldn't the MediaPlayer be in its prepared state when onPrepared()
is invoked?
Question 4:
How do I resolve the statements in the documentation that seem to contradict each other?
What really confuses me:
The quote above says none of these methods should be called when the MediaPlayer is in its idle state:
- getCurrentPosition()
- getDuration()
- getVideoHeight()
- getVideoWidth()
- setAudioStreamType(int)
- setLooping(boolean)
- setVolume(float
- float)
- pause()
- start()
- stop()
- seekTo(int)
- prepare()
- prepareAsync()
This statement (along with our error message) makes me think our error occurs because the MediaPlayer has not been successfully prepared.
But, for some reason there is no problem calling setAudioStreamType()
.
Question 5:
Why is there a problem with setLooping()
but not with setAudioStreamType()
?
Both methods are in the list of forbidden methods above.
(That said, I would've thought both are valid in the onPrepared()
method...)
What am I missing?
Is there a bug with the Motorola Xoom?
I'd be happy to just get an answer to question 1, but I'm really perplexed by all of this.
I'll admit I'm pretty new to Android development...
Our Xoom is running Ice Cream Sandwich 4.0.4.
Here's some sample code:
class VideoActivity {
VideoView mVidView;
@Override
protected void onCreate(Bundle b) {
mVidView = new VideoView(this);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(mWidth, mHeight);
mVidView.setLayoutParams(params);
mVidView.setVideoURI(mUri);
mVidView.setZOrderOnTop(true);
mMediaController = new MediaController(this, true);
mMediaController.setAnchorView(null);
mVidView.setMediaController(mMediaController);
mVidView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
.
.
.
}
});
mVidView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
.
.
.
}
});
mVidView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mDialog.dismiss();
mMediaPlayer = mp;
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setLooping(false);
mp.setScreenOnWhilePlaying(true);
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
public void onSeekComplete(MediaPlayer mp) {
mp.start();
}
});
if (mTimecode > 0) {
mp.seekTo(mTimecode * ONE_SEC);
} else {
mp.start();
}
mMediaController.show(0);
}
});
LinearLayout ll = (LinearLayout) this.findViewById(R.id.parentpopup);
ll.addView(mVidView);
}
}
来源:https://stackoverflow.com/questions/17461025/why-does-mediaplayer-setlooping-cause-an-error-when-using-videoview