Nexus 5x reverse landscape sensor fix in a android camera preview app

I am kind of newbie in Android development, so my apologies in advance if my question is trivial. In one part of my app I need a live preview of my rear camera, so I created a custom class which extends SurfaceView and implement SurfaceHolder.Callback (I followed basically the instructions in the android documentation).

Unfortunately, I am testing my app in a Nexus 5x, which I've just realized that it has installed the camera sensor in a reverse way. For that reason, the camera preview of my app when running on my Nexus 5x appears upside down, which is something I dont want.

It seems that the new android.hardware.camera2 API is able to handle this issue automatically. Eventually I'll need to update all my code using this new API, but for now what I need is a quick fix while using the old camera API.

So I was reading out there and I found a piece of code that I would need to introduce in the SurfaceChanged method to workaround this issue. Here it is:

Display display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

        if(display.getRotation() == Surface.ROTATION_0)
        {
            parameters.setPreviewSize(capHeight, capWidth);                           
            camera.setDisplayOrientation(90);
        }

        if(display.getRotation() == Surface.ROTATION_90)
        {
            parameters.setPreviewSize(capWidth, capHeight);                           
        }

        if(display.getRotation() == Surface.ROTATION_180)
        {
            parameters.setPreviewSize(capHeight, capWidth);               
        }

        if(display.getRotation() == Surface.ROTATION_270)
        {
            parameters.setPreviewSize(capWidth, capHeight);
            camera.setDisplayOrientation(180);
        }

        camera.setParameters(parameters);*/

        camera.startPreview();

The problem is that I don't see that something has changed.

Any thoughts?


Solution 1:

The 5X camera is not "reverse"; it does report the correct camera orientation in its parameters, so no special workarounds are needed, just make sure you're setting the display orientation correctly:

 public static void setCameraDisplayOrientation(Activity activity,
     int cameraId, android.hardware.Camera camera) {
 android.hardware.Camera.CameraInfo info =
         new android.hardware.Camera.CameraInfo();
 android.hardware.Camera.getCameraInfo(cameraId, info);
 int rotation = activity.getWindowManager().getDefaultDisplay()
         .getRotation();
 int degrees = 0;
 switch (rotation) {
     case Surface.ROTATION_0: degrees = 0; break;
     case Surface.ROTATION_90: degrees = 90; break;
     case Surface.ROTATION_180: degrees = 180; break;
     case Surface.ROTATION_270: degrees = 270; break;
 }

 int result;
 if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
     result = (info.orientation + degrees) % 360;
     result = (360 - result) % 360;  // compensate the mirror
 } else {  // back-facing
     result = (info.orientation - degrees + 360) % 360;
 }
 camera.setDisplayOrientation(result);
}

From http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation%28int%29

Solution 2:

if (Build.MODEL.equals("Nexus 5X")){
     // rotate camera 180°
     mCamera.setDisplayOrientation(180);
}

Change 5x to 5X will be ok.