-1

At first please excuse my bad English. I have problem with programmatically taking photo. I wrote an app, that makes collection of photos based on countdown timer and after that, photos are being processed using c++ code.

I'm using dummy SurfaceView, because I don't need preview in UI. The code below is working on my phone Xperia mini - API 15 (so permissions and code would be correct), but I borrowed school Nexus 5 - API 21 and there is problem with preview.

takePicture: camera 0: Cannot take picture without preview enabled

I found a solution, which uses setPreviewTexture (commented below) instead of setPreviewDisplay. It working for the first photo, which is normally saved, but I get the same error after the second call of takePicture().

Thanks for every advice, LS

Camera camera;
@Override
protected void onResume() {
    super.onResume();
    // is camera on device?
    if(!checkCameraHardware()) return;

    releaseCamera();
    try {
        camera.stopPreview();
    } catch (Exception e){
      Log.d(TAG, "No preview before.");
    }

    SurfaceView dummy = new SurfaceView(this);
    camera = Camera.open();
    Camera.Parameters params = camera.getParameters();
    params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    camera.setParameters(params);

    try {
        //camera.setPreviewTexture(new SurfaceTexture(10));
        camera.setPreviewDisplay(dummy.getHolder());
    } catch (IOException e) {
        e.printStackTrace();
    }
    camera.startPreview();
}

SOLUTION:

I needed to refresh preview. The code below is working on Xperie and Nexus too. Question remains why I have to use setPreviewTexture, because setPreviewDisplay always returns error on Nexus.

    camera.takePicture(null, null, new PictureCallback() {
        @Override
        public void onPictureTaken(final byte[] data, Camera camera) {
            // save picture
            refreshPreview();
        }
    });

public void refreshPreview() {
    try {
        camera.stopPreview();
    } catch (Exception e) {}

    try {
        camera.startPreview();
    } catch (Exception e) {}
}

and in function onResume()

try {
    camera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e) {}
Community
  • 1
  • 1
Lukas
  • 15
  • 5
  • You don't need a SurfaceView. See http://stackoverflow.com/questions/22462360/android-use-camera-without-surfaceview-or-textureview/ – fadden Apr 22 '15 at 15:37

2 Answers2

1

Just add a callback for starting preview on your camera instance. The thing is that after starting preview on camera instance, it needs some time to be able take a picture. Try this:

           camera.startPreview();
            camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    camera.takePicture(null, null, new Camera.PictureCallback() {
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera) {
                   // do something you want with your picture and stop preview
                            camera.stopPreview();
                        }
                    });
0

Once the picture is taken, refresh you're surfaceview & stop the preview and releasee camera and restart the process again.

        try {
                camera.takePicture(null, null, new PictureCallback() {
            public void onPictureTaken(final byte[] data, Camera camera) {
                //once ur logic done
                refreshCamera();
            }
        });
            } catch (Exception e2) {
                // Toast.makeText(getApplicationContext(), "Picture not taken", Toast.LENGTH_SHORT).show();
                e2.printStackTrace();
            }

        public void refreshCamera() {
            if (dummy.getHolder().getSurface() == null) {
                return;
            }

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

            try {
                camera.setPreviewDisplay(dummy.getHolder());
                camera.startPreview();
            } catch (Exception e) {

            }
        }

Hope this solution may help you.

Harsha Vardhan
  • 3,324
  • 2
  • 17
  • 22