What I want to achieve is capturing a picture without showing the preview, sending directly the output to an ImageReader.  I have used the Camera2Basic example as a starting point.  However, the callback of my ImageReader is never called, hence no image is sent to its Surface. Do I really need to display a preview first?
This is the camera code, which is ordered following the flow of the asynchronous callbacks:
private ImageReader imageReader; private Handler backgroundHandler; private HandlerThread backgroundThread; private String cameraId; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession;     @Override     public void onCreate() {         setupCamera2();     }      private void setupCamera2() {         CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);          try {              for (String cameraId : manager.getCameraIdList()) {             CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);              if (characteristics.get(CameraCharacteristics.LENS_FACING) != CameraCharacteristics.LENS_FACING_FRONT) {                 continue;             }              this.cameraId = cameraId;              int[] picSize = Settings.getPictureSize();             int picWidth = picSize[0];             int picHeight = picSize[1];              imageReader = ImageReader.newInstance(picWidth, picHeight, ImageFormat.JPEG, 2);             imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler);             }          } catch (CameraAccessException | NullPointerException e) {             e.printStackTrace();         }     }       private void openCamera2() {         CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);         try {              manager.openCamera(cameraId, cameraStateCallback, backgroundHandler);          } catch (CameraAccessException e) {             e.printStackTrace();         }     }        private final CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() {         @Override         public void onOpened(CameraDevice device) {             cameraDevice = device;             createCameraCaptureSession();         }          @Override         public void onDisconnected(CameraDevice cameraDevice) {}          @Override         public void onError(CameraDevice cameraDevice, int error) {}     };        private void createCaptureSession() {         List<Surface> outputSurfaces = new LinkedList<>();         outputSurfaces.add(imageReader.getSurface());          try {              cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {                 @Override                 public void onConfigured(CameraCaptureSession session) {                     cameraCaptureSession = session;                 }                  @Override                 public void onConfigureFailed(CameraCaptureSession session) {}             }, null);          } catch (CameraAccessException e) {             e.printStackTrace();         }     }       private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {         @Override         public void onImageAvailable(ImageReader reader) {             createCaptureRequest();         }     };       private void createCaptureRequest() {         try {              CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);             requestBuilder.addTarget(imageReader.getSurface());              // Focus             requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);              // Orientation             int rotation = windowManager.getDefaultDisplay().getRotation();             requestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));              cameraCaptureSession.capture(requestBuilder.build(), camera2Callback, null);          } catch (CameraAccessException e) {             e.printStackTrace();         }     } 
                camera2 API for new applications. This class was deprecated in API level 21. We recommend using the new android.
Full: These devices support all of the major capabilities of Camera API2 and must use Camera HAL 3.2 or higher and Android 5.0 or higher. Level_3: These devices support YUV reprocessing and RAW image capture, along with additional output stream configurations on top of full Camera2 API support.
Camera2 is the latest low-level Android camera package and replaces the deprecated Camera class. Camera2 provides in-depth controls for complex use cases, but requires you to manage device-specific configurations.
For new apps, we recommend starting with CameraX. It provides a consistent, easy-to-use API that works across the vast majority of Android devices, with backward-compatibility to Android 5.0 (API level 21).
You should capture photos in "onConfigured" function but not onImageAvailable.
public void onConfigured(CameraCaptureSession session) {             cameraCaptureSession = session;             createCaptureRequest();         }   In this function "onImageAvailable",you should save images,
Image image = mImageReader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); try {     save(bytes, file); } catch (IOException e) {     e.printStackTrace(); } image.close();   "onImageAvailable" function will be invoked after session.capture() .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With