安卓屏幕方向自适应传感器

10

我想在按钮点击时强制屏幕方向为横屏,通过设置

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

它可以正常工作。现在我想让应用程序跟随传感器,这样当向纵向倾斜时方向就会恢复为纵向。我知道可以通过设置setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);来实现,但不知道在哪里设置它。如果将方向强制设为横向,则无论您向任何方向倾斜,方向都将保持为横向。有人能指定如何重置方向标志吗?

3个回答

11

目前的YouTube应用程序可以满足您的要求。
我在视频播放应用程序中也遇到了同样的问题。

如果用户将设备从竖向旋转成横向,则应初始化OrientationEventListener,该侦听器通过SensorManager通知您设备的方向,范围为0至360。

请观察设备是否倾斜到横向方向范围内,这个范围大约是 (orientation >= 60 && orientation <= 120) || (orientation >= 240 && orientation <= 300) ,并将此状态保存到枚举或标志中。然后,如果设备回到纵向方向范围(orientation <= 40 || orientation >= 320),检查枚举/标志并调用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);,重置枚举/标志并禁用传感器直到用户再次强制旋转设备。

以下是演示代码:

private enum SensorStateChangeActions {
        WATCH_FOR_LANDSCAPE_CHANGES, SWITCH_FROM_LANDSCAPE_TO_STANDARD, WATCH_FOR_POTRAIT_CHANGES, SWITCH_FROM_POTRAIT_TO_STANDARD;
}

private SensorStateChangeActions mSensorStateChanges;

public void goFullScreen() {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        mSensorStateChanges = SensorStateChangeActions.WATCH_FOR_LANDSCAPE_CHANGES;
        if (null == sensorEvent)
            initialiseSensor(true);
        else
            sensorEvent.enable();
}

public void shrinkToPotraitMode() {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        mSensorStateChanges = SensorStateChangeActions.WATCH_FOR_POTRAIT_CHANGES;
        if (null == sensorEvent)
            initialiseSensor(true);
        else
            sensorEvent.enable();
}
/**
 * Initialises system sensor to detect device orientation for player changes.
 * Don't enable sensor until playback starts on player
 *
 * @param enable if set, sensor will be enabled.
 */
private void initialiseSensor(boolean enable) {
    sensorEvent = new OrientationEventListener(this,
            SensorManager.SENSOR_DELAY_NORMAL) {

        @Override
        public void onOrientationChanged(int orientation) {
            /*
             * This logic is useful when user explicitly changes orientation using player controls, in which case orientation changes gives no callbacks.
             * we use sensor angle to anticipate orientation and make changes accordingly.
             */
            if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.WATCH_FOR_LANDSCAPE_CHANGES
                    && ((orientation >= 60 && orientation <= 120) || (orientation >= 240 && orientation <= 300))) {
                mSensorStateChanges = SensorStateChangeActions.SWITCH_FROM_LANDSCAPE_TO_STANDARD;
            } else if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.SWITCH_FROM_LANDSCAPE_TO_STANDARD
                    && (orientation <= 40 || orientation >= 320)) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                mSensorStateChanges = null;
                sensorEvent.disable();
            } else if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.WATCH_FOR_POTRAIT_CHANGES
                    && ((orientation >= 300 && orientation <= 359) || (orientation >= 0 && orientation <= 45))) {
                mSensorStateChanges = SensorStateChangeActions.SWITCH_FROM_POTRAIT_TO_STANDARD;
            } else if (null != mSensorStateChanges
                    && mSensorStateChanges == SensorStateChangeActions.SWITCH_FROM_POTRAIT_TO_STANDARD
                    && ((orientation <= 300 && orientation >= 240) || (orientation <= 130 && orientation >= 60))) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                mSensorStateChanges = null;
                sensorEvent.disable();
            }
        }
    };
    if (enable)
        sensorEvent.enable();
}

这类似于YouTube的功能,希望能对您有所帮助。

这正是我一直在寻找的:模拟YouTube应用程序正在执行的操作!谢谢 :) - wblaschko
@CodeFury 如何使用它,sensorEvent是什么? - Shivam Kumar
这是一个非常好的答案。 - Sandeep
你能演示如何在项目或演示项目中使用这段代码吗? - pavel
当从纵向模式切换到横向模式时,这个不起作用。 - Waqas Yousaf

4
我认为在这里你应该使用 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)

1

这取决于您希望传感器何时再次检测旋转。

就我个人而言,在我正在开发的应用程序中,我有一个特定的活动需要处于纵向模式,因此我在该活动的onResume()中使用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);,并在onPause()中使用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);,它可以正常工作。当我进入该活动时,如果它不是纵向模式,则设置为纵向模式,并且不允许更改,退出时传感器再次起作用...

您试图在哪里启用和禁用传感器?


我的应用程序默认为竖屏模式。用户可以通过点击按钮或倾斜设备来切换到横屏模式。但在横屏模式下,没有办法将活动带回到竖屏模式。如果必须提供另一个按钮来强制定向为竖屏,则这将是最后的选择。我想知道在强制为横屏后是否可能设置为传感器模式。我尝试了您在暂停时设置为传感器模式的选项,但当我想要在设备处于竖屏模式时强制为横屏模式时,它会恢复为竖屏模式。 - Kulai

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