You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制全屏视频随屏幕旋转?Amazon Fire TV Stick适配问题

问题描述

我在实现设备屏幕旋转功能时,遇到了Amazon Fire TV Stick特有的问题:除该设备外,其他测试设备上代码运行正常,屏幕能完成旋转,但YouTube、Netflix等流媒体应用的全屏视频仍保持默认方向——比如YouTube界面已经倒置,但视频本身还是默认方向。

相关代码如下:

private WindowManager.LayoutParams mainLayoutParams;
private TextView fakeTextView;
private WindowManager windowManager;
private static final int OVERLAY_FLAGS =
        FLAG_NOT_FOCUSABLE | FLAG_KEEP_SCREEN_ON | FLAG_DISMISS_KEYGUARD | FLAG_TURN_SCREEN_ON |
                FLAG_SHOW_WHEN_LOCKED | FLAG_NOT_TOUCHABLE | FLAG_WATCH_OUTSIDE_TOUCH;
@Override
public void onCreate() {
    super.onCreate();
    LogUtils.dTag("NotificationDebug", "onCreate from notification");
    createNotificationChannel();
    mainLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT,
        (Build.VERSION.SDK_INT >= 26) ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE,
        OVERLAY_FLAGS,
        PixelFormat.TRANSLUCENT);

    fakeTextView = new TextView(this);
    windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    WindowManager.LayoutParams layoutParams = mainLayoutParams;
    layoutParams.x = 0;
    layoutParams.y = 0;
    layoutParams.gravity = Gravity.CENTER;
    windowManager.addView(fakeTextView, layoutParams);
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    String orientationType = intent.getStringExtra("NEW_ORIENT_STRING_INTENT_EXTRA_KEY");
    if (orientationType != null)
        if (orientationType.equalsIgnoreCase("landscape")) {
            mainLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        } else if (orientationType.equalsIgnoreCase("portrait")) {
            mainLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        } else if (orientationType.equalsIgnoreCase("landscape_reverse")) {
            mainLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
        } else if (orientationType.equalsIgnoreCase("portrait_reverse")) {
            mainLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
        }
    windowManager.updateViewLayout(fakeTextView, mainLayoutParams);
    return START_STICKY;
}
解决方案

问题根源

当前方案通过添加全屏透明Overlay视图、修改其screenOrientation来强制旋转,但Fire TV上的流媒体应用(如YouTube、Netflix)可能直接调用底层显示服务处理视频渲染,不受WindowManager的Overlay方向控制,导致界面旋转但视频内容保持原方向。

需要改用系统级屏幕旋转控制,直接修改系统显示方向,才能覆盖所有应用(包括流媒体视频)的渲染方向。

1. 申请必要权限

在AndroidManifest.xml中添加WRITE_SETTINGS权限,用于修改系统显示设置:

<uses-permission android:name="android.permission.WRITE_SETTINGS" android:required="false" />

2. 替换为系统级旋转控制代码

删除原有的Overlay相关逻辑,改用以下代码控制屏幕旋转:

private void setSystemOrientation(int orientation) {
    ContentResolver resolver = getContentResolver();
    // Android 6.0+ 需要引导用户授权WRITE_SETTINGS权限
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(this)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        return;
    }

    // 根据目标方向设置系统旋转参数
    switch (orientation) {
        case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
            Settings.System.putInt(resolver, Settings.System.USER_ROTATION, Surface.ROTATION_0);
            break;
        case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
            Settings.System.putInt(resolver, Settings.System.USER_ROTATION, Surface.ROTATION_180);
            break;
        case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
            Settings.System.putInt(resolver, Settings.System.USER_ROTATION, Surface.ROTATION_270);
            break;
        case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
            Settings.System.putInt(resolver, Settings.System.USER_ROTATION, Surface.ROTATION_90);
            break;
    }
}

3. 修改onStartCommand逻辑

替换原有的Overlay更新逻辑,调用新的系统旋转方法:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    String orientationType = intent.getStringExtra("NEW_ORIENT_STRING_INTENT_EXTRA_KEY");
    if (orientationType != null) {
        int targetOrientation = -1;
        switch (orientationType.toLowerCase()) {
            case "landscape":
                targetOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                break;
            case "portrait":
                targetOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                break;
            case "landscape_reverse":
                targetOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                break;
            case "portrait_reverse":
                targetOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                break;
        }
        if (targetOrientation != -1) {
            setSystemOrientation(targetOrientation);
        }
    }
    return START_STICKY;
}

4. 清理Overlay代码

删除onCreate中与fakeTextView、WindowManager Overlay相关的所有代码,不需要再创建透明覆盖视图。

原理说明

通过修改系统USER_ROTATION设置,直接改变整个屏幕的物理显示方向,所有应用(包括流媒体视频的渲染层)都会跟随这个系统级方向旋转,从根源解决Fire TV上视频不跟随旋转的问题。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:43:13