user2424511
user2424511

Reputation: 335

What's the correct way to detect a screen rotation from 0 to 180, or 90 to 270?

I'm attempting to orient a camera preview according to the screen's rotation.

I've noticed that when rotating directly between orientations with matching dimensions (so, 0 -> 180, and 90 -> 270), the configuration is not changed and the activity is not restarted.

I'm currently using Display.getRotation() within Activity.onCreate(), but this information becomes out of date.

What's the best way to detect this change so that I can appropriately re-orient my camera preview?

Upvotes: 1

Views: 2499

Answers (1)

Patrick
Patrick

Reputation: 35234

Use an OrientationEventListener

In your SurfaceHolder.Callback

    orientationListener = createOrientationListener();

    private OrientationEventListener createOrientationListener() {
            return new OrientationEventListener(getActivity()) {
                public void onOrientationChanged(int orientation) {
                    try {
                        if (orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
                            setCameraDisplayOrientation(getActivity().getWindowManager().getDefaultDisplay().getRotation());
                        }
                    } catch (Exception e) {
                        Log.w(TAG, "Error while onOrientationChanged", e);
                    }
                }
            };
        }


     @Override
     public void surfaceCreated(SurfaceHolder holder) {
         orientationListener.enable();
     }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        orientationListener.disable();
    }

Your change rotation method has to manage unneeded double rotations

public void setCameraDisplayOrientation(int displayRotation) {
            int degrees = 0;
            switch (displayRotation) {
                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 (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                result = (cameraInfo.orientation + degrees) % 360;
                result = (360 - result) % 360;  // compensate the mirror
            } else {  // back-facing
                result = (cameraInfo.orientation - degrees + 360) % 360;
            }
            if(result != currentSetRotation) {
                    currentSetRotation = result;
                    camera.setDisplayOrientation(result);
                    Log.d(TAG,"For displayRotation "+displayRotation+" we set a camera rotation of "+result);

            }
    }

See also: Rotating phone quickly 180 degrees, camera preview turns upside down

Upvotes: 3

Related Questions