Utiliser le capteur d’orientation
Découvrez comment utiliser les capteurs d’orientation pour déterminer l’orientation de l’appareil.
API importantes
Prérequis
Vous devez être familiarisé avec le langage XAML (Extensible Application Markup Language), Microsoft Visual C# et les événements.
L’appareil ou l’émulateur que vous utilisez doit prendre en charge un capteur d’orientation.
Créer une application OrientationSensor
Un capteur d’orientation est l’un des différents types de capteurs environnementaux qui permettent aux applications de répondre aux modifications apportées à l’orientation de l’appareil.
Il existe deux types différents d’API de capteur d’orientation inclus dans l’espace de noms Windows.Devices.Sensors : OrientationSensor et SimpleOrientation. Bien que ces deux capteurs soient des capteurs d’orientation, ce terme est surchargé et ils sont utilisés à des fins très différentes. Toutefois, étant donné que les deux sont des capteurs d’orientation, ils sont tous les deux abordés dans cet article.
L’API OrientationSensor est utilisée pour les applications 3D, deux obtiennent un quaternion et une matrice de rotation. Un quaternion peut être facilement compris comme une rotation d’un point [x,y,z] sur un axe arbitraire (contrasté avec une matrice de rotation, qui représente des rotations autour de trois axes). Les mathématiques derrière les quaternions sont assez exotiques car elles impliquent les propriétés géométriques des nombres complexes et des propriétés mathématiques des nombres imaginaires, mais l’utilisation de ces derniers est simple, et les frameworks comme DirectX les prennent en charge. Une application 3D complexe peut utiliser le capteur Orientation pour ajuster la perspective de l’utilisateur. Ce capteur combine l’entrée de l’accéléromètre, du gyromètre et de la boussole.
L’API SimpleOrientation est utilisée pour déterminer l’orientation actuelle de l’appareil en termes de définitions telles que portrait vers le haut, portrait vers le bas, paysage gauche et paysage droit. Il peut également détecter si un appareil est face vers le haut ou face vers le bas. Au lieu de renvoyer des propriétés telles que « portrait vers le haut » ou « paysage gauche », ce capteur retourne une valeur de rotation : « Non pivoté », « Rotationed90DegreesCounterclockwise », et ainsi de suite. Le tableau suivant mappe les propriétés d’orientation courantes à la lecture du capteur correspondante.
Orientation | Lecture de capteur correspondante |
---|---|
Portrait vers le haut | NotRotated |
Paysage gauche | Rotation de90DegreesCounterclockwise |
Portrait vers le bas | Rotation180DegreesCounterclockwise |
Paysage droit | Rotation 270DegreesCounterclockwise |
Remarque
Pour une implémentation plus complète, consultez :
Instructions
Créez un projet, en choisissant une application vide (Windows universel) à partir des modèles de projet Visual C# .
Ouvrez le fichier MainPage.xaml.cs de votre projet et remplacez le code existant par ce qui suit.
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);
}
}
}
Vous devez renommer l’espace de noms dans l’extrait de code précédent avec le nom que vous avez donné à votre projet. Par exemple, si vous avez créé un projet nommé OrientationSensorCS, vous devez remplacer namespace App1
namespace OrientationSensorCS
par .
- Ouvrez le fichier MainPage.xaml et remplacez le contenu d’origine par le code XML suivant.
<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>
Vous devez remplacer la première partie du nom de classe dans l’extrait de code précédent par l’espace de noms de votre application. Par exemple, si vous avez créé un projet nommé OrientationSensorCS, vous devez remplacer x:Class="App1.MainPage"
x:Class="OrientationSensorCS.MainPage"
par . Vous devez également remplacer xmlns:local="using:App1"
xmlns:local="using:OrientationSensorCS"
par .
- Appuyez sur F5 ou sélectionnez Démarrer>le débogage pour générer, déployer et exécuter l’application.
Une fois l’application en cours d’exécution, vous pouvez modifier l’orientation en déplaçant l’appareil ou en utilisant les outils de l’émulateur.
- Arrêtez l’application en retournant à Visual Studio et en appuyant sur Maj+F5 ou sélectionnez Arrêter>le débogage pour arrêter l’application.
Explication
L’exemple précédent montre comment peu de code que vous devez écrire pour intégrer l’entrée du capteur d’orientation dans votre application.
L’application établit une connexion avec le capteur d’orientation par défaut dans la méthode MainPage .
_sensor = OrientationSensor.GetDefault();
L’application établit l’intervalle de rapport dans la méthode MainPage . Ce code récupère l’intervalle minimal pris en charge par l’appareil et le compare à un intervalle demandé de 16 millisecondes (ce qui correspond approximativement à un taux d’actualisation de 60-Hz). Si l’intervalle minimal pris en charge est supérieur à l’intervalle demandé, le code définit la valeur sur la valeur minimale. Sinon, elle définit la valeur sur l’intervalle demandé.
uint minReportInterval = _sensor.MinimumReportInterval;
uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
_sensor.ReportInterval = reportInterval;
Les nouvelles données de capteur sont capturées dans la méthode ReadingChanged . Chaque fois que le pilote de capteur reçoit de nouvelles données du capteur, il transmet les valeurs à votre application à l’aide de ce gestionnaire d’événements. L’application inscrit ce gestionnaire d’événements sur la ligne suivante.
_sensor.ReadingChanged += new TypedEventHandler<OrientationSensor,
OrientationSensorReadingChangedEventArgs>(ReadingChanged);
Ces nouvelles valeurs sont écrites dans les TextBlocks trouvés dans le code XAML du projet.
Créer une application SimpleOrientation
Cette section est divisée en deux sous-sections. La première sous-section vous guide tout au long des étapes nécessaires pour créer une application d’orientation simple à partir de zéro. La sous-section suivante explique l’application que vous venez de créer.
Instructions
Créez un projet, en choisissant une application vide (Windows universel) à partir des modèles de projet Visual C# .
Ouvrez le fichier MainPage.xaml.cs de votre projet et remplacez le code existant par ce qui suit.
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);
}
}
}
}
Vous devez renommer l’espace de noms dans l’extrait de code précédent avec le nom que vous avez donné à votre projet. Par exemple, si vous avez créé un projet nommé SimpleOrientationCS, vous devez remplacer namespace App1
namespace SimpleOrientationCS
par .
- Ouvrez le fichier MainPage.xaml et remplacez le contenu d’origine par le code XML suivant.
<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>
Vous devez remplacer la première partie du nom de classe dans l’extrait de code précédent par l’espace de noms de votre application. Par exemple, si vous avez créé un projet nommé SimpleOrientationCS, vous devez remplacer x:Class="App1.MainPage"
x:Class="SimpleOrientationCS.MainPage"
par . Vous devez également remplacer xmlns:local="using:App1"
xmlns:local="using:SimpleOrientationCS"
par .
- Appuyez sur F5 ou sélectionnez Démarrer>le débogage pour générer, déployer et exécuter l’application.
Une fois l’application en cours d’exécution, vous pouvez modifier l’orientation en déplaçant l’appareil ou en utilisant les outils de l’émulateur.
- Arrêtez l’application en retournant à Visual Studio et en appuyant sur Maj+F5 ou sélectionnez Arrêter>le débogage pour arrêter l’application.
Explication
L’exemple précédent montre comment peu de code que vous devez écrire pour intégrer une entrée de capteur d’orientation simple dans votre application.
L’application établit une connexion avec le capteur par défaut dans la méthode MainPage .
_simpleorientation = SimpleOrientationSensor.GetDefault();
Les nouvelles données de capteur sont capturées dans la méthode OrientationChanged . Chaque fois que le pilote de capteur reçoit de nouvelles données du capteur, il transmet les valeurs à votre application à l’aide de ce gestionnaire d’événements. L’application inscrit ce gestionnaire d’événements sur la ligne suivante.
_simpleorientation.OrientationChanged += new TypedEventHandler<SimpleOrientationSensor,
SimpleOrientationSensorOrientationChangedEventArgs>(OrientationChanged);
Ces nouvelles valeurs sont écrites dans un TextBlock trouvé dans le code XAML du projet.
<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"/>