2011-01-17 14 views
4

Ich muss sowohl im Hoch- als auch im Querformat den Tonhöhenwert (wie weit das Telefon geneigt ist) ablesen. ich benutze den unten stehenden Code im Portrait Ich bekomme meinen Wert von Wert [1] mit 0.0, wenn das Telefon flach mit der Vorderseite nach oben, -90 im Stehen und 180 im Liegen flach auf dem Gerät liegt. Alles gut bis jetzt ... Das Problem kommt, wenn das Gerät im Querformatmodus ist. An dieser Stelle verwende ich den Wert [2], um die Neigung des Geräts zu messen, aber das Problem liegt bei den Werten: 0 wenn das Telefon flach liegt (OK), steigt es auf 90, wenn es aufrecht steht (OK), aber wenn ich fortfahre die Bewegung der Wert fällt wieder unter 90 (80, 75, etc ...), also kann ich grundsätzlich nicht zwischen diesen 2 Positionen unterscheiden, da die Werte identisch sind. Also, was mache ich falsch, welche anderen Werte von den Sensoren kann ich lesen, um ein vollständiges Bild des Gerätes sowohl im Hoch- als auch im Querformat zu haben?Tonhöhenprobleme im Querformat

Same questoion wie hier: http://groups.google.com/group/android-beginners/browse_thread/thread/c691bbac3e294c7c?pli=1

Ich habe den folgenden Code:

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

}

Antwort

4

Sensor.TYPE_ORIENTATION ist veraltet und sollte nicht verwendet werden.

Das Lesen der Geräteausrichtung gab mir auch einige Kopfschmerzen. Hier ist eine Basisklasse, die ich für Tätigkeiten bin mit, dass das Gerät die Orientierung benötigen:

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

Orientierung geht so:

/** 
* 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 + "}"; 
} 
} 

Sie müssen setAxisMapping() anrufen um die Ausrichtung zu erhalten ausgerichtet Hoch- oder Landschaftsmodus. Ich habe es nur innerhalb des Konstruktors aufgerufen, sodass ich Ihnen nicht sagen kann, was passiert, wenn Sie es aufrufen, während die Aktivität ausgeführt wird. Möglicherweise müssen Sie die Matrizen zurücksetzen.

+0

Danke Michael, scheint ein sehr Gott Code zu teilen! – Alex

+0

Danke Michael, scheint eine sehr gute Code-Freigabe, aber hier ist getAxisMapping definiert? – Alex

+0

Entschuldigung: Tippfehler. Behoben. – Michael