0

I am creating a basic camera app as a small project I'm doing to get started with Android development.

When I click on the button to take a picture, there is about a 1-second delay in which the preview freezes before unfreezing again. There is no issue with crashing - just the freezing issue. Why is this happening and how can I fix it?

Below is the method where the camera is instantiated, as well as my SurfaceView class.

 private void startCamera() {

    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    cameraPreviewLayout = (FrameLayout) findViewById(R.id.camera_preview);

    camera = checkDeviceCamera();
    camera.setDisplayOrientation(90);

    mImageSurfaceView = new ImageSurfaceView(MainActivity.this, camera);
    cameraPreviewLayout.addView(mImageSurfaceView);

    ImageButton captureButton = (ImageButton)findViewById(R.id.imageButton);
    captureButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            camera.takePicture(null, null, pictureCallback);
            camera.stopPreview();
            camera.startPreview();
        }
    });
}

public class ImageSurfaceView extends SurfaceView implements 

SurfaceHolder.Callback {
    private Camera camera;
    private SurfaceHolder surfaceHolder;

    public ImageSurfaceView(Context context, Camera camera) {
        super(context);
        this.camera = camera;
        this.surfaceHolder = getHolder();
        this.surfaceHolder.addCallback(this);

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
                this.camera.setPreviewDisplay(holder);
                this.camera.startPreview();
                this.camera.setDisplayOrientation(90);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }


}

EDIT: There is currently nothing in the pictureCallback.

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

}
Daniel
  • 137
  • 2
  • 11

2 Answers2

1
  1. You don't need to call stopPreview() after takePicture(). And you don't need startPreview() on the next line. You do need startPreview() inside your onPictureTaken() callback (not in onClick() as in the posted code!!) if you want live preview to restart after the picture is captured into a Jpeg stream.

  2. To keep your UI responsive while using camera, you should do all work with the camera on a background thread. But it is not enough to call Camera.open() or Camera.close() on some background thread. You must create a Handler thread and use it for Camera.open(). The same Looper will be used for all camera callbacks, including PictureCallback.onPictureTaken(). See my detailed walkthrough about the use of HandlerThread.

  3. As I explained elsewhere, you can achieve even better performance if you use the new camera2 API on devices that fully support this API (but better use the old API with devices that provide only LEGACY level of camera2 support).

But if you want to get maximum from the camera ISP, this kind of freeze may be inevitable (this depends on many hardware and firmware design choices, made by the manufacturer). Some clever UI tweaks may help to conceal this effect.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • Thanks for your reply. I did exactly what you laid out in both part 1 and the answer you linked to in part 2. However, there is still a significant "lag" or "freezing" that is occurring after each picture is taken, even after the implementation of the background thread. Any other ideas? – Daniel Aug 29 '18 at 20:16
  • If you are willing to sacrifice image quality for speed, you can choose to save a preview image. Modern cameras may give reasonable resolution even this way. Don't underestimate camera2 if it is applicable. But sometimes this 'freeze' is inevitable. – Alex Cohn Aug 29 '18 at 20:21
  • Will try to implement camera2 soon. However, I just don't understand why this freeze is inevitable. Obviously, the built-in camera app on any device regardless of android version would not have this type of freeze, though I'm sure the developers used methods I'm not familiar with. – Daniel Aug 29 '18 at 20:41
  • *> Obviously, the built-in camera app on any device regardless of android version would not have this type of freeze* Why do you think that's obvious? With which device do you have this experience? Most of my devices have this type of freeze in the built-in camera app. – Alex Cohn Aug 30 '18 at 07:19
  • Really? Which devices do you use? Every android device that I have owned personally has never had frozen previews when taking photos. Frankly, that would be very strange to see in a built-in camera app. However, the device I use currently runs on the latest version of Android (and thus the camera2 api). The previews always update near instantaneously, with no noticeable freeze. My custom app’s freezing occurs for at least .5 seconds. – Daniel Aug 30 '18 at 21:10
0

You’ll need to enable access to the hidden “Developer options” menu on your Android phone. To do that, simply tap the “About phone” option in Settings. Then tap “Build number” seven times and you’re done. Now you can just back out to the main Settings menu and you’ll find Developer options somewhere near the bottom of the list.

==>Now that you’re done with that part, let the real fun begins. Tap the new Developer options menu you just enabled and scroll until you see the following three settings (note that they may be located within an “Advanced” subsection):

Window animation scale Transition animation scale Animator animation scale

==>Did you see them? By default, each of those three options is set to “1x” but tapping them and changing them to “.5x” will dramatically speed up your phone. This harmless tweak forces the device to speed up all transition animations, and the entire user experience is faster and smoother as a result

Xay
  • 248
  • 3
  • 10
  • This is simply a band-aid and has nothing to do with the deeper problem. The default camera app has absolutely no delay or freezing when taking pictures, while my app does - once again, this has nothing to do with animation speed. There must be programmatic error at play. – Daniel Aug 28 '18 at 17:07