I work with camera 2 API.
I use standard google sample for camera.
Issue is code allow to user take a picture even if image is not in a focus...
private final CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) { } @Override public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { process(result); } private void process(CaptureResult result) { switch (mState) { case CameraHelper.STATE_PREVIEW: { // We have nothing to do when the camera preview is working normally. break; } case CameraHelper.STATE_WAITING_LOCK: { Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); if (afState == null) { captureStillPicture(); } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState || CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) { // CONTROL_AE_STATE can be null on some devices Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); if (aeState == null || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { mState = CameraHelper.STATE_PICTURE_TAKEN; captureStillPicture(); } else { runPrecaptureSequence(); } } break; } case CameraHelper.STATE_WAITING_PRECAPTURE: { // CONTROL_AE_STATE can be null on some devices Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); if (aeState == null || aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) { mState = CameraHelper.STATE_WAITING_NON_PRECAPTURE; } break; } case CameraHelper.STATE_WAITING_NON_PRECAPTURE: { // CONTROL_AE_STATE can be null on some devices Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) { mState = CameraHelper.STATE_PICTURE_TAKEN; captureStillPicture(); } break; } } } };
It is standard callback
How i can implement smth like in a regular camera, when user click take picture button, the first camera take a focus and only after that take a picture...
But in my case even if picture not in a focus anyway it is allow to take a picture...
What am i doing wrong?
EDIT
private void captureStillPicture() { try { if (null == cameraDevice) { return; } // This is the CaptureRequest.Builder that we use to take a picture. final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(imageReader.getSurface()); captureBuilder.set(CaptureRequest.JPEG_QUALITY, (byte) 100); // Use the same AE and AF modes as the preview. captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); setAutoFlash(captureBuilder); // Orientation int rotation = getWindowManager().getDefaultDisplay().getRotation(); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, CameraHelper.ORIENTATIONS.get(rotation)); // Этот метод показывает, что будет происходить после того как снимок будет сделан final CameraCaptureSession.CaptureCallback CaptureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { Logger.logGeneral("LENS_FOCAL_LENGTH : " + request.get(CaptureRequest.LENS_FOCAL_LENGTH)); unlockFocus(); } }; captureSession.stopRepeating(); captureSession.capture(captureBuilder.build(), CaptureCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } }
EDIT2
Maybe i don't have to allow user take a picture if focus doesn't set up? It means i should track focus condition every moment and eventually when user click take picture button i should check focus condition and if it is in focus - take picture, if not - show Toast - set up focus
i have found snip of code according to this question
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); } };
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?
What am i doing wrong?
How i can take a picture only when camera in focus?