android修改framework固定屏幕

本文介绍如何在Android系统中修改WindowManagerService的updateRotationUncheckedLocked方法,实现特定的屏幕旋转行为。涉及屏幕旋转动画、显示状态检查及应用方向变更处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件位置:
.\frameworks\base\services\java\com\android\server\wm
文件:
WindowManagerService.java
找到updateRotationUncheckedLocked方法,按以下      "//add by ytmfdw"    处进行修改
代码:
 
public boolean updateRotationUncheckedLocked(boolean inTransaction) {
        if (mDeferredRotationPauseCount > 0) {
            // Rotation updates have been paused temporarily.  Defer the update until
            // updates have been resumed.
            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused." );
            return false ;
        }

        ScreenRotationAnimation screenRotationAnimation =
                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
        if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
            // Rotation updates cannot be performed while the previous rotation change
            // animation is still in progress.  Skip this update.  We will try updating
            // again after the animation is finished and the display is unfrozen.
            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress." );
            return false ;
        }

        if (!mDisplayEnabled) {
            // No point choosing a rotation if the display is not enabled.
            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled." );
            return false ;
        }

        // TODO: Implement forced rotation changes.
        //       Set mAltOrientation to indicate that the application is receiving
        //       an orientation that has different metrics than it expected.
        //       eg. Portrait instead of Landscape.

        int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
        boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
                mForcedAppOrientation, rotation);

        if (DEBUG_ORIENTATION) {
            Slog.v(TAG, "Application requested orientation "
                    + mForcedAppOrientation + ", got rotation " + rotation
                    + " which has " + (altOrientation ? "incompatible" : "compatible" )
                    + " metrics");
        }
        // add by ytmfdw   
       rotation=0;    //修改这里,0:竖屏,3:横屏 
       
        if (mRotation == rotation && mAltOrientation == altOrientation) {
            // No change.
            return false ;
        }

        if (DEBUG_ORIENTATION) {
            Slog.v(TAG,
                "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "" )
                + " from " + mRotation + (mAltOrientation ? " (alt)" : "" )
                + ", forceApp=" + mForcedAppOrientation);
        }

        mRotation = rotation;
        mAltOrientation = altOrientation;
        mPolicy.setRotationLw(mRotation);

        mWindowsFreezingScreen = true;
        mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
        mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
                WINDOW_FREEZE_TIMEOUT_DURATION);
        mWaitingForConfig = true;
        getDefaultDisplayContentLocked().layoutNeeded = true;
        startFreezingDisplayLocked(inTransaction, 0, 0);
        // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
        screenRotationAnimation =
                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);

        // We need to update our screen size information to match the new
        // rotation.  Note that this is redundant with the later call to
        // sendNewConfiguration() that must be called after this function
        // returns...  however we need to do the screen size part of that
        // before then so we have the correct size to use when initializing
        // the rotation animation for the new rotation.
        computeScreenConfigurationLocked( null);

        final DisplayContent displayContent = getDefaultDisplayContentLocked();
        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
        if (!inTransaction) {
            if (SHOW_TRANSACTIONS) {
                Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
            }
            Surface.openTransaction();
        }
        try {
            // NOTE: We disable the rotation in the emulator because
            //       it doesn't support hardware OpenGL emulation yet.
            if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
                    && screenRotationAnimation.hasScreenshot()) {
                if (screenRotationAnimation.setRotationInTransaction(
                        rotation, mFxSession,
                        MAX_ANIMATION_DURATION, mTransitionAnimationScale,
                        displayInfo.logicalWidth, displayInfo.logicalHeight)) {
                    updateLayoutToAnimationLocked();
                }
            }

            mDisplayManagerService.performTraversalInTransactionFromWindowManager();
        } finally {
            if (!inTransaction) {
                Surface.closeTransaction();
                if (SHOW_LIGHT_TRANSACTIONS) {
                    Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
                }
            }
        }

        final WindowList windows = displayContent.getWindowList();
        for (int i = windows.size() - 1; i >= 0; i--) {
            WindowState w = windows.get(i);
            if (w.mHasSurface) {
                if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
                w.mOrientationChanging = true;
                mInnerFields.mOrientationChangeComplete = false;
            }
        }

        for (int i=mRotationWatchers.size()-1; i>=0; i--) {
            try {
                mRotationWatchers.get(i).onRotationChanged(rotation);
            } catch (RemoteException e) {
            }
        }

        scheduleNotifyRotationChangedIfNeededLocked(displayContent, rotation);

        return true ;
    }


Android 开发中,若需要将屏幕方向设置为固定方向,可以通过多种方式实现。以下几种方法可以根据具体需求进行选择。 ### 通过 `AndroidManifest.xml` 设置固定方向 可以在应用的 `AndroidManifest.xml` 文件中为特定的 Activity 指定固定屏幕方向。例如,要将某个 Activity 的屏幕方向设置为(portrait)或横屏(landscape),可以添加如下代码: ```xml <activity android:name=".MainActivity" android:screenOrientation="portrait" /> ``` 或者: ```xml <activity android:name=".MainActivity" android:screenOrientation="landscape" /> ``` 这种方式适用于不需要动态调整屏幕方向的应用场景,并且能够确保该 Activity 始终保持指定的方向[^1]。 ### 在 Java/Kotlin 代码中动态设置屏幕方向 如果需要在运行时根据某些条件更改屏幕方向,可以在 Activity 的 Java 或 Kotlin 代码中使用 `setRequestedOrientation()` 方法。例如,在 Java 中可以这样设置: ```java setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); ``` 或者设置为横屏: ```java setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); ``` 这种方法提供了更高的灵活性,允许在应用的不同部分根据需要更改屏幕方向。 ### 强制所有设备上的应用横屏显示(如 LineageOS) 对于定制 ROM(如 LineageOS),可以通过修改系统级别的配置来强制某些应用始终以横屏模式运行。例如,在 LineageOS 22.1(基于 Android 15)中,可以修改特定应用的包名并重新编译系统服务: ```bash make -j12 services adb push lineageos/out/target/product/blueline/system/framework/services.jar /system/framework/services.jar ``` 此方法适用于深度定制的 ROM 环境,不适合普通开发者直接在标准 Android 设备上操作。 ### 保持屏幕常亮 除了固定屏幕方向外,有时还需要确保屏幕始终保持开启状态。可以通过在 Activity 的 `onCreate()` 方法中添加以下代码实现: ```java getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); ``` 此方法会阻止系统自动关闭屏幕,从而确保特定 Activity 的屏幕始终处于打开状态。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ytmfdw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值