提示:强制横竖屏功能实现,实现竖屏应用也可以横屏显示
文章目录
- @[TOC](文章目录)
- 前言
- 一、需求
- 二、相关资料
- 三、修改文件
- 四、实现方案
- 属性配置作为一个开关
- 实现屏幕方向控制方式-业务逻辑
- 五、实际能够实现的效果
- 实现竖屏应用也可以横屏显示
- 做菜单功能选项-拓展丰富功能
- 总结
文章目录
- @[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中是最基本的需求,需要掌握
- 这里没有研究源码,有兴趣的可以了解一下源码,很有意思的。