Använda orienteringssensorerna

Lär dig hur du använder orienteringssensorerna för att fastställa enhetens orientering.

Det här exemplet skapar en enkel app som förlitar sig på en orienteringssensor som en indataenhet. En orienteringssensor är en av flera typer av miljösensorer som gör att appar kan svara på ändringar i enhetens orientering.

Note

Den här artikeln fokuserar på kod som visar hur du använder en orienteringssensor. En översikt över orienteringssensorerna finns i Sensorer: Orienteringssensor.

Förutsättningar

Du bör känna till orienteringssensorn och dess användning. Se Sensorer: Orienteringssensor.

Enheten som du använder måste ha stöd för en orienteringssensor.

Typer av orienteringssensorer

Det finns två olika typer av API:er för orienteringssensorer som ingår i Windows. Devices.Sensors namespace: OrientationSensor och SimpleOrientation. Båda dessa sensorer är orienteringssensorer, men termen är överbelastad och används för mycket olika syften. Men eftersom båda är orienteringssensorer beskrivs båda i den här artikeln.

API:et OrientationSensor används för 3D-appar, två hämtar en quaternion och en rotationsmatris. En quaternion kan enklast tolkas som en rotation av en punkt [x,y,z] om en godtycklig axel (kontrasterad med en rotationsmatris, som representerar rotationer runt tre axlar). Matematiken bakom quaternions är ganska exotisk eftersom den omfattar geometriska egenskaper hos komplexa tal och matematiska egenskaper hos imaginära tal, men att arbeta med dem är enkelt, och ramverk som DirectX stöder dem. En komplex 3D-app kan använda orienteringssensorn för att justera användarens perspektiv. Denna sensor kombinerar indata från accelerometer, gyrometer och kompass.

API:t SimpleOrientationSensor används för att fastställa enhetens aktuella fysiska orientering utifrån definitioner som stående uppåt, stående nedåt, liggande åt vänster och liggande åt höger. Den kan också identifiera om en enhet är uppåt eller nedåtvänd. I stället för att returnera värden som "stående uppåt" eller "liggande åt vänster" returnerar den här sensorn ett rotationsvärde: "Ej roterad", "Roterad 90 grader moturs" och så vidare. I följande tabell mappas vanliga orienteringsegenskaper till motsvarande sensoravläsning.

Orientering Motsvarande sensoravläsning
Porträtt uppåt Inte roterad
Liggande åt vänster Roterad90GraderMoturs
Stående läge upp och ned Roterad180GraderMoturs
Liggande höger Roterad 270 grader moturs

Exempelkod – orienteringssensor

using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using Windows.Devices.Sensors;

namespace DevicesDemo.Pages
{
    public sealed partial class OrientationSensorPage : Page
    {
        private OrientationSensor? orientationSensor;

        public OrientationSensorPage()
        {
            InitializeComponent();

            // Get the default orientation sensor object.
            orientationSensor = OrientationSensor.GetDefault();

            if (orientationSensor != null)
            {
                // Establish the report interval.
                uint minReportInterval = orientationSensor.MinimumReportInterval;
                uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
                orientationSensor.ReportInterval = reportInterval;

                // Assign an event handler for the reading-changed event.
                orientationSensor.ReadingChanged += OrientationSensor_ReadingChanged;
            }
            else
            {
                statusBar.Message = "No orientation sensor was found.";
                statusBar.Severity = InfoBarSeverity.Error;
                statusBar.IsOpen = true;
            }
        }

        // This event handler writes the current orientation
        // reading to the text blocks on the XAML page.
        private void OrientationSensor_ReadingChanged(OrientationSensor sender, OrientationSensorReadingChangedEventArgs args)
        {
            DispatcherQueue?.TryEnqueue(DispatcherQueuePriority.Normal, () =>
            {
                OrientationSensorReading reading = args.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);
            });
        }
    }
}
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid Margin="24">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto" MinWidth="66"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto" MinWidth="66"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto" MinWidth="66"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
        </Grid.RowDefinitions>
        <TextBlock Text="M11:" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM11" Grid.Column="1" Text="---"/>
        <TextBlock Text="M12:" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM12" Grid.Column="1" Grid.Row="1" Text="---"/>
        <TextBlock Text="M13:" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM13" Grid.Column="1" Grid.Row="2" Text="---"/>

        <TextBlock Text="M21:" Grid.Column="2" Grid.Row="0" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM21" Grid.Column="3" Grid.Row="0" Text="---"/>
        <TextBlock Text="M22:" Grid.Column="2" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM22" Grid.Column="3" Grid.Row="1" Text="---"/>
        <TextBlock Text="M23:" Grid.Column="2" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM23" Grid.Column="3" Grid.Row="2" Text="---"/>

        <TextBlock Text="M31:" Grid.Column="4" Grid.Row="0" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM31" Grid.Column="5" Grid.Row="0" Text="---"/>
        <TextBlock Text="M32:" Grid.Column="4" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM32" Grid.Column="5" Grid.Row="1" Text="---"/>
        <TextBlock Text="M33:" Grid.Column="4" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtM33" Grid.Column="5" Grid.Row="2" Text="---"/>

    </Grid>
    <Grid Margin="24" Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
            <RowDefinition Height="44"/>
        </Grid.RowDefinitions>

        <TextBlock Text="Quaternion X:" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionX" Grid.Column="1" Grid.Row="0" Text="---"/>
        <TextBlock Text="Quaternion Y:" Grid.Row="1" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionY" Grid.Column="1" Grid.Row="1" Text="---"/>
        <TextBlock Text="Quaternion Z:" Grid.Row="2" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionZ" Grid.Column="1" Grid.Row="2" Text="---"/>
        <TextBlock Text="Quaternion W:" Grid.Row="3" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtQuaternionW" Grid.Column="1" Grid.Row="3" Text="---"/>
    </Grid>

    <InfoBar x:Name="statusBar" Grid.Row="2"/>
</Grid>

När appen körs kan du ändra orienteringsvärdena genom att flytta enheten.

I föregående exempel visas den viktiga kod som du behöver skriva för att integrera orienteringssensorindata i din app.

Anslut till sensorn

Anropa metoden GetDefault för att upprätta en anslutning till standardorienteringssensorn.

private OrientationSensor? orientationSensor;
// ...
orientationSensor = OrientationSensor.GetDefault();

Du kan också anropa FromIdAsync för att skapa ettOrientationSensor-objekt från ett DeviceInformation.Id värde. Mer information finns i Räkna upp enheter.

Om ingen orienteringssensor har identifierats uppdateras statusmeddelandet för att informera användaren.

Ange rapportintervallet

Rapportintervallet anges i sidans konstruktor. Den här koden hämtar det minsta intervall som stöds av enheten och jämför det med ett begärt intervall på 16 millisekunder (vilket motsvarar en uppdateringshastighet på 60 Hz). Om det minsta intervall som stöds är större än det begärda intervallet anger koden värdet till minimum. Annars anges värdet till det begärda intervallet.

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

Läs sensordata

De nya orienteringssensordata samlas in i händelsehanteraren ReadingChanged . Varje gång sensordrivrutinen tar emot nya data från sensorn skickar den värdena till din app med den här händelsen. I det här exemplet skrivs dessa nya värden till de textblock som finns i XAML för motsvarande sida.

orientationSensor.ReadingChanged += OrientationSensor_ReadingChanged;
// ...

private void OrientationSensor_ReadingChanged(OrientationSensor sender, OrientationSensorReadingChangedEventArgs args)
{
    DispatcherQueue?.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        OrientationSensorReading reading = args.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);
    });
}

Exempelkod – enkel orienteringssensor

using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using Windows.Devices.Sensors;

namespace DevicesDemo.Pages
{
    public sealed partial class SimpleOrientationPage : Page
    {
        private SimpleOrientationSensor? simpleOrientationSensor;

        public SimpleOrientationPage()
        {
            InitializeComponent();

            // Get the default simple orientation sensor object.
            simpleOrientationSensor = SimpleOrientationSensor.GetDefault();

            // Assign an event handler.
            if (simpleOrientationSensor != null)
            {
                // Assign an event handler for the reading-changed event.
                simpleOrientationSensor.OrientationChanged 
                    += SimpleOrientationSensor_OrientationChanged;
            }
            else
            {
                statusBar.Message = "No simple orientation sensor was found.";
                statusBar.Severity = InfoBarSeverity.Error;
                statusBar.IsOpen = true;
            }
        }

        // This event handler writes the current simple orientation
        // reading to the text block on the XAML page.
        private void SimpleOrientationSensor_OrientationChanged(SimpleOrientationSensor sender, 
            SimpleOrientationSensorOrientationChangedEventArgs args)
        {
            DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
            {
                switch (args.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;
                }
            });
        }
    }
}
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid Margin="24">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="44"/>
        </Grid.RowDefinitions>
        <TextBlock Text="Orientation:" Style="{StaticResource LabelTextBlockStyle}"/>
        <TextBlock x:Name="txtOrientation" Grid.Column="1" Text="---"/>
    </Grid>

    <InfoBar x:Name="statusBar" Grid.Row="1"/>
</Grid>

När appen körs kan du ändra orienteringsvärdena genom att flytta enheten.

I föregående exempel visas den viktiga kod som du behöver skriva för att integrera enkel orienteringssensorindata i din app.

Anslut till den enkla orienteringssensorn

Anropa metoden GetDefault för att upprätta en anslutning till standardorienteringssensorn.

private SimpleOrientationSensor? simpleOrientationSensor;
// ...
simpleOrientationSensor = SimpleOrientationSensor.GetDefault();

Du kan också anropa FromIdAsync för att skapa ettSimpleOrientationSensor-objekt från ett DeviceInformation.Id värde. Mer information finns i Räkna upp enheter.

Om ingen enkel orienteringssensor har identifierats uppdateras statusmeddelandet för att informera användaren.

Läs de enkla orienteringssensordata

De nya enkla orienteringssensordata samlas in i hanteraren för OrientationChanged-händelse . Varje gång sensordrivrutinen tar emot nya data från sensorn skickar den värdena till din app med den här händelsen. I det här exemplet skrivs dessa nya värden till textblocket som finns i XAML för motsvarande sida.

simpleOrientationSensor.OrientationChanged 
    += SimpleOrientationSensor_OrientationChanged;
// ...

private void SimpleOrientationSensor_OrientationChanged(SimpleOrientationSensor sender,
    SimpleOrientationSensorOrientationChangedEventArgs args)
{
    DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
    {
        switch (args.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;
        }
    });
}

Som ett alternativ till händelsen OrientationChanged kan du läsa den aktuella orienteringen en gång genom att anropa metoden GetCurrentOrientation .