强制app横屏显示或者竖屏显示(动态)
需求:某个app横屏显示不全,需要强制它竖屏显示,强制APP旋转优先级>系统方向优先级
如果系统没有强制横竖屏,一般都是默认应用本身的方向设置!
./frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java
rotationForOrientation()和updateOrientation() 来负责修改当前app的显示方向
@Surface.Rotation
int rotationForOrientation(@ScreenOrientation int orientation,
@Surface.Rotation int lastRotation) {
...
} else {
// No overriding preference.
// We will do exactly what the application asked us to do.
preferredRotation = -1;
}
String rot = SystemProperties.get("persist.sys.app.rotation", "middle_port");
//add start 动态控制
if (rot.equals("force_landscape_customer")) {
orientation = mLandscapeRotation;//强制Activity显示横
} else if (rot.equals("force_portrait_customer")) {
orientation = mPortraitRotation;//强制Activity显示竖
}
//add end
if (rot.equals("force_land") && "box".equals(SystemProperties.get("ro.target.product"))) {
Slog.v(TAG, "asx force_land :" + mLandscapeRotation);
return mLandscapeRotation;
}
//根据orientation 来显示应用方向
switch (orientation) {
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT://如果是竖屏
// Return portrait unless overridden.
if (isAnyPortrait(preferredRotation)) {
return preferredRotation;
}
/*如果不要动态根据参数修改,前面的拦截add start 部分注释掉,然后直接在switch里面改,把return mPortraitRotation;
改成 return mLandscapeRotation;或者return Surface.ROTATION_90 */
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;
...
}
boolean updateOrientation(@ScreenOrientation int newOrientation, boolean forceUpdate) {
if (newOrientation == mLastOrientation && !forceUpdate) {
return false;
}
mLastOrientation = newOrientation;
if (newOrientation != mCurrentAppOrientation) {
mCurrentAppOrientation = newOrientation;
String rot = SystemProperties.get("persist.sys.app.rotation", "middle_port");//系统给了一个原生的,就用这个,如果系统没有给,那就自己创建
//add start
if (rot.equals("force_landscape_customer")) {
mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
} else if (rot.equals("force_portrait_customer")) {
mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
}
//add end
if (rot.equals("force_land") && "box".equals(SystemProperties.get("ro.target.product")))
mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
if (isDefaultDisplay) {
updateOrientationListenerLw();
}
}
return updateRotationUnchecked(forceUpdate);
}
2.1 切换横屏时SystemUI导航栏固定在桌面右侧而不是底部
R.bool.config_navBarCanMove 是否固定跟这个变量有关系,SystemUI导航栏跟随旋转false 不跟随旋转true
+++ b/frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2895,9 +2895,10 @@ public class DisplayPolicy {
void updateConfigurationAndScreenSizeDependentBehaviors() {
final Resources res = getCurrentUserResources();
- mNavigationBarCanMove =
- mDisplayContent.mBaseDisplayWidth != mDisplayContent.mBaseDisplayHeight
- && res.getBoolean(R.bool.config_navBarCanMove);
+ //mNavigationBarCanMove =
+ // mDisplayContent.mBaseDisplayWidth != mDisplayContent.mBaseDisplayHeight
+ // && res.getBoolean(R.bool.config_navBarCanMove);
+ mNavigationBarCanMove = false;
mDisplayContent.getDisplayRotation().updateUserDependentConfiguration(res);
}
https://blog.csdn.net/An_Times/article/details/123346561
2.2 Android11 强制所有应用跟随 Gsensor旋转
处理app旋转的地方位于frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java中的rotationForOrientation()函数,
我们在这个函数进行拦截,rotationForOrientation函数第一个参数orientation,就是app的属性值了,我们把这个属性值强制改成所有方向跟随重力感应方向显示。
@Surface.Rotation
int rotationForOrientation(@ScreenOrientation int orientation,
@Surface.Rotation int lastRotation) {
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" : "");
orientation = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;//add text //跟随G_Sensor旋转
if (isFixedToUserRotation()) {
return mUserRotation;
}
int sensorRotation = mOrientationListener != null
? mOrientationListener.getProposedRotation() // may be -1
: -1;
if (sensorRotation < 0) {
sensorRotation = lastRotation;//sensorRotation 是G_Sensor角度
}
...