title: Android: how to detect if camera flashed
body: <p>I'm using Android's Camera2 API and I currently want the camera to perform a certain action whenever it prepares to flash.</p>
  
  <p>When building the CaptureRequest, the following line:</p>
  
  <pre><code>captureRequest.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
  </code></pre>
  
  <p>allows the camera to flash under low-lighting conditions. However, I am at a loss as to how I can detect whether the camera is prepped to flash or not.  It seems like the literature online about this particular action is pretty sparse.</p>
  
  <p>I have tried checking if <code>FLASH_STATE</code> is in <code>FLASH_STATE_READY</code> while processing a partialresult in the camera's <code>CaptureCallback</code>, but it seems like the key wasn't available - it kept returning <code>null</code>.  Perhaps I'm not checking in the right place?</p>
  
  <p>The camera's <code>CaptureCallback</code>, shown below (based off Google's <code>Camera2Basic</code> code sample):</p>
  
  <pre><code>private CameraCaptureSession.CaptureCallback mCaptureCallback
          = new CameraCaptureSession.CaptureCallback()    {
      private void process(CaptureResult result)  {
          switch(mState)  {
              case STATE_PREVIEW: break;
              case STATE_WAITING_LOCK:
                  // checking if result.get(CaptureResult.FLASH_STATE) == 
                  // CaptureResult.FLASH_READY over here didn't work because
                  // null was returned
                  int afState = result.get(CaptureResult.CONTROL_AF_STATE);
                  if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                          CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                      Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                      if (aeState == null ||
                              aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                          mState = STATE_WAITING_NON_PRECAPTURE;
                          captureStillPicture();
                      } else {
                          runPrecaptureSequence();
                      }
                  }
                  break;
              case STATE_WAITING_PRECAPTURE:
                  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:
                  Integer aeState1 = result.get(CaptureResult.CONTROL_AE_STATE);
                  if (aeState1 == null || aeState1 != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
                      mState = STATE_PICTURE_TAKEN;
                      captureStillPicture();
                  }
                  break;
          }
      }
  
      @Override
      public void onCaptureProgressed(CameraCaptureSession session,
                                      CaptureRequest request, CaptureResult partialResult) {
          super.onCaptureProgressed(session, request, partialResult);
          process(partialResult);
      }
  
      @Override
      public void onCaptureCompleted(CameraCaptureSession session,
                                     CaptureRequest request, TotalCaptureResult result) {
          super.onCaptureCompleted(session, request, result);
          process(result);
      }
  };
  </code></pre>