Compartir a través de


Usar el sensor de orientación

Obtenga información sobre cómo usar los sensores de orientación para determinar la orientación del dispositivo.

API importantes

Requisitos previos

Debes estar familiarizado con el lenguaje de marcado extensible de aplicaciones (XAML), Microsoft Visual C# y eventos.

El dispositivo o emulador que usa debe admitir un sensor de orientación.

Creación de una aplicación OrientationSensor

Un sensor de orientación es uno de los varios tipos de sensores ambientales que permiten a las aplicaciones responder a los cambios en la orientación del dispositivo.

Hay dos tipos diferentes de API de sensor de orientación incluidas en el espacio de nombres Windows.Devices.Sensors: OrientationSensor y SimpleOrientation. Aunque ambos sensores son sensores de orientación, ese término está sobrecargado y se usan con fines muy diferentes. Sin embargo, dado que ambos son sensores de orientación, ambos se tratan en este artículo.

OrientationSensor API se usa para las aplicaciones 3D dos obtienen un cuaternión y una matriz de rotación. Un cuaternión se puede entender más fácilmente como un giro de un punto [x,y,z] sobre un eje arbitrario (contrastado con una matriz de rotación, que representa rotaciones alrededor de tres ejes). Las matemáticas detrás de cuaterniones son bastante exóticas en que implica las propiedades geométricas de números complejos y propiedades matemáticas de números imaginarios, pero trabajar con ellos es simple, y marcos como DirectX los admiten. Una aplicación compleja 3D puede usar el sensor Orientation para ajustar la perspectiva del usuario. Este sensor combina la entrada del acelerómetro, el girómetro y la brújula.

La API SimpleOrientation se usa para determinar la orientación del dispositivo actual en términos de definiciones como vertical hacia arriba, vertical hacia abajo, horizontal izquierda y horizontal derecha. También puede detectar si un dispositivo está cara arriba o abajo. En lugar de devolver propiedades como "vertical hacia arriba" o "horizontal izquierda", este sensor devuelve un valor de rotación: "No girado", "Rotationed90DegreesCounterclockwise", etc. En la tabla siguiente se asignan las propiedades de orientación comunes a la lectura del sensor correspondiente.

Orientación Lectura del sensor correspondiente
Vertical hacia arriba NotRotated
Horizontal izquierdo Rotated90DegreesCounterclockwise
Vertical hacia abajo Rotated180DegreesCounterclockwise
Horizontal derecha Rotated270DegreesCounterclockwise

Nota:

Para obtener una implementación más completa, consulte:

Instrucciones

  • Cree un nuevo proyecto y elija una aplicación en blanco (Windows universal) en las plantillas de proyecto de Visual C# .

  • Abra el archivo MainPage.xaml.cs del proyecto y reemplace el código existente por lo siguiente.

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;

    using Windows.UI.Core;
    using Windows.Devices.Sensors;

    // The Blank Page item template is documented at https://go.microsoft.com/fwlink/p/?linkid=234238

    namespace App1
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            private OrientationSensor _sensor;

            private async void ReadingChanged(object sender, OrientationSensorReadingChangedEventArgs e)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    OrientationSensorReading reading = e.Reading;

                    // Quaternion values
                    txtQuaternionX.Text = String.Format("{0,8:0.00000}", reading.Quaternion.X);
                    txtQuaternionY.Text = String.Format("{0,8:0.00000}", reading.Quaternion.Y);
                    txtQuaternionZ.Text = String.Format("{0,8:0.00000}", reading.Quaternion.Z);
                    txtQuaternionW.Text = String.Format("{0,8:0.00000}", reading.Quaternion.W);

                    // Rotation Matrix values
                    txtM11.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M11);
                    txtM12.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M12);
                    txtM13.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M13);
                    txtM21.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M21);
                    txtM22.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M22);
                    txtM23.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M23);
                    txtM31.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M31);
                    txtM32.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M32);
                    txtM33.Text = String.Format("{0,8:0.00000}", reading.RotationMatrix.M33);
                });
            }

            public MainPage()
            {
                this.InitializeComponent();
                _sensor = OrientationSensor.GetDefault();

                // Establish the report interval for all scenarios
                uint minReportInterval = _sensor.MinimumReportInterval;
                uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
                _sensor.ReportInterval = reportInterval;

                // Establish event handler
                _sensor.ReadingChanged += new TypedEventHandler<OrientationSensor, OrientationSensorReadingChangedEventArgs>(ReadingChanged);
            }
        }
    }

Deberá cambiar el nombre del espacio de nombres en el fragmento de código anterior con el nombre que asignó al proyecto. Por ejemplo, si creó un proyecto denominado OrientationSensorCS, reemplazaría por namespace App1 namespace OrientationSensorCS.

  • Abra el archivo MainPage.xaml y reemplace el contenido original por el siguiente XML.
        <Page
        x:Class="App1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">

        <Grid x:Name="LayoutRoot" Background="Black">
            <TextBlock HorizontalAlignment="Left" Height="28" Margin="4,4,0,0" TextWrapping="Wrap" Text="M11:" VerticalAlignment="Top" Width="46"/>
            <TextBlock HorizontalAlignment="Left" Height="23" Margin="4,36,0,0" TextWrapping="Wrap" Text="M12:" VerticalAlignment="Top" Width="39"/>
            <TextBlock HorizontalAlignment="Left" Height="24" Margin="4,72,0,0" TextWrapping="Wrap" Text="M13:" VerticalAlignment="Top" Width="39"/>
            <TextBlock HorizontalAlignment="Left" Height="31" Margin="4,118,0,0" TextWrapping="Wrap" Text="M21:" VerticalAlignment="Top" Width="39"/>
            <TextBlock HorizontalAlignment="Left" Height="24" Margin="4,160,0,0" TextWrapping="Wrap" Text="M22:" VerticalAlignment="Top" Width="39"/>
            <TextBlock HorizontalAlignment="Left" Height="24" Margin="8,201,0,0" TextWrapping="Wrap" Text="M23:" VerticalAlignment="Top" Width="35"/>
            <TextBlock HorizontalAlignment="Left" Height="23" Margin="4,234,0,0" TextWrapping="Wrap" Text="M31:" VerticalAlignment="Top" Width="39"/>
            <TextBlock HorizontalAlignment="Left" Height="28" Margin="4,274,0,0" TextWrapping="Wrap" Text="M32:" VerticalAlignment="Top" Width="46"/>
            <TextBlock HorizontalAlignment="Left" Height="21" Margin="4,322,0,0" TextWrapping="Wrap" Text="M33:" VerticalAlignment="Top" Width="39"/>
            <TextBlock x:Name="txtM11" HorizontalAlignment="Left" Height="19" Margin="43,4,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM12" HorizontalAlignment="Left" Height="23" Margin="43,36,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM13" HorizontalAlignment="Left" Height="15" Margin="43,72,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM21" HorizontalAlignment="Left" Height="20" Margin="43,114,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM22" HorizontalAlignment="Left" Height="19" Margin="43,156,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM23" HorizontalAlignment="Left" Height="16" Margin="43,197,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM31" HorizontalAlignment="Left" Height="17" Margin="43,230,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM32" HorizontalAlignment="Left" Height="19" Margin="43,270,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock x:Name="txtM33" HorizontalAlignment="Left" Height="21" Margin="43,322,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="53"/>
            <TextBlock HorizontalAlignment="Left" Height="15" Margin="194,8,0,0" TextWrapping="Wrap" Text="Quaternion X:" VerticalAlignment="Top" Width="81"/>
            <TextBlock HorizontalAlignment="Left" Height="23" Margin="194,36,0,0" TextWrapping="Wrap" Text="Quaternion Y:" VerticalAlignment="Top" Width="81"/>
            <TextBlock HorizontalAlignment="Left" Height="15" Margin="194,72,0,0" TextWrapping="Wrap" Text="Quaternion Z:" VerticalAlignment="Top" Width="81"/>
            <TextBlock x:Name="txtQuaternionX" HorizontalAlignment="Left" Height="15" Margin="279,8,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="104"/>
            <TextBlock x:Name="txtQuaternionY" HorizontalAlignment="Left" Height="12" Margin="275,36,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="108"/>
            <TextBlock x:Name="txtQuaternionZ" HorizontalAlignment="Left" Height="19" Margin="275,68,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="89"/>
            <TextBlock HorizontalAlignment="Left" Height="21" Margin="194,96,0,0" TextWrapping="Wrap" Text="Quaternion W:" VerticalAlignment="Top" Width="81"/>
            <TextBlock x:Name="txtQuaternionW" HorizontalAlignment="Left" Height="12" Margin="279,96,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="72"/>

        </Grid>
    </Page>

Deberá reemplazar la primera parte del nombre de clase en el fragmento de código anterior por el espacio de nombres de la aplicación. Por ejemplo, si creó un proyecto denominado OrientationSensorCS, reemplazaría por x:Class="App1.MainPage" x:Class="OrientationSensorCS.MainPage". También debe reemplazar por xmlns:local="using:App1" xmlns:local="using:OrientationSensorCS".

  • Presione F5 o seleccione Depurar Iniciar depuración> para compilar, implementar y ejecutar la aplicación.

Una vez que se ejecuta la aplicación, puedes cambiar la orientación moviendo el dispositivo o usando las herramientas del emulador.

  • Detenga la aplicación volviendo a Visual Studio y presionando Mayús+F5 o seleccione Depurar Detener depuración> para detener la aplicación.

Explicación

En el ejemplo anterior se muestra la poca cantidad de código que necesitará escribir para integrar la entrada del sensor de orientación en la aplicación.

La aplicación establece una conexión con el sensor de orientación predeterminado en el método MainPage .

_sensor = OrientationSensor.GetDefault();

La aplicación establece el intervalo de informe dentro del método MainPage . Este código recupera el intervalo mínimo admitido por el dispositivo y lo compara con un intervalo solicitado de 16 milisegundos (que aproxima una frecuencia de actualización de 60 Hz). Si el intervalo mínimo admitido es mayor que el intervalo solicitado, el código establece el valor en el mínimo. De lo contrario, establece el valor en el intervalo solicitado.

uint minReportInterval = _sensor.MinimumReportInterval;
uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
_sensor.ReportInterval = reportInterval;

Los nuevos datos del sensor se capturan en el método ReadingChanged . Cada vez que el controlador del sensor recibe nuevos datos del sensor, pasa los valores a la aplicación mediante este controlador de eventos. La aplicación registra este controlador de eventos en la línea siguiente.

_sensor.ReadingChanged += new TypedEventHandler<OrientationSensor,
OrientationSensorReadingChangedEventArgs>(ReadingChanged);

Estos nuevos valores se escriben en los TextBlocks que se encuentran en el XAML del proyecto.

Creación de una aplicación SimpleOrientation

Esta sección se divide en dos subsecciones. La primera subsección le llevará a través de los pasos necesarios para crear una aplicación de orientación sencilla desde cero. En la subsección siguiente se explica la aplicación que acaba de crear.

Instrucciones

  • Cree un nuevo proyecto y elija una aplicación en blanco (Windows universal) en las plantillas de proyecto de Visual C# .

  • Abra el archivo MainPage.xaml.cs del proyecto y reemplace el código existente por lo siguiente.

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;

    using Windows.UI.Core;
    using Windows.Devices.Sensors;
    // The Blank Page item template is documented at https://go.microsoft.com/fwlink/p/?linkid=234238

    namespace App1
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            // Sensor and dispatcher variables
            private SimpleOrientationSensor _simpleorientation;

            // This event handler writes the current sensor reading to
            // a text block on the app' s main page.

            private async void OrientationChanged(object sender, SimpleOrientationSensorOrientationChangedEventArgs e)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    SimpleOrientation orientation = e.Orientation;
                    switch (orientation)
                    {
                        case SimpleOrientation.NotRotated:
                            txtOrientation.Text = "Not Rotated";
                            break;
                        case SimpleOrientation.Rotated90DegreesCounterclockwise:
                            txtOrientation.Text = "Rotated 90 Degrees Counterclockwise";
                            break;
                        case SimpleOrientation.Rotated180DegreesCounterclockwise:
                            txtOrientation.Text = "Rotated 180 Degrees Counterclockwise";
                            break;
                        case SimpleOrientation.Rotated270DegreesCounterclockwise:
                            txtOrientation.Text = "Rotated 270 Degrees Counterclockwise";
                            break;
                        case SimpleOrientation.Faceup:
                            txtOrientation.Text = "Faceup";
                            break;
                        case SimpleOrientation.Facedown:
                            txtOrientation.Text = "Facedown";
                            break;
                        default:
                            txtOrientation.Text = "Unknown orientation";
                            break;
                    }
                });
            }

            public MainPage()
            {
                this.InitializeComponent();
                _simpleorientation = SimpleOrientationSensor.GetDefault();

                // Assign an event handler for the sensor orientation-changed event
                if (_simpleorientation != null)
                {
                    _simpleorientation.OrientationChanged += new TypedEventHandler<SimpleOrientationSensor, SimpleOrientationSensorOrientationChangedEventArgs>(OrientationChanged);
                }
            }
        }
    }

Deberá cambiar el nombre del espacio de nombres en el fragmento de código anterior con el nombre que asignó al proyecto. Por ejemplo, si creó un proyecto denominado SimpleOrientationCS, reemplazaría por namespace App1 namespace SimpleOrientationCS.

  • Abra el archivo MainPage.xaml y reemplace el contenido original por el siguiente XML.
    <Page
        x:Class="App1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">

        <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
            <TextBlock HorizontalAlignment="Left" Height="24" Margin="8,8,0,0" TextWrapping="Wrap" Text="Current Orientation:" VerticalAlignment="Top" Width="101" Foreground="#FFF8F7F7"/>
            <TextBlock x:Name="txtOrientation" HorizontalAlignment="Left" Height="24" Margin="118,8,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="175" Foreground="#FFFEFAFA"/>

        </Grid>
    </Page>

Deberá reemplazar la primera parte del nombre de clase en el fragmento de código anterior por el espacio de nombres de la aplicación. Por ejemplo, si creó un proyecto denominado SimpleOrientationCS, reemplazaría por x:Class="App1.MainPage" x:Class="SimpleOrientationCS.MainPage". También debe reemplazar por xmlns:local="using:App1" xmlns:local="using:SimpleOrientationCS".

  • Presione F5 o seleccione Depurar Iniciar depuración> para compilar, implementar y ejecutar la aplicación.

Una vez que se ejecuta la aplicación, puedes cambiar la orientación moviendo el dispositivo o usando las herramientas del emulador.

  • Detenga la aplicación volviendo a Visual Studio y presionando Mayús+F5 o seleccione Depurar Detener depuración> para detener la aplicación.

Explicación

En el ejemplo anterior se muestra la poca cantidad de código que necesitará escribir para integrar la entrada del sensor de orientación simple en la aplicación.

La aplicación establece una conexión con el sensor predeterminado en el método MainPage .

_simpleorientation = SimpleOrientationSensor.GetDefault();

Los nuevos datos del sensor se capturan en el método OrientationChanged . Cada vez que el controlador del sensor recibe nuevos datos del sensor, pasa los valores a la aplicación mediante este controlador de eventos. La aplicación registra este controlador de eventos en la línea siguiente.

_simpleorientation.OrientationChanged += new TypedEventHandler<SimpleOrientationSensor,
SimpleOrientationSensorOrientationChangedEventArgs>(OrientationChanged);

Estos nuevos valores se escriben en un TextBlock que se encuentra en el XAML del proyecto.

<TextBlock HorizontalAlignment="Left" Height="24" Margin="8,8,0,0" TextWrapping="Wrap" Text="Current Orientation:" VerticalAlignment="Top" Width="101" Foreground="#FFF8F7F7"/>
 <TextBlock x:Name="txtOrientation" HorizontalAlignment="Left" Height="24" Margin="118,8,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="175" Foreground="#FFFEFAFA"/>