2013-02-12 6 views
7

Dies könnte leicht ein Duplikat einer anderen Frage sein, ich bin gerade dabei herauszufinden, wonach gesucht werden soll.Erhalten Sie Telefonausrichtung, wenn Sie in einer Ausrichtung gesperrt sind

Meine Kamera-App im Querformat gesperrt ist (im Manifest) wie folgt aus:

android:screenOrientation="landscape" 

Allerdings möchte ich noch auf einige UI-Elemente drehen, wenn das Gerät in den Portrait gedreht wird (obwohl android noch denken es ist in der Landschaft, aber das ist absichtlich).

Ich habe das also versucht, die Orientierung

int rotation = this.getWindowManager().getDefaultDisplay() 
      .getRotation(); 
    int degrees = 0; 
    switch (rotation) { 
     case Surface.ROTATION_0: 
      Log.d("Rotation", "0"); 
      break; 
     case Surface.ROTATION_90: 
      Log.d("Rotation", "90"); 
      break; 
     case Surface.ROTATION_180: 
      Log.d("Rotation", "180"); 
      break; 
     case Surface.ROTATION_270: 
      Log.d("Rotation", "270"); 
      break; 
    } 

Und leider immer es gibt 90 zu überprüfen, unabhängig davon, wie ich das Telefon einzuschalten. Gibt es einen stabileren Weg zur Orientierung, unabhängig davon, was Android "denkt", ist die Ausrichtung?

+0

wann Sie können sich die Orientierung? Zum Zeitpunkt des Starts der Aktivität? –

+0

Ich möchte es ständig überprüfen können, damit ich sofort auf eine Änderung reagieren kann. Also überprüfe ich jeden Kamerarahmen (zumindest für den Moment) – Jameo

+0

Werfen Sie einen Blick auf diese: http://stackoverflow.com/a/41104983/2267723 Diese Lösung mit SensorManager. –

Antwort

5

So, nachdem ich darüber nachdachte, wurde mir klar, ich könnte einen ähnlichen Algorithmus wie einfach implementieren, was Android verwendet, um sich um die Ausrichtung, um herauszufinden. Ich mache es den onSenseorChanged Rückruf mit

public static final int UPSIDE_DOWN = 3; 
public static final int LANDSCAPE_RIGHT = 4; 
public static final int PORTRAIT = 1; 
public static final int LANDSCAPE_LEFT = 2; 
public int mOrientationDeg; //last rotation in degrees 
public int mOrientationRounded; //last orientation int from above 
private static final int _DATA_X = 0; 
private static final int _DATA_Y = 1; 
private static final int _DATA_Z = 2; 
private int ORIENTATION_UNKNOWN = -1; 
@Override 
public void onSensorChanged(SensorEvent event) 
{ 
    Log.d(TAG, "Sensor Changed"); 
    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; 
    // Don't trust the angle if the magnitude is small compared to the y value 
    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 
     while (orientation >= 360) { 
      orientation -= 360; 
     } 
     while (orientation < 0) { 
      orientation += 360; 
     } 
    } 
    //^^ thanks to google for that code 
    //now we must figure out which orientation based on the degrees 
    Log.d("Oreination", ""+orientation); 
    if (orientation != mOrientationDeg) 
    { 
     mOrientationDeg = orientation; 
     //figure out actual orientation 
     if(orientation == -1){//basically flat 

     } 
     else if(orientation <= 45 || orientation > 315){//round to 0 
      tempOrientRounded = 1;//portrait 
     } 
     else if(orientation > 45 && orientation <= 135){//round to 90 
      tempOrientRounded = 2; //lsleft 
     } 
     else if(orientation > 135 && orientation <= 225){//round to 180 
      tempOrientRounded = 3; //upside down 
     } 
     else if(orientation > 225 && orientation <= 315){//round to 270 
      tempOrientRounded = 4;//lsright 
     } 

    } 

    if(mOrientationRounded != tempOrientRounded){ 
      //Orientation changed, handle the change here 
     mOrientationRounded = tempOrientRounded; 

    } 
} 

Es sieht mehr complecated als es ist, aber weiß nur, dass es funktioniert (ich würde sagen, genauso gut wie das System arbeitet man). Vergessen Sie nicht, Beschleunigungsmesser für Sensorwechsel-Ereignis-Listener in onResume und onPause registrieren

+0

Nur sinnvoll innerhalb einer Aktivität.In vielen Fällen müssen Sie die Ausrichtung außerhalb einer Aktivität bestimmen. – AndroidDev

+0

Zum Beispiel ??? Auch in der Frage gebe ich zu, dass das, was ich tue, nicht normal ist, aber es wurde für die Kamera-Bibliothek benötigt, die ich verwendete – Jameo

+0

Dienste, die die Verarbeitung von Bildern behandeln. – AndroidDev

3

Für Orientierungen erkennen ich das Sensormanager für das Register verwenden:

mSensorOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);  
mSensorManager.registerListener(this, mSensorOrientation, SensorManager.SENSOR_DELAY_NORMAL); 

Und dann diese für Änderungen Orientierungen erkennen, in den Kommentaren können Sie Ihre eigene Methode Implementierungen setzen.

Konstanten:

public static final int LYING = 0; 
public static final int LANDSCAPE_RIGHT = 1; 
public static final int PORTRAIT = 2; 
public static final int LANDSCAPE_LEFT = 3; 



public void onSensorChanged(SensorEvent event) { 

Sensor sensorEvent = event.sensor; 

if ((sensorEvent.getType() == Sensor.TYPE_ORIENTATION)) { 

    float [] eventValues = event.values; 

    // current orientation of the phone 
    float xAxis = eventValues[1]; 
    float yAxis = eventValues[2]; 

    if ((yAxis <= 25) && (yAxis >= -25) && (xAxis >= -160)) { 

     if (previousOrientation != PORTRAIT){ 
      previousOrientation = PORTRAIT; 

      // CHANGED TO PORTRAIT 
     } 

    } else if ((yAxis < -25) && (xAxis >= -20)) { 

     if (previousOrientation != LANDSCAPE_RIGHT){ 
      previousOrientation = LANDSCAPE_RIGHT; 

      // CHANGED TO LANDSCAPE RIGHT 
     } 

    } else if ((yAxis > 25) && (xAxis >= -20)){ 

     if (previousOrientation != LANDSCAPE_LEFT){ 
      previousOrientation = LANDSCAPE_LEFT; 

      // CHANGED TO LANDSCAPE LEFT 
     } 
    } 
} 

}

+0

Sensor.TYPE_ORIENTATION wurde in API 8 nicht weiter unterstützt. Ich teste das jetzt, aber wahrscheinlich muss ich etwas mehr vorwärtskompatibel finden. Sie behauptet, dass SensorManager.getOrientation das ist, was Sie stattdessen verwenden sollten – Jameo

+0

Ich habe einen anderen Weg gefunden, es zu tun, Sie möchten vielleicht sehen, ob Sie immer noch Ihre Methode verwenden. Es funktionierte nicht auf meinem Android 4.2 Telefon – Jameo

+0

Schön, als Antwort zu posten und sich dann zu akzeptieren;) – PaNaVTEC

1

Nach einigen Recherchen und ein paar Sachen versuchen, es für mich nur funktionieren, wenn ich den Sensor nach:

mSensorOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 

Sensor.TYPE_ORIENTATION ist veraltet und hat mir nach einigen Beispielcodes von verschiedenen Leuten schlechte Ergebnisse zum Abrufen von Orientierung gegeben. Ich weiß nicht, ob es in Ordnung ist oder nicht, aber es hat für mich funktioniert.

0

Eine Übersetzung von @panavtec Antwort auf 23 API, mit this als Referenz

class MyActivity extends Activity implements SensorEventListener { 

    private SensorManager sensorManager; 
    private float[] lastMagFields = new float[3];; 
    private float[] lastAccels = new float[3];; 
    private float[] rotationMatrix = new float[16]; 
    private float[] orientation = new float[4]; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 
    } 

    protected void onResume() { 
     super.onResume(); 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME); 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
    } 

    protected void onPause() { 
     super.onPause(); 
     sensorManager.unregisterListener(this); 
    } 

    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, lastAccels, 0, 3); 
       break; 
      case Sensor.TYPE_MAGNETIC_FIELD: 
       System.arraycopy(event.values, 0, lastMagFields, 0, 3); 
       break; 
      default: 
       return; 
     } 

     if (SensorManager.getRotationMatrix(rotationMatrix, null, lastAccels, lastMagFields)) { 
      SensorManager.getOrientation(rotationMatrix, orientation); 

      float xAxis = (float) Math.toDegrees(orientation[1]); 
      float yAxis = (float) Math.toDegrees(orientation[2]); 

      int orientation = Configuration.ORIENTATION_UNDEFINED; 
      if ((yAxis <= 25) && (yAxis >= -25) && (xAxis >= -160)) { 
       Log.d(TAG, "Portrait"); 
       orientation = Configuration.ORIENTATION_PORTRAIT; 
      } else if ((yAxis < -25) && (xAxis >= -20)) { 
       Log.d(TAG, "Landscape Right"); 
       orientation = Configuration.ORIENTATION_LANDSCAPE; 
      } else if ((yAxis > 25) && (xAxis >= -20)){ 
       orientation = Configuration.ORIENTATION_LANDSCAPE; 
       Log.d(TAG, "Landscape Left"); 
      } 
     } 
    } 
}