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?