关闭视频播放器后设备方向未恢复为Portrait Mode的问题求助
解决视频退出全屏后无法自动恢复竖屏的问题
这个问题我之前帮不少开发者处理过,核心逻辑很清晰:你的应用默认锁定竖屏,但视频全屏播放时会临时允许横屏,关键是要在视频退出全屏的瞬间,立刻把屏幕方向重置回竖屏锁定状态。下面分Android和iOS两个平台给你具体的实现方案:
Android 端实现步骤
默认锁定竖屏:在你的主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); // 其他初始化代码 }视频全屏时临时允许横屏:当用户点击全屏按钮时,调用代码切换到横屏模式(以ExoPlayer为例):
// 进入全屏的触发逻辑,比如点击全屏按钮 private void enterFullScreen() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); // 这里添加你的全屏UI切换代码,比如隐藏状态栏、切换布局等 }退出全屏时立刻恢复竖屏:监听视频播放器的退出全屏回调,在回调里重置屏幕方向:
// 以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 端实现步骤
默认锁定竖屏:在
Info.plist中设置UISupportedInterfaceOrientations只包含UIInterfaceOrientationPortrait,确保应用默认只能竖屏显示。全局控制屏幕旋转权限:在
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 }监听视频全屏/退出事件并切换权限:以系统的
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要监听
WebChromeClient的onShowCustomView和onHideCustomView,iOS则可以通过注入JS监听H5的全屏事件,再触发屏幕方向重置
内容的提问来源于stack exchange,提问作者Dimple Shah




