我在Samsung S5上使用新的Camera2 API.该设备报告的支持硬件级别是LEGACY,这很好.
但是,我似乎无法自动关注此设备.触发自动对焦的请求如下所示:
- previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_AUTO);
- previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_START);
- state = STATE_PREVIEW;
- try {
- captureSession.setRepeatingRequest(previewRequestBuilder.build(),captureCallback,backgroundHandler);
- } catch (CameraAccessException e) {
- e.printStackTrace();
- }
发送请求后,请求的结果始终为CONTROL_AF_STATE_ACTIVE_SCAN,偶尔为CONTROL_AF_STATE_NOT_FOCUSED_LOCKED.
奇怪的是,当状态为CONTROL_AF_STATE_NOT_FOCUSED_LOCKED时,自动对焦会返回CONTROL_AF_STATE_ACTIVE_SCAN状态一段时间,然后返回CONTROL_AF_STATE_NOT_FOCUSED_LOCKED,从而产生无限焦点循环.根据文档,当状态为CONTROL_AF_STATE_NOT_FOCUSED_LOCKED时……
The lens will remain stationary until the AF mode (android.control.afMode) is changed or a new AF trigger is sent to the camera device (android.control.afTrigger).
我想知道这种差异是否是因为硬件级别是LEGACY并且我应该回到使用已弃用的Camera API这一事实,但这对于诸如自动对焦这样的流行功能来说似乎很疯狂.
是否有任何建议如何处理报告LEGACY的设备?
解决方法
我分支表格
google’s Camera2Basic example并将其更改为使用CaptureRequest.CONTROL_AF_MODE_AUTO而不是CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE
您可以从git中获取该项目并对其进行测试 – https://github.com/pinhassi/android-Camera2Basic
或者只是将其添加到Camera2BasicFragment:
- private static final long LOCK_FOCUS_DELAY_ON_FOCUSED = 5000;
- private static final long LOCK_FOCUS_DELAY_ON_UNFOCUSED = 1000;
- private Integer mLastAfState = null;
- private Handler mUiHandler = new Handler(); // UI handler
- private Runnable mLockAutoFocusRunnable = new Runnable() {
- @Override
- public void run() {
- lockAutoFocus();
- }
- };
- public void lockAutoFocus() {
- try {
- // This is how to tell the camera to lock focus.
- mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CameraMetadata.CONTROL_AF_TRIGGER_START);
- CaptureRequest captureRequest = mPreviewRequestBuilder.build();
- mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,null); // prevent CONTROL_AF_TRIGGER_START from calling over and over again
- mCaptureSession.capture(captureRequest,mCaptureCallback,mBackgroundHandler);
- } catch (CameraAccessException e) {
- e.printStackTrace();
- }
- }
- /**
- *
- * @return
- */
- private float getMinimumFocusDistance() {
- if (mCameraId == null)
- return 0;
- Float minimumLens = null;
- try {
- CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
- CameraCharacteristics c = manager.getCameraCharacteristics(mCameraId);
- minimumLens = c.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
- } catch (Exception e) {
- Log.e(TAG,"isHardwareLevelSupported Error",e);
- }
- if (minimumLens != null)
- return minimumLens;
- return 0;
- }
- /**
- *
- * @return
- */
- private boolean isAutoFocusSupported() {
- return isHardwareLevelSupported(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) || getMinimumFocusDistance() > 0;
- }
- // Returns true if the device supports the required hardware level,or better.
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private boolean isHardwareLevelSupported(int requiredLevel) {
- boolean res = false;
- if (mCameraId == null)
- return res;
- try {
- CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
- CameraCharacteristics cameraCharacteristics = manager.getCameraCharacteristics(mCameraId);
- int deviceLevel = cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
- switch (deviceLevel) {
- case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3:
- Log.d(TAG,"Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_3");
- break;
- case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL:
- Log.d(TAG,"Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_FULL");
- break;
- case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY:
- Log.d(TAG,"Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY");
- break;
- case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED:
- Log.d(TAG,"Camera support level: INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED");
- break;
- default:
- Log.d(TAG,"Unknown INFO_SUPPORTED_HARDWARE_LEVEL: " + deviceLevel);
- break;
- }
- if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
- res = requiredLevel == deviceLevel;
- } else {
- // deviceLevel is not LEGACY,can use numerical sort
- res = requiredLevel <= deviceLevel;
- }
- } catch (Exception e) {
- Log.e(TAG,e);
- }
- return res;
- }
然后,添加到STATE_PREVIEW块:
- case STATE_PREVIEW: {
- // We have nothing to do when the camera preview is working normally.
- // TODO: handle auto focus
- Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
- if (afState != null && !afState.equals(mLastAfState)) {
- switch (afState) {
- case CaptureResult.CONTROL_AF_STATE_INACTIVE:
- Log.d(TAG,"CaptureResult.CONTROL_AF_STATE_INACTIVE");
- lockAutoFocus();
- break;
- case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
- Log.d(TAG,"CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN");
- break;
- case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
- Log.d(TAG,"CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED");
- mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
- mUiHandler.postDelayed(mLockAutoFocusRunnable,LOCK_FOCUS_DELAY_ON_FOCUSED);
- break;
- case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
- mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
- mUiHandler.postDelayed(mLockAutoFocusRunnable,LOCK_FOCUS_DELAY_ON_UNFOCUSED);
- Log.d(TAG,"CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED");
- break;
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
- mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
- //mUiHandler.postDelayed(mLockAutoFocusRunnable,"CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED");
- break;
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
- Log.d(TAG,"CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN");
- break;
- case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
- mUiHandler.removeCallbacks(mLockAutoFocusRunnable);
- //mUiHandler.postDelayed(mLockAutoFocusRunnable,LOCK_FOCUS_DELAY_ON_FOCUSED);
- Log.d(TAG,"CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED");
- break;
- }
- }
- mLastAfState = afState;
- break;
- }
并替换所有出现的:
- mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
附:
- if (isAutoFocusSupported())
- mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_AUTO);
- else
- mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);