在看android自带的samples源码里面的AccelerometerPlayActivity当我看到下面的代码时,我不明白
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
return;
}
switch (mDisplay.getRotation()) {
case Surface.ROTATION_0:///手机处于正常状态
mSensorX = event.values[0];
mSensorY = event.values[1];
break;
case Surface.ROTATION_90://手机旋转90度
mSensorX = -event.values[1];
mSensorY = event.values[0];
break;
case Surface.ROTATION_180:
mSensorX = -event.values[0];
mSensorY = -event.values[1];
break;
case Surface.ROTATION_270:
mSensorX = event.values[1];
mSensorY = -event.values[0];
break;
}
}
通过查阅资料的大体了解
通过AndroidManifest.xml如果设置屏幕方向,安装后无法更改,程序内设置屏幕方向无此限制。主要靠这两个API:getRequestedOrientation()和setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)这两个API通过ActivityManagerService.java的转换后,其实都是调用WindowManagerService同名法。
每个Activity在WindowManagerService端都有一个AppWindowToken作为代表,屏幕的方向信息存储在这里。
PhoneWindowManager屏幕的方向将根据屏幕的物理特性自动确定,并查看此代码:
if (mPortraitRotation < 0) {
// Initialize the rotation angles for each orientation once.
Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
if (d.getWidth() > d.getHeight()) {
mPortraitRotation = Surface.ROTATION_90;
mLandscapeRotation = Surface.ROTATION_0;
mUpsideDownRotation = Surface.ROTATION_270;
mSeascapeRotation = Surface.ROTATION_180;
} else {
mPortraitRotation = Surface.ROTATION_0;
mLandscapeRotation = Surface.ROTATION_90;
mUpsideDownRotation = Surface.ROTATION_180;
mSeascapeRotation = Surface.ROTATION_270;
}
}
这里的d.getWidth() 和 d.getHeight()得到的是物理屏幕的宽高。一般来说,平板和手机的是不一样的。
平板宽比高(0度位于landscape右转90度进入模式porit模式),手机高比宽(0度位于porit右转90度进入模式landscape模式)。若应用程序只关心目前是横屏还是竖屏,而不直接使用传感器,则无问题。如果传感器像依赖重力感应的游戏一样直接使用,则需要根据物理屏幕的坐标系转换传感器数据,否则会出现坐标系混乱的问题。
如果没有没有通过,d.getWidth()和d.getHeight()检测设备的物理屏幕,从确定哪个是landscape和porit模式,但直接假设设备与手机相同。因为游戏在运行landscape传感器数据在模式下右转90度。这种做法在手机上没有问题,但不应该在平板电脑上转换。这是因为当物理屏幕宽比高时,默认情况是landscape模式。
现在回到源代码,这里没有区分手机和平板电脑,只是用来转换加速度的方向,没有必要区分.
case Surface.ROTATION_0:///手机处于正常状态
mSensorX = event.values[0];
mSensorY = event.values[1];
break;
如果手机的方向不旋转,无论手机在哪里landscape还是porit模式,加速度的方向都不用变,而下面,如果手机旋转了180度,说明x轴和y轴的方向完全反过来了,这时候对于加速度的方向就要调整到反向.还有类似90度和270度的情况.
case Surface.ROTATION_180:
mSensorX = -event.values[0];
mSensorY = -event.values[1];
break;