// Sets up member variables related to camera. private void SetUpCameraOutputs(int width, int height) { var activity = Activity; var manager = (CameraManager)activity.GetSystemService(Context.CameraService); try { //var cameraId = manager.GetCameraIdList()[i]; var cameraId = _context.Settings.CameraId; CameraCharacteristics characteristics = manager.GetCameraCharacteristics(cameraId); var map = (StreamConfigurationMap)characteristics.Get(CameraCharacteristics.ScalerStreamConfigurationMap); mImageReader = ImageReader.NewInstance(_context.Settings.CameraResolutionSelected.Width, _context.Settings.CameraResolutionSelected.Height, ImageFormatType.Jpeg, /*maxImages*/ 2); mImageReader.SetOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); // Find out if we need to swap dimension to get the preview size relative to sensor // coordinate. var displayRotation = activity.WindowManager.DefaultDisplay.Rotation; //noinspection ConstantConditions mSensorOrientation = (int)characteristics.Get(CameraCharacteristics.SensorOrientation); bool swappedDimensions = false; switch (displayRotation) { case SurfaceOrientation.Rotation0: case SurfaceOrientation.Rotation180: if (mSensorOrientation == 90 || mSensorOrientation == 270) { swappedDimensions = true; } break; case SurfaceOrientation.Rotation90: case SurfaceOrientation.Rotation270: if (mSensorOrientation == 0 || mSensorOrientation == 180) { swappedDimensions = true; } break; default: Log.Error(TAG, "Display rotation is invalid: " + displayRotation); break; } Point displaySize = new Point(); activity.WindowManager.DefaultDisplay.GetSize(displaySize); var rotatedPreviewWidth = width; var rotatedPreviewHeight = height; var maxPreviewWidth = displaySize.X; var maxPreviewHeight = displaySize.Y; if (swappedDimensions) { rotatedPreviewWidth = height; rotatedPreviewHeight = width; maxPreviewWidth = displaySize.Y; maxPreviewHeight = displaySize.X; } if (maxPreviewWidth > MAX_PREVIEW_WIDTH) { maxPreviewWidth = MAX_PREVIEW_WIDTH; } if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) { maxPreviewHeight = MAX_PREVIEW_HEIGHT; } // Danger, W.R.! Attempting to use too large a preview size could exceed the camera // bus' bandwidth limitation, resulting in gorgeous previews but the storage of // garbage capture data. mPreviewSize = CameraUtilities.ChooseOptimalSize(map?.GetOutputSizes(Class.FromType(typeof(SurfaceTexture))), rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth, maxPreviewHeight, _context.Settings.CameraResolutionSelected); // We fit the aspect ratio of TextureView to the size of preview we picked. if (AppContextLiveData.Instance.IsPortrait) { mTextureView.SetAspectRatio(_context.Settings.CameraResolutionSelected.Height, _context.Settings.CameraResolutionSelected.Width); } else { mTextureView.SetAspectRatio(_context.Settings.CameraResolutionSelected.Width, _context.Settings.CameraResolutionSelected.Height); } // Check if the flash is supported. var available = (Boolean)characteristics.Get(CameraCharacteristics.FlashInfoAvailable); if (available == null) { mFlashSupported = false; } else { mFlashSupported = (bool)available; } mCameraId = cameraId; } catch (CameraAccessException e) { e.PrintStackTrace(); } catch (NullPointerException) { //### // Currently an NPE is thrown when the Camera2API is used but not supported on the // device this code runs. ErrorDialog.NewInstance("Camera error").Show(ChildFragmentManager, FRAGMENT_DIALOG); } }