7

Ich brauche etwas sehr einfaches, aber ich konnte kein geeignetes Beispiel finden, von zu lernen. Mein einziger Zweck ist die folgende:Get Rotation und Anzeige in Grad


Da das Gerät flach gelegt wird (auf dem Rücken) auf dem Schreibtisch, sollte es zeigen 0 (oder nahe 0) für X und Y-Achse. Wenn ich es vom oberen Teil abhebe (wo der Lautsprecher ist) und vom unteren Teil (wo das Mikrofon ist) bleibt stehen - es sollte mir zeigen, um wie viel Grad das Telefon gekippt ist. Mathematisch beschrieben - zeigen Sie in Grad den Winkel zwischen der Rückseite des Telefons und dem Tisch für eine der Achsen. Wenn ich den unteren Teil anhebe (und der obere Teil bleibt liegen), zeige minus Grad an.

Das gleiche gilt für die andere Achse - Drehen des Telefons um seine langen Seiten.


Ich habe versucht, eine App aus verschiedenen Beispielen montiert, mit Gyroskop oder Accelerometer oder Rotation Vector Sensoren, aber kommen kann nicht mit etwas richtig funktioniert.

Kann jemand mir ein Beispiel für die onSensorChanged Funktion geben (wie die ganze Arbeit hier geht) und mir nur sagen, welcher Sensor verwendet wird, damit ich weiß was zu registrieren?

Antwort

13

Es gibt ein paar Beispiele und Tutorials im Internet, aber seien Sie vorsichtig. Sensor.TYPE_ORIENTATION wurde veraltet. Sie müssen Rotationen berechnen, indem Sie diese beiden Sensoren Sensor.TYPE_ACCELEROMETER und Sensor.TYPE_MAGNETIC_FIELD abhören.

Der schwierige Teil nach der Registrierung, um Benachrichtigungen von diesen Sensoren zu erhalten, ist herauszufinden, wie die von ihnen empfangenen Daten behandelt werden. Der wichtigste Teil ist die folgende:

public void onSensorChanged(SensorEvent event) { 
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) 
     mGravity = event.values; 

    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) 
     mGeomagnetic = event.values; 

    if (mGravity != null && mGeomagnetic != null) { 
     float R[] = new float[9]; 
     float I[] = new float[9]; 

     boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic); 
     if (success) { 
      float orientation[] = new float[3]; 
      SensorManager.getOrientation(R, orientation); 
      azimut = orientation[0]; // orientation contains: azimut, pitch and roll 
      pitch = orientation[1]; 
      roll = orientation[2]; 
     } 
    } 
} 

Dies ist, wie sollte man die Azimut, Nick-, Roll- Werte Ihres Geräts in dem onSensorChanged(SensorEvent event) Rückruf Berechnung werden. Beachten Sie, dass "Alle drei obigen Winkel im Bogenmaß und positiv im Gegenuhrzeigersinn" sind. Sie können sie einfach mit Math.toDegrees()

konvertieren Wie es Louis CAD in den Kommentaren darauf hingewiesen, ist es eine gute Idee, die Initialisierung der I, R und Ausrichtung Arrays aus dem OnSensorChanged Callback zu verschieben, da es häufig aufgerufen wird . Das Erstellen und dann das Zurücklassen für den GC ist schlecht für die Leistung Ihrer Apps. Ich habe es der Einfachheit halber dort gelassen.

Je nachdem, wie Ihr Gerät gedreht wird, müssen Sie möglicherweise die Koordinaten neu zuordnen, um das gewünschte Ergebnis zu erhalten. Sie können mehr über remapCoordinateSystem lesen und auch über getRotationMatrix und getOrientation im android documentation

Beispielcode: http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html

+0

Hallo Csaba, folgte ich Ihrem Beispiel und es gibt sehr zuverlässige Werte, aber ich wollte diese bekommen Werte im Uhrzeigersinn positiv ist das möglich? Welche Änderungen muss ich an Ihrem bestehenden Code vornehmen? –

+0

@ParagKadam Ich denke, Sie müssen nur den Grad gegen den Uhrzeigersinn von 360 subtrahieren und Sie erhalten den Grad im Uhrzeigersinn: 'float im Uhrzeigersinn = 360 - counterClockwise;' Also wenn der Wert gegen den Uhrzeigersinn 15 war, dann im Uhrzeigersinn Wert ist 345. –

+0

Ja genau ... vielen Dank dafür :) –

0

Erstellen Sie die Datei layouts.xml in den Ordnern res/values-land und res/values-port mit folgendem Inhalt:

res/values-land/layouts.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <bool name="is_landscape">true</bool> 
</resources> 

Res/Werte-Port/Layouts.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <bool name="is_landscape">false</bool> 
</resources> 

In Ihrem Quellcode können Sie jetzt die aktuelle Ausrichtung Zugriff wie folgt:

context.getResources().getBoolean(R.bool.is_landscape)