2011-05-04 21 views
13

Estoy probando la salida del acelerómetro en 2 dispositivos diferentes (Elocity A7 y la tableta Archos 7 Home) pero el sensor parece estar dando resultados diferentes. Lo tengo programado para establecer el modo de paisaje, pero los ejes xey parecen ser el oppisite entre los 2 dispositivos. El eje x devuelve 10 cuando se mantiene perpendicular al suelo y el eje X de Archos devuelve 0. La tableta Elocity es Android 2.2 y Archos es 2.1. ¿Puede alguien señalarme en la dirección correcta cómo conseguir que la orientación del acelerómetro esté sincronizada entre estos 2 dispositivos?Orientación desde el acelerómetro Android

Respuesta

7

Por lo que sé, esto se debe a la orientación predeterminada del dispositivo. F.e. Las nuevas tabletas Android con Honeycomb tienen una orientación vertical cuando se usan como paisaje en los teléfonos.

http://developer.android.com/reference/android/hardware/SensorEvent.html

En la documentación androide Hay información de que:

El sistema de coordenadas se define en relación con la pantalla del teléfono en su orientación predeterminada. Los ejes no se intercambian cuando cambia la orientación de la pantalla del dispositivo.

El eje X es horizontal y apunta hacia la derecha, el eje Y es vertical y apunta hacia arriba y el eje Z apunta hacia el exterior de la cara frontal de la pantalla. En este sistema, las coordenadas detrás de la pantalla tienen valores Z negativos.

¿Quizás uno de estos dispositivos también tiene una orientación horizontal (vertical) como paisaje?

Espero que te ayude de alguna manera.

4

Como se indicó anteriormente, la orientación de la pantalla predeterminada puede variar de un dispositivo a otro. Las coordenadas del acelerómetro siempre coincidirán con la orientación predeterminada del dispositivo. Este comportamiento es diferente para las coordenadas de pantalla. A medida que el dispositivo gira, las coordenadas de la pantalla también rotan, de modo que (0, 0) siempre es la esquina superior izquierda actual de la pantalla. En un dispositivo con una orientación de retrato predeterminada, el bloqueo de la orientación a vertical garantizará que las coordenadas del sensor se desplacen a lo largo del mismo eje que las coordenadas de la pantalla, independientemente de la rotación. Por otro lado, si se fija la orientación de la pantalla a vertical en un dispositivo con una orientación horizontal predeterminada, el eje del sensor se ejecutará en una dirección diferente que el eje de la pantalla.

Este artículo: http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html explica esto con mayor profundidad y ofrece una solución para resolver el problema.

15

De hecho, los ejes del acelerómetro son relativos a la orientación predeterminada del dispositivo.

Aquí cómo tratar con él:

static void canonicalOrientationToScreenOrientation(
     int displayRotation, float[] canVec, float[] screenVec) 
{ 
    final int axisSwap[][] = { 
    { 1, -1, 0, 1 },  // ROTATION_0 
    {-1, -1, 1, 0 },  // ROTATION_90 
    {-1, 1, 0, 1 },  // ROTATION_180 
    { 1, 1, 1, 0 } }; // ROTATION_270 

    final int[] as = axisSwap[displayRotation]; 
    screenVec[0] = (float)as[0] * canVec[ as[2] ]; 
    screenVec[1] = (float)as[1] * canVec[ as[3] ]; 
    screenVec[2] = canVec[2]; 
} 

Esta solución fue proporcionado por NVidia. Consulte su white paper sobre el acelerómetro Android para obtener más detalles.

+0

Lo siento, pero lo que se puede añadir en canVec y en screenVec? La supertrotación supongo que es para las constantes PROTRAIT o LANDSCAPE, ¿verdad? – Dante

+2

Para más detalles, consultar este enlace http://developer.download.nvidia.com/tegra/docs/tegra_android_accelerometer_v5f.pdf – Hartok

+0

en mi humilde opinión, de user1504495 volver a trabajar de esto es más fácil de entender. – ToolmakerSteve

11

solo quería agregar algo a la respuesta de Hartok ya que no pude entenderlo al principio ...

me he reescrito el método a ser:

public static float[] adjustAccelOrientation(int displayRotation, float[] eventValues) 
{ 
    float[] adjustedValues = new float[3]; 

    final int axisSwap[][] = { 
    { 1, -1, 0, 1 },  // ROTATION_0 
    {-1, -1, 1, 0 },  // ROTATION_90 
    {-1, 1, 0, 1 },  // ROTATION_180 
    { 1, 1, 1, 0 } }; // ROTATION_270 

    final int[] as = axisSwap[displayRotation]; 
    adjustedValues[0] = (float)as[0] * eventValues[ as[2] ]; 
    adjustedValues[1] = (float)as[1] * eventValues[ as[3] ]; 
    adjustedValues[2] = eventValues[2]; 

    return adjustedValues; 
} 

Exactamente lo mismo, sólo con los nombres de variables más asequibles y que recrean el flotador interno porque necesitaba así ... sólo tiene que llamar esta función, poner en el getRotation y los event.values ​​flotar matriz, compruebe los valores de su red de flotadores retorno y elegir cualquier número que prefiere ...

Espero que esto ayude a alguien!

+0

lo siento, pero ¿qué pongo en la visualización de rotación int? He puesto el evento llamado SensorEvent del vacío público enSensorChanged (evento SensorEvent). ¿Qué me estoy perdiendo? ¿Qué debo agregar? – Dante

+1

Necesita la rotación de la pantalla. (WindowManager) this.getSystemService (WINDOW_SERVICE) .getDefaultDisplay(). GetRotation() – user1504495

Cuestiones relacionadas