MediaPlayer.prepareAsync的IllegalStateException

时间:2011-05-19 15:57:59

标签: android android-mediaplayer

05-19 11:52:51.622: ERROR/MediaPlayer(1291): prepareAsync called in state 8
05-19 11:52:51.622: WARN/System.err(1291): java.lang.IllegalStateException
try {
    mp = MediaPlayer.create(
            Main.this,
            Uri.parse("http://codejanitor.us/good.mp3"));
    mp.setOnPreparedListener(new OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });
    try {
        mp.prepareAsync();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
} finally {
    if (mp != null) {
        mp.release();
        mp = null;
    }
}

交替

如果我这样做:

try {
    mp = MediaPlayer.create(
            AmazonClipActivity.this,
            Uri.parse("http://codejanitor.us/good.mp3"));
    mp.setOnPreparedListener(new OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });
} finally {
    if (mp != null) {
        mp.release();
        mp = null;
    }
}

我明白了:

05-19 12:22:57.472: DEBUG/MediaPlayer(1635): Couldn't open file on client side, trying server side
05-19 12:22:57.472: INFO/StagefrightPlayer(68): setDataSource('http://codejanitor.us/good.mp3')
05-19 12:22:57.482: INFO/NuHTTPDataSource(68): connect to codejanitor.us:80/good.mp3 @0
05-19 12:23:00.632: INFO/NuCachedSource2(68): ERROR_END_OF_STREAM

5 个答案:

答案 0 :(得分:87)

mp = MediaPlayer.create(...);已经准备好返回的MediaPlayer,因此您无法再次调用prepare(或其变体)(并且也不需要onPreparedListener)。

答案 1 :(得分:9)

“在状态8中调用的prepareAsync”表示Mediaplayer已经准备好了。

你在代码中调用了mp.prepare();吗?

答案 2 :(得分:8)

您更新的问题:

  1. 检查您的AndroidManifest.xml
  2. 是否拥有INTERNET权限
  3. 检查您是否启用了某些数据连接,因为您希望从互联网流式传输
  4. 你对“这个解决方案也失败了”是什么意思?它会抛出IllegalStateException吗?从我看到的,它根本不会做任何事情,因为你在MediaPlayer对象准备好之后注册你的OnPreparedListener,导致永远不会调用onPrepared()方法。
  5. 更好的方法是写:

    MediaPlayer mp = new MediaPlayer();  
    mp.setDataSource("http://.../movie.mp4");  
    mp.setOnPreparedListener(this);  
    mp.prepareAsync();
    

答案 3 :(得分:0)

我使用下面的代码来播放http。

的声音文件
BackgroundSound mBackgroundSound = new BackgroundSound();

public void onSoundRequested(final Uri uri) {
    mBackgroundSound = new BackgroundSound();
    mBackgroundSound.execute(new SoundModel(dicId, uri));
}

public class BackgroundSound extends AsyncTask<SoundModel, Void, Void> {
    MediaPlayer mediaPlayer;

    @Override
    protected Void doInBackground(SoundModel... params) {
        SoundModel model = params[0];
        final Uri uri = model.getUri();

        if (uri == null || uri == Uri.EMPTY) return null;
        if (mediaPlayer != null) mediaPlayer.stop();

        try {
            mediaPlayer = MediaPlayer.create(VocabularyActivity.this, uri);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        } catch (Exception e) {
            // do nothing.
        }
        if (mediaPlayer == null) return null;

        mediaPlayer.setVolume(1.0f, 1.0f);
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mediaPlayer.reset();
                mediaPlayer.release();
                mediaPlayer = null;
            }
        });
        mediaPlayer.start();
        return null;
    }
}

它显示warnimg W/MediaPlayer: Couldn't open https://something.com/test.mp3: java.io.FileNotFoundException: No content provider: https://something.com/test.mp3但工作正常。

答案 4 :(得分:0)

基本问题在于在“不允许的状态”下调用MediaPlayer的方法。状态图为shown here。例如,不允许在没有准备的情况下调用start()方法,并且会引发异常。

由于MediaPlayer不公开getState()方法,因此您应该从外部跟踪状态。示例实现可以为found here