RuntimeException when taking a picture using custom camera - "takePicture failed"

android surfaceview camera take picture
android custom camera preview example
android custom camera source code
android custom camera like whatsapp
custom camera android github
android.hardware.camera2 example
how to open front camera in surfaceview in android programmatically
how to open camera in android programmatically

The error occurs inside CameraFragment - a fragment containing just a FrameLayout (to hold the camera preview) and ImageButton (used to capture the image). In my Fragment I have a PictureCallback:

private static Camera.PictureCallback mPicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        CameraFragment.DATA=data;
        final int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_STORAGE
            );
            return;
        }
        saveImageToDevice();

    }
};

and I get my Camera instance from a HandlerThread:

private CameraHandlerThread mThread = null;

private static class CameraHandlerThread extends HandlerThread {
    Handler mHandler = null;
    private Camera handlerCamera;

    CameraHandlerThread() {
        super("CameraHandlerThread");
        start();
        mHandler = new Handler(getLooper());
    }

    synchronized void notifyCameraOpened() {
        notify();
    }

    void openCamera() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                handlerCamera = getCameraInstance();
                notifyCameraOpened();
            }
        });
        try {
            wait();
        }
        catch (InterruptedException e) {

        }
    }

    public Camera getCamera() {
        return handlerCamera;
    }
}

then I call this method (where the exception occurs) in OnCreateView():

private void launchCamera() {
    newOpenCamera();
    mPreview = new CameraPreview(getContext(), mCamera, activity);
    mPreview.setCameraDisplayOrientation(activity, CAMERA_ID, mCamera);
    preview = (FrameLayout) view.findViewById(R.id.tvCamera);
    preview.addView(mPreview);
    ivCaptureImage = (ImageView) view.findViewById(R.id.ivCaptureImage);
    ivCaptureImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mCamera.takePicture(null, null, mPicture); 
        }
    });
}

where newOpenCamera is:

private void newOpenCamera() {
    if (mThread == null) {
        mThread = new CameraHandlerThread();
    }

    synchronized (mThread) {
        mThread.openCamera();
        mCamera = mThread.getCamera();
    }
}

I have ran the debugger and can see that the line where the error occurs (mCamera.takePicture(...) in launchCamera()) gets called but the error gets thrown before the PictureCallback. The error is:

E/UncaughtException: java.lang.RuntimeException: takePicture failed
        at android.hardware.Camera.native_takePicture(Native Method)
        at android.hardware.Camera.takePicture(Camera.java:1523)
        at android.hardware.Camera.takePicture(Camera.java:1468)
        at com.myapp.myapp.camera.CameraFragment$2.onClick(CameraFragment.java:175)
        at android.view.View.performClick(View.java:5697)
        at android.view.View$PerformClick.run(View.java:22526)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:158)
        at android.app.ActivityThread.main(ActivityThread.java:7229)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
05-28 17:09:22.600 1171-1171/com.myapp.myapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myapp.myapp, PID: 1171
    java.lang.RuntimeException: takePicture failed
        at android.hardware.Camera.native_takePicture(Native Method)
        at android.hardware.Camera.takePicture(Camera.java:1523)
        at android.hardware.Camera.takePicture(Camera.java:1468)
        at com.myapp.myapp.camera.CameraFragment$2.onClick(CameraFragment.java:175)
        at android.view.View.performClick(View.java:5697)
        at android.view.View$PerformClick.run(View.java:22526)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:158)
        at android.app.ActivityThread.main(ActivityThread.java:7229)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Does anyone know what could be wrong? As you can see I always get two of the same error with every one picture taken.

Any help is HIGHLY appreciated, cheers.

Edit:

I have put guards to stop single touches registering as multi as described here: java.lang.RuntimeException: takePicture failed

Still no luck

I would advise you to use third-party libraries.

Android Camera Library Comparison Fotoapparat vs. CameraKit

Camera Advanced: Building a Custom Camera Application, open the hardware camera. create a live preview of the camera image. take When you need to create a custom camera, you can use Android's Camera object. applications try to open the camera, the call will throw a RuntimeException. In Windows Phone Silverlight (8.0 and 8.1) we can use Camera Capture Task to capture a picture using build-in camera. It’s quite easy and we don’t have to do much to make it work. When writing a Windows Runtime App, the situation it’s little

I think you forgot to call startPreview() method on your camera object. From the official documentation:

6.Important: Call startPreview() to start updating the preview surface. Preview must be started before you can take a picture.

https://developer.android.com/reference/android/hardware/Camera

android.hardware.Camera, We recommend using the new android.hardware.camera2 API for new applications. To take pictures with this class, use the following steps: RuntimeException, if starting autofocus fails; usually this would be because of a  CameraView. CameraView is a well documented, high-level library that makes capturing pictures and videos easy, addressing most of the common issues and needs, and still leaving you with flexibility where needed.

Use this way to open camera using surface view Java Code

public class CameraOverlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    Camera camera;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    boolean previewing = false;
    LayoutInflater controlInflater = null;

    private File videoPath;
    private ImageView imgCapture;
    int camBackId;
    String strVideoFolderPath;
    private ProgressDialog progressDialog;
    Camera.Parameters parameters;
    public boolean hasFlash;
    public boolean camRotation = false;
    private RelativeLayout relativeLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_overlay);

        relativeLayout = findViewById(R.id.control);

        camBackId = Camera.CameraInfo.CAMERA_FACING_BACK;
        hasFlash = this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
        surfaceView = findViewById(R.id.surface);
        progressDialog = new ProgressDialog(this);
        progressDialog.setTitle(null);
        progressDialog.setCancelable(false);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        strVideoFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        controlInflater = LayoutInflater.from(getBaseContext());
        videoPath = new File(Environment.getExternalStorageDirectory() + "/sw/raw");
        if (videoPath.exists()) {
            if (videoPath.isDirectory()) {
                if (videoPath.listFiles().length != 0) {
                    String[] children = videoPath.list();
                    for (int i = 0; i < children.length; i++) {
                        new File(videoPath, children[i]).delete();
                    }
                }
            }
        }
        if (!videoPath.exists()) {
            videoPath.mkdirs();
        }

        imgCapture = findViewById(R.id.img_capture);
        imgCapture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (camera != null) {
                    if (previewing) {
                        System.gc();
                        try {
                            capturePhoto();
                        } catch (Exception e) {
                            Log.v("ERRORR", e.getMessage());
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

    }

    public void capturePhoto() throws Exception {
        camera.takePicture(null, null, myPictureCallback_JPG);

    }

    @Override
    protected void onResume() {
        super.onResume();
        Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
    }

    Camera.PictureCallback myPictureCallback_JPG = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1) {
            // TODO Auto-generated method stub
            FileOutputStream outStream = null;
            //camera.startPreview();
            try {
                Date date = new Date();
                String filename = "/rec" + date.toString().replace(" ", "_").replace(":", "_") + ".jpg";
                filename = filename.replace("+", "");
                File file = new File(Environment.getExternalStorageDirectory() + "/Switch It");
                if (!file.exists())
                    file.mkdirs();
                outStream = new FileOutputStream(file + filename);
                outStream.write(arg0);
                outStream.close();
                Log.v("File_Path", file.getAbsolutePath());
                Intent returnIntent = new Intent();
                returnIntent.putExtra("img_capture", file.getAbsolutePath() + filename);
                setResult(Activity.RESULT_OK, returnIntent);
                finish();
            } catch (FileNotFoundException e) {
                Log.e("ERROR 1", e.getMessage());
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("ERROR 2", e.getMessage());
            } finally {
            }
        }
    };


    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
        // TODO Auto-generated method stub
        if (previewing) {
            camera.stopPreview();
            previewing = false;
        }

        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);
                parameters = camera.getParameters();
                if (getPackageManager().hasSystemFeature("android.hardware.camera.autofocus")) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                }

                camera.startPreview();
                if (hasFlash) {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                }
                camera.setParameters(parameters);
                previewing = true;

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        camera = Camera.open();
        if (android.os.Build.VERSION.SDK_INT > 7) {
            Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
            if (display.getRotation() == Surface.ROTATION_0) {
                camera.setDisplayOrientation(90);
                camRotation = true;
            }
        }


    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        if (camera != null) {
            camera.stopPreview();
            camera.release();
            camera = null;
            previewing = false;
        }
    }

}

XML code

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/control"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <SurfaceView
        android:id="@+id/surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />




    <ImageView
        android:id="@+id/img_capture"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="5dp"
        android:src="@drawable/ic_lens_black_24dp" />


</RelativeLayout>

Camera API, The Android framework includes support for various cameras and camera features available on devices, allowing you to capture pictures and videos in your​  This is useful if you are using the camera app on the tablet device like the Surface Pro. Next, if you set the timer in the camera app, which I explain below, you can have the camera app automatically take a time lapse. So if you set the timer to every 5 seconds, it will keep taking pictures until you press the camera button again.

Check whether the permission for using the Camera has been set for that particular application. Go to Settings -> Apps -> "Your app name" -> Permissions -> Turn on the permission for Camera. Also make sure that the permission has been set in the manifest.xml file. It is given as:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Check out this link for more details:

https://developer.android.com/guide/topics/media/camera

Custom camera TakePicture, Didn't take much to get this to work well. Did change the code to generate unique Picture Filenames using Date and Time Stamp like this: String dataDir = (String)  It turns out to be a conflict with the zxing.net.mobile.forms barcode scanner functionality (I was using 2.4.1 (the latest & stable)). When I removed the zxing from my xaml I noticed that the camera started working (I wasn't even attempting to do a scan, but there is that option on the page along with the option to take a picture). xaml code:

Try this one works for me and check permission given in the manifest file.

 mCamera = Camera.open(id);
 setCameraDisplayOrientation(mContext, id, mCamera);
 mCamera.setPreviewDisplay(new DummySurfaceHolder());
 SurfaceTexture st = new SurfaceTexture(MODE_PRIVATE);
 mCamera.setPreviewTexture(st);

 mCamera.startPreview();
 mCamera.autoFocus(new Camera.AutoFocusCallback() {
    @Override
     public void onAutoFocus(boolean b, Camera camera) {

      try {
         Thread.sleep(500);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }

      mCamera.takePicture(null, null, null, new PictureCapture(mContext));

       }
     });

Android Camera 2 Api Example With & Without Preview, I'd created two classes named as CameraControllerV2WithPreview for taking picture with preview and another one is Camera 2 Api is latest Api introduced in android version Lollipop, throw new RuntimeException("Time out waiting to lock camera opening."); custom-toolbar-with-searchview-featured  Check whether the permission for using the Camera has been set for that particular application. Go to Settings -> Apps -> "Your app name" -> Permissions -> Turn on the permission for Camera. Also make sure that the permission has been set in the manifest.xml file.

[Camera Plugin] It's not working on Android 8.1, Hi,. I used the camera plugin on my application but it's not working on android 8.1​. When I tryed to take a picture the aplication stops. Its only  A Live Photo captures what happens just before and after you take your photo, including the audio. Choose Photo mode. Tap to turn Live Photos on or off. Tap the Shutter button to take the shot. You can edit Live Photos in Photos. In your albums, Live Photos are marked with “Live” in the corner.

Augmented camera previews for the Dropbox Android document , With Dropbox's document scanner, a user can take a photo of a document This requires custom interaction with the Android camera and access to 270; break; default: throw new RuntimeException("Unsupported display  In this Video we will capture image with Camera using the Camera Intent. Camera will be opened after clicking the button. Take Picture with Camera - Android Studio Custom Camera API using

Android custom camera Preview photo Switch front and rear camera , RuntimeException: setParameters failed solution (6) Call Camera's takePicture​() method to take a photo. the end of the program, call the Camera's stopPreview() method to stop the preview and release the resources via Camera.​release(). Instead of using the capture intent to capture photos "the easy way", a custom camera can be used within your app directly leveraging the Camera2 API. This custom camera is much more complicated to implement but sample code can be found here and this CameraView from Google aims to help Android developers easily integrate Camera features.

Comments
  • Try to remove the permission check first. Narrow the code. Get rid of all the irrelevant.
  • Which device you are using?
  • Looks like you are still using Camera 1 API which no longer works with new devices. Its time you move to Camera 2 API.
  • It is called in the CameraPreview class