Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Aprenda a usar os sensores de orientação para determinar a orientação do dispositivo.
Este exemplo cria uma aplicação simples que depende de um sensor de orientação como dispositivo de entrada. Um sensor de orientação é um dos vários tipos de sensores ambientais que permitem às aplicações responder a alterações na orientação do dispositivo.
- APIs importantes: Windows. Devices.Sensors, OrientationSensor, SimpleOrientationSensor
Note
Este artigo foca-se em código que demonstra como usar um sensor de orientação. Para uma visão geral dos sensores de orientação, veja Sensores: Sensor de orientação.
Pré-requisitos
Deves estar familiarizado com o sensor de orientação e as suas utilizações. Ver Sensores: Sensor de orientação.
O dispositivo que está a usar deve suportar um sensor de orientação.
Tipos de sensores de orientação
Existem dois tipos diferentes de APIs de sensor de orientação incluídas no espaço de nomes Windows.Devices.Sensors: OrientationSensor e SimpleOrientation. Embora ambos estes sensores sejam sensores de orientação, esse termo está sobrecarregado e são usados para fins muito diferentes. No entanto, como ambos são sensores de orientação, ambos são abordados neste artigo.
A API OrientationSensor é usada para aplicações 3D que obtêm um quaternião e uma matriz de rotação. Um quatérnion pode ser mais facilmente entendido como uma rotação de um ponto [x,y,z] em torno de um eixo arbitrário (em contraste com uma matriz de rotação, que representa rotações em torno de três eixos). A matemática por trás dos quatérnios é bastante exótica, pois envolve as propriedades geométricas dos números complexos e as propriedades matemáticas dos números imaginários, mas trabalhar com elas é simples, e frameworks como o DirectX suportam-nas. Uma aplicação 3D complexa pode usar o sensor de Orientação para ajustar a perspetiva do utilizador. Este sensor combina a entrada do acelerómetro, giroscópio e bússola.
A API SimpleOrientationSensor é usada para determinar a orientação física atual do dispositivo em termos de definições como retrato para cima, retrato para baixo, paisagem à esquerda e paisagem à direita. Também pode detetar se um dispositivo está virado para cima ou virado para baixo. Em vez de devolver orientações como "retrato na vertical" ou "paisagem para a esquerda", este sensor devolve um valor de rotação: "Sem rotação", "Rodado 90 graus no sentido anti-horário", e assim sucessivamente. A tabela seguinte mapeia as propriedades de orientação comum para a leitura correspondente do sensor.
| Orientação | Leitura correspondente do sensor |
|---|---|
| Retrato para cima | NotRotated |
| Paisagem à esquerda | Rodado 90 graus no sentido contrário ao dos ponteiros do relógio |
| Retrato em Baixo | Rodado 180 graus no sentido contrário aos ponteiros do relógio |
| Direita da Paisagem | Rodado270Grausno sentido contrário aos ponteiros do relógio |
Código de exemplo - sensor de orientação
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>
Quando a aplicação corre, pode alterar os valores de orientação movendo o dispositivo.
O exemplo anterior demonstra o código essencial que precisa de escrever para integrar a entrada do sensor de orientação na sua aplicação.
Liga-te ao sensor
Chame o método GetDefault para estabelecer uma ligação com o sensor de orientação padrão.
private OrientationSensor? orientationSensor;
// ...
orientationSensor = OrientationSensor.GetDefault();
Também pode chamar FromIdAsync para criar um objeto OrientationSensor a partir de um valor DeviceInformation.Id. Para mais informações, consulte Enumerar dispositivos.
Se não for detetado sensor de orientação, a mensagem de estado é atualizada para informar o utilizador.
Definir o intervalo de relatório
O intervalo de relatório é definido dentro do construtor da página. Este código recupera o intervalo mínimo suportado pelo dispositivo e compara-o com um intervalo solicitado de 16 milissegundos (que aproxima uma taxa de atualização de 60 Hz). Se o intervalo mínimo suportado for maior do que o intervalo solicitado, o código define o valor para o mínimo. Caso contrário, define o valor para o intervalo solicitado.
uint minReportInterval = orientationSensor.MinimumReportInterval;
uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
orientationSensor.ReportInterval = reportInterval;
Ler dados dos sensores
Os novos dados do sensor de orientação são capturados no gestor de eventos ReadingChanged . Cada vez que o driver do sensor recebe novos dados do sensor, ele transmite os valores para a sua aplicação através deste evento. Neste exemplo, estes novos valores são escritos nos blocos de texto encontrados no XAML da página correspondente.
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);
});
}
Código de exemplo - sensor de orientação simples
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>
Quando a aplicação corre, pode alterar os valores de orientação movendo o dispositivo.
O exemplo anterior demonstra o código essencial que precisa de escrever para integrar a entrada do sensor de orientação simples na sua aplicação.
Ligar ao sensor de orientação básico
Chame o método GetDefault para estabelecer uma ligação com o sensor de orientação padrão.
private SimpleOrientationSensor? simpleOrientationSensor;
// ...
simpleOrientationSensor = SimpleOrientationSensor.GetDefault();
Também pode chamar FromIdAsync para criar um objeto SimpleOrientationSensor a partir de um valor DeviceInformation.Id. Para mais informações, consulte Enumerar dispositivos.
Se não for detetado um sensor de orientação simples, a mensagem de estado é atualizada para informar o utilizador.
Leia os dados simples do sensor de orientação
Os novos dados simples do sensor de orientação são capturados no gestor de eventos OrientationChanged . Cada vez que o driver do sensor recebe novos dados do sensor, ele transmite os valores para a sua aplicação através deste evento. Neste exemplo, estes novos valores são escritos no bloco de texto encontrado no XAML para a página correspondente.
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;
}
});
}
Como alternativa ao OrientationChanged evento, pode fazer uma leitura única da orientação atual chamando o método GetCurrentOrientation .
Tópicos relacionados
Windows developer