如何将屏幕锁定横屏

先看GIF

这是修改之前

 

这是修改之后

 

需要修改的文件

   frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java   

简要分析

在点开Activity时,会调用到窗口relayout。就自然到了WindowManagerService.java。这部分就不分析了。

一、relayoutWindow函数代码

    public int relayoutWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int requestedWidth,
            int requestedHeight, int viewVisibility, int flags,
            Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
            Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
            Surface outSurface) {
        boolean toBeDisplayed = false;
        boolean inTouchMode;
        boolean configChanged;
        boolean surfaceChanged = false;
        boolean animating;
        boolean hasStatusBarPermission =
                mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                        == PackageManager.PERMISSION_GRANTED;

        long origId = Binder.clearCallingIdentity();

        synchronized(mWindowMap) {
            ......
            configChanged = updateOrientationFromAppTokensLocked(false);
            performLayoutAndPlaceSurfacesLocked();
            ......
        }

        if (configChanged) {
            sendNewConfiguration();
        }

        Binder.restoreCallingIdentity(origId);

        return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
                | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
                | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
                | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
    }

执行到relayoutWindow后,核心部分看updateOrientationFromAppTokensLocked。

二、updateOrientationFromAppTokensLocked(boolean)函数代码

   /*

     * Determine the new desired orientation of the display, returning

     * a non-null new Configuration if it has changed from the current

     * orientation.  IF TRUE IS RETURNED SOMEONE MUST CALL

     * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE

     * SCREEN.  This will typically be done for you if you call

     * sendNewConfiguration().

     *

     * The orientation is computed from non-application windows first. If none of

     * the non-application windows specify orientation, the orientation is computed from

     * application tokens.

     * @see android.view.IWindowManager#updateOrientationFromAppTokens(

     * android.os.IBinder)

     */

    boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {

        long ident = Binder.clearCallingIdentity();

        try {

            int req = getOrientationFromWindowsLocked();

            if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {

                req = getOrientationFromAppTokensLocked();

            }

 

            if (req != mForcedAppOrientation) {

                mForcedAppOrientation = req;

                //send a message to Policy indicating orientation change to take

                //action like disabling/enabling sensors etc.,

                mPolicy.setCurrentOrientationLw(req);

                if (updateRotationUncheckedLocked(inTransaction)) {

                    // changed

                    return true;

                }

            }

 

            return false;

        } finally {

            Binder.restoreCallingIdentity(ident);

        }

    }


注释是一定要看的。Determine the new desired orientation of the display

可以看到,mForcedAppOrientation会被赋值。然后,通过mPolicy的setCurentOrientationLw方法将新的orientation值作为新参数设置上去。

updateRotationUncheckedLocked(inTransaction)函数会mForcedAppOrientation用起来。

三、updateRotationUncheckedLocked(boolean)函数代码

    // TODO(multidisplay): Rotate any display?

    /**

     * Updates the current rotation.

     *

     * Returns true if the rotation has been changed.  In this case YOU

     * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.

     */

    public boolean updateRotationUncheckedLocked(boolean inTransaction) {

        ......

        // 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);

        ......

        return true;

}

注意看红色字体。

四、小结

如何让屏幕强制横屏。

    boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
        long ident = Binder.clearCallingIdentity();
        try {
            int req = getOrientationFromWindowsLocked();
            if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
                req = getOrientationFromAppTokensLocked();
            }

           req = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            if (req != mForcedAppOrientation) {
                mForcedAppOrientation = req;
                //send a message to Policy indicating orientation change to take
                //action like disabling/enabling sensors etc.,
                mPolicy.setCurrentOrientationLw(req);
                if (updateRotationUncheckedLocked(inTransaction)) {
                    // changed
                    return true;
                }
            }

            return false;
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }


要强制横屏。只需要在 boolean updateOrientationFromAppTokensLocked(boolean inTransaction)中,将req强制成ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE即可。

具体效果,可以看文章头的gif动态图。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在移动端上设置屏幕横屏,你可以使用`screen.orientation` API或`screen.lockOrientation`方法。以下是一个示例代码: ```javascript function setLandscapeMode() { if (screen.orientation && screen.orientation.lock) { screen.orientation.lock('landscape'); } else if (screen.lockOrientation) { screen.lockOrientation('landscape'); } else if (screen.mozLockOrientation) { screen.mozLockOrientation('landscape'); } else if (screen.msLockOrientation) { screen.msLockOrientation('landscape'); } } setLandscapeMode(); ``` 在上面的代码中,我们定义了一个`setLandscapeMode`函数来设置屏幕横屏模式。首先,我们检查浏览器是否支持`screen.orientation` API并且有`lock`方法。如果支持,则调用`lock`方法并传入`'landscape'`参数来锁定屏幕方向为横屏。如果浏览器不支持`screen.orientation` API,我们继续检查是否支持`screen.lockOrientation`、`screen.mozLockOrientation`和`screen.msLockOrientation`方法,并使用相应的方法来锁定屏幕方向为横屏。 最后,我们调用`setLandscapeMode`函数来设置屏幕横屏模式。 请注意,由于浏览器的安全策略,屏幕方向设置通常需要用户手势触发。因此,你可能需要在用户与页面进行交互后再调用`setLandscapeMode`函数,以确保设置屏幕横屏时能够成功。 请注意,不是所有浏览器都支持或实现了相同的屏幕方向锁定API。在实际使用时,请根据所支持的浏览器和设备进行适当的兼容性处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值