2011-01-17 8 views
4

가로 세로 모드에서 피치 값 (앞뒤로 기울이는 정도)을 읽어야합니다. 초상화에서 코드 벨로우즈를 사용하여 휴대 전화가 얼굴을 위로하여 평평하게 누워있을 때 값이 [1] 인 경우, 수직으로 서있는 경우 -90, 기기의 얼굴에 평평하게 누워있을 때 180을 사용합니다. 지금까지 모든 위대한 ... 장치가 가로 모드 인 경우 문제가 발생합니다. 이 시점에서 저는 장치의 기울기를 측정하기 위해 [2] 값을 사용하고 있습니다. 문제는 값으로 나타냅니다 : 0 (평평하게 놓여있는 전화가 수평으로 놓여있을 때 0) 똑바로 서서 (OK) 서있을 때 90으로 상승하지만 계속할 때 움직임이 90 (80, 75 등 ...) 이하로 떨어지면 기본적으로 값이 동일하므로이 두 위치를 구별 할 수 없습니다. 그래서 내가 잘못하고있는 것, 장치의 전체 그림을 가로 및 세로 모드로 기울이기 위해 읽을 수있는 센서의 다른 값은 무엇입니까? 로 여기가로 모드의 피치 문제

같은 questoion : http://groups.google.com/group/android-beginners/browse_thread/thread/c691bbac3e294c7c?pli=1

나는 다음과 같은 코드를 가지고 :

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); 

}

답변

4

Sensor.TYPE_ORIENTATION가 더 이상 사용되지 않습니다.

기기 방향을 읽으면 두통이 생겼습니다.

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"); 
    }  
} 
} 

방향은 다음과 같이 진행됩니다 : 당신은 세로 또는 중 하나에 정렬 방향을받을 setAxisMapping()를 호출 할 필요가

/** 
* 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 [email protected] 
* 
*/ 
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 + "}"; 
} 
} 

여기 장치의 방향을 필요로 활동을 위해 사용하고 기본 클래스입니다 가로 모드. 저는 생성자 내에서만 호출 했으므로 활동이 실행되는 동안 호출 할 때 어떤 일이 발생하는지 말할 수 없습니다. 매트릭스를 재설정해야 할 수도 있습니다.

+0

감사합니다. Michael, 매우 신의 코드 공유처럼 보입니다! – Alex

+0

감사합니다. Michael, 매우 신의 코드 공유처럼 보이지만 여기에 getAxisMapping이 정의되어 있습니까? – Alex

+0

죄송합니다. typo. 고쳤다. – Michael