surfaceCreated() Never Called

23,517

Solution 1

I have had the same problem. For me it was because the View size was being set to 0, and therefore the surface was never created. I checked this by setting a specific size, and all of a sudden the callbacks were called. (Same, apparently, holds if the View is laid out off-screen).

Solution 2

Apparently this is due to FrameLayout being empty and thus not creating any kind of SurfaceView. You can try to force the parent LinearLayout setting height and width manually or simply adding an imageView inside the FrameLayout. Since FrameLayout may contain many widgets, but it only shows the last of them you can put a ImageView inside the FrameLayout showing a small image only for the SurfaceView to be created.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<FrameLayout android:id="@+id/cPreview"
    android:layout_weight="1" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

<!-- Adding small dummy image -->
<ImageView android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    src="@drawable/small_picture">

</FrameLayout>

</LinearLayout>

Solution 3

@jvnane I tried your code, it works, with minor bug.

surfaceChanged is called without problem. In what way you think it doesn't work? Try adding debug message and see it in LogCat:

@Override
public void surfaceCreated(final SurfaceHolder holder)
{
    Log.i("Camera Test", "It works!");
    try
    {
        //Open the Camera in preview mode
        this.camera = Camera.open();
        this.camera.setPreviewDisplay(this.holder);
    }
    catch(final IOException ioe)
    {
        ioe.printStackTrace(System.out);
    }
}

Minor bug: Camera object is released in surfaceDestroyed so you don't need to release it again in the activity's onPause. Also, you need to call super.onPause() when overriding onPause() method.

Share:
23,517
jvhashe
Author by

jvhashe

Updated on July 26, 2022

Comments

  • jvhashe
    jvhashe almost 2 years

    I've seen similar problems to the one I'm having, but I still can't find a solution. I'm very new to Android development, so I'm having trouble tracking down my problem. Anyways, I'm trying to create a camera preview using a CameraSurfaceView class I created that extends SurfaceView and implements SurfaceHolder.Callback. No matter what I try in my StartCamera class, the surfaceCreated() method is never called, hence my camera never starts. Any help would be great, thanks!

    StartCamera.java

    import net.peterd.zombierun.R;
    import android.hardware.Camera;
    import android.os.Bundle;
    import android.widget.FrameLayout;
    
    public class StartCamera extends BaseActivity {
    
        private Camera mCamera;
        private CameraSurfaceView mView;
    
        public void onCreate(Bundle state) {
            // TODO Auto-generated constructor stub
            super.onCreate(state);
            setContentView(R.layout.start_camera);
        }
    
        public void onResume() {
            super.onResume();
    
            mView = new CameraSurfaceView(this);
            FrameLayout preview = (FrameLayout) findViewById(R.id.cPreview);
            preview.addView(mView);
        }
    
        public void onPause() {
            mCamera.stopPreview();
            mCamera.release();
        }
    
    }
    

    CameraSurfaceView.java

    import java.io.IOException;
    import android.content.Context;
    import android.hardware.Camera;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback
    {
            private SurfaceHolder holder;
            private Camera camera;
    
            public CameraSurfaceView(Context context) 
            {
                    super(context);
    
                    //Initiate the Surface Holder properly
                    this.holder = this.getHolder();
                    this.holder.addCallback(this);
                    this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
    
            @Override
            public void surfaceCreated(SurfaceHolder holder) 
            {
                    try
                    {
                            //Open the Camera in preview mode
                            this.camera = Camera.open();
                            this.camera.setPreviewDisplay(this.holder);
                    }
                    catch(IOException ioe)
                    {
                            ioe.printStackTrace(System.out);
                    }
            }
    
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
            {
                    // Now that the size is known, set up the camera parameters and begin
                    // the preview.
                    Camera.Parameters parameters = camera.getParameters();
                    parameters.setPreviewSize(width, height);
                    camera.setParameters(parameters);
                    camera.startPreview();
            }
    
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) 
            {
                    // Surface will be destroyed when replaced with a new screen
                    //Always make sure to release the Camera instance
                    camera.stopPreview();
                    camera.release();
                    camera = null;
            }
    
            public Camera getCamera() {
                return camera;
            }
    }
    

    start_camera.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    
        <FrameLayout android:id="@+id/cPreview"
            android:layout_weight="1" android:layout_width="fill_parent"
            android:layout_height="fill_parent">
        </FrameLayout>
    
    </LinearLayout>