Android 8.1 MTK平台 强制第三方 APP 横屏(微信、今日头条等)

前言

我们都知道 activity 的横竖屏是通过 AndroidManifest.xml 中 android:screenOrientation 属性来配置的,或者在 java 代码中配置方向。but 没有 app 源码这就无能为力了,尤其像微信这种流量级的 app,官网已经没有横屏版本,对于手机厂商来说,做默认横屏的设备时就会遇到困难,网上的一些改横屏方法或多或少都存在些问题。我假设你的系统已经是横屏状态, 但装上 android:screenOrientation=“portrait” 属性的 app 时又变成竖屏的情况,那么恭喜你找到了修改方法。我们的目的就是 hook 掉 screenOrientation,让 app 始终横屏。

效果图

修改前

Android 8.1 MTK平台 强制第三方 APP 横屏(微信、今日头条等)_第1张图片

修改后

Android 8.1 MTK平台 强制第三方 APP 横屏(微信、今日头条等)_第2张图片

修改源码

frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java

 @Override
    public int rotationForOrientationLw(int orientation, int lastRotation) {
        if (false) {
            Slog.v(TAG, "rotationForOrientationLw(orient="
                        + orientation + ", last=" + lastRotation
                        + "); user=" + mUserRotation + " "
                        + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
                            ? "USER_ROTATION_LOCKED" : "")
                        );
        }
        //cczheng add for force screenOrientation landscape [S]
        Log.e("ccz","mForceDefaultOrientation="+mForceDefaultOrientation);
        if (true/*mForceDefaultOrientation*/) {
            return Surface.ROTATION_0;//默认横屏
        }
        //cczheng add for force screenOrientation landscape [S]

        synchronized (mLock) {
            int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
            if (sensorRotation < 0) {
                sensorRotation = lastRotation;
            }

            final int preferredRotation;
            if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
                // Ignore sensor when lid switch is open and rotation is forced.
                preferredRotation = mLidOpenRotation;
            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
                    && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
                // Ignore sensor when in car dock unless explicitly enabled.
                // This case can override the behavior of NOSENSOR, and can also
                // enable 180 degree rotation while docked.
                preferredRotation = mCarDockEnablesAccelerometer
                        ? sensorRotation : mCarDockRotation;
            } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
                    || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
                    || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
                    && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {

			.....

	}

将 mForceDefaultOrientation 改为 true,默认返回 Surface.ROTATION_0 横屏

frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java

/**
     * Update rotation of the display.
     *
     * Returns true if the rotation has been changed.  In this case YOU MUST CALL
     * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
     */
    boolean updateRotationUnchecked(boolean inTransaction) {
        //cczheng add for force screenOrientation landscape [S]
        if (true) {
            return true;
        }
        //cczheng add for force screenOrientation landscape [S]
        
        if (mService.mDeferredRotationPauseCount > 0) {
            // Rotation updates have been paused temporarily.  Defer the update until
            // updates have been resumed.
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
            return false;
        }

		......

将 updateRotationUnchecked 直接返回 true, 不去更新 DisplayInfo

最后

关于屏幕旋转流程分析可参考 屏幕旋转

关于横屏可参考 Android6.0设置开机启动默认横屏并兼顾自动旋转功能

你可能感兴趣的:(Android8.1,源码修改)