4

I have successfully captured the single photo using camera in Android. But when I tried to capture 5 photos at once, app stops responding, camera preview turns to green and no picture is saved. What I saw in stack trace is as follows (partial)

03-17 14:19:54.804: INFO/QualcommCameraHardware(19268): deinitPreview E 03-17 14:19:54.804: INFO/QualcommCameraHardware(19268): deinitPreview X 03-17 14:19:54.804: DEBUG/QualcommCameraHardware(19268): frame_thread X 03-17 14:19:54.834: DEBUG/QualcommCameraHardware(19268): snapshot_thread E 03-17 14:19:54.854: DEBUG/CameraService(19268): takePicture (pid 20509) 03-17 14:19:54.884: WARN/AudioFlinger(19268): write blocked for 85 msecs 03-17 14:19:55.154: DEBUG/CameraService(19268): postShutter 03-17 14:19:55.284: DEBUG/CameraService(19268): postRaw 03-17 14:19:55.314: DEBUG/QualcommCameraHardware(19268): snapshot_thread X 03-17 14:19:55.344: DEBUG/QualcommCameraHardware(19268): snapshot_thread E 03-17 14:19:55.364: DEBUG/CameraService(19268): takePicture (pid 20509) 03-17 14:19:55.984: DEBUG/CameraService(19268): postShutter 03-17 14:19:56.064: DEBUG/CameraService(19268): postRaw 03-17 14:19:56.074: ERROR/QualcommCameraHardware(19268): native_jpeg_encode: jpeg_encoder_encode failed. 03-17 14:19:56.074: ERROR/QualcommCameraHardware(19268): jpeg encoding failed 03-17 14:19:56.084: DEBUG/QualcommCameraHardware(19268): snapshot_thread X 03-17 14:19:56.154: INFO/DEBUG(19267): * ** * ** * ** * ** * ** * 03-17 14:19:56.164: INFO/DEBUG(19267): Build fingerprint: 'google_ion/google_ion/sapphire/sapphire:1.6/DRC83/14721:user/adp,test-keys' 03-17 14:19:56.164: INFO/DEBUG(19267): pid: 19268, tid: 20813 >>> /system/bin/mediaserver ... ... ... 14:19:59.894: INFO/ServiceManager(46): service 'media.camera' died 03-17 14:19:59.894: WARN/Camera(20509): Camera server died! 03-17 14:19:59.894: WARN/Camera(20509): ICamera died 03-17 14:19:59.894: ERROR/Camera(20509): Error 100 03-17 14:19:59.915: WARN/AudioSystem(71): AudioFlinger server died! 03-17 14:20:00.014: INFO/Process(71): Sending signal. PID: 18636 SIG: 3 03-17 14:20:00.054: INFO/dalvikvm(18636): threadid=7: reacting to signal 3

I am calling the takePicture method in a loop to capture multiple photos;

for(int m = 0 ; m < 6; m++) {

    mPrimCamera.takePicture(null, mPictureCallbackMet, mPictureCallbackMet);
}

I am doing this on HTC Magic running Android 1.6. I think, I am using the wrong way to take multiple photos. What is the correct way to capture multiple photos using Android Camera API?

Mudassir
  • 13,031
  • 8
  • 59
  • 87
  • 1
    See also *[How to effectively re-start the preview having taken a photo inside an Android app?](http://stackoverflow.com/questions/24214362)* and *[Android 2.3.1 Camera takePicture() Multiple images with one button click](http://stackoverflow.com/questions/5545952)* – Alex Cohn Jun 14 '14 at 09:07

3 Answers3

10

I'm not sure the android api even supports a burst mode. One thing's for sure, you can't just call takePicture() in a loop like that. That is just abusing those poor api's.

How about taking the next picture in onPictureTaken() ? (Obviously you have to keep a track of the number of pictures taken etc ..)

Also like the documentation says, don't assume it will work on every device.

I wrote the above answer in 2011, since then Camera has evolved

EDIT : Burst mode is now supported in Camera2 : https://developer.android.com/reference/android/hardware/camera2/package-summary.html

See https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession.html

Reno
  • 33,594
  • 11
  • 89
  • 102
3

You can take next photo only after callback method Camera.PictureCallback.onPictureTaken is called and camera preview is restarted.

private void takePhoto() {
    if (!(cameraPreview.isRunning())) {
        Log.i(LOG_TAG, "Camera is not ready. Skip frame");
        return;
    }

    camera.takePicture(null, null, this);
    cameraPreview.onPictureTook();
}

public void onPictureTaken(byte[] data, Camera camera) {
    // save photo
    cameraPreview.start();
}


public class CameraPreview extends SurfaceView {

    private boolean previewRunning = false;

    /**
     * Should be called after calling camera.takePicture
     */
    public void onPictureTook() {
        previewRunning = false;
    }

    public boolean isRunning() {
        return previewRunning;
    }

    public void start() {
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            previewRunning = true;
        } catch (Exception ignored) {
            Log.e(LOG_TAG, "Error starting camera preview", ignored);
        }
    }
}
danik
  • 796
  • 9
  • 17
1

I didn't find any API support for this. And repeatedly calling the takePicture method from the loop is not working. So, I get a workaround. The code is still in loop but I'm now using Thread;

private class CaptureThread extends Thread {

        @Override
        public void run() {

            int count = 0;

            while(count < mNo) {
                mFileName = mLocation + "/pic" + count + ".jpg";

                mCamera.takePicture(null, mPictureCallback, mPictureCallback);

                count++;

                try {
                    Thread.sleep(3000);
                } catch (InterruptedException exception) {
                    exception.printStackTrace();
                }
            }
        }
}
Mudassir
  • 13,031
  • 8
  • 59
  • 87
  • 2
    Thread.sleep here is a bad idea. Concider using PictureCallback. – Alex Apr 27 '15 at 06:40
  • It may be an old post but I have to comment for other beginners that events are there for a reason to not run into hardware issues. 3 seconds would possibly not be enough on a phone camera that has a shutter. Thread.sleep is really bad practice and I don't think marking your own answer as correct is good when it's dodgy code. – Wancieho Oct 21 '16 at 23:15