我们要实现开机强制系统横屏或者竖屏,并且可以再系统中实时切换横竖屏,首先分析代码找到

WindowManagerService.java

@Overridepublic int getRotation() {return mRotation;}

查看WindowManagerService.java代码发现我们获取当前屏幕参数时返回的是mRotation参数,继续查看mRotation初始化调用

  /** All DisplayContents in the world, kept here */SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);int mRotation = 0; //初始化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 (mRotation == rotation && mAltOrientation == altOrientation) {// No change.return false;}if (DEBUG_ORIENTATION) {Slog.v(TAG,"Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")+ " from " + mRotation + (mAltOrientation ? " (alt)" : "")+ ", forceApp=" + mForcedAppOrientation);}mRotation = rotation;//代码中唯一一次赋值

发现代码中只有一次赋值,我们先尝试初始化时直接修改我这里为0 显示是横屏,修改为1,编译后发现开机刚进去时竖了过来,但是马上又横了过来,说明有别的地方重新设置了参数,查看log发现是上述代码修改了参数

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 (mRotation == rotation && mAltOrientation == altOrientation) {// No change.return false;}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);

根据mPolicy.rotationForOrientationLw查看发现

PhoneWindowManager.java

  @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" : ""));}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 && 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 (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.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|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {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: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;}}}

发现是这个方法修改了屏幕方向参数,由于我们这边直接强制修改,不需要动态判断所以实行简单粗暴的方法直接在最上面return我们想要的参数,写上我们自己修改屏幕方向的参数。

这里我们实现了修改参数后重新开机实现横竖屏切换,但是我们要实现开机时动态修改横竖屏并实时显示,

/*** 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);}//public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean             forceRelayout) {if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("+ "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");long origId = Binder.clearCallingIdentity();boolean changed;synchronized(mWindowMap) {changed = updateRotationUncheckedLocked(false);if (!changed || forceRelayout) {getDefaultDisplayContentLocked().layoutNeeded = true;performLayoutAndPlaceSurfacesLocked();}}if (changed || alwaysSendConfiguration) {sendNewConfiguration();}Binder.restoreCallingIdentity(origId);}

查看上述代码发现是此处刷新,我们可以再此刷新我们的参数,然后在应用界面设置的旋转参数,然后通过系统服务调用updateRotation方法进行刷新

 try {IWindowManager  mWm =                        IWindowManager.Stub.asInterface(ServiceManager.getService("window"));mWm.updateRotation(true, true);} catch (SecurityException e) {// expected} catch (RemoteException e) {}

此时旋转成功,但是发现在竖屏时有的软件是写了强制横屏的参数的话会出现显示异常的情况,参考mstar设置强制横屏属性mstar.forcelandscape

  // MStar Android Patch Beginpublic int screenOrientation = (1 == SystemProperties.getInt("mstar.forcelandscape", 0) ?ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);// MStar Android Patch End//查看activityinfo文件/** @hide */@IntDef({SCREEN_ORIENTATION_UNSPECIFIED,SCREEN_ORIENTATION_LANDSCAPE,SCREEN_ORIENTATION_PORTRAIT,SCREEN_ORIENTATION_USER,SCREEN_ORIENTATION_BEHIND,SCREEN_ORIENTATION_SENSOR,SCREEN_ORIENTATION_NOSENSOR,SCREEN_ORIENTATION_SENSOR_LANDSCAPE,SCREEN_ORIENTATION_SENSOR_PORTRAIT,SCREEN_ORIENTATION_REVERSE_LANDSCAPE,SCREEN_ORIENTATION_REVERSE_PORTRAIT,SCREEN_ORIENTATION_FULL_SENSOR,SCREEN_ORIENTATION_USER_LANDSCAPE,SCREEN_ORIENTATION_USER_PORTRAIT,SCREEN_ORIENTATION_FULL_USER,SCREEN_ORIENTATION_LOCKED})

这里强制竖屏我们用到SCREEN_ORIENTATION_PORTRAIT,所以修改系统中mstar所有mstar.forcelandscape属性判断操作的

SCREEN_ORIENTATION_UNSPECIFIED 为 SCREEN_ORIENTATION_PORTRAIT

开机动画修改为竖屏

BootAnimation.cpp

 sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),forcelandscape ? dinfo.h : dinfo.w,forcelandscape ? dinfo.w : dinfo.h,

安卓系统强制旋转屏幕实现横竖屏切换相关推荐

  1. vue标签旋转_vue.js编写移动端页面,检测旋转屏幕,横竖屏。

    初学vue,想要在检测到旋转屏幕后显示遮罩层. 现在我的想法是在mounted时期添加监听屏幕旋转事件,如果检测到了,则修改data中的值isShowCover来改变v-show中的真假值,来达到显示 ...

  2. Android开发中横竖屏切换的问题以及系统提供的常用Activity

    Android开发中横竖屏切换的问题以及系统提供的常用Activity(总结) 2018年06月28日 16:18:45 北极熊的微笑 阅读数:72 横竖屏切换与状态保存的问题 前面也也说到了App横 ...

  3. android的横竖屏切换,Android横竖屏切换 初步探究

    当手机横竖屏切换的时候,activity,默认会重新走一遍生命周期,即销毁当前,然后重新创建 首先,很多软件在设计和开发中为了避免横竖屏切换时引发不必要的麻烦,通常需要让App禁止掉横竖屏的切换,这就 ...

  4. android横竖屏切换函数,Android横竖屏切换小结.PDF

    Android横竖屏切换小结 Android横竖屏切换小结 Android手机或平板都会存在横竖屏切换的功能,通常是由物理重力感应触发的,但是 有时候也不尽然,通常在设置里面我们可以对手机的横竖屏切换 ...

  5. Android横竖屏切换小结

    (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/franksunny/635350788930000000.pdf) Android手机或平板都会存在横竖 ...

  6. Android横竖屏切换相关知识点

    转载自:http://www.cnblogs.com/franksunny/p/3714442.html (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/ ...

  7. Android横竖屏切换小结(重建、非重建Activity)

    来自:http://www.cnblogs.com/franksunny/p/3714442.html (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/f ...

  8. Android 横竖屏切换小结

    (自己体会:每次横竖屏自动切时都会run Activity的onCreate,即相当后重新进入Activity初始化一样:) 转自:http://www.cnblogs.com/franksunny/ ...

  9. Android横竖屏切换

    尊重原创,本文转载自 http://www.cnblogs.com/franksunny/p/3714442.html Android横竖屏切换小结 (老样子,图片啥的详细文档,可以下载后观看 htt ...

  10. Android横竖屏切换重载问题与小结

    (转自:http://www.cnblogs.com/franksunny/p/3714442.html) (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com ...

最新文章

  1. PyQt5教程——组件 Ⅱ(八)
  2. 银行系普惠和小贷系普惠,哪个贷款更靠谱?
  3. SAP License:sap培训
  4. 远程办公绝非远程监控,该如何挖掘远程办公的红利?
  5. 没有Angular 3,下一个Angular主版本将是Angular 4
  6. 学习jQuery.Deferred
  7. 面试:C++实现访问者模式
  8. Apache AXIS 1.4 RCE
  9. ionic ion-refresher 下拉刷新的使用。
  10. 第三章 决策树-隐形眼镜
  11. 获取token(/oauth/token)
  12. 黑名单电话自动拦截【Android】
  13. 1034. 边框着色
  14. 从初级工程师发展到高级工程师,需要跨越的鸿沟
  15. visual c++ 棋牌类游戏编程实例
  16. PanGu STM32MP开发板更新固件
  17. Weston中shm window渲染
  18. 通过OneDrive实现office多人协同
  19. 1 - 4 电路元件
  20. 用dw写php怎么运行,dw怎么运行php程序?

热门文章

  1. C语言填空概念题及答案,C语言填空题以及答案
  2. 序列化和反序列化(示例)
  3. Python创建分栏排版的Word文档
  4. 如何在服务器发布网站
  5. 知乎周源微信_每周源代码3
  6. 高仿淘宝首页 - 刚把CSS和JS弄出成了外部,原本写的时候都在HTML一个文件里哈
  7. 简单的java华氏转摄氏温度
  8. 网络训练时使用不同学习率策略(Poly)以及学习率是如何计算
  9. 集成学习算法策略 Boosting和Bagging
  10. Linux查看电脑启动时间,几种常用的「查看Linux开机时间」的命令