Hichem Acher
Hichem Acher

Reputation: 433

Using Android Camera2, app gets stuck indefinitely in STATE_WAITING_PRECAPTURE or STATE_WAITING_NON_PRECAPTURE

I'm using the Android Camera2 API. I would like to know when is the appropriate time to:

  1. show the TakePicture button initially (i.e. the camera is ready to capture a picture).
  2. show this button again (if the process of taking a picture fails, and of course when done) because I hide it when clicking on it (to capture a picture).

I tried takePicture.setVisibility(View.GONE) in lockFocus() and takePicture.setVisibility(View.VISIBLE) in unlockFocus(). While this works most of the time, sometimes the button disappears and never appears again (when the process of taking a picture fails I guess) especially when clicking on it very quickly (as soon as it appears on the screen). No errors and no crash happen at this point.

The code is taken from googlesamples/android-Camera2Basic.

Update:

I tried takePicture.setVisibility(View.VISIBLE) inside onCaptureSequenceCompleted. The button does appear but the process of capturing a picture is not re-initiated when clicking on it (See this seven-second video). When this happens, the onCaptureFailed is not called. However, it gets stuck indefinitely in STATE_WAITING_PRECAPTUREor STATE_WAITING_NON_PRECAPTURE because of aeState which doesn't satisfy the if condition.

           case 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 = STATE_WAITING_NON_PRECAPTURE;
                }
                break;
            }
            case 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 = STATE_PICTURE_TAKEN;
                    captureStillPicture();
                }
                break;
            }

Upvotes: 1

Views: 1514

Answers (2)

Anil Raavi
Anil Raavi

Reputation: 139

i think it should be like this,

 case STATE_WAITING_PRECAPTURE:
              {
                JQLog.d(TAG, "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
                    || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                  state = STATE_WAITING_NON_PRECAPTURE;
                }
                break;
              }

Upvotes: 1

Hong Duan
Hong Duan

Reputation: 4294

When it fails to take a picture, the CameraCaptureSession.CaptureCallback's onCaptureCompleted will not be called, so your takePicture.setVisibility(View.VISIBLE) in unlockFocus() which is called inside onCaptureCompleted will not be called, then the button is disappeared.

You should handle the situation when the capture request fails. onCaptureFailed and onCaptureSequenceCompleted in CameraCaptureSession.CaptureCallback will fulfill your requirement, and I prefer to use onCaptureSequenceCompleted because it will be called no matter the capture request fail or succeed. However, you may also need consider about the abort situation, which is relevant to the callback method onCaptureSequenceAborted.

See CameraCaptureSession.CaptureCallback for the full docs.

Upvotes: 0

Related Questions