android 修改UI默认屏幕方向

简介: android 修改UI默认屏幕方向


1. modify WindowManagerService.java
/**
     * 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) {
  alog("updateRotationUncheckedLocked");
        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");
        }
        if (mRotateOnBoot) {
             mRotation = Surface.ROTATION_0;
             rotation = Surface.ROTATION_90;//AnsonCode default is 0, but if tablet should be Surface.ROTATION_90
        }
        if (!mRotateOnBoot/****AnsonCode for exec onBoot.*****/ && mRotation == rotation && mAltOrientation == altOrientation) {
            // No change.
            return false;
        }
        if (Math.abs(mRotation - rotation) == 2) {
            mMirrorOrientation = true;
            final WindowList windows = getDefaultWindowListLocked();
            final int N = windows.size();
            for (int i = 0; i < N; i++) {
                WindowState ws = windows.get(i);
                ws.mWinAnimator.mMirrorOrientation = true;
            }
        }
        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);
        if (mRotateOnBoot) {
            try {
                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                if (surfaceFlinger != null) {
                    //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                    Parcel data = Parcel.obtain();
                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
                                            data, null, 0);
                    data.recycle();
                }
            } catch (RemoteException ex) {
                Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
            }
            // Waiting for boot animation to finish;
            SystemClock.sleep(1000);
        }
        // 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;
    }
2. modify PhoneWindowManager.java
//this part will make some APK user android:screenOrientation="nosensor" in AndroidMainfest.xml
//show in correct orientation
    @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" : "")
                        );
        }
        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)) {
                // Ignore sensor when in desk dock unless explicitly enabled.
                // This case can override the behavior of NOSENSOR, and can also
                // enable 180 degree rotation while docked.
                preferredRotation = mDeskDockEnablesAccelerometer
                        ? sensorRotation : mDeskDockRotation;
            } else if (mHdmiPlugged && mHdmiRotationLock) {
                // Ignore sensor when plugged into HDMI.
                // Note that the dock orientation overrides the HDMI orientation.
                preferredRotation = mHdmiRotation;
                return mHdmiRotation;
            } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
                            && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
                                    || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED))
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
                // Otherwise, use sensor only if requested by the application or enabled
                // by default for USER or UNSPECIFIED modes.  Does not apply to NOSENSOR.
                if (mAllowAllRotations < 0) {
                    // Can't read this during init() because the context doesn't
                    // have display metrics at that time so we cannot determine
                    // tablet vs. phone then.
                    mAllowAllRotations = mContext.getResources().getBoolean(
                            com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
                }
                if (sensorRotation != Surface.ROTATION_180
                        || mAllowAllRotations == 1
                        || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) {
                    preferredRotation = sensorRotation;
                } else {
                    preferredRotation = lastRotation;
                }
            } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
                    && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
                // Apply rotation lock.  Does not apply to NOSENSOR.
                // The idea is that the user rotation expresses a weak preference for the direction
                // of gravity and as NOSENSOR is never affected by gravity, then neither should
                // NOSENSOR be affected by rotation lock (although it will be affected by docks).
                preferredRotation = mUserRotation;
            } else {
                // No overriding preference.
                // We will do exactly what the application asked us to do.
                preferredRotation = -1;
            }
            switch (orientation) {
                case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
                    // Return portrait unless overridden.
                    if (isAnyPortrait(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mPortraitRotation;
                case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
                    // Return landscape unless overridden.
                    if (isLandscapeOrSeascape(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mLandscapeRotation;
                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
                    // Return reverse portrait unless overridden.
                    if (isAnyPortrait(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mUpsideDownRotation;
                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
                    // Return seascape unless overridden.
                    if (isLandscapeOrSeascape(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mSeascapeRotation;
                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
                    // Return either landscape rotation.
                    if (isLandscapeOrSeascape(preferredRotation)) {
                        return preferredRotation;
                    }
                    if (isLandscapeOrSeascape(lastRotation)) {
                        return lastRotation;
                    }
                    return mLandscapeRotation;
                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
                    // Return either portrait rotation.
                    if (isAnyPortrait(preferredRotation)) {
                        return preferredRotation;
                    }
                    if (isAnyPortrait(lastRotation)) {
                        return lastRotation;
                    }
                    return mPortraitRotation;
                default:
                    // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
                    // just return the preferred orientation we already calculated.
                    if (preferredRotation >= 0) {
                        return preferredRotation;
                    }
                    return Surface.ROTATION_90;/**********AnsonCode 2014.1.2 return default orientation.************/
            }
        }
    }

PS: 以上代码仅在RK上测试过, 其它平台无从考证

相关文章
|
2月前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
随着移动应用市场的蓬勃发展,用户对界面设计的要求日益提高。为此,掌握由Google推出的Material Design设计语言成为提升应用颜值和用户体验的关键。本文将带你深入了解Material Design的核心原则,如真实感、统一性和创新性,并通过丰富的组件库及示例代码,助你轻松打造美观且一致的应用界面。无论是色彩搭配还是动画效果,Material Design都能为你的Android应用增添无限魅力。
57 1
|
3月前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
2月前
|
编解码 开发工具 Android开发
Android平台实现屏幕录制(屏幕投影)|音频播放采集|麦克风采集并推送RTMP或轻量级RTSP服务
Android平台屏幕采集、音频播放声音采集、麦克风采集编码打包推送到RTMP和轻量级RTSP服务的相关技术实现,做成高稳定低延迟的同屏系统,还需要有配套好的RTMP、RTSP直播播放器
|
3月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
54 1
|
3月前
|
API Android开发
Android项目架构设计问题之选择和使用合适的UI库如何解决
Android项目架构设计问题之选择和使用合适的UI库如何解决
46 0
|
4月前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
【7月更文挑战第28天】随着移动应用市场的发展,用户对界面设计的要求不断提高。Material Design是由Google推出的设计语言,强调真实感、统一性和创新性,通过模拟纸张和墨水的物理属性创造沉浸式体验。它注重色彩、排版、图标和布局的一致性,确保跨设备的统一视觉风格。Android Studio提供了丰富的Material Design组件库,如按钮、卡片等,易于使用且美观。
132 1
|
5月前
|
Android开发 开发者
Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。
【6月更文挑战第26天】Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。要更改主题,首先在该文件中创建新主题,如`MyAppTheme`,覆盖所需属性。然后,在`AndroidManifest.xml`中应用主题至应用或特定Activity。运行时切换主题可通过重新设置并重启Activity实现,或使用`setTheme`和`recreate()`方法。这允许开发者定制界面并与品牌指南匹配,或提供多主题选项。
75 6
|
5月前
|
开发工具 Android开发 开发者
Android `.9.png` 图像是用于UI的可拉伸格式,保持元素清晰度和比例
【6月更文挑战第26天】Android `.9.png` 图像是用于UI的可拉伸格式,保持元素清晰度和比例。通过边上的黑线定义拉伸区域,右下角黑点标识内容区域,适应文本或组件大小变化。常用于按钮、背景等,确保跨屏幕尺寸显示质量。Android SDK 提供`draw9patch.bat`工具来创建和编辑。**
251 6
|
5月前
|
API Android开发 开发者
`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView
【6月更文挑战第26天】`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView。它提供高效的数据视图复用,优化的布局管理,支持多种布局(如线性、网格),并解耦数据、适配器和视图。RecyclerView的灵活性、性能(如局部刷新和动画支持)和扩展性使其成为现代Android开发的首选,特别是在处理大规模数据集时。
62 2
|
6月前
|
Android开发
Android修改媒体音量以及修改屏幕亮度
Android修改媒体音量以及修改屏幕亮度
79 0