SurfaceView for Camera Preview won't get destroyed when pressing Power-Botton

Posted by for3st on Stack Overflow See other posts from Stack Overflow or by for3st
Published on 2013-11-03T21:51:07Z Indexed on 2013/11/03 21:53 UTC
Read the original article Hit count: 298

I want to implement a camera preview. For that I have a custom View CameraView extends ViewGroup that in the constructor programatically creates an surfaceView.

I have the following components (higly simplified for beverity):

ScannerFragment.java

public View onCreateView(..) {
   //inflate view and get cameraView
}

public void onResume() {
   //open camera -> set rotation -> startPreview (in a thread) -> 
   //set preview callback -> start decoding worker
}

public void onPause() {
   // stop decoding worker -> stop Preview -> release camera
}

CameraView.java extends ViewGroup

public void setUpCalledInConstructor(Context context) {
   //create a surfaceview and add it to this viewgroup ->
   //get SurfaceHolder and set callback
}

/* SurfaceHolder.Callback */
public void surfaceCreated(SurfaceHolder holder) {
   camera.setPreviewDisplay(holder);
}

public void surfaceDestroyed(SurfaceHolder holder) {
    //NOTHING is done here
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    camera.getParameters().setPreviewSize(previewSize.width, previewSize.height);
}

fragment_scanner.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.myapp.camera.CameraView
        android:id="@+id/cameraPreview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

I think I have set the lifecycle correct (getting resources onResume(), releasing it onPause() roughly said) and the following works just fine:

  • pressing home and returning
  • pressing Taskswitcher and returning
  • rotation

But one thing doesn't work and that is when I press the power-button on the device and then return to the camera-preview. The result is: the preview is stuck with the image that was last captured before button was pressed. If I rotate it works fine again, since it will get through the lifecycle.

After some research I found out that this is probably due to the fact that surfaceView won't get destroyed when the power-button is pressed, i.e. SurfaceHolder.Callback.surfaceDestroyed(SurfaceHolder holder) won't be called. And in fact when I compare the (very verbose) log output of the home-button-case and the power-button-case it's the same except that 'surfaceDestroyed' won't get called.

So far I found no solution whatsoever to work around it. I purposely avoid any resource cleaning code in my surfaceDestroyed(), but this does not help. My idea was to manually destroy the surfaceView like asked in this question but this seems not possible. I also tested other applications with surfaceViews/cameras and they don't seem to have this issue. So I would appreciate any hints or tips on that.

© Stack Overflow or respective owner

Related posts about java

Related posts about android