getDefaultDisplay()已废弃,如何获取包含上下颠倒选项的屏幕方向?
解决屏幕旋转状态(含颠倒)检测的替代方案
嘿,我完全懂你的痛点——getConfiguration().orientation只能区分横竖屏,根本满足不了要识别正竖、倒竖、正横、倒横四种状态的需求,而你又不想再用旧的getDefaultDisplay().getRotation()方法对吧?下面给你几个靠谱的替代方案:
方案1:官方推荐的DisplayManager替代法
虽然getDefaultDisplay()被标记为废弃,但获取屏幕旋转状态的核心方法getRotation()并没有被淘汰!我们只需要换一种方式获取Display对象即可,这是官方认可的替代方案,逻辑和你原来的代码几乎一致,还能避免废弃API的警告:
// 获取DisplayManager服务 DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); // 获取默认显示屏 Display defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); // 获取旋转状态:返回0、1、2、3,对应ROTATION_0、ROTATION_90、ROTATION_180、ROTATION_270 int rotation = defaultDisplay.getRotation(); // 同样可以转成角度 int orientationAngle = rotation * 90;
这个方法和你原来的代码效果完全一样,只是用DisplayManager替代了WindowManager.getDefaultDisplay(),既合规又能精准区分四种屏幕状态。
方案2:完全绕开getRotation()——用传感器检测物理方向
如果你真的想彻底不用getRotation(),可以通过设备的传感器来计算物理方向,再映射到屏幕旋转状态。不过这个方法需要处理传感器的生命周期,而且精度可能受环境影响,适合特殊场景使用:
注意:旧的TYPE_ORIENTATION已废弃,推荐用加速度计+磁力计组合
private SensorManager sensorManager; private Sensor accelerometer; private Sensor magneticSensor; private float[] accelerometerValues = new float[3]; private float[] magneticValues = new float[3]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); } @Override protected void onResume() { super.onResume(); // 注册传感器监听 sensorManager.registerListener(sensorListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(sensorListener, magneticSensor, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); // 注销监听,避免资源浪费 sensorManager.unregisterListener(sensorListener); } private SensorEventListener sensorListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { // 保存传感器数据 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { accelerometerValues = event.values.clone(); } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { magneticValues = event.values.clone(); } // 计算旋转矩阵和方向角 float[] rotationMatrix = new float[9]; boolean success = SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerValues, magneticValues); if (success) { float[] orientation = new float[3]; SensorManager.getOrientation(rotationMatrix, orientation); // 将弧度转为角度,并调整到0-360范围 float angle = (float) Math.toDegrees(orientation[0]); if (angle < 0) angle += 360; // 映射到屏幕旋转状态 int screenRotation; if (angle >= 315 || angle < 45) { screenRotation = Surface.ROTATION_0; // 正竖屏 } else if (angle >= 45 && angle < 135) { screenRotation = Surface.ROTATION_90; // 右横屏 } else if (angle >= 135 && angle < 225) { screenRotation = Surface.ROTATION_180; // 倒竖屏 } else { screenRotation = Surface.ROTATION_270; // 左横屏 } // 这里就拿到了你需要的旋转状态值,接下来可以按需处理 } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {} };
传感器方案的优缺点
- 优点:完全不依赖Display的旋转API,直接从设备物理状态获取方向
- 缺点:需要处理传感器注册/注销逻辑,精度受设备摆放(比如放在桌面上)、磁场干扰影响,响应有轻微延迟
总结
如果只是想替换掉旧的getDefaultDisplay()方法,方案1是最优选择——它既符合官方规范,又能精准获取四种屏幕旋转状态,和你原来的代码逻辑无缝衔接。传感器方案只适合特殊场景下使用。
内容的提问来源于stack exchange,提问作者Violet Giraffe
相关产品推荐
相关产品推荐

