Android Camera2: Implementing TouchFocus + AutoFocus, Simultaneously

Viewed 87

I want my camera application to support both touch focus and auto focus. I understand how to make touch focus work...

public boolean touchFocus(float touchX, float touchY){
    try {
        final Rect activeRect = mCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
        int flippedX = (int) Math.abs(getWidth() - touchX);
        final int y = (int) ((flippedX  / (float) getWidth()) * (float) activeRect.height());
        final int x = (int) ((touchY / (float) getHeight()) * (float) activeRect.width());

        final int halfTouchWidth = 50;
        final int halfTouchHeight = 50;

        MeteringRectangle focusArea = new MeteringRectangle(
                Math.max(x - halfTouchWidth, 0),
                Math.max(y - halfTouchHeight, 0),
                halfTouchWidth * 2 - 2,
                halfTouchHeight * 2 - 2,
            MeteringRectangle.METERING_WEIGHT_MAX);

        mCameraSession.stopRepeating();
        if (isMeteringAreaAFSupported() && isAutoFocus() && !isLensFixedFocus()) {
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
        }
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
        mCameraSession.capture(mPreviewRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                super.onCaptureCompleted(session, request, result);

                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null);// As documentation says AF_trigger can be null in some device

                //Then...?
                //mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, getMeteringRectFromZoomRect());
                //mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                //mCameraSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler);
            }
        }, mBackgroundHandler);
        return true;
    } catch (Exception e) { e.printStackTrace(); }
    return false;
}

But: I don't know how to then resume the auto focus routine(via CONTROL_AF_MODE_CONTINUOUS_PICTURE) , such that the camera does not immediately refocus, thereby nullifying the effect of the touch focus.

I was going to do something like: touch focus, lock the auto focus until CONTROL_AF_SCENE_CHANGE_DETECTED, then unlock auto focus. But this won't work as my phone is too old to support CONTROL_AF_SCENE_CHANGE_DETECTED, which is only available in api level 28 and beyond. However, I know this feature is achievable, because other camera apps on my phone have it. The question is: how?

0 Answers
Related