如何在安卓竖屏锁定界面中检测屏幕方向?

11

我希望在锁定纵向方向模式下找到相机屏幕方向,我正在使用我的片段类中的相机,并已将屏幕方向设置为纵向,但我面临的问题是,当我将相机从纵向变为横向时,它会发生改变,我需要仅在相机处于纵向模式时设置捕获按钮可见。有人能帮我获取纵向模式下的方向更改吗? 以下是我的代码:

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

sensorManager.registerListener(new SensorEventListener() {

    int orientation=-1;;

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.values[1] < 6.5 && event.values[1] > -6.5) {
            if (orientation!=1) {
                Log.d("Sensor", "Landscape");
            }
            orientation = 1;
        } else {
            if (orientation!=0) {
                Log.d("Sensor", "Portrait");
            }
            orientation = 0;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);

if (orientation == 0) {
    // capture button visisble
} else {
    // invisible
}

https://dev59.com/Km025IYBdhLWcg3w6aUX#5726776 - Rakeeb Rajbhandari
看一下这个:https://dev59.com/2H7aa4cB1Zd3GeqPvNAK#41104983 这个解决方案使用SensorManager。 - Maher Abuthraa
3个回答

38
您可以使用OrientationEventListener来实现此功能。这是一个自定义此功能的类。
public abstract class SimpleOrientationListener extends OrientationEventListener {

        public static final int CONFIGURATION_ORIENTATION_UNDEFINED = Configuration.ORIENTATION_UNDEFINED;
        private volatile int defaultScreenOrientation = CONFIGURATION_ORIENTATION_UNDEFINED;
        public int prevOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
        private Context ctx;
        private ReentrantLock lock = new ReentrantLock(true);

        public SimpleOrientationListener(Context context) {
            super(context);
            ctx = context;
        }

        public SimpleOrientationListener(Context context, int rate) {
            super(context, rate);
            ctx = context;
        }

        @Override
        public void onOrientationChanged(final int orientation) {
            int currentOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
            if (orientation >= 330 || orientation < 30) {
                currentOrientation = Surface.ROTATION_0;
            } else if (orientation >= 60 && orientation < 120) {
                currentOrientation = Surface.ROTATION_90;
            } else if (orientation >= 150 && orientation < 210) {
                currentOrientation = Surface.ROTATION_180;
            } else if (orientation >= 240 && orientation < 300) {
                currentOrientation = Surface.ROTATION_270;
            }

            if (prevOrientation != currentOrientation && orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
                prevOrientation = currentOrientation;
                if (currentOrientation != OrientationEventListener.ORIENTATION_UNKNOWN)
                    reportOrientationChanged(currentOrientation);
            }

        }

        private void reportOrientationChanged(final int currentOrientation) {

            int defaultOrientation = getDeviceDefaultOrientation();
            int orthogonalOrientation = defaultOrientation == Configuration.ORIENTATION_LANDSCAPE ? Configuration.ORIENTATION_PORTRAIT
                    : Configuration.ORIENTATION_LANDSCAPE;

            int toReportOrientation;

            if (currentOrientation == Surface.ROTATION_0 || currentOrientation == Surface.ROTATION_180)
                toReportOrientation = defaultOrientation;
            else
                toReportOrientation = orthogonalOrientation;

            onSimpleOrientationChanged(toReportOrientation);
        }

        /**
         * Must determine what is default device orientation (some tablets can have default landscape). Must be initialized when device orientation is defined.
         *
         * @return value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        private int getDeviceDefaultOrientation() {
            if (defaultScreenOrientation == CONFIGURATION_ORIENTATION_UNDEFINED) {
                lock.lock();
                defaultScreenOrientation = initDeviceDefaultOrientation(ctx);
                lock.unlock();
            }
            return defaultScreenOrientation;
        }

        /**
         * Provides device default orientation
         *
         * @return value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        private int initDeviceDefaultOrientation(Context context) {

            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Configuration config = context.getResources().getConfiguration();
            int rotation = windowManager.getDefaultDisplay().getRotation();

            boolean isLand = config.orientation == Configuration.ORIENTATION_LANDSCAPE;
            boolean isDefaultAxis = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180;

            int result = CONFIGURATION_ORIENTATION_UNDEFINED;
            if ((isDefaultAxis && isLand) || (!isDefaultAxis && !isLand)) {
                result = Configuration.ORIENTATION_LANDSCAPE;
            } else {
                result = Configuration.ORIENTATION_PORTRAIT;
            }
            return result;
        }

        /**
         * Fires when orientation changes from landscape to portrait and vice versa.
         *
         * @param orientation value of {@link Configuration#ORIENTATION_LANDSCAPE} or {@link Configuration#ORIENTATION_PORTRAIT}
         */
        public abstract void onSimpleOrientationChanged(int orientation);

    }

然后在您想要检测方向的地方调用该函数即可

SimpleOrientationListener mOrientationListener = new SimpleOrientationListener(
                context) {

            @Override
            public void onSimpleOrientationChanged(int orientation) {
                if(orientation == Configuration.ORIENTATION_LANDSCAPE){

                }else if(orientation == Configuration.ORIENTATION_PORTRAIT){

                }
            }
        };
        mOrientationListener.enable();

只需要在onCreate()方法中编写代码,就可以处理屏幕方向的变化。 - Suhail Mehta
非常好的回答@SuhailMehta。 对于其他人...不要忘记在您的onStop()中调用 mOrientationListener.disable(); (如果您在onCreate()中启用了它) - Tim
感谢 @SuhailMehta 提供了很好的答案,但是我该如何用这段代码区分横向和反横向呢? - Antwan
你是个救命恩人啊..我被这个问题困扰了一个星期。刚才找到了你的帖子..真的很开心..继续加油! - karthik kolanji
如何调整此代码以处理正常和反向方向? - Antwan
显示剩余6条评论

0
你需要使用:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);


    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        //do your stuff with the button
    }
}

如果您不希望在屏幕方向更改时重新创建活动,则使用以下内容: android:configChanges="orientation|keyboardHidden|screenSize" 如果您希望强制使您的活动保持纵向,则需要在清单文件中的活动中使用以下代码: android:screenOrientation="portrait" 希望能对您有所帮助!!!

我遇到了空指针异常 @if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) - Vicky
好的,尽管当我将屏幕旋转到横向时,它被检测为纵向,但它仍然没有获得正确的结果。 - Vicky
我的代码目前可以使用,但数值一直在变化,稍微的更改就可能导致代码崩溃。我需要确定正确的数值来设置纵向和横向。如果 (event.values[1] < ? && event.values[1] > ?),则达到要求。 - Vicky
onOrientationChanged() 回调怎么样? - IgorGanapolsky

0

当您的活动仅设置为纵向或横向特定,并且您希望在方向更改时执行某些操作时,您可以实现方向更改值。

private OrientationEventListener orientationEventListener;

在你的类中初始化这个变量,并在onCreate中实现它的监听器。
orientationEventListener = new OrientationEventListener(this) {
        @Override
        public void onOrientationChanged(int orientation) {

            Log.d("Orientation", orientation + " - " + currentOrientation);

            if (orientation >= 330 || orientation < 30) {
                currentOrientation = Surface.ROTATION_0;

            } else if (orientation >= 60 && orientation < 120) {
                currentOrientation = Surface.ROTATION_90;

            } else if (orientation >= 150 && orientation < 210) {
                currentOrientation = Surface.ROTATION_180;

            } else if (orientation >= 240 && orientation < 300) {
                currentOrientation = Surface.ROTATION_270;

            }
        }
    };

currentOrentation 是整数值,用于在活动中使用其他单位。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接