Como utilizar a bússola no Windows Phone

Veja neste artigo como construir um aplicativo que utilize bússola no Windows Phone, será feito um exemplo que mostra como utilizar os recursos nativos oferecidos

Entre os diversos recursos de sensores que o Windows Phone oferece para as aplicações, entre elas está a Bussola que oferece coordenadas 3D em relação ao norte magnético, esse recurso é opcional nos aparelhos, podendo ter uma variação de precisão de até 20 graus e também está sujeito a interferências eletromagnéticas e necessita de calibração para uma maior precisão.

Figura 1. Imagem ilustrando uma bússola

Abra o Visual Studio 2012 e crie um novo projeto do tipo Windows Phone App e dê o nome de AplicacaoBussolaWP, conforme mostra a figura 2.

Figura 2. Criando um projeto Windows Phone App no Visual Studio 2012

Ao criar o projeto é exibida uma caixa com a opção de escolha da versão do Windows Phone, escolha a 7.1, pois assim o seu aplicativo funcionará em todas as versões de Windows Phone disponíveis.

Após criar o projeto a primeira coisa a ser feita é adicionar para a solução a dll necessária para utilizar a bússola na aplicação que será criada, então vá ao solution explorer, clique com o botão direito em References e depois clique em Add Reference conforme mostra a figura 3.

Figura 3. Adicionando Referência para a solução

E então será exibida uma janela em que você deverá buscar a dll necessária para o projeto em questão, na aba framework selecione as referências: Microsoft.Devices.Sensors e Microsoft.Xna.Framework e depois clique em Ok conforme mostra a figura 4 abaixo.

Figura 4. Adicionando as dlls para a solução do projeto

Agora na página principal da aplicação MainPage.xaml os controles necessários para a aplicação devem ser adicionados, primeiro serão colocados dois botões de Iniciar e Parar, e então três textblocks para as variáveis X,Y e Z da bússola. Também será colocado um Textblock com o estado da bússola na aplicação.

Uma caixa será colocada como Collapsed e conterá o botão para calibrar a bússola do aparelho, veja como ficará o arquivo MainPage.xaml na listagem 1.

<phone:PhoneApplicationPage x:Class="AplicacaoBussolaWP.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True"> <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" /> <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" /> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel Width="450" Height="600"> <StackPanel Orientation="Horizontal" Width="450" Height="80"> <Button Width="160" Content="Start" Name="btnIniciar" Click="btnIniciar_Click" /> <Button Width="160" Content="Stop" Name="btnParar" Click="btnParar_Click" /> </StackPanel> <StackPanel Orientation="Horizontal" Width="450" Height="40"> <TextBlock Height="30" Name="txbX" Text="X: 1.0" VerticalAlignment="Top" Foreground="Red" FontSize="28" FontWeight="Bold" /> <TextBlock Height="30" Margin="30,0,0,0" Name="txbY" Text="Y: 1.0" VerticalAlignment="Top" Foreground="Green" FontSize="28" FontWeight="Bold" /> <TextBlock Height="30" Margin="30,0,0,0" Name="txbZ" Text="Z: 1.0" VerticalAlignment="Top" Foreground="Blue" FontSize="28" FontWeight="Bold" /> </StackPanel> <StackPanel Width="450" Height="40"> <TextBlock TextAlignment="Center" Height="35" Name="txtStatus" Text="Status" Foreground="Red" FontSize="28" FontWeight="Bold" /> </StackPanel> </StackPanel> <StackPanel Width="450" Height="200" Name="stckCalibracao" Background="Gray" Opacity="1" Visibility="Collapsed"> <TextBlock TextWrapping="Wrap" TextAlignment="Center"> Calibre a sua bússola, para isso você deve segurar o aparelho à frente e então fazer um movimento em formato de 8. </TextBlock> <StackPanel Orientation="Horizontal" Margin="0,10" HorizontalAlignment="Center"> <TextBlock>Heading Accuracy:</TextBlock> <TextBlock Name="lblCalibracao">0.0°</TextBlock> </StackPanel> <Button Name="btnCalibrar" Content="Calibrar" Click="btnCalibrar_Click" /> </StackPanel> </Grid> </Grid> </phone:PhoneApplicationPage>
Listagem 1. Código da página MainPage.xaml

Agora deve-se codificar a classe da página principal, para isso abra o arquivo MainPage.xaml.cs, e adicione a referência para as dlls Microsoft.Devices.Sensors, Microsoft.Xna.Framework e System.Windows.Threading.

Você deverá criar no escopo da classe duas variáveis, uma do tipo Compass e outra do tipo bool, no construtor da classe será verificado se existe o compasso no aparelho ou não, para que a mensagem seja exibida informando a situação. Os eventos dos clicks dos botões também deverão ser tratados e veja como fica a classe MainPage.xaml.cs na listagem 2.

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Devices.Sensors; using Microsoft.Xna.Framework; using System.Windows.Threading; namespace AplicacaoBussolaWP { public partial class MainPage : PhoneApplicationPage { Compass bussola; bool calibrando = false; // Constructor public MainPage() { InitializeComponent(); if (!Compass.IsSupported) { txtStatus.Text = "Esse dispositivo não suporta bússola!"; btnIniciar.IsEnabled = false; btnParar.IsEnabled = false; } } private void btnIniciar_Click(object sender, RoutedEventArgs e) { if (bussola == null) { bussola = new Compass(); bussola.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20); bussola.CurrentValueChanged += bussola_CurrentValueChanged; bussola.Calibrate += bussola_Calibrate; try { txtStatus.Text = "Iniciando a bússola..."; } catch (Exception) { txtStatus.Text = "Houve erro durante a inicialização da bússola!"; } } } void bussola_Calibrate(object sender, CalibrationEventArgs e) { Dispatcher.BeginInvoke(() => { stckCalibracao.Visibility = System.Windows.Visibility.Visible; }); calibrando = true; } void bussola_CurrentValueChanged(object sender, SensorReadingEventArgs<CompassReading> e) { Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading)); } private void btnParar_Click(object sender, RoutedEventArgs e) { if (bussola != null && bussola.IsDataValid) { bussola.Stop(); txtStatus.Text = "Bússola parada."; } } private void UpdateUI(CompassReading compassReading) { txtStatus.Text = "Recuperando Dados"; Vector3 vc3 = compassReading.MagnetometerReading; txbX.Text = "X: " + vc3.X.ToString("0.00"); txbY.Text = "Y: " + vc3.Y.ToString("0.00"); txbZ.Text = "Z: " + vc3.Z.ToString("0.00"); } private void btnCalibrar_Click(object sender, RoutedEventArgs e) { stckCalibracao.Visibility = System.Windows.Visibility.Collapsed; calibrando = false; } } }
Listagem 2. Código da classe MainPage.xaml.cs

Sua aplicação deverá estar conforme a figura 5, infelizmente o emulador não pode rodar o recurso de bússola, então você terá que executar a aplicação no aparelho diretamente.

Figura 5. Executando a aplicação

Artigos relacionados