RK3568-Android15-强制横竖屏-默认App应用界面显示方向-屏幕显示方向跟随Sensor旋转
2026/7/19 14:11:01 网站建设 项目流程

提示:强制横竖屏功能实现,实现竖屏应用也可以横屏显示

文章目录

    • @[TOC](文章目录)
  • 前言
  • 一、需求
  • 二、相关资料
  • 三、修改文件
  • 四、实现方案
    • 属性配置作为一个开关
    • 实现屏幕方向控制方式-业务逻辑
  • 五、实际能够实现的效果
    • 实现竖屏应用也可以横屏显示
    • 做菜单功能选项-拓展丰富功能
  • 总结

前言

强制横竖屏什么意思呢?
就是字面意思,强制让屏幕横屏显示、竖屏显示。 这样的好处就是 解决了竖屏应用App 也可以横屏显示

一、需求

让应用可以随着GSensor 屏幕旋转二实现应用的横竖屏显示。

如下横屏状态下,同一个应用 讯飞输入法显示的两种不同状态,修改前和修改后:

所以对于很多应用在AndroidMenifest.xml 中配置属性:android:screenOrientation="port",或者android:screenOrientation="landscape"都是无效的,因为我们的最终目标是随GSensor 方向,不由App 配置决定。

二、相关资料

这里有关联的关联性资料,针对不同的需求相关知识点有了解的必要:虽然如下知识点跟这里没有什么关系,但是都是关联性的需求与知识点,有掌握的必要,针对不同的需求。

MTK-Android13-假横屏-竖屏开机解决各类APP USB相机适配问题 : 假横屏开机案例,系统起来后横屏显示或者跟随GSensor 方向显示

系统实现屏幕横竖屏-180非180横竖屏切换配置 :MTK、RK UBoot、Kernel、屏幕方向旋转案例

MTKAndroid12-13-实现WIFI-蓝牙默认打开-自动旋转屏幕管理默认关闭-屏幕超时默认30分钟-屏幕旋转方向 :MTK 自动旋转屏幕相关设置与默认

三、修改文件

frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java

四、实现方案

属性配置作为一个开关

可以配置一个属性,方便自己拓展功能,比如属性:persist.fise.rotate.lock

persist.fise.rotate.lock=1\

实现屏幕方向控制方式-业务逻辑

路径:frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java

rotationForOrientation方法中添加自己的业务逻辑判断:

mFiseRotationLock=SystemProperties.get("persist.fise.rotate.lock","0");//Slog.d("wfc","mFiseRotationLock = "+mFiseRotationLock);if(mFiseRotationLock.equals("0")){}elseif(mFiseRotationLock.equals("1")){returnsensorRotation;}elseif(mFiseRotationLock.equals("2")){returnmLandscapeRotation;}elseif(mFiseRotationLock.equals("3")){returnmPortraitRotation;}

我把源码rotationForOrientation方法贴出来,方便后续大家自己研究:

/** * Given an orientation constant, returns the appropriate surface rotation, taking into account * sensors, docking mode, rotation lock, and other factors. * * @param orientation An orientation constant, such as * {@link ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}. * @param lastRotation The most recently used rotation. * @return The surface rotation to use. */@Surface.RotationintrotationForOrientation(@ScreenOrientationintorientation,@Surface.RotationintlastRotation){ProtoLog.v(WM_DEBUG_ORIENTATION,"rotationForOrientation(orient=%s (%d), last=%s (%d)); user=%s (%d) %s",ActivityInfo.screenOrientationToString(orientation),orientation,Surface.rotationToString(lastRotation),lastRotation,Surface.rotationToString(mUserRotation),mUserRotation,mUserRotationMode==WindowManagerPolicy.USER_ROTATION_LOCKED?"USER_ROTATION_LOCKED":"");if(isFixedToUserRotation()){returnmUserRotation;}@Surface.RotationintsensorRotation=mOrientationListener!=null?mOrientationListener.getProposedRotation()// may be -1:-1;if(mFoldController!=null&&mFoldController.shouldIgnoreSensorRotation()){sensorRotation=-1;}if(mDeviceStateController.shouldReverseRotationDirectionAroundZAxis(mDisplayContent)){sensorRotation=RotationUtils.reverseRotationDirectionAroundZAxis(sensorRotation);}mLastSensorRotation=sensorRotation;if(sensorRotation<0){sensorRotation=lastRotation;}finalintlidState=mDisplayPolicy.getLidState();finalintdockMode=mDisplayPolicy.getDockMode();finalbooleanhdmiPlugged=mDisplayPolicy.isHdmiPlugged();finalbooleancarDockEnablesAccelerometer=mDisplayPolicy.isCarDockEnablesAccelerometer();finalbooleandeskDockEnablesAccelerometer=mDisplayPolicy.isDeskDockEnablesAccelerometer();@Surface.RotationfinalintpreferredRotation;if(!isDefaultDisplay){// For secondary displays we ignore things like displays sensors, docking mode and// rotation lock, and always prefer user rotation.preferredRotation=mUserRotation;}elseif(lidState==LID_OPEN&&mLidOpenRotation>=0){// Ignore sensor when lid switch is open and rotation is forced.preferredRotation=mLidOpenRotation;}elseif(dockMode==Intent.EXTRA_DOCK_STATE_CAR&&(carDockEnablesAccelerometer||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=carDockEnablesAccelerometer?sensorRotation:mCarDockRotation;}elseif((dockMode==Intent.EXTRA_DOCK_STATE_DESK||dockMode==Intent.EXTRA_DOCK_STATE_LE_DESK||dockMode==Intent.EXTRA_DOCK_STATE_HE_DESK)&&(deskDockEnablesAccelerometer||mDeskDockRotation>=0)&&!(orientation==ActivityInfo.SCREEN_ORIENTATION_LOCKED||orientation==ActivityInfo.SCREEN_ORIENTATION_NOSENSOR)){// Ignore sensor when in desk dock unless explicitly enabled.// This case can enable 180 degree rotation while docked.preferredRotation=deskDockEnablesAccelerometer?sensorRotation:mDeskDockRotation;}elseif(hdmiPlugged&&mDemoHdmiRotationLock){// Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.// Note that the dock orientation overrides the HDMI orientation.preferredRotation=mDemoHdmiRotation;}elseif(hdmiPlugged&&dockMode==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;}elseif(mDemoRotationLock){// Ignore sensor when demo rotation lock is enabled.// Note that the dock orientation and HDMI rotation lock override this.preferredRotation=mDemoRotation;}elseif(mDisplayPolicy.isPersistentVrModeEnabled()){// While in VR, apps always prefer a portrait rotation. This does not change// any apps that explicitly set landscape, but does cause sensors be ignored,// and ignored any orientation lock that the user has set (this conditional// should remain above the ORIENTATION_LOCKED conditional below).preferredRotation=mPortraitRotation;}elseif(orientation==ActivityInfo.SCREEN_ORIENTATION_LOCKED){// Application just wants to remain locked in the last rotation.preferredRotation=lastRotation;}elseif(!mSupportAutoRotation){if(mFixedToUserRotation==IWindowManager.FIXED_TO_USER_ROTATION_IF_NO_AUTO_ROTATION){preferredRotation=mUserRotation;}else{// If we don't support auto-rotation then bail out here and ignore// the sensor and any rotation lock settings.preferredRotation=-1;}}elseif(((mUserRotationMode==WindowManagerPolicy.USER_ROTATION_FREE||isTabletopAutoRotateOverrideEnabled())&&(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(sensorRotation!=Surface.ROTATION_180||getAllowAllRotations()==ALLOW_ALL_ROTATIONS_ENABLED||orientation==ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR||orientation==ActivityInfo.SCREEN_ORIENTATION_FULL_USER){preferredRotation=sensorRotation;}else{preferredRotation=lastRotation;}}elseif(mUserRotationMode==WindowManagerPolicy.USER_ROTATION_LOCKED&&orientation!=ActivityInfo.SCREEN_ORIENTATION_NOSENSOR&&orientation!=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE&&orientation!=ActivityInfo.SCREEN_ORIENTATION_PORTRAIT&&orientation!=ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE&&orientation!=ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT){// Apply rotation lock. Does not apply to NOSENSOR or specific rotations.// 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).// Also avoid setting user rotation when app has preference over one particular rotation// to avoid leaving the rotation to the reverse of it which has the compatible// orientation, but isn't what app wants, when the user rotation is the reverse of the// preferred rotation.preferredRotation=mUserRotation;}else{// No overriding preference.// We will do exactly what the application asked us to do.preferredRotation=-1;}//huanghb addmFiseRotationLock=SystemProperties.get("persist.fise.rotate.lock","0");//Slog.d("huanghb","mFiseRotationLock = "+mFiseRotationLock);if(mFiseRotationLock.equals("0")){//huanghb}elseif(mFiseRotationLock.equals("1")){returnsensorRotation;}elseif(mFiseRotationLock.equals("2")){returnmLandscapeRotation;}elseif(mFiseRotationLock.equals("3")){returnmPortraitRotation;}//huanghb endswitch(orientation){caseActivityInfo.SCREEN_ORIENTATION_PORTRAIT:// Return portrait unless overridden.if(isAnyPortrait(preferredRotation)){returnpreferredRotation;}returnmPortraitRotation;caseActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:// Return landscape unless overridden.if(isLandscapeOrSeascape(preferredRotation)){returnpreferredRotation;}returnmLandscapeRotation;caseActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:// Return reverse portrait unless overridden.if(isAnyPortrait(preferredRotation)){returnpreferredRotation;}returnmUpsideDownRotation;caseActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:// Return seascape unless overridden.if(isLandscapeOrSeascape(preferredRotation)){returnpreferredRotation;}returnmSeascapeRotation;caseActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:caseActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:// Return either landscape rotation.if(isLandscapeOrSeascape(preferredRotation)){returnpreferredRotation;}if(isLandscapeOrSeascape(lastRotation)){returnlastRotation;}returnmLandscapeRotation;caseActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:caseActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:// Return either portrait rotation.if(isAnyPortrait(preferredRotation)){returnpreferredRotation;}if(isAnyPortrait(lastRotation)){returnlastRotation;}returnmPortraitRotation;default:// For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,// just return the preferred orientation we already calculated.if(preferredRotation>=0){returnpreferredRotation;}returnSurface.ROTATION_0;}}

五、实际能够实现的效果

实现竖屏应用也可以横屏显示

如上讯飞语音效果,竖屏应用直接横屏显示。常见场景:车载、TV、PC模式、桌面模式,忽略APP方向请求

做菜单功能选项-拓展丰富功能

如下,可以实现的基本需求:

总结

  • 这里只是一个案例,最基本需求就是让竖屏应用也可以横屏显示
  • 强制横竖屏在大多数平板、车载、KTV中是最基本的需求,需要掌握
  • 这里没有研究源码,有兴趣的可以了解一下源码,很有意思的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询