问题描述
我有固定我的屏幕取向的活性
I have fixed my screen orientation in an activity with
android:screenOrientation="portrait"
不过,我想找到的角度为用户当前持有的屏幕,即0,90或270。因此我必须执行一些动作。
Still, I want to find the angle at which the user is currently holding the screen, i.e, 0, 90 or 270. Accordingly I have to perform some actions.
getWindowManager().getDefaultDisplay()
.getRotation()
以上code将始终返回0,因为我有固定的屏幕的方向。可有人建议我怎么确定屏幕的方向在这种情况下。
The above code will always return 0 since I have fixed the orientation of the screen. Can someone please suggest how do I determine the screen orientation in this situation.
推荐答案
您的活动应该贯彻 SensorEventListener
和 onSensorChanged()
方法:
Your activity should implement the SensorEventListener
and the onSensorChanged()
method:
protected void onCreate(Bundle savedInstanceState) {
...
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
...
}
@Override
public void onSensorChanged(SensorEvent event) {
int ORIENTATION_UNKNOWN = -1;
int _DATA_X = 0;
int _DATA_Y = 1;
int _DATA_Z = 2;
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
float[] values = event.values;
int orientation = ORIENTATION_UNKNOWN;
float X = -values[_DATA_X];
float Y = -values[_DATA_Y];
float Z = -values[_DATA_Z];
float magnitude = X*X + Y*Y;
if (magnitude * 4 >= Z*Z) {
float OneEightyOverPi = 57.29577957855f;
float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi;
orientation = 90 - (int)Math.round(angle);
// normalize to 0 - 359 range
orientation = compensateOrientation(orientation);
while (orientation >= 360) {
orientation -= 360;
}
while (orientation < 0) {
orientation += 360;
}
}
if (orientation != lastOrientation) {
lastOrientation = orientation;
int generalOrientation = getGeneralOrientation(orientation);
if(generalOrientation != GENERAL_ORIENTATION_UNCHANGED && generalOrientation != lastGeneralOrientation){
lastGeneralOrientation = generalOrientation;
onOrientationChanged(generalOrientation);
}
}
}
}
/**
* Only returns 4 orientations and gives some buffer zones where the orientation is not affected
*
* @param degrees
* @return
*/
private static int getGeneralOrientation(int degrees){
if(degrees >= 330 || degrees <= 30 ) return 0;
if(degrees <= 300 && degrees >= 240) return 270;
if(degrees <= 210 && degrees >= 160) return 180;
if(degrees <= 120 && degrees >= 60) return 90;
return GENERAL_ORIENTATION_UNCHANGED;
}
您也可以用这种方法来弥补设备特定的方向。一些设备报告人像为0辈分,而另一些可能会报告其为270度。这需要所有组合的护理:
You can also use this method to compensate for the device-specific orientation. Some devices report portrait as 0 degress, while other may report it as 270 degrees. This takes care of all the combinations:
/**
*
* Compensate orientation based on the default rotation degrees for the device.
* Some devices 0 degrees is landscape while on other 0 degrees is portrait
*
* @param degrees
* @return
*/
private int compensateOrientation(int degrees){
Display display = getWindowManager().getDefaultDisplay();
switch(display.getRotation()){
case(Surface.ROTATION_270):
return degrees + 270;
case(Surface.ROTATION_180):
return degrees + 180;
case(Surface.ROTATION_90):
return degrees + 90;
default:
return degrees;
}
}
另外注册传感器监听器和注销它是这样的:
Also register the sensor listener and unregister it like this:
@Override
protected void onPause() {
super.onPause();
if(sensorManager != null) sensorManager.unregisterListener(this);
}
@Override
protected void onResume(){
super.onResume();
if(sensorManager != null) sensorManager.registerListener(this, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
这篇关于查找屏幕角度时,方向是固定在机器人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!