2015-08-23 2 views
7

Я пытаюсь выяснить, как обратиться к ошибке «State mismatch» для Android MediaPlayer, которая иногда возникает при воспроизведении звука при попытке сделать паузу.Подходит для ошибки несоответствия состояния MediaPlayer для Android на isPlaying()?

Как обсуждалось в this question, существует известная проблема с Android-медиаплеер иногда бросали ошибку на вызове isPlaying()

Результатом является вызов pause() или isPlaying() заставляет MediaPlayer, чтобы остановить не отвечать на запросы, пока он сбрасывается.

Вот лог с момента, когда происходит эта ошибка:

I/MusicPlaybackService﹕ I got a pause message 
E/MediaPlayer[Native]﹕ internal/external state mismatch corrected 

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

Мое текущее решение невероятно уродливый:

/** 
* 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(); 
} 

Моя теория состоит в том, что MediaPlayer теряет след своего государства, и называя start() и seekTo() перед паузой заставит MediaPlayer сбросить свою концепцию его собственное государство.

Это решение является взломанным и, как представляется, вызывает other issues.

Google, похоже, отметил, что open issue для этого поведения является устаревшим.

Я тестирую это на Android-головоломке LG G3 5.0.1.

Таким образом, мой вопрос: Что мне делать? Есть ли лучший способ заставить MediaPlayer проверить свое состояние до паузы?

+2

Проблема была помечена устаревшей сценарием, потому что первоначальный доклад был представлен Android 2.3. Комментарий к этому предполагает открытие нового. – Fildor

+2

Вы пытались вызвать mp.reset() сразу после создания экземпляра объекта? Это исправляет проблему для некоторых людей, не вызывая больше. Я не пробовал это сам так, да. –

+2

@ManPerson Я попробую это. Я не решался сделать сброс, потому что я не хочу перезапускать песню, когда происходит пауза. –

ответ

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

Это решение заставляет сброс состояния машины без перезагрузки всей медиа-плеер, и без вызова play.

Аннотированный state machine для справки:

enter image description here

Смежные вопросы