Bagikan melalui


Menggunakan sensor orientasi

Pelajari cara menggunakan sensor orientasi untuk menentukan orientasi perangkat.

API penting

Prasyarat

Anda harus terbiasa dengan Extensible Application Markup Language (XAML), Microsoft Visual C#, dan peristiwa.

Perangkat atau emulator yang Anda gunakan harus mendukung sensor orientasi.

Membuat aplikasi OrientationSensor

Sensor orientasi adalah salah satu dari beberapa jenis sensor lingkungan yang memungkinkan aplikasi merespons perubahan orientasi perangkat.

Ada dua jenis API sensor orientasi yang berbeda yang disertakan dalam namespace Windows.Devices.Sensors: OrientationSensor dan SimpleOrientation. Meskipun kedua sensor ini adalah sensor orientasi, istilah tersebut kelebihan beban dan digunakan untuk tujuan yang sangat berbeda. Namun, karena keduanya adalah sensor orientasi, keduanya dibahas dalam artikel ini.

OrientationSensor API digunakan untuk aplikasi 3-D dua mendapatkan kuaternion dan matriks rotasi. Kuaternion dapat paling mudah dipahami sebagai rotasi titik [x,y,z] tentang sumbu sewenang-wenang (kontras dengan matriks rotasi, yang mewakili rotasi di sekitar tiga sumbu). Matematika di balik kuaternion cukup eksotis karena melibatkan sifat geometris dari bilangan kompleks dan sifat matematika angka imajiner, tetapi bekerja dengannya sederhana, dan kerangka kerja seperti DirectX mendukungnya. Aplikasi 3-D yang kompleks dapat menggunakan sensor Orientasi untuk menyesuaikan perspektif pengguna. Sensor ini menggabungkan input dari akselerometer, gyrometer, dan kompas.

API SimpleOrientation digunakan untuk menentukan orientasi perangkat saat ini dalam hal definisi seperti potret ke atas, potret ke bawah, lanskap kiri, dan kanan lanskap. Ini juga dapat mendeteksi apakah perangkat menghadap ke atas atau menghadap ke bawah. Daripada mengembalikan properti seperti "portrait up" atau "lanskap kiri", sensor ini mengembalikan nilai rotasi: "Tidak diputar", "Rotated90DegreesCounterclockwise", dan sebagainya. Tabel berikut memetakan properti orientasi umum ke pembacaan sensor yang sesuai.

Orientasi Pembacaan sensor yang sesuai
Potret Ke Atas NotRotated
Lanskap Kiri Rotated90DegreesCounterclockwise
Potret Bawah Diputar180DegreesCounterclockwise
Lanskap Kanan Diputar270DegreesCounterclockwise

Catatan

Untuk implementasi yang lebih lengkap, lihat:

Petunjuk

  • Buat proyek baru, pilih Aplikasi Kosong (Universal Windows) dari templat proyek Visual C# .

  • Buka file MainPage.xaml.cs proyek Anda dan ganti kode yang ada dengan yang berikut ini.

    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);
            }
        }
    }

Anda harus mengganti nama namespace layanan di cuplikan sebelumnya dengan nama yang Anda berikan pada proyek Anda. Misalnya, jika Anda membuat proyek bernama OrientationSensorCS, Anda akan mengganti namespace App1 dengan namespace OrientationSensorCS.

  • Buka file MainPage.xaml dan ganti konten asli dengan XML berikut.
        <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>

Anda harus mengganti bagian pertama dari nama kelas di cuplikan sebelumnya dengan namespace aplikasi Anda. Misalnya, jika Anda membuat proyek bernama OrientationSensorCS, Anda akan mengganti x:Class="App1.MainPage" dengan x:Class="OrientationSensorCS.MainPage". Anda juga harus mengganti xmlns:local="using:App1" dengan xmlns:local="using:OrientationSensorCS".

  • Tekan F5 atau pilih Debug>Mulai Debugging untuk membangun, menyebarkan, dan menjalankan aplikasi.

Setelah aplikasi berjalan, Anda dapat mengubah orientasi dengan memindahkan perangkat atau menggunakan alat emulator.

  • Hentikan aplikasi dengan kembali ke Visual Studio dan tekan Shift+F5 atau pilih Debug>Hentikan Penelusuran Kesalahan untuk menghentikan aplikasi.

Penjelasan

Contoh sebelumnya menunjukkan bagaimana kode kecil yang perlu Anda tulis untuk mengintegrasikan input sensor orientasi di aplikasi Anda.

Aplikasi ini membuat koneksi dengan sensor orientasi default dalam metode MainPage .

_sensor = OrientationSensor.GetDefault();

Aplikasi menetapkan interval laporan dalam metode MainPage . Kode ini mengambil interval minimum yang didukung oleh perangkat dan membandingkannya dengan interval yang diminta sebesar 16 milidetik (yang perkiraan laju refresh 60 Hz). Jika interval minimum yang didukung lebih besar dari interval yang diminta, kode akan mengatur nilai ke minimum. Jika tidak, nilainya diatur ke interval yang diminta.

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

Data sensor baru diambil dalam metode ReadingChanged . Setiap kali driver sensor menerima data baru dari sensor, driver tersebut meneruskan nilai ke aplikasi Anda menggunakan penanganan aktivitas ini. Aplikasi ini mendaftarkan penanganan aktivitas ini pada baris berikut.

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

Nilai baru ini ditulis ke TextBlocks yang ditemukan di XAML proyek.

Membuat aplikasi SimpleOrientation

Bagian ini dibagi menjadi dua subbagian. Sub bagian pertama akan membawa Anda melalui langkah-langkah yang diperlukan untuk membuat aplikasi orientasi sederhana dari awal. Sub bagian berikut menjelaskan aplikasi yang baru saja Anda buat.

Petunjuk

  • Buat proyek baru, pilih Aplikasi Kosong (Universal Windows) dari templat proyek Visual C# .

  • Buka file MainPage.xaml.cs proyek Anda dan ganti kode yang ada dengan yang berikut ini.

    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);
                }
            }
        }
    }

Anda harus mengganti nama namespace layanan di cuplikan sebelumnya dengan nama yang Anda berikan pada proyek Anda. Misalnya, jika Anda membuat proyek bernama SimpleOrientationCS, Anda akan mengganti namespace App1 dengan namespace SimpleOrientationCS.

  • Buka file MainPage.xaml dan ganti konten asli dengan XML berikut.
    <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>

Anda harus mengganti bagian pertama dari nama kelas di cuplikan sebelumnya dengan namespace aplikasi Anda. Misalnya, jika Anda membuat proyek bernama SimpleOrientationCS, Anda akan mengganti x:Class="App1.MainPage" dengan x:Class="SimpleOrientationCS.MainPage". Anda juga harus mengganti xmlns:local="using:App1" dengan xmlns:local="using:SimpleOrientationCS".

  • Tekan F5 atau pilih Debug>Mulai Debugging untuk membangun, menyebarkan, dan menjalankan aplikasi.

Setelah aplikasi berjalan, Anda dapat mengubah orientasi dengan memindahkan perangkat atau menggunakan alat emulator.

  • Hentikan aplikasi dengan kembali ke Visual Studio dan tekan Shift+F5 atau pilih Debug>Hentikan Penelusuran Kesalahan untuk menghentikan aplikasi.

Penjelasan

Contoh sebelumnya menunjukkan bagaimana kode kecil yang perlu Anda tulis untuk mengintegrasikan input sensor orientasi sederhana di aplikasi Anda.

Aplikasi ini membuat koneksi dengan sensor default dalam metode MainPage .

_simpleorientation = SimpleOrientationSensor.GetDefault();

Data sensor baru diambil dalam metode OrientationChanged . Setiap kali driver sensor menerima data baru dari sensor, driver tersebut meneruskan nilai ke aplikasi Anda menggunakan penanganan aktivitas ini. Aplikasi ini mendaftarkan penanganan aktivitas ini pada baris berikut.

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

Nilai baru ini ditulis ke TextBlock yang ditemukan di XAML proyek.

<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"/>