如何将屏幕锁定横屏

来源:互联网 发布:python 动态创建字典 编辑:程序博客网 时间:2024/05/15 08:35

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


0 0
原创粉丝点击