前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Windows Phone 7 Motion Sensor 使用指南

Windows Phone 7 Motion Sensor 使用指南

作者头像
ShiJiong
发布2018-01-10 17:26:58
1.7K0
发布2018-01-10 17:26:58
举报

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 (2)
Screen Capture (5)
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
image

图2:添加Motion API相关的namespace

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

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

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

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

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

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

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

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

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

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

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

4. 测试结果

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

Screen Capture (6)
Screen Capture (6)

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

参考链接:

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

2. Sensors Overview for Windows Phone

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-10-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档