Windows Phone 7 Motion Sensor 使用指南

简介:

1. 为什么要引入Motion API?   

    在上一篇《Windows Phone 7 数字罗盘使用指南》中,我们已经对WP7中的传感器有所了解,事实上,WP7正是通过这些传感器来获取手机当前的姿态和位置等信息。但是,对于开发者来说,他们所关心的并不是这些数据的值本身,而是这些数据所表示的含义。举个例子,之前做Windows Mobile设备定位应用的时候,一般会涉及到GPS数据的获取。在WM2003平台上,开发者需要自己写串口通信类,实现NEMA数据的解析。分析这个过程,最终我们提供给应用的有意义的数据其实就是经纬度和时间等信息,而并不是原始的NEMA协议数据。因此,微软在WM5.0平台中引入了GPSID(即GPS中间层驱动),对于应用程序来说,GPSID为其提供经纬度等信息;而与GPS硬件打交道的过程,就交给了GPSID。这样一来,应用程序开发者就从中解脱出来了。

    那么,在我看来,Motion API所做的事情,其实质就和GPSID类似。在应用程序开发过程中,如果我们开发者获取原始的传感器数据,然后对其数据进行分析,从而去判断手机的姿态和移动方向,这样一个处理流程确实有点复杂,而且有时候也很难处理,如加速度传感器的返回值中,不仅仅包含了手机移动的加速度,还包括了重力加速度(事实上,在Windows Phone OS 7.0上,处理加速度传感器时,我们的确是需要经历上面的过程)。

    因此,在Windows Phone OS 7.1(Mango)中,引入了Motion API,用它来对底层的传感器数据进行分析和处理,从而得到开发者需要的信息,如设备的姿态(yaw, pitch, and roll)、旋转加速度和线性加速度。我们可以对原始的加速度传感器信息与Motion API中的加速度传感器信息进行对比,了解它们的区别。如下图1所示,左边是获取加速度传感器原始数据的页面,右边是获取Motion数据的页面。

Screen Capture (2)Screen Capture (5)

图1:加速度传感器的原始数据与Motion获取的数据对比

   从Y轴的数据来看,原始的加速度传感器数据包含了重力加速度与手机在外力作用下的加速度,而从Motion API获取到的加速度数据来看,它已经为我们排除了重力加速度的影响。因此,对于开发者而言,Motion API有助于简化应用程序的开发。

 

2. 使用Motion API的前提

    首先,需要注意的是,一代的Windows Phone 7手机没有开放Motion API。因此,如果想要在Windows Phone OS 7.0上写基于Motion的应用程序,那是无法实现的。但是,自从这个月初微软提供了Mango升级以后,很多设备厂商都对其生产的WP7推送了Mango更新。在OS升级以后,有些设备就提供了对Motion API的支持。如我的三星Focus i917就支持,因此才有了以下的尝试。下文中的内容,参考了MSDN上的文章:How to: Use the Combined Motion API for Windows Phone

 

3. 如何在应用程序中使用Motion API?

    这里以silverlight应用程序为例,展示了在应用程序中使用Motion API的方法。

(1)添加对Microsoft.Devices.Sensors与Microsoft.Xna.Framework的引用,如下图2所示:

image

图2:添加Motion API相关的namespace

(2)在主页面的XAML中,加入6个Textblock,表示手机姿态的yall、pitch、roll和加速度传感器的三个返回值。为了使得表现形式更加得直观,引入三个三角形,用其旋转的角度来表征yall、pitch、roll的数值,同时引入三个相互垂直的轴线,用来表示加速度传感器的值,其代码如下:

   1:         <!--TitlePanel contains the name of the application and page title-->
   2:          <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
   3:              <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
   4:              <TextBlock x:Name="PageTitle" Text="Simple Motion" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
   5:          </StackPanel>
   6:   
   7:          <StackPanel>
   8:              <TextBlock Text="attitude" Margin="12,130,0,28" Style="{StaticResource PhoneTextLargeStyle}"/>
   9:              <Grid Margin="12 0 12 0">
  10:                  <TextBlock Height="30" HorizontalAlignment="Left"  Name="yawTextBlock" Text="YAW: 000" VerticalAlignment="Top" Foreground="Red" FontSize="25" FontWeight="Bold"/>
  11:                  <TextBlock Height="30" HorizontalAlignment="Center"  Name="pitchTextBlock" Text="PITCH: 000" VerticalAlignment="Top" Foreground="Green" FontSize="25" FontWeight="Bold"/>
  12:                  <TextBlock Height="30" HorizontalAlignment="Right"   Name="rollTextBlock" Text="ROLL: 000" VerticalAlignment="Top"  Foreground="Blue" FontSize="25" FontWeight="Bold"/>
  13:              </Grid>
  14:              <Grid Height="200">
  15:                  <Polygon Name="yawtriangle" Points="45,135 80,50 115,135"  Stroke="Red" StrokeThickness="2" >
  16:                      <Polygon.Fill>
  17:                          <SolidColorBrush Color="Red" Opacity="0.3"/>
  18:                      </Polygon.Fill>
  19:                      <Polygon.RenderTransform>
  20:                          <RotateTransform CenterX="80" CenterY="100"></RotateTransform>
  21:                      </Polygon.RenderTransform>
  22:                  </Polygon>
  23:                  <Polygon Name="pitchtriangle" Points="205,135 240,50 275,135" Stroke="Green" StrokeThickness="2" >
  24:                      <Polygon.Fill>
  25:                          <SolidColorBrush Color="Green" Opacity="0.3"/>
  26:                      </Polygon.Fill>
  27:                      <Polygon.RenderTransform>
  28:                          <RotateTransform CenterX="240" CenterY="100"></RotateTransform>
  29:                      </Polygon.RenderTransform>
  30:                  </Polygon>
  31:                  <Polygon Name="rolltriangle" Points="365,135 400,50 435,135" Stroke="Blue" StrokeThickness="2" >
  32:                      <Polygon.Fill>
  33:                          <SolidColorBrush Color="Blue" Opacity="0.3"/>
  34:                      </Polygon.Fill>
  35:                      <Polygon.RenderTransform>
  36:                          <RotateTransform CenterX="400" CenterY="100"></RotateTransform>
  37:                      </Polygon.RenderTransform>
  38:                  </Polygon>
  39:              </Grid>
  40:              <TextBlock Text="acceleration" Style="{StaticResource PhoneTextLargeStyle}"/>
  41:              <Grid Margin="12 0 12 0">
  42:                  <TextBlock Height="30" HorizontalAlignment="Left"  Name="xTextBlock" Text="X: 000" VerticalAlignment="Top" Foreground="Red" FontSize="25" FontWeight="Bold"/>
  43:                  <TextBlock Height="30" HorizontalAlignment="Center"  Name="yTextBlock" Text="Y: 000" VerticalAlignment="Top" Foreground="Green" FontSize="25" FontWeight="Bold"/>
  44:                  <TextBlock Height="30" HorizontalAlignment="Right"   Name="zTextBlock" Text="Z: 000" VerticalAlignment="Top"  Foreground="Blue" FontSize="25" FontWeight="Bold"/>
  45:              </Grid>
  46:              <Grid Height="300">
  47:                  <Line x:Name="xLine" X1="240" Y1="150" X2="340" Y2="150" Stroke="Red" StrokeThickness="4"></Line>
  48:                  <Line x:Name="yLine" X1="240" Y1="150" X2="240" Y2="50" Stroke="Green" StrokeThickness="4"></Line>
  49:                  <Line x:Name="zLine" X1="240" Y1="150" X2="190" Y2="200" Stroke="Blue" StrokeThickness="4"></Line>
  50:              </Grid>
  51:          </StackPanel>

 

(3)在主页面的MainPage.xaml.cs中,声明一个Motion类的对象。

(4)重写页面的OnNavigatedTo(NavigationEventArgs)方法,检查设备是否支持Motion,初始化Motion对象,添加CurrentValueChanged事件,代码如下:

   1:  protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
   2:  {
   3:    // Check to see whether the Motion API is supported on the device.
   4:    if (! Motion.IsSupported)
   5:    {
   6:      MessageBox.Show("the Motion API is not supported on this device.");
   7:      return;
   8:    }
   9:   
  10:    // If the Motion object is null, initialize it and add a CurrentValueChanged
  11:    // event handler.
  12:    if (motion == null)
  13:    {
  14:      motion = new Motion();
  15:      motion.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
  16:      motion.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<MotionReading>>(motion_CurrentValueChanged);
  17:    }
  18:   
  19:    // Try to start the Motion API.
  20:    try
  21:    {
  22:      motion.Start();
  23:    }
  24:    catch (Exception ex)
  25:    {
  26:      MessageBox.Show("unable to start the Motion API.");
  27:    }
  28:  }

 

(5)通过周期性地调用CurrentValueChanged事件获得Motion数据,但是该事件是在后台进程中调用,无法对UI元素进行更改。因此,我们需要在UI线程中使用BeginInvoke来调用CurrentValueChanged。

(6)创建CurrentValueChanged方法,在其中设置6个Textblock和4个图的内容。使用XNA Framework中的MathHelper类实现弧度和角度的转换,代码如下:

   1:  private void CurrentValueChanged(MotionReading e)
   2:  {
   3:    // Check to see if the Motion data is valid.
   4:    if (motion.IsDataValid)
   5:    {
   6:      // Show the numeric values for attitude.
   7:      yawTextBlock.Text = "YAW: " + MathHelper.ToDegrees(e.Attitude.Yaw).ToString("0") + "°";
   8:      pitchTextBlock.Text = "PITCH: " + MathHelper.ToDegrees(e.Attitude.Pitch).ToString("0") + "°";
   9:      rollTextBlock.Text = "ROLL: " + MathHelper.ToDegrees(e.Attitude.Roll).ToString("0") + "°";
  10:   
  11:      // Set the Angle of the triangle RenderTransforms to the attitude of the device.
  12:      ((RotateTransform)yawtriangle.RenderTransform).Angle = MathHelper.ToDegrees(e.Attitude.Yaw);
  13:      ((RotateTransform)pitchtriangle.RenderTransform).Angle = MathHelper.ToDegrees(e.Attitude.Pitch);
  14:      ((RotateTransform)rolltriangle.RenderTransform).Angle = MathHelper.ToDegrees(e.Attitude.Roll);
  15:   
  16:      // Show the numeric values for acceleration.
  17:      xTextBlock.Text = "X: " + e.DeviceAcceleration.X.ToString("0.00");
  18:      yTextBlock.Text = "Y: " + e.DeviceAcceleration.Y.ToString("0.00");
  19:      zTextBlock.Text = "Z: " + e.DeviceAcceleration.Z.ToString("0.00");
  20:   
  21:      // Show the acceleration values graphically.
  22:      xLine.X2 = xLine.X1 + e.DeviceAcceleration.X * 100;
  23:      yLine.Y2 = yLine.Y1 - e.DeviceAcceleration.Y * 100;
  24:      zLine.X2 = zLine.X1 - e.DeviceAcceleration.Z * 50;
  25:      zLine.Y2 = zLine.Y1 + e.DeviceAcceleration.Z * 50;
  26:    }
  27:  }

 

4. 测试结果

    对三星Focus i917(已升级到Mango,版本号为7720.68)进行Compass测试,获得的结果如下图3所示:

Screen Capture (6)

图3:Focus上的Motion API测试结果

 

参考链接:

1. How to: Use the Combined Motion API for Windows Phone

2. Sensors Overview for Windows Phone




本文转自施炯博客园博客,原文链接:http://www.cnblogs.com/dearsj001/archive/2011/10/30/MotionSensorOnWP7.html,如需转载请自行联系原作者

相关文章
|
Android开发 iOS开发 Windows
Windows Phone 寿终正寝了,这些经典机型你还记得吗?
不久前,随着最后一家WP手机厂商惠普宣布取消今后Windows Phone的研发计划,以及微软官方声明对WP8.1系统今后所有升级维护的终止,WP手机,作为曾经和安卓手机、苹果手机并驾齐驱的三大智能手机之一,正式寿终正寝。
1553 0
Windows Phone 寿终正寝了,这些经典机型你还记得吗?
|
XML 开发框架 前端开发
Windows Phone快速入门需掌握哪些能力
在此之前,先普及下Windows Phone的概念和开发工具的介绍。 Windows Phone是微软公司开发的手机操作系统,它将微软旗下的Xbox Live游戏、Xbox Music音乐与独特的视频体验集成至手机中。2012年6月21日,微软正式发布Windows Phone 8,采用和Windows 8相同的Windows NT内核,同时也针对市场的Windows Phone 7.5发布Windows Phone 7.8。
182 0
Windows Phone快速入门需掌握哪些能力
|
移动开发 Android开发 开发者
Windows Phone 8.1 新功能汇总 开发者预览版开放下载
在Build 2014大会上,微软正式发布了传闻已久的Windows Phone 8.1系统,所有的Windows Phone 8手机都可以升级,微软这次可谓是十分厚道。虽然并非迭代升级,但WP 8.1还是拥有很多重大更新,对于微软进一步完善移动平台拥有积极的意义。下面,就一起来了解一下WP 8.1的主要新特性。
279 0
Windows Phone 8.1 新功能汇总 开发者预览版开放下载
|
编解码 前端开发 JavaScript
Windows Phone 下开发 LBS 应用
基于位置的服务(Location Based Service,LBS),它是通过电信移动运营商的无线电通讯网络(如GSM网、CDMA网)或外部定位方式(如GPS)获取移动终端用户的位置信息(地理坐标,或大地坐标),在GIS(Geographic Information System,地理信息系统)平台的支持下,为用户提供相应服务的一种增值业务。
216 0
|
传感器 物联网 Windows
张高兴的 Windows 10 IoT 开发笔记:ToF Sensor VL53L0X
  GitHub : https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/VL53L0X
909 0
|
Shell Go 开发工具
Git 系列之三:Windows 下 Git 配置与使用指南-转载
Git 系列之三:Windows 下 Git 配置与使用指南 一、安装 默认安装:msysGit 二、配置 1、C:\Program Files\Git\etc\gitconfig 添加:【注意!】请将第二行最后的 “your-id” 修改成你在服务器上的实际 id,默认是姓名拼音。
1076 0
|
16天前
|
安全 关系型数据库 MySQL
Windows Server 安装 MySQL 8.0 详细指南
安装 MySQL 需要谨慎,特别注意安全配置和权限管理。根据实际业务需求调整配置,确保数据库的性能和安全。
87 9
|
2月前
|
网络安全 Windows
Windows server 2012R2系统安装远程桌面服务后无法多用户同时登录是什么原因?
【11月更文挑战第15天】本文介绍了在Windows Server 2012 R2中遇到的多用户无法同时登录远程桌面的问题及其解决方法,包括许可模式限制、组策略配置问题、远程桌面服务配置错误以及网络和防火墙问题四个方面的原因分析及对应的解决方案。
127 4