2012/2/9
本主题将带您完成创建加速度计应用程序,该应用程序为您提供加速度计数据的数字显示以及图形表示。
加速度计测量在某一时刻施加于设备的力。可以使用这些力来确定用户正在向哪个方向移动设备。加速度值采用 3 维矢量表示,该矢量表示在 X、Y 和 Z 轴中的加速度分量(采用重力单位)。当设备面朝平台时,加速度的方向相对于设备以便对 Z 轴应用 -1g,当垂直于平台顶部放置设备时,对 Y 轴应用 -1g。
加速度计传感器检测重力以及由于手机运动而产生的任何力。使用 Motion 类访问的组合运动 API 使用多个设备传感器将重力矢量与设备加速度分离,并且允许您轻松确定设备的当前属性(yaw、pitch、roll)。
以下步骤向您介绍如何创建加速度计应用程序。
创建加速度计应用程序的步骤
在 Visual Studio 中,创建一个新的“Windows Phone 应用程序”项目。此模板在“Silverlight for Windows Phone”类别中。
该应用程序需要引用包含传感器 API 和 XNA Framework 的程序集,因为加速度计数据采用 XNA Framework Vector3 对象的形式传递。从“项目”菜单中,单击“添加引用...”,选择“Microsoft.Devices.Sensors”和“Microsoft.Xna.Framework”,然后单击“确定”。
在 MainPage.xaml 文件中,将以下 XAML 代码放置在名为“ContentPanel”的 Grid 元素中。该代码创建两个按钮,一个用于开始从加速度计获取数据,一个用于停止从加速度计获取数据。还创建三个将用于显示数字读数的 TextBlock 元素以及三个将用于采用图形表示读数数据的 Line 元素。最后,该代码添加一个状态 TextBlock 元素,该元素将用于显示应用程序的当前状态。
<Button Content="Start" Height="72" HorizontalAlignment="Left" Margin="20,10,0,0" Name="startButton" VerticalAlignment="Top" Width="160" Click="startButton_Click" /> <Button Content="Stop" Height="72" HorizontalAlignment="Right" Margin="0,10,20,0" Name="stopButton" VerticalAlignment="Top" Width="160" Click="stopButton_Click"/> <TextBlock Height="30" HorizontalAlignment="Left" Margin="20,100,0,0" Name="xTextBlock" Text="X: 1.0" VerticalAlignment="Top" Foreground="Red" FontSize="28" FontWeight="Bold"/> <TextBlock Height="30" HorizontalAlignment="Center" Margin="0,100,0,0" Name="yTextBlock" Text="Y: 1.0" VerticalAlignment="Top" Foreground="Green" FontSize="28" FontWeight="Bold"/> <TextBlock Height="30" HorizontalAlignment="Right" Margin="0,100,20,0" Name="zTextBlock" Text="Z: 1.0" VerticalAlignment="Top" Foreground="Blue" FontSize="28" FontWeight="Bold"/> <Line x:Name="xLine" X1="240" Y1="350" X2="340" Y2="350" Stroke="Red" StrokeThickness="4"></Line> <Line x:Name="yLine" X1="240" Y1="350" X2="240" Y2="270" Stroke="Green" StrokeThickness="4"></Line> <Line x:Name="zLine" X1="240" Y1="350" X2="190" Y2="400" Stroke="Blue" StrokeThickness="4"></Line> <TextBlock Height="30" HorizontalAlignment="Center" Margin="6,571,6,0" Name="statusTextBlock" Text="TextBlock" VerticalAlignment="Top" Width="444" />
现在,打开 MainPage.xaml.cs 代码隐藏页面并向该页面顶部的其他 using 指令中添加传感器和 XNA Framework 命名空间的 using 指令。
using Microsoft.Devices.Sensors; using Microsoft.Xna.Framework;
在 MainPage 类定义的顶部声明一个类型为 Accelerometer 的变量。
public partial class MainPage : PhoneApplicationPage { Accelerometer accelerometer;
在页面的构造函数中,查看其上运行应用程序的设备是否支持加速计传感器。并非所有设备都支持所有传感器,因此使用传感器之前您应该始终进行检查。用下面的代码替换现有的页面构造函数。
// Constructor public MainPage() { InitializeComponent(); if (!Accelerometer.IsSupported) { // The device on which the application is running does not support // the accelerometer sensor. Alert the user and disable the // Start and Stop buttons. statusTextBlock.Text = "device does not support accelerometer"; startButton.IsEnabled = false; stopButton.IsEnabled = false; } }
为“开始”按钮添加单击事件的处理程序。根据上面添加 XAML 代码的方式,Visual Studio 可能已为您添加此处理程序。如果是这样,则删除该处理程序中的任何代码。如果为自动添加该处理程序,请将下面的空函数复制并粘贴到 MainPage 类定义中。
private void startButton_Click(object sender, RoutedEventArgs e) { }
在“开始”按钮单击处理程序中,查看加速度计对象是否为 null,在初始化该对象之前该对象应该为 null。如果加速度计为 null,则使用构造函数初始化该对象。接下来,通过设置 TimeBetweenUpdates 属性设置您希望从加速度计接收数据的速度。默认值为 2 毫秒。之后,为 CurrentValueChanged 事件设置处理程序。将以下代码粘贴到空的“开始”按钮单击处理程序中。
if (accelerometer == null) { // Instantiate the Accelerometer. accelerometer = new Accelerometer(); accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20); accelerometer.CurrentValueChanged+=new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(accelerometer_CurrentValueChanged); }
现在,使用 Start()()()() 方法启动加速度计。调用 Start 有可能会失败,因此您应该将此调用放置在一个 try 块中。在 catch 块中,您可以警告用户加速度计可能无法启动。将该代码粘贴到“开始”按钮单击处理程序中,放置在之前的代码部分之后。
try { statusTextBlock.Text = "starting accelerometer."; accelerometer.Start(); } catch (InvalidOperationException ex) { statusTextBlock.Text = "unable to start accelerometer."; }
现在,实现 CurrentValueChanged 事件处理程序。具有新加速度计数据的系统会以使用 TimeBetweenUpdates 指定的频率调用该方法。该处理程序接收包含加速度计数据的 AccelerometerReading 对象。在对 UI 没有访问权限的后台线程上调用该处理程序。因此,该事件处理程序使用 Dispatcher.Invoke 方法,该方法在 UI 线程上调用指定的代码。Dispatcher.Invoke 用于调用将在下一步中定义的 UpdateUI 并传递 AccelerometerReading 对象。
void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e) { // Call UpdateUI on the UI thread and pass the AccelerometerReading. Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading)); }
实现将向用户显示加速度计数据的 UpdateUI 方法。此方法首先更新状态 TextBlock 以指示正在接收数据。接下来,更新三个 TextBlock 对象以显示传感器每个轴上的加速度数值。最后,更新 Line 对象以采用图形的形式演示加速度。
private void UpdateUI(AccelerometerReading accelerometerReading) { statusTextBlock.Text = "getting data"; Vector3 acceleration = accelerometerReading.Acceleration; // Show the numeric values. xTextBlock.Text = "X: " + acceleration.X.ToString("0.00"); yTextBlock.Text = "Y: " + acceleration.Y.ToString("0.00"); zTextBlock.Text = "Z: " + acceleration.Z.ToString("0.00"); // Show the values graphically. xLine.X2 = xLine.X1 + acceleration.X * 200; yLine.Y2 = yLine.Y1 - acceleration.Y * 200; zLine.X2 = zLine.X1 - acceleration.Z * 100; zLine.Y2 = zLine.Y1 + acceleration.Z * 100; }
最后一步是实现将允许用户停止从加速度计获取数据的“停止”按钮单击处理程序。再次,如果编辑器自动添加了此处理程序,则将此处理程序的内容替换为以下内容。
private void stopButton_Click(object sender, RoutedEventArgs e) { if (accelerometer != null) { // Stop the accelerometer. accelerometer.Stop(); statusTextBlock.Text = "accelerometer stopped."; } }
如果您拥有一个物理 Windows Phone 设备,则可以只生成该应用程序,将该应用程序部署到该设备并左右摇摆该设备以查看加速度计数据是否更改。如果您使用的是 Windows Phone 模拟器,则需要使用该模拟器的加速度计模拟器工具来测试应用程序。
使用加速度计模拟器的步骤
从 Visual Studio 的标准工具栏的“为 Windows Phone 项目选择目标”列表中选择“Windows Phone 模拟器”。
按 F5 或单击“调试”菜单上的“开始调试”。
等待模拟器启动和加速度计应用程序加载。
在模拟器工具栏中,单击“其他工具”按钮,该按钮的图标是两个指向右的箭头。
在“其他工具”窗口中,选择“加速度计”标签。
在您在主模拟器窗口中创建的加速度计应用程序中,单击“开始”按钮。
在“其他工具”窗口周围移动粉红色的圆点以更改虚拟手机的方向并在主模拟器窗口中观察数据的更改情况。