如何将屏幕锁定横屏

先看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动态图。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值