问题
在Android服务中,每当屏幕旋转发生变化时,我都希望检测到。所谓旋转,我指的不仅仅是肖像和风景;我指的是屏幕旋转的任何改变。这种变化的例子是对以下方面的修改:
请注意,此问题与设备方向的更改无关。它只是关于屏幕的方向/旋转。
我试过的
Configuration
通过ACTION_CONFIGURATION_CHANGED
进行更改。这只包括肖像和景观之间的变化,所以180°的变化不会触发这一点。我为什么要这么做
我正在开发一个自定义屏幕方向管理应用程序。
发布于 2015-05-22 02:41:38
使用隐藏的API
您可以使用名为IWindowManager.watchRotation(IRotationWatcher)
的隐藏API来完成此操作。从我的测试来看,似乎每次屏幕旋转发生变化时都会调用回调。回调似乎也被赋予当前屏幕的旋转。
作为一个隐藏的API,您不能直接调用它。如何使用隐藏的API本身就是一个主题。当然,从可维护性的角度来看,这可能不像普通API那样可靠。
而且,onRotationChanged
不是在以前调用watchRotation
的线程中调用的。在onRotationChanged
中,您可能希望将一些工作委托给不同的线程,比如UI线程。
兼容性
测试并在API 14 - 28中工作.
示例
有一种方法可以让它发挥作用:
android.view.IRotationWatcher
复制到应用程序中。一定要把它保存在原来的包里。这似乎导致开发工具认为您的代码可以访问它,同时也导致操作系统仍然使用真正的代码,而不是您自己的副本。watchRotation
:
尝试{ Class stub = Class.forName("android.view.IWindowManager$Stub");Object windowManagerService = stub.getMethod("asInterface",IBinder.class).invoke(stub,serviceBinder);方法watchRotation;if (Build.VERSION.SDK_INT >= 26) watchRotation = windowManagerService.getClass().getMethod("watchRotation",IRotationWatcher.class,int.class);否则watchRotation = windowManagerService.getClass().getMethod("watchRotation",IRotationWatcher.class);//这个方法似乎是在Android4.3中引入的,所以不要总是认为它是removeRotationWatcher = null;尝试{ removeRotationWatcher = IRotationWatcher.class);} catch (NoSuchMethodException screenRotationChanged ) {} IRotationWatcher.Stub screenRotationChanged=新的IRotationWatcher.Stub() {@覆盖公共空onRotationChanged(int旋转)抛出RemoteException {//执行您在这里想做的事情//警告:这不是在调用watchRotation }时所在的线程中调用的;//开始监视更改if (Build.VERSION.SDK_INT >= 26) watchRotation.invoke(windowManagerService,screenRotationChanged,Display.DEFAULT_DISPLAY);否则watchRotation.invoke(windowManagerService,screenRotationChanged);//停止监视如果(removeRotationWatcher != null) {windowManagerService screenRotationChanged);} catch (ClassNotFoundException _ ClassCastException ClassCastException InvocationTargetException NoSuchMethodException IllegalAccessException e) {抛出新的InvocationTargetException(E);发布于 2015-05-20 04:28:09
批准的答案将有效,但如果您想要更高的检测分辨率(或支持更远的API 3),尝试OrientationEventListener
,它可以报告手机的方向,以度为单位。
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
OrientationEventListener orientationEventListener = new OrientationEventListener(this,
SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(int orientation) {
Display display = mWindowManager.getDefaultDisplay();
int rotation = display.getRotation();
if(rotation != mLastRotation){
//rotation changed
if (rotation == Surface.ROTATION_90){} // check rotations here
if (rotation == Surface.ROTATION_270){} //
}
mLastRotation = rotation;
}
};
if (orientationEventListener.canDetectOrientation()) {
orientationEventListener.enable();
}
发布于 2015-05-20 04:28:31
另一种方法(而不是上述学院提供的方法)是在onCreate
中手动检查旋转角度。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
if (rotation == Surface.ROTATION_180) { // reverse portrait
setContentView(R.layout.main_reverse_portrait);
} else { // for all other orientations
setContentView(R.layout.main);
}
...
}
https://stackoverflow.com/questions/30349460
复制