camera startPreview failed

17,774

Solution 1

I have solved deleting some lines in surfaceChanged

 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.
        Log.d("Function", "surfaceChanged iniciado");
        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here


        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

So the error must be in i one of these lines:

Parameters parameters= mCamera.getParameters();
    parameters.setPreviewSize(w, h);
    mCamera.setParameters(parameters);

Someone could explain me what was wrong in those lines?

Solution 2

Is (w, h) a valid preview size for your camera?

You can use mCamera.getParameters().getSupportedPreviewSizes() to get all of the valid preview sizes.

Solution 3

Its late, but if someones looking for the answer

The variables w and h are not the optimal preview sizes . You can get optimal preview sizes using the function

public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio=(double)h / w;
        if (sizes == null) return null;

        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        for (Camera.Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

and you can call the function using

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
..
size=getOptimalPreviewSize(parameters.getSupportedPreviewSizes(), w, h);
 parameters.setPreviewSize(size.getWidth(), size.getHeight());
..

}

Solution 4

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, now tell the camera where to draw the preview.
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.getParameters().getSupportedPreviewSizes();
        mCamera.startPreview();
        Log.d(TAG, "Camera preview started.");
    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}
Share:
17,774
user1805792
Author by

user1805792

Updated on July 19, 2022

Comments

  • user1805792
    user1805792 almost 2 years

    I am creating a camera app but I have problems on startPreview, it sends me:

    java.lang.RuntimeException: startPreview failed
    

    here is my camera Activity:

    public class CameraActivity extends Activity {
    
    private Camera mCamera;
    private CameraPreview  mPreview;
    private Target_Frame targetFrame;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera_layout);
    
    
    
    
        mCamera=getCameraInstance();
        mPreview=new CameraPreview(this, mCamera);
    
    
    
    
        FrameLayout preview=(FrameLayout)findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    
    }
    
    
    
    
    /** Check if this device has a camera only if not specified in the manifest */
    public boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }
    
    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        }
        catch (Exception e){
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }
    
    /**Check if the device has flash*/
    public boolean checkFlash(Context context){
        if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){
            //the device has flash
            return true;
        }else{
            //no flash
            return false;
        }
    
    }
    
    
    
    
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        releaseCamera();
    }
    
    
    
    
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        releaseCamera();
    }
    
    
    
    
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
    
        //Test if i have to put all this code like in onCreate
        if(mCamera!=null){
            return;
        }
        mCamera=getCameraInstance();
    
        if(mPreview!=null){
            return;
        }
        mPreview=new CameraPreview(this, mCamera);
        FrameLayout preview=(FrameLayout)findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    
    
    }
    
    
    private void releaseCamera(){
        if (mCamera != null){
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
    }}
    

    And here is my SurfaceView code:

    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
        private static final String TAG = "CameraPreview";
        private SurfaceHolder mHolder;
        private Camera mCamera;
    
        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
    
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    
        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, now tell the camera where to draw the preview.
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
    
            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
            // empty. Take care of releasing the Camera preview in your activity.
        }
    
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
    
            if (mHolder.getSurface() == null){
              // preview surface does not exist
              return;
            }
    
            // stop preview before making changes
            try {
                mCamera.stopPreview();
            } catch (Exception e){
              // ignore: tried to stop a non-existent preview
            }
    
            // set preview size and make any resize, rotate or
            // reformatting changes here
            Parameters parameters= mCamera.getParameters();
            parameters.setPreviewSize(w, h);
            mCamera.setParameters(parameters);
    
            // start preview with new settings
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
    
            } catch (Exception e){
                Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }
    }
    

    And here is my error log:

    12-01 13:17:01.135: E/AndroidRuntime(1161): FATAL EXCEPTION: main
    
    12-01 13:17:01.135: E/AndroidRuntime(1161): java.lang.RuntimeException: startPreview
    
    12-01 13:17:01.135: E/AndroidRuntime(1161):     at com.example.prueba.CameraPreview.surfaceCreated(CameraPreview.java:36) 
    
  • Alex Cohn
    Alex Cohn over 10 years
    This is most likely the reason of the RuntimeException. For some devices, call to Camera.setParameters() with unsupported preview size can cause RuntimeException. For others, the exception is thrown on Camera.startPreview()
  • hybrid
    hybrid over 8 years
    I have posted the answer below.