一般手机只能旋转3个方向,这里将介绍如何让手机可以旋转180度,也就是上下颠倒。

1.静态方法
frameworks/base/core/res/res/values/config.xml
config_allowAllRotations通过这个来设置。

    <!-- Auto-rotation behavior --><!-- If true, enables auto-rotation features using the accelerometer.Otherwise, auto-rotation is disabled.  Applications may still requestto use specific orientations but the sensor is ignored and sensor-basedorientations are not available.  Furthermore, all auto-rotation relatedsettings are omitted from the system UI.  In certain situations we maystill use the accelerometer to determine the orientation, such as whendocked if the dock is configured to enable the accelerometer. --><bool name="config_supportAutoRotation">true</bool><!-- If true, the screen can be rotated via the accelerometer in all 4rotations as the default behavior. --><bool name="config_allowAllRotations">true</bool>

2.动态方法
在手机确认要旋转后,就会走PhoneWindowManager.java的onProposedRotationChanged。

    class MyOrientationListener extends WindowOrientationListener {private final Runnable mUpdateRotationRunnable = new Runnable() {@Overridepublic void run() {// send interaction hint to improve redraw performancemPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);updateRotation(false);}};MyOrientationListener(Context context, Handler handler) {super(context, handler);}@Overridepublic void onProposedRotationChanged(int rotation) {if (localLOGV) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);mHandler.post(mUpdateRotationRunnable);}}

然后走

    void updateRotation(boolean alwaysSendConfiguration) {try {//set orientation on WindowManagermWindowManager.updateRotation(alwaysSendConfiguration, false);} catch (RemoteException e) {// Ignore}}

再走WindowManagerService.java的updateRotation。

    /*** Recalculate the current rotation.** Called by the window manager policy whenever the state of the system changes* such that the current rotation might need to be updated, such as when the* device is docked or rotated into a new posture.*/@Overridepublic void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);}

再走

    private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:"+ " alwaysSendConfiguration=" + alwaysSendConfiguration+ " forceRelayout=" + forceRelayout);Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation");long origId = Binder.clearCallingIdentity();try {// TODO(multi-display): Update rotation for different displays separately.final boolean rotationChanged;final int displayId;synchronized (mWindowMap) {final DisplayContent displayContent = getDefaultDisplayContentLocked();Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");rotationChanged = displayContent.updateRotationUnchecked(false /* inTransaction */);Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);if (!rotationChanged || forceRelayout) {displayContent.setLayoutNeeded();Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,"updateRotation: performSurfacePlacement");mWindowPlacerLocked.performSurfacePlacement();Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}displayId = displayContent.getDisplayId();}if (rotationChanged || alwaysSendConfiguration) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: sendNewConfiguration");sendNewConfiguration(displayId);Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}} finally {Binder.restoreCallingIdentity(origId);Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}}

再走DisplayContent.java的updateRotationUnchecked

/*** 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) {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;}ScreenRotationAnimation screenRotationAnimation =mService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);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_WM, "Deferring rotation, animation in progress.");return false;}if (mService.mDisplayFrozen) {// Even if the screen rotation animation has finished (e.g. isAnimating// returns false), there is still some time where we haven't yet unfrozen// the display. We also need to abort rotation here.if (DEBUG_ORIENTATION) Slog.v(TAG_WM,"Deferring rotation, still finishing previous rotation");return false;}if (!mService.mDisplayEnabled) {// No point choosing a rotation if the display is not enabled.if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, display is not enabled.");return false;}final int oldRotation = mRotation;final int lastOrientation = mLastOrientation;final boolean oldAltOrientation = mAltOrientation;int rotation = mService.mPolicy.rotationForOrientationLw(lastOrientation, oldRotation);final boolean rotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(oldRotation,rotation);if (rotateSeamlessly) {final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);if (seamlessRotated != null) {// We can't rotate (seamlessly or not) while waiting for the last seamless rotation// to complete (that is, waiting for windows to redraw). It's tempting to check// w.mSeamlessRotationCount but that could be incorrect in the case of// window-removal.return false;}}。。。。。。
}

最后走PhoneWindowManager.java的rotationForOrientationLw

    @Overridepublic 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" : ""));//Aaron addmAllowAllRotations = -1;if (mForceDefaultOrientation) {return Surface.ROTATION_0;}synchronized (mLock) {int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1if (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 || mWifiDisplayConnected) && mDemoHdmiRotationLock) {// Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.// Note that the dock orientation overrides the HDMI orientation.preferredRotation = mDemoHdmiRotation;} else if (mWifiDisplayConnected && (mWifiDisplayCustomRotation > -1)) {// Ignore sensor when WFD is active and UIBC rotation is enabledpreferredRotation = mWifiDisplayCustomRotation;} else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED&& mUndockedHdmiRotation >= 0) {// Ignore sensor when plugged into HDMI and an undocked orientation has// been specified in the configuration (only for legacy devices without// full multi-display support).// Note that the dock orientation overrides the HDMI orientation.preferredRotation = mUndockedHdmiRotation;} else if (mDemoRotationLock) {// Ignore sensor when demo rotation lock is enabled.// Note that the dock orientation and HDMI rotation lock override this.preferredRotation = mDemoRotation;} else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {// Application just wants to remain locked in the last rotation.preferredRotation = lastRotation;} else if (!mSupportAutoRotation) {// If we don't support auto-rotation then bail out here and ignore// the sensor and any rotation lock settings.preferredRotation = -1;} else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE&& (orientation == ActivityInfo.SCREEN_ORIENTATION_USER|| orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED|| orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE|| orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))|| 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.//这里注释掉原来的 添加自己修改的//Aaron change/*mAllowAllRotations = mContext.getResources().getBoolean(com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;*/mAllowAllRotations = Global.getInt(mContext.getContentResolver(), Global.ALLOW_ALL_ROTATION_ON,0);int enable = Global.getInt(mContext.getContentResolver(), Global.AUTO_ROTATION, 0);if (enable != 1)mAllowAllRotations = -1;}if (sensorRotation != Surface.ROTATION_180|| mAllowAllRotations == 1|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {// In VrMode, we report the sensor as always being in default orientation so:// 1) The orientation doesn't change as the user moves their head.// 2) 2D apps within VR show in the device's default orientation.// This only overwrites the sensor-provided orientation and does not affect any// explicit orientation preferences specified by any activities.preferredRotation =mPersistentVrModeEnabled ? Surface.ROTATION_0 : 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:case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:// Return either landscape rotation.if (isLandscapeOrSeascape(preferredRotation)) {return preferredRotation;}if (isLandscapeOrSeascape(lastRotation)) {return lastRotation;}return mLandscapeRotation;case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:case ActivityInfo.SCREEN_ORIENTATION_USER_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_0;}}}

这里主要就是修改mAllowAllRotations的值,虽然每次旋转都要走这个判断要不要选择180度,但是实际上就判断一次,因为mAllowAllRotations这个值变了之后就不会再走赋值的地方了,可以看代码。所以我们要每次都要去根据要不要选择180度来改变这个值,所以每次进来先mAllowAllRotations=-1,然后就会走到赋值的那个里面,进行赋值。

是否要旋转180度的数据库。

mAllowAllRotations = Global.getInt(mContext.getContentResolver(), Global.ALLOW_ALL_ROTATION_ON,0);

注意:如果先把180度关闭,打开自动选择,把手机选择180度,然后再打开180度开关,这时候屏幕不会选择180度,正确的,但是当你再关闭自动旋转的时候,屏幕会先选择180度,然后再旋转回来。有问题,所以多加了个判断。

当自动旋转打开的时候才能旋转180。数据库自己加的。

                    int enable = Global.getInt(mContext.getContentResolver(), Global.AUTO_ROTATION, 0);if (enable != 1)mAllowAllRotations = -1;

Android8.0 屏幕旋转180度相关推荐

  1. 手机屏幕旋转180度

    客户需求:手机可以旋转到180度 代码路径: frameworks/base/policy/src/com/android/interal/policy/impl/PhoneWindowManager ...

  2. android 屏幕旋转180度

    //横屏正方向if(getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {setRequestedOrien ...

  3. Android 11.0 recovery页面旋转180度问题的解决方案

    1.前言 在11.0的系统rom定制化开发工作中,在系统中recovery的页面也是相关重要的一部分,在系统recovery ota升级等功能,都是需要recovery功能的,在某些产品定制化中 在r ...

  4. 高通平台android7.1系统显示旋转180度

    实现方法 内核层修改 kernel\msm-3.18\arch\arm\boot\dts\qcom\dsi-panel-lm215w-lvds-1080p-video.dtsi增加qcom,mdss- ...

  5. 什么!卷积要旋转180度?!

    全文共988个字,6张图,预计阅读时间8分钟. 一看这个标题就会想,这有什么大惊小怪的,可能好多人觉得这是个脑残话题,但我确实误解了两三年-- 今天在读<OpenCV算法精解>的时候,发现 ...

  6. 在html中让图片旋转180度,gif图片旋转教程:怎么把gif旋转90度/180度 附gif图片旋转软件...

    视频可以用视频编辑软件将视频旋转90度>>gif旋转90度或180度呢,往下看,你可在本文中找到答案. 先睹为快,看看旋转的效果对比图: 原图                    顺时旋 ...

  7. 苹果屏幕旋转怎么设置_笔记本电脑维修|笔记本电脑屏幕旋转90度怎么复原

    大家在使用笔记本电脑的时候,有没有遇到过这样一个问题.在某一次打开电脑的时候,突然就发现笔记本电脑的屏幕旋转了90度,而且不管打开哪个界面,都是旋转了90度的.遇到这个问题的时候,有小伙伴不知道怎么解 ...

  8. 基于html+css的盒子内容旋转180度

    准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 20 ...

  9. Python视频旋转180度

    Python视频旋转180度 from moviepy.editor import *aviFileName = r'video.mp4' resultFileName = r'rotate.mp4' ...

  10. 菜单箭头旋转180度

    今天练手了一个简单的小案例,就是手指hover住菜单的时候,菜单旁边的小箭头旋转180度. 用到了transform变形中rotate()旋转和transition过渡中animation动画的知识点 ...

最新文章

  1. OpenCV,马赛克 常用图像增强算法的实现
  2. c ++atoi函数_atoi()函数以及C ++中的示例
  3. weblogic部署,常见错误解决——Unmarshaller failed
  4. windows查看端口号占用
  5. 浙大java语言程序设计_浙江大学java语言程序设计实验答案全集.doc
  6. 类的变量初始化是直接使用初始化器还是放在构造函数中?
  7. python opencv保存图片到指定路径_OpenCV-将图像保存到所选的特定文件夹
  8. python defaultdict(list)_Python collections.defaultdict() 与 dict的使用和区别
  9. 有哪些函数可以反截图、_视频微课:征服反三角函数——反三角函数核心思想与方法——“1个概念”、“2类关系”、“3个层次”...
  10. HTML显示日期时间代码
  11. GPS模块运用: GPS模块数据提取、常规参数配置(脉冲频率、输出指定命令、定位模式等)
  12. Redhat开机丢失引导
  13. 【目标检测】雷达目标CFAR检测算法
  14. Java总结及面试题
  15. centos7 安装最新rabbitmq,并设置开机自启
  16. 裴蜀定理详解+例题: BZOJ 1441 MIN
  17. ZOC7-ssh工具配置快速登录执行命令
  18. 用AdGuard Home搭建一个内部的DNS服务器,开启局域网内无广告和追踪的浏览体验
  19. 前端项目如何向一个后端项目传递数组?(批量删除如何传参)
  20. 克里斯·麦克切斯尼《高效能人士的执行4原则》读书笔记

热门文章

  1. Leetcode--K 站中转内最便宜的航班
  2. 数学物理方法_第二次作业_王怀帅_202018019427053
  3. php七牛云amr转mp3,asp.net音频转换之.amr转.mp3(利用七牛转换法)
  4. python3.6版本安装TensorFlow
  5. Quick-Cocos2d-x初学者游戏教程(2) ——【Quick内部的代码结构及相应的原理】
  6. Python : Pygame函数大全
  7. 是我们控制着技术,还是技术控制着我们?
  8. ITU-T Rec. G.988 Amendment 3翻译——9.3 Layer 2 data services
  9. 解决SpringBoot中jar包部署没有主清单属性的问题
  10. QT编译错误:Fault tolerant heap shim applied to current process. 解决办法