7

So, I managed to create the functionality i wanted with the old camera the way I wanted it.

With mCamera.autoFocus(autoFocusCallback); i detect when I have focus and run the required code while in preview-mode.

Now I have a hard time grasping how to do the same in camera2 API. My first idea was that i'd use

        private void process(CaptureResult result) {
        switch (mState) {
            case STATE_PREVIEW: {
                // We have nothing to do when the camera preview is working normally.
                int afState = result.get(CaptureResult.CONTROL_AF_STATE);
                //if (CaptureResult.CONTROL_AF_STATE == afState) {
                    Log.d("SOME KIND OF FOCUS", "WE HAVE");
                //}

                break;
            }
}

but I fail to find some kind of state that tells me we have gotten focus. Does someone have any idea how this can be done with Camera2 API?

Alexandre Marcondes
  • 5,859
  • 2
  • 25
  • 31
Hiam
  • 303
  • 1
  • 4
  • 12

2 Answers2

5

For those interested I ended up with a mix of this:

private CameraCaptureSession.CaptureCallback mCaptureCallback
        = new CameraCaptureSession.CaptureCallback() {

    private void process(CaptureResult result) {
        switch (mState) {
            case STATE_PREVIEW: {

                int afState = result.get(CaptureResult.CONTROL_AF_STATE);
                if (CaptureResult.CONTROL_AF_TRIGGER_START == afState) {
                    if (areWeFocused) {
                        //Run specific task here
                    }
                }
                if (CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState) {
                    areWeFocused = true;
                } else {
                    areWeFocused = false;
                }

                break;
            }
        }
    }

   @Override
    public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
                                    CaptureResult partialResult) {
        process(partialResult);
    }

    @Override
    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                                   TotalCaptureResult result) {
        process(result);
    }
};

It works good enough :)

Hiam
  • 303
  • 1
  • 4
  • 12
  • Hiam if i understand correctly this valeu in basic should to be `false`? – Sirop4ik Oct 21 '16 at 20:28
  • And i faced with such case `result.get(CaptureResult.CONTROL_AF_STATE);` always return 0 ... 0 it is `CaptureResult.CONTROL_AF_STATE_INACTIVE` . I faced it testing on Samsung S5... But the same code always return 1 or 2 on Meizu MX5... What is the difference? – Sirop4ik Oct 21 '16 at 20:50
  • Maybe you know how to solve my issue, how can i take a picture only when camera in focus? There is my question http://stackoverflow.com/questions/40185407/how-to-take-picture-only-if-image-in-focus-camera-2-api Thanks in advance! – Sirop4ik Oct 22 '16 at 09:52
  • could anyone provide a kotlin version of this? – Tooniis Feb 13 '20 at 17:39
3

You've basically got it. The list of states you can check for and their transitions can be found here.

It depends on what CONTROL_AF_MODE you are using, but generally you check for FOCUSED_LOCKED or perhaps PASSIVE_FOCUSED, though you may want to have cases for NOT_FOCUSED_LOCKED and PASSIVE_UNFOCUSED in case the camera just cannot focus on the scene.

rcsumner
  • 1,623
  • 13
  • 12
  • The CONTROL_AF_MODE is CONTROL_AF_MODE_CONTINUOUS_PICTURE The PASSIVE_FOCUSED works in weird ways. It will stop getting the state if i for instance put the phone down with the camera pointing towards the table, and if i hold it up, i'll get that spammed all the time, it does not seem to detect when i've gotten focus. And I can't really catch on FOCUSED_LOCKED because I want the preview to never lock up, making preview contunue being fluent. *UPDATE* Actually just found out that CONTROL_AF_TRIGGER_START seems to do what I'm after, thanks a bunch for confirming I was on the right track :) – Hiam Apr 30 '15 at 07:24
  • There are certainly situations in which it will never find focus. For example, if the scene is closer than the MINIMUM_FOCUS_DISTANCE for your device. Also, the actual AF routine the device uses is dependent on factors you can't control, i.e. the hardware. The only thing you are guaranteed is that the state machine will follow the link I cited, which does say ambiguous things like "device may initiate another scan". That is the best we can get. – rcsumner Apr 30 '15 at 07:26
  • Maybe you know how to solve my issue, how can i take a picture only when camera in focus? There is my question http://stackoverflow.com/questions/40185407/how-to-take-picture-only-if-image-in-focus-camera-2-api Thanks in advance! – Sirop4ik Oct 22 '16 at 09:51
  • Here is a good [source](https://source.android.com/devices/camera/camera3_3Amodes.html) for the focus states and what the keys represent too – Clocker Dec 28 '16 at 19:30