title: Android Camera2 Wrong Rotation
body: <p>I'm trying to implement <strong>android.hardware.camera2</strong>, but I'm a little bit confused with it.</p>
  <p>The camera is rotating with the phone.</p>
  <p>BEFORE Taking the picture, If I rotated the phone the camera is rotating instead of keeping the same position.</p>
  <p>Example image <a href="https://imgur.com/fE1EqXv" rel="nofollow noreferrer">here</a>.</p>
  <p>I don't know why it happens. I don't have two layouts for the holder.</p>
  <p>Camera XML:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  &lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
      xmlns:fab=&quot;http://schemas.android.com/apk/res-auto&quot;
      xmlns:tools=&quot;http://schemas.android.com/tools&quot;
      android:layout_width=&quot;match_parent&quot;
      android:layout_height=&quot;match_parent&quot;
      tools:context=&quot;.Camera&quot; &gt;
  
      &lt;TextureView
          android:id=&quot;@+id/texture&quot;
          android:layout_width=&quot;match_parent&quot;
          android:layout_height=&quot;match_parent&quot;
          android:layout_alignParentTop=&quot;true&quot; /&gt;
  
      &lt;com.getbase.floatingactionbutton.FloatingActionButton
          android:id=&quot;@+id/btn_takepicture&quot;
          android:layout_width=&quot;wrap_content&quot;
          android:layout_height=&quot;wrap_content&quot;
          fab:fab_icon=&quot;@drawable/ic_fab_foto&quot;
          fab:fab_colorNormal=&quot;#FFFF56B9&quot;
          fab:fab_colorPressed=&quot;#FFD5379B&quot;
          android:layout_alignParentBottom=&quot;true&quot;
          android:layout_centerHorizontal=&quot;true&quot;
          android:layout_marginBottom=&quot;16dp&quot; /&gt;
  
      &lt;com.getbase.floatingactionbutton.FloatingActionButton
          android:id=&quot;@+id/btn_switchcam&quot;
          android:layout_width=&quot;wrap_content&quot;
          android:layout_height=&quot;wrap_content&quot;
          fab:fab_icon=&quot;@drawable/ic_fab_switch&quot;
          fab:fab_colorNormal=&quot;#267300&quot;
          fab:fab_colorPressed=&quot;#1e5b00&quot;
          fab:fab_size=&quot;mini&quot;
          android:layout_alignParentTop=&quot;true&quot;
          android:layout_alignParentRight=&quot;true&quot;
          android:layout_marginTop=&quot;16dp&quot;
          android:layout_marginRight=&quot;16dp&quot; /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  <p>Camera Activity:</p>
  <pre class="lang-java prettyprint-override"><code>public class AppCamera extends AppCompatActivity {
      private Size mPreviewSize;
  
      private TextureView mTextureView;
      private CameraDevice mCameraDevice;
      private CaptureRequest.Builder mPreviewBuilder;
      private CameraCaptureSession mPreviewSession;
      private static int cam = 0;
  
      private FloatingActionButton mBtnShot;
      private FloatingActionButton mBtnSwitch;
  
      private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
  
      static {
          ORIENTATIONS.append(Surface.ROTATION_0, 90);
          ORIENTATIONS.append(Surface.ROTATION_90, 0);
          ORIENTATIONS.append(Surface.ROTATION_180, 270);
          ORIENTATIONS.append(Surface.ROTATION_270, 180);
      }
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
          setContentView(R.layout.camera);
  
          mTextureView = (TextureView)findViewById(R.id.texture);
          mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
  
          mBtnShot = (FloatingActionButton)findViewById(R.id.btn_takepicture);
          mBtnSwitch = (FloatingActionButton)findViewById(R.id.btn_switchcam);
  
          mBtnShot.setOnClickListener(new OnClickListener(){
  
              @Override
              public void onClick(View v) {
                  takePicture();
              }
  
          });
  
          mBtnSwitch.setOnClickListener(new OnClickListener(){
  
              @Override
              public void onClick(View v) {
                  if (cam == 0) {
                      cam = 1;
                  } else {
                      cam = 0;
                  }
                  if (null != mCameraDevice) {
                      mCameraDevice.close();
                      mCameraDevice = null;
                  }
                  openCamera();
              }
  
          });
  
      }
  
      protected void takePicture() {
          if(null == mCameraDevice) {
              return;
          }
  
          CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
          try {
              CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraDevice.getId());
  
              Size[] jpegSizes = null;
              if (characteristics != null) {
                  jpegSizes = characteristics
                          .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
                          .getOutputSizes(ImageFormat.JPEG);
              }
              int width = 640;
              int height = 480;
              if (jpegSizes != null &amp;&amp; 0 &lt; jpegSizes.length) {
                  width = jpegSizes[0].getWidth();
                  height = jpegSizes[0].getHeight();
              }
  
              ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
              List&lt;Surface&gt; outputSurfaces = new ArrayList&lt;Surface&gt;(2);
              outputSurfaces.add(reader.getSurface());
              outputSurfaces.add(new Surface(mTextureView.getSurfaceTexture()));
  
              final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
              captureBuilder.addTarget(reader.getSurface());
              captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH);
  
              // Orientation
              int rotation = getWindowManager().getDefaultDisplay().getRotation();
              captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
  
              final File file = new File(Environment.getExternalStorageDirectory()+&quot;/DCIM&quot;, &quot;teste.jpg&quot;);
  
              ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
  
                  @Override
                  public void onImageAvailable(ImageReader reader) {
  
                      Image image = null;
                      try {
                          image = reader.acquireLatestImage();
                          ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                          byte[] bytes = new byte[buffer.capacity()];
                          buffer.get(bytes);
                          save(bytes);
                      } catch (FileNotFoundException e) {
                          e.printStackTrace();
                      } catch (IOException e) {
                          e.printStackTrace();
                      } finally {
                          if (image != null) {
                              image.close();
                          }
                      }
                  }
  
                  private void save(byte[] bytes) throws IOException {
                      OutputStream output = null;
                      try {
                          output = new FileOutputStream(file);
                          output.write(bytes);
                      } finally {
                          if (null != output) {
                              output.close();
                          }
                      }
                  }
  
              };
  
              HandlerThread thread = new HandlerThread(&quot;CameraPicture&quot;);
              thread.start();
              final Handler backgroudHandler = new Handler(thread.getLooper());
              reader.setOnImageAvailableListener(readerListener, backgroudHandler);
  
              final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
  
                  @Override
                  public void onCaptureCompleted(CameraCaptureSession session,
                                                 CaptureRequest request, TotalCaptureResult result) {
  
                      super.onCaptureCompleted(session, request, result);
                      Toast.makeText(AppCamera.this, &quot;Saved:&quot;+file, Toast.LENGTH_SHORT).show();
                      startPreview();
                  }
  
              };
  
              mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
  
                  @Override
                  public void onConfigured(CameraCaptureSession session) {
  
                      try {
                          session.capture(captureBuilder.build(), captureListener, backgroudHandler);
                      } catch (CameraAccessException e) {
  
                          e.printStackTrace();
                      }
                  }
  
                  @Override
                  public void onConfigureFailed(CameraCaptureSession session) {
  
                  }
              }, backgroudHandler);
  
          } catch (CameraAccessException e) {
              e.printStackTrace();
          }
  
      }
  
      @Override
      protected void onResume() {
          super.onResume();
      }
  
      private void openCamera() {
  
          CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
          try {
              String cameraId = manager.getCameraIdList()[cam];
              CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
              StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
              mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
  
              manager.openCamera(cameraId, mStateCallback, null);
          } catch (CameraAccessException e) {
              e.printStackTrace();
          }
      }
  
      private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener(){
  
          @Override
          public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
              openCamera();
          }
  
          @Override
          public void onSurfaceTextureSizeChanged(SurfaceTexture surface,
                                                  int width, int height) {
          }
  
          @Override
          public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
              return false;
          }
  
          @Override
          public void onSurfaceTextureUpdated(SurfaceTexture surface) {
              //Log.e(TAG, &quot;onSurfaceTextureUpdated&quot;);
          }
  
      };
  
      private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
  
          @Override
          public void onOpened(CameraDevice camera) {
  
              mCameraDevice = camera;
              startPreview();
          }
  
          @Override
          public void onDisconnected(CameraDevice camera) {
  
          }
  
          @Override
          public void onError(CameraDevice camera, int error) {
  
          }
  
      };
  
      @Override
      protected void onPause() {
  
          super.onPause();
          if (null != mCameraDevice) {
              mCameraDevice.close();
              mCameraDevice = null;
          }
      }
  
      protected void startPreview() {
  
          if(null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
              return;
          }
  
          SurfaceTexture texture = mTextureView.getSurfaceTexture();
          if(null == texture) {
              return;
          }
  
          texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
          Surface surface = new Surface(texture);
  
          try {
              mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
          } catch (CameraAccessException e) {
  
              e.printStackTrace();
          }
          mPreviewBuilder.addTarget(surface);
  
          try {
              mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
  
                  @Override
                  public void onConfigured(CameraCaptureSession session) {
  
                      mPreviewSession = session;
                      updatePreview();
                  }
  
                  @Override
                  public void onConfigureFailed(CameraCaptureSession session) {
  
                      Toast.makeText(AppCamera.this, &quot;onConfigureFailed&quot;, Toast.LENGTH_LONG).show();
                  }
              }, null);
          } catch (CameraAccessException e) {
  
              e.printStackTrace();
          }
      }
  
      protected void updatePreview() {
  
          if(null == mCameraDevice) {
          }
  
          mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
          HandlerThread thread = new HandlerThread(&quot;CameraPreview&quot;);
          thread.start();
          Handler backgroundHandler = new Handler(thread.getLooper());
  
          try {
              mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler);
          } catch (CameraAccessException e) {
  
              e.printStackTrace();
          }
      }
  }
  </code></pre>