1

I was trying to use SurfaceView and MediaPlayer to Display video on Android.

I got a bug now that if I press the power button to lock the screen and then unlock it, The Video displayed on the MediaPlayer is gone and there is only sound. Normally for this situation the surfaceView would be somehow freeze to the last frame of the video before I lock the phone.

It works fine when I hide the screen(such as go to home and open another application) But it just does not work when I lock the phone. I think they both pass the onPause and onResume so I do not understand why would there be different logic.

I'd like to know if there is a solution to solve my problem.

Thanks!

Tamaki Sakura
  • 482
  • 5
  • 22

2 Answers2

2

I'm not sure exactly what's going on, but there's a general class of problem that is likely the cause of your trouble.

If your lockscreen is orientation-independent, or wants to be oriented the same way the device is, then the Activity won't be restarted to change orientation. In this case, turning the display off and back on with the power button won't cause the SurfaceView's surface to be destroyed. So if your app is relying on the surfaceCreated and surfaceChanged callbacks to fire to make things happen, then things won't happen.

If you leave the Activity and come back, the Surface does get destroyed and re-created.

The relationship between the Activity lifecycle and the Surface lifecycle is a bit complicated; you can find some notes about it in this article, including two basic patterns for structuring an app. Examples of both "styles" of SurfaceView management can be found in Grafika.

I can't make specific recommendations without knowing how your app works, but mainly you just need to look at what your app does with the idea that Activity and Surface lifetimes are not tightly coupled.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Thanks for your response! The only thing I have under **surfaceChanged** and **surfaceCreated** is `mMediaPlayer.setDisplay(myHolder);` . I add it to other places that is not **surfaceCreated** and **surfaceChanged**. But The problem still persist. – Tamaki Sakura Jul 24 '14 at 20:34
  • I would guess that mMediaPlayer is being re-created when the Activity pauses/resumes, but `setDisplay()` is not being called because the Surface isn't re-created. You need to call `setDisplay()` again, which means you need to retain a handle to the SurfaceHolder you get from the `surfaceCreated` callback. See https://github.com/google/grafika/blob/master/src/com/android/grafika/TextureFromCameraActivity.java for an example -- it keeps the SurfaceHolder in a static. – fadden Jul 25 '14 at 00:36
0

OK, I fix this in a weird way, I think it is probably a bug of Android. Don't have time to do enough testing on this.

First surely as @fadden says you need to have a mMediaPlayer.setDisplay(myHolder) elsewhere not in the surfaceChanged or surfaceCreated since they may not be called while resume from locked screen.

For me the problem still persist after I changed it this way. Here is what I changed that solved the problem: Instead of mMediaPlayer = new MediaPlayer(), we should use mMediaPlayer = MediaPlayer.create(MediaActivity.this, fileUri)

Tamaki Sakura
  • 482
  • 5
  • 22