После долгих поисков и поиска по голове диаграммы состояний из MediaPlayer
мне наконец удалось избежать этого так называемого черного экрана. Я уже писал в разделе комментариев OP, что эта проблема, кажется, решена с последними версиями Android (более 4.x), и поэтому я решил, что аналогичное поведение на устройствах Gingerbread.
Само собой разумеется, SurfaceHolder
методы обратного вызова играют очень важную роль в жизненном цикле ограниченной реализации MediaPlayer
- SurfaceView
. И эти методы обратного вызова пригодились мне для выхода из этой ситуации.
First:
inside onCreate (): - Базовые элементы инициализации ..
mVideoSurface = (SurfaceView) findViewById(R.id.videoSurface);
videoHolder = mVideoSurface.getHolder();
videoHolder.addCallback(this);
// For Android 2.2
videoHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Media Player and Controller
player = new MediaPlayer();
controller = new VideoControllerView(this);
Тогда,
Обратные вызовы SurfaceView:
не забудьте установить Display
на MediaPlayer
, и ИМХО, surfaceCreated()
- лучшее место для этого.
@Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
try {
player.prepareAsync();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
А вот и самая важная вещь. Когда пользователь покидает текущее действие, нажав кнопку «Домой» или открыв другое действие, ожидая каких-либо результатов, наш SurfaceView
будет уничтожен. Я хотел добиться возобновления воспроизведения текущего видео с той позиции, где оно воспроизводилось, когда контекст переключался.
Итак, для этого
Сохраните текущую позицию воспроизведения в переменной, чтобы мы могли использовать ее позже для поиска нашего воспроизведения в этой конкретной позиции.
И еще один. Отпустите проклятый экземпляр MediaPlayer
. Я пытался избежать выпуска экземпляра MediaPlayer
и его воссоздания, но я продолжаю терпеть неудачу снова и снова. Итак ... точка сделана.
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (player != null) {
mCurrentVideoPosition = player.getCurrentPosition();
player.release();
player = null;
}
}
Теперь onPrepared ()
Инициализируйте любой MediaController
здесь, если вы заинтересованы. Проверьте, воспроизводилось ли уже видео, и найдите его в этой позиции.
@Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer(this);
controller.setAnchorView((FrameLayout) findViewById(R.id.videoSurfaceContainer));
player.start();
if (mCurrentVideoPosition != 0) {
player.seekTo(mCurrentVideoPosition);
player.start();
}
}
Наконец, для воспроизведения видео:
void playVideo(){
try {
if (player == null)
player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource("SOME_VIDEO_FILE.3gp");
player.setOnPreparedListener(this);
player.setOnErrorListener(new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
});
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
И это все. Я знаю, что проблема не в новых версиях и все отлично, но ... много ГБ все еще там.