isPlaying()的Android MediaPlayer状态不匹配错误的方法?

T.D*_*ith 7 java android

I'm trying to figure out how to address the Android MediaPlayer's "state mismatch" error which is occasionally thrown during audio playback when I try to pause.

As discussed in this question, there is a known issue with the Android MediaPlayer occasionally throwing an error on a call to isPlaying()

The result is a call to pause() or isPlaying() causes the MediaPlayer to stop responding to requests until it is reset.

Here's a log from when this error occurs:

I/MusicPlaybackService? I got a pause message
E/MediaPlayer[Native]? internal/external state mismatch corrected
Run Code Online (Sandbox Code Playgroud)

Here's a github bug with more details related to this issue.

My current solution is incredibly ugly:

/**
 * Pause the currently playing song.
 */
private synchronized void pause() {
    try{
        // this is a hack, but it seems to be the most consistent way to address the problem
        // this forces the media player to check its current state before trying to pause.
        int position = mp.getCurrentPosition();
        mp.seekTo(position);
        mp.start();
        mp.pause();
    } catch (Exception e){
        Log.w(TAG, "Caught exception while trying to pause ", e);
    }
    updateNotification();
}
Run Code Online (Sandbox Code Playgroud)

我的理论是MediaPlayer失去了对自己状态的跟踪,start()并且seekTo()在暂停之前调用将迫使MediaPlayer重置其自身状态的概念.

这个解决方案很糟糕,似乎引起了其他问题.

Google似乎已将此行为的未解决问题标记为已废弃.

我正在运行Android 5.0.1的LG G3上测试这个.

因此我的问题是:我该怎么做?有没有更好的方法来强制MediaPlayer在暂停之前检查自己的状态?

T.D*_*ith 2

这是我能想到的最好的解决方案。它似乎解决了暂停问题,并且没有引起任何意想不到的副作用:

private synchronized void pause() {
    // Sometimes the call to isPlaying can throw an error "internal/external state mismatch corrected"
    // When this happens, I think the player moves itself to "paused" even though it's still playing.
    try{
        // this is a hack, but it seems to be the most consistent way to address the problem
        int position = mp.getCurrentPosition();
        mp.stop();
        mp.prepare();
        mp.seekTo(position);
    } catch (Exception e){
        Log.w(TAG, "Caught exception while trying to pause ", e);
    }
}
Run Code Online (Sandbox Code Playgroud)

该解决方案强制重置状态机,而无需重置整个媒体播放器,也无需调用play.

带注释的状态机供参考:

在此输入图像描述