Question

I am trying to switch between the device's Front and Back Camera while showing the camera preview. I am following the sample provide by common ware. Below is the code which I am using. Whenever I click on the Flip button, the surface view goes black, and I don't know where I am going wrong. I have tried to restart the current activity, but I don't want like that.

package com.commonsware.android.camera;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Toast;
import android.widget.ToggleButton;
public class PreviewDemo extends Activity {
    private SurfaceView preview = null;
    private SurfaceHolder previewHolder = null;
    private Camera camera = null;
    private boolean inPreview = false;
    private boolean cameraConfigured = false;
    private ToggleButton flipCamera;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    flipCamera = (ToggleButton) findViewById(R.id.flip);
    preview = (SurfaceView) findViewById(R.id.preview);
    previewHolder = preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    flipCamera.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            // TODO Auto-generated method stub
            restartPreview(isChecked);
        }
    });

}

@Override
public void onResume() {
    super.onResume();

    // camera=Camera.open();
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
    if (Camera.getNumberOfCameras() > 1
            && camId < Camera.getNumberOfCameras() - 1) {
        // startCamera(camId + 1);
        camera = Camera.open(camId + 1);
    } else {
        // startCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
        camera = Camera.open(camId);
    }
    startPreview();
}

void restartPreview(boolean isFront) {
    if (inPreview) {
        camera.stopPreview();
    }
    //
    camera.release();

    // camera=null;
    // inPreview=false;
    // /*int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
    // if (Camera.getNumberOfCameras() > 1 && camId <
    // Camera.getNumberOfCameras() - 1) {
    // //startCamera(camId + 1);
    // camera = Camera.open(camId + 1);
    // } else {
    // //startCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
    // camera = Camera.open(camId);
    // }*/
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
    if (isFront) {
        camera = Camera.open(camId);
        camera.startPreview();

    } else {
        camera = Camera.open(camId + 1);
        camera.startPreview();

    }
    // startPreview();
}

@Override
public void onPause() {
    if (inPreview) {
        camera.stopPreview();
    }

    camera.release();
    camera = null;
    inPreview = false;

    super.onPause();
}

private Camera.Size getBestPreviewSize(int width, int height,
        Camera.Parameters parameters) {
    Camera.Size result = null;

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
        if (size.width <= width && size.height <= height) {
            if (result == null) {
                result = size;
            } else {
                int resultArea = result.width * result.height;
                int newArea = size.width * size.height;

                if (newArea > resultArea) {
                    result = size;
                }
            }
        }
    }

    return (result);
}

private void initPreview(int width, int height) {
    if (camera != null && previewHolder.getSurface() != null) {
        try {
            camera.setPreviewDisplay(previewHolder);
        } catch (Throwable t) {
            Log.e("PreviewDemo-surfaceCallback",
                    "Exception in setPreviewDisplay()", t);
            Toast.makeText(PreviewDemo.this, t.getMessage(),
                    Toast.LENGTH_LONG).show();
        }

        if (!cameraConfigured) {
            Camera.Parameters parameters = camera.getParameters();
            Camera.Size size = getBestPreviewSize(width, height, parameters);

            if (size != null) {
                parameters.setPreviewSize(size.width, size.height);
                camera.setParameters(parameters);
                cameraConfigured = true;
            }
        }
    }
}

private void startPreview() {
    if (cameraConfigured && camera != null) {

        camera.startPreview();
        inPreview = true;
    }
}

SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
        // no-op -- wait until surfaceChanged()
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        initPreview(width, height);
        startPreview();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // no-op
        if (camera != null) {
            /*
             * Call stopPreview() to stop updating the preview surface.
             */
            camera.stopPreview();

            /*
             * Important: Call release() to release the camera for use by
             * other applications. Applications should release the camera
             * immediately in onPause() (and re-open() it in onResume()).
             */
            camera.release();

            camera = null;
        }
    }
};
}
Was it helpful?

Solution

You seem to have forgotten to call setPreviewDisplay() (or, in your case, initPreview()) before calling startPreview() from your restartPreviev() method. Effectively, you're trying to start preview without specifying a surface to render the preview into.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top