Reputation: 2444
I need to use Camera2 API on my application. (Api21+) I found the next sample: https://github.com/googlesamples/android-Camera2Basic
I downloaded it and started on my phone. When I pressed the "Picture" Button, it's call the takePhoto method.
private void takePicture() {
lockFocus();
}
It is a State machine. Sometimes this machine stuck on STATE_WAITING_LOCK
.
My device is waiting for Focus, but nothing happens! (Yes, my device is support auto focus)
case 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 = STATE_PICTURE_TAKEN;
captureStillPicture();
} else {
runPrecaptureSequence();
}
}
break;
}
What is the good solution for this problem? And this program sometimes crashed here:
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
setAutoFlash(mPreviewRequestBuilder);
/*HERE*/ mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
Why can't focus my device?
Upvotes: 9
Views: 3684
Reputation: 531
When I found Lautern's answer, I had to adjust it a little, as it wasn't working for me.
As the program stucks sometimes in CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED, you can try to restart the AF_TRIGGER:
if (afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
restartFocus();
}
private void restartFocus(){
try {
mPreviewRequestBuilder.set(
CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
mCaptureSession.capture(
captureRequestBuilder.build(),
captureSessionCaptureCallback,
mBackgroundHandler);
lockFocus();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void lockFocus() {
try {
mPreviewRequestBuilder.set(
CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_START);
mState = STATE_WAIT_LOCK;
mCaptureSession.capture(
mPreviewRequestBuilder.build(),
mPreviewCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
As some time has passed, since I implemented this, I'm not entirely sure why I had to restart the capture session. But without it, it doesn't work for me.
Upvotes: 2
Reputation: 37
It seems that your program stucks sometimes in CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED where according to documentation "The AF algorithm has been unable to focus. The lens is not moving." link
Try to cancel the AF_TRIGGER and start it again. Something like this:
if (afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
getRidOfNotFocusedLock();
}
And:
private void getRidOfNotFocusedLock(){
try {
mPreviewRequestBuilder.set(
CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
mCaptureSession.capture(
captureRequestBuilder.build(), captureSessionCaptureCallback, backgroundHandler);
mPreviewRequestBuilder.set(
CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
Upvotes: 2