MediaPlayer 状态 4 错误

Error in state 4 of MediaPlayer

我正在尝试创建一个 MediaPlayer 应用程序。为了实现同样的功能,我创建了一个在 MediaPlayer 中播放 mp3 文件的服务。 打开 mp3 文件时出现 NullPointerException。

媒体播放器的实例化代码在onStartCommand()中,如下所示:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {        
    mediaPlayer = new MediaPlayer();
    return super.onStartCommand(intent, flags, startId);
}

服务内部实现的处理程序在MediaPlayer上设置数据源并准备播放歌曲,如下所示:

class MyHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case Constants.INT_PLAY_SONG:
                try {
                    mediaPlayer.reset();
                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    File file = new File(msg.getData().getString(Constants.STRING_BUNDLE_KEY_PLAY_SONG));
                    Uri uri = Uri.fromFile(file);
                    mediaPlayer.setDataSource(getApplicationContext(), uri);
                    mediaPlayer.prepareAsync();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            default:
                super.handleMessage(msg);
        }
    }
}

在上面的代码片段中,msg.getData().getString(Constants.STRING_BUNDLE_KEY_PLAY_SONG)代表mp3文件的路径。同样的例子: /storage/extSdCard/Songs/yaara re.mp3 这与我的 phone.

中的歌曲路径相同

mp3文件路径取自MediaStore.Audio.Media.DATA

在 Activity 中添加了向服务发送消息的代码。代码如下:

private void sendMessageToService(String stringPath) {
    Message message = Message.obtain(null, Constants.INT_PLAY_SONG, 0, 0);
    Bundle bundle = new Bundle();
    bundle.putString(Constants.STRING_BUNDLE_KEY_PLAY_SONG, stringPath);
    message.setData(bundle);
    try {
        messenger.send(message);
    } catch (RemoteException e) {
        System.out.println("exception while sending message in messenger");
    }
}

新堆栈跟踪

    02-07 23:29:50.019    1399-1399/com.varunk314.mymp3 V/MediaPlayer﹕ isPlaying: 0
    02-07 23:29:50.019    1399-1399/com.varunk314.mymp3 V/MediaPlayer﹕ reset
    02-07 23:29:50.029    1399-1399/com.varunk314.mymp3 V/MediaPlayer﹕ MediaPlayer::setAudioStreamType
    02-07 23:29:50.029    1399-1399/com.varunk314.mymp3 V/MediaPlayer﹕ setDataSource(55, 0, 576460752303423487)
    02-07 23:29:50.059    1399-1399/com.varunk314.mymp3 V/MediaPlayer﹕ setVideoSurfaceTexture
    02-07 23:29:50.059    1399-1399/com.varunk314.mymp3 V/MediaPlayer﹕ prepareAsync
    02-07 23:29:50.069    1399-1411/com.varunk314.mymp3 V/MediaPlayer﹕ message received msg=5, ext1=0, ext2=0
    02-07 23:29:50.069    1399-1411/com.varunk314.mymp3 V/MediaPlayer﹕ New video size 0 x 0
    02-07 23:29:50.069    1399-1411/com.varunk314.mymp3 V/MediaPlayer﹕ callback application
    02-07 23:29:50.069    1399-1411/com.varunk314.mymp3 V/MediaPlayer﹕ back from callback
    02-07 23:29:50.069    1399-1399/com.varunk314.mymp3 I/MediaPlayer﹕ Don't send intent. msg.arg1 = 0, msg.arg2 = 0
    02-07 23:29:50.069    1399-1412/com.varunk314.mymp3 V/MediaPlayer﹕ message received msg=1, ext1=0, ext2=0
    02-07 23:29:50.069    1399-1412/com.varunk314.mymp3 V/MediaPlayer﹕ prepared
    02-07 23:29:50.069    1399-1412/com.varunk314.mymp3 V/MediaPlayer﹕ callback application
    02-07 23:29:50.069    1399-1412/com.varunk314.mymp3 V/MediaPlayer﹕ back from callback

OnPreparedListener的实现也如下图:

@Override
public void onPrepared(MediaPlayer mp) {
    mediaPlayer.start();
}

谁能帮我找出代码中的实际问题。

两个选项:

  1. msg.getData()的值为NULL
  2. msg.getData().getString(Constants.STRING_BUNDLE_KEY_PLAY_SONG)的值为NULL

附加调试器或定义一些额外的检查以了解哪个是真正的原因(1 或 2)。

更新:您以错误的顺序传递了一些参数! 改变这个:

bundle.putString(stringPath, Constants.STRING_BUNDLE_KEY_PLAY_SONG);

对此:

bundle.putString(Constants.STRING_BUNDLE_KEY_PLAY_SONG, stringPath);

这引发了 java.io.File.fixSlashes 方法的错误,因为 Constants.STRING_BUNDLE_KEY_PLAY_SONG 不是文件名。

更新 2 您需要致电

mediaplayer.prepare()

而不是

prepareAsync()

如果想直接下一行播放。异步方法将在准备就绪时触发专用回调(这是将媒体播放器启动的正确位置)