You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关闭视频播放器后设备方向未恢复为Portrait Mode的问题求助

解决视频退出全屏后无法自动恢复竖屏的问题

这个问题我之前帮不少开发者处理过,核心逻辑很清晰:你的应用默认锁定竖屏,但视频全屏播放时会临时允许横屏,关键是要在视频退出全屏的瞬间,立刻把屏幕方向重置回竖屏锁定状态。下面分Android和iOS两个平台给你具体的实现方案:

Android 端实现步骤

  1. 默认锁定竖屏:在你的主Activity的AndroidManifest.xml里配置竖屏锁定,或者在代码里设置:

    <activity
        android:name=".MainActivity"
        android:screenOrientation="portrait">
    </activity>
    

    或者代码中:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        // 其他初始化代码
    }
    
  2. 视频全屏时临时允许横屏:当用户点击全屏按钮时,调用代码切换到横屏模式(以ExoPlayer为例):

    // 进入全屏的触发逻辑,比如点击全屏按钮
    private void enterFullScreen() {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        // 这里添加你的全屏UI切换代码,比如隐藏状态栏、切换布局等
    }
    
  3. 退出全屏时立刻恢复竖屏:监听视频播放器的退出全屏回调,在回调里重置屏幕方向:

    // 以ExoPlayer的全屏状态监听为例
    playerView.setFullscreenButtonClickListener(v -> {
        boolean isFullScreen = playerView.isFullScreen();
        if (isFullScreen) {
            // 退出全屏
            playerView.setFullScreen(false);
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        } else {
            // 进入全屏
            playerView.setFullScreen(true);
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
        }
    });
    
    // 还要监听视频播放结束的情况,避免播放完自动退出全屏但没恢复竖屏
    player.addListener(new Player.Listener() {
        @Override
        public void onPlaybackStateChanged(int playbackState) {
            if (playbackState == Player.STATE_ENDED && playerView.isFullScreen()) {
                playerView.setFullScreen(false);
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
        }
    });
    

iOS 端实现步骤

  1. 默认锁定竖屏:在Info.plist中设置UISupportedInterfaceOrientations只包含UIInterfaceOrientationPortrait,确保应用默认只能竖屏显示。

  2. 全局控制屏幕旋转权限:在AppDelegate(或SceneDelegate,针对iOS 13+)中添加一个全局变量来控制是否允许横屏:

    var allowRotation = false
    
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return allowRotation ? .allButUpsideDown : .portrait
    }
    

    如果是用SceneDelegate,对应方法是:

    func windowScene(_ windowScene: UIWindowScene, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return allowRotation ? .allButUpsideDown : .portrait
    }
    
  3. 监听视频全屏/退出事件并切换权限:以系统的AVPlayerViewController为例,实现其代理方法:

    class YourVideoViewController: UIViewController, AVPlayerViewControllerDelegate {
        let playerVC = AVPlayerViewController()
    
        func playVideo() {
            let player = AVPlayer(url: yourVideoURL)
            playerVC.player = player
            playerVC.delegate = self
            present(playerVC, animated: true)
        }
    
        // 进入全屏时允许旋转
        func playerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
            (UIApplication.shared.delegate as? AppDelegate)?.allowRotation = true
        }
    
        // 退出全屏时禁止旋转并强制回竖屏
        func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
            (UIApplication.shared.delegate as? AppDelegate)?.allowRotation = false
            // 强制切换回竖屏
            UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
        }
    }
    

    针对iOS 16+,推荐使用更规范的requestGeometryUpdate方法替代直接设置设备方向:

    // 进入全屏时
    if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
        scene.requestGeometryUpdate(.iOS(interfaceOrientations: .allButUpsideDown))
    }
    
    // 退出全屏时
    if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
        scene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait))
    }
    

额外注意事项

  • 如果使用的是第三方播放器(比如ijkplayer、腾讯云播放器等),一定要找到对应的全屏状态回调方法,确保退出全屏时的重置逻辑被触发
  • 测试时要覆盖所有场景:手动点击退出全屏、视频播放完毕自动退出、按返回键退出全屏等
  • 若用WebView加载H5视频,Android要监听WebChromeClientonShowCustomViewonHideCustomView,iOS则可以通过注入JS监听H5的全屏事件,再触发屏幕方向重置

内容的提问来源于stack exchange,提问作者Dimple Shah

火山引擎 最新活动