Android 景观模式中的沥青问题

Android 景观模式中的沥青问题,android,landscape,sensors,pitch,tilt,Android,Landscape,Sensors,Pitch,Tilt,我需要在纵向和横向模式下读取音高值(手机前后倾斜的程度)。使用“纵向”中的代码,我从值[1]中获得我的值,当手机面朝上平放时为0.0,直立时为90,平放在设备表面时为180。直到现在一切都很好。。。 当设备处于横向模式时会出现问题。在这一点上,我使用数值[2]来测量设备的倾斜度,但问题在于数值:当手机保持平放(OK)时为0,当它直立(OK)时为90,但当我继续移动时,数值再次下降到90以下(80、75等),因此基本上我无法区分这两个位置,因为数值相同。 那么,我做错了什么,为了在横向和纵向模式下

我需要在纵向和横向模式下读取音高值(手机前后倾斜的程度)。使用“纵向”中的代码,我从值[1]中获得我的值,当手机面朝上平放时为0.0,直立时为90,平放在设备表面时为180。直到现在一切都很好。。。 当设备处于横向模式时会出现问题。在这一点上,我使用数值[2]来测量设备的倾斜度,但问题在于数值:当手机保持平放(OK)时为0,当它直立(OK)时为90,但当我继续移动时,数值再次下降到90以下(80、75等),因此基本上我无法区分这两个位置,因为数值相同。 那么,我做错了什么,为了在横向和纵向模式下获得设备倾斜的完整图像,我可以从传感器读取哪些其他值

与此处相同的问题:

我有以下代码:

private void ReadOrientationSensor(){
 final SensorManager sensorManager;

 final TextView text = (TextView) this.findViewById(R.id.TextView01);

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);


SensorEventListener listener = new SensorEventListener() {

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        float x,y,z;
        x=event.values[0];
        y=event.values[1];
        z=event.values[2];


        //text.setText(String.valueOf(event.values[0]));
        text.setText("x: " + x + " y: " + y + " z: " + z);


        }

    };

        sensorManager.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_FASTEST);

}

传感器。类型_方向
已弃用,不应使用

阅读设备的方位也让我有些头疼。以下是我用于需要设备定向的活动的基类:

public abstract class SensorActivity extends Activity implements SensorEventListener {

private SensorManager sensorManager;

private final float[] accelerometerValues = new float[3];

private final float[] R = new float[9];

private final float[] I = new float[9];

private final float[] orientation = new float[3];

private final float[] remappedR = new float[9];

private final List<HasOrientation> observers = new ArrayList<HasOrientation>();

private int x;

private int y;

protected SensorActivity() {
    this(SensorManager.AXIS_X, SensorManager.AXIS_Y);
}

/**
 * Initializes a new instance.
 * 
 */
protected SensorActivity(int x, int y) {
    setAxisMapping(x, y);
}

/**
 * The parameters specify how to map the axes of the device to the axes of
 * the sensor coordinate system.
 *  
 * The device coordinate system has its x-axis pointing from left to right along the
 * display, the y-axis is pointing up along the display and the z-axis is pointing
 * upward.
 * 
 * The <code>x</code> parameter defines the direction of the sensor coordinate system's
 * x-axis in device coordinates. The <code>y</code> parameter defines the direction of 
 * the sensor coordinate system's y-axis in device coordinates.
 * 
 * For example, if the device is laying on a flat table with the display pointing up,
 * specify <code>SensorManager.AXIS_X</code> as the <code>x</code> parameter and
 * <code>SensorManager.AXIS_Y</code> as the <code>y</code> parameter.
 * If the device is mounted in a car in landscape mode,
 * specify <code>SensorManager.AXIS_Z</code> as the <code>x</code> parameter and
 * <code>SensorManager.AXIS_MINUS_X</code> as the <code>y</code> parameter.
 * 
 * @param x specifies how to map the x-axis of the device.
 * @param y specifies how to map the y-axis of the device.
 */
public void setAxisMapping(int x, int y) {
    this.x = x;
    this.y = y;     
}

/**
 * Registers an orientation observer.
 * 
 * @param hasOrientation is the observer to register.
 */
protected void register(HasOrientation hasOrientation) {
    observers.add(hasOrientation);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);        
}

@Override
protected void onResume() {
    super.onResume();

    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);             
}

@Override
protected void onPause() {
    sensorManager.unregisterListener(this);

    super.onPause();
}

public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

public void onSensorChanged(SensorEvent event) {        
    switch(event.sensor.getType())
    {
    case Sensor.TYPE_ACCELEROMETER:
        System.arraycopy(event.values, 0, accelerometerValues, 0, accelerometerValues.length);
        break;

    case Sensor.TYPE_MAGNETIC_FIELD:            
        if (SensorManager.getRotationMatrix(R, I, accelerometerValues, event.values)) {                             
            if (SensorManager.remapCoordinateSystem(R, x, y, remappedR)) {
                SensorManager.getOrientation(remappedR, orientation);

                for (HasOrientation observer : observers) {
                    observer.onOrientation(Orientation.fromRadians(orientation));
                }
            }
        }
        break;

    default:
        throw new IllegalArgumentException("unknown sensor type");
    }       
}   
}
方向是这样的:

/**
 * An angular direction vector.
 * 
 * The vector consists of three angles {azimuth, pitch, roll}. Within a body-fixed
 * cartesian system, the values of these angles define rotations of the three body axes.
 * 
 * All angles are in degrees.
 * 
 * @author michael@mictale.com
 *
 */
public class Orientation {

/**
 * Represents the angle to rotate the up axis. 
 */
public float azimuth;

/**
 * Represents the angle to rotate the axis pointing right.
 */
public float pitch;

/**
 * Represents the angle to rotate the forward axis. 
 */
public float roll;

/**
 * Initializes an instance that is empty.
 */
public Orientation() {  
}

/**
 * Initializes an instance from the specified rotation values in degrees.
 *  
 * @param azimuth is the azimuth angle.
 * @param pitch is the pitch angle.
 * @param roll is the roll angle.
 */
public Orientation(float azimuth, float pitch, float roll) {
    this.azimuth = azimuth;
    this.pitch = pitch;
    this.roll = roll;
}

/**
 * Sets the current values to match the specified orientation.
 * 
 * @param o is the orientation to copy.
 */
public void setTo(Orientation o) {
    this.azimuth = o.azimuth;
    this.pitch = o.pitch;
    this.roll = o.roll;     
}

/**
 * Normalizes the current instance.
 * 
 * Limits the azimuth to [0...360] and pitch and roll to [-180...180]. 
 */
public void normalize() {
    azimuth = Angle.normalize(azimuth);
    pitch = Angle.tilt(pitch);
    roll = Angle.tilt(roll);
}

/**
 * Creates a new vector from an array of radian values in the form
 * [azimuth, pitch, roll].
 * 
 * This method is useful to fill sensor data into a vector.
 * 
 * @param vec is the array of radians.
 * @return the vector.
 */
public static Orientation fromRadians(float[] vec) {
    return new Orientation((float)Math.toDegrees(vec[0]), (float)Math.toDegrees(vec[1]), 
            (float)Math.toDegrees(vec[2]));
}

@Override
public String toString() {
    return "{a=" + azimuth + ", p=" + pitch + ", r=" + roll + "}";
}
}

您需要调用
setAxisMapping()
以接收与纵向或横向模式对齐的方向。我只是从构造函数中调用它,所以我无法告诉您在活动运行时调用它时会发生什么。您可能需要重置矩阵。

谢谢Michael,这似乎是一个非常好的代码共享,但这里定义了getAxisMapping?Michael,Angle(如Angle.normalize())是某个库中的标准类还是留给读者作为练习?谢谢。它的定义如下:public static float normalize(float azority){float a=azority%360;return a>=0?a:a+360;}@Michael您的代码中HasOrientation和Angle类在哪里?我没有发布这个实用程序类,但您已经想到了。tilt()将值放入[-180…180]