与众不同 windows phone (18) - Device(设备)之加速度传感器, 数字罗盘传感器
原文:与众不同 windows phone (18) - Device(设备)之加速度传感器, 数字罗盘传感器
作者:webabcd
介绍
与众不同 windows phone 7.5 (sdk 7.1) 之设备
- 加速度传感器(加速度计)
- 数字罗盘(磁力计)
示例
1、演示如何使用加速度传感器
AccelerometerDemo.xaml
<phone:PhoneApplicationPage
x:Class="Demo.Device.AccelerometerDemo"
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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent">
<StackPanel Orientation="Vertical"> <TextBlock Name="lblAccelerometerSupported" />
<Button Name="btnStart" Content="打开加速度传感器" Click="btnStart_Click" />
<Button Name="btnStop" Content="关闭加速度传感器" Click="btnStop_Click" />
<TextBlock Name="lblAccelerometerStatus" />
<TextBlock Name="lblTimeBetweenUpdates" />
<TextBlock Name="lblMsg" /> </StackPanel>
</Grid> </phone:PhoneApplicationPage>
AccelerometerDemo.xaml.cs
/*
* 演示如何使用加速度传感器
*
* Accelerometer - 用于访问设备中的加速度计
* IsSupported - 设备是否支持加速度传感器
* IsDataValid - 是否可从加速度传感器中获取到有效数据
* CurrentValue - 加速度传感器当前的数据,AccelerometerReading 类型
* TimeBetweenUpdates - 触发 CurrentValueChanged 事件的时间间隔,如果设置的值小于 Accelerometer 允许的最小值,则此属性的值将被设置为 Accelerometer 允许的最小值
* State - 加速度计的当前的状态(Microsoft.Devices.Sensors.SensorState 枚举)
* NotSupported - 设备不支持加速度传感器
* Ready - 加速度传感器已准备好,并且正在解析数据
* Initializing - 加速度传感器正在初始化
* NoData - 加速度传感器无法获取数据
* NoPermissions - 无权限调用加速度传感器
* Disabled - 加速度传感器被禁用
* Start() - 打开加速度计
* Stop() - 关闭加速度计
* CurrentValueChanged - 加速度传感器获取到的数据发生改变时所触发的事件,属性 TimeBetweenUpdates 的值决定触发此事件的时间间隔
*
* AccelerometerReading - 加速度传感器数据
* Acceleration - 详细数据,Vector3 类型的值
* DateTimeOffset - 从加速度传感器中获取到数据的时间点
*
*
*
* 关于从加速度传感器中获取到的 Vector3 类型的值中 X Y Z 的解释如下
* 手机坐标系:以手机位置为参照,假设手机垂直水平面放(竖着放),屏幕对着你,那么
* 1、左右是 X 轴,右侧为正方向,左侧为负方向
* 2、上下是 Y 轴,上侧为正方向,下侧为负方向
* 3、里外是 Z 轴,靠近你为正方向,远离你为负方向
* 以上可以用相对于手机位置的右手坐标系来理解
* X Y Z 的值为中心点到地平面方向的线与各个对应轴线正方向的夹角的余弦值
*/ 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; namespace Demo.Device
{
public partial class AccelerometerDemo : PhoneApplicationPage
{
private Accelerometer _accelerometer; public AccelerometerDemo()
{
InitializeComponent(); // 判断设备是否支持加速度传感器
if (Accelerometer.IsSupported)
{
lblAccelerometerStatus.Text = "此设备支持加速度传感器";
}
else
{
lblAccelerometerStatus.Text = "此设备不支持加速度传感器"; btnStart.IsEnabled = false;
btnStop.IsEnabled = false;
}
} private void btnStart_Click(object sender, RoutedEventArgs e)
{
if (_accelerometer == null)
{
// 实例化 Accelerometer,注册相关事件
_accelerometer = new Accelerometer();
_accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds();
_accelerometer.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(_accelerometer_CurrentValueChanged); lblTimeBetweenUpdates.Text = "TimeBetweenUpdates 设置为 1 毫秒,实际为 " + _accelerometer.TimeBetweenUpdates.TotalMilliseconds.ToString() + " 毫秒";
} try
{
// 打开加速度传感器
_accelerometer.Start();
lblAccelerometerStatus.Text = "加速度传感器已打开";
}
catch (Exception ex)
{
lblAccelerometerStatus.Text = "加速度传感器已打开失败";
MessageBox.Show(ex.ToString());
}
} private void btnStop_Click(object sender, RoutedEventArgs e)
{
if (_accelerometer != null)
{
// 关闭加速度传感器
_accelerometer.Stop();
lblAccelerometerStatus.Text = "加速度传感器已关闭";
}
} void _accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
// 注:此方法是在后台线程运行的,所以需要更新 UI 的话注意要调用 UI 线程
Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));
} // 更新 UI
private void UpdateUI(AccelerometerReading accelerometerReading)
{
Vector3 acceleration = accelerometerReading.Acceleration; // 输出 X Y Z 的值
lblMsg.Text = "acceleration.X: " + acceleration.X.ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "acceleration.Y: " + acceleration.Y.ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "acceleration.Z: " + acceleration.Z.ToString("0.0");
}
}
}
2、演示如何使用数字罗盘传感器
CompassDemo.xaml
<phone:PhoneApplicationPage
x:Class="Demo.Device.CompassDemo"
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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent">
<StackPanel Orientation="Vertical"> <TextBlock Name="lblCompassSupported" />
<Button Name="btnStart" Content="打开数字罗盘" Click="btnStart_Click" />
<Button Name="btnStop" Content="关闭数字罗盘" Click="btnStop_Click" />
<TextBlock Name="lblCompassStatus" />
<TextBlock Name="lblTimeBetweenUpdates" />
<TextBlock Name="lblOrientation" />
<TextBlock Name="lblMsg" /> </StackPanel> <Grid x:Name="gridCalibration" Visibility="Collapsed" Background="Black" Opacity="1">
<StackPanel>
<Image Source="CompassCalibrate.png" HorizontalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" TextAlignment="Center">
设备需要校准。校准方法:如图所示,对手机做“8字”旋转,直至完成校准(即 HeadingAccuracy 小于等于 10)
</TextBlock>
<Button Name="btnKnown" Content="知道了" Click="btnKnown_Click" />
</StackPanel>
</Grid>
</Grid> </phone:PhoneApplicationPage>
CompassDemo.xaml.cs
/*
* 演示如何使用数字罗盘传感器
*
* Compass - 用于访问设备中的磁力计
* IsSupported - 设备是否支持数字罗盘
* IsDataValid - 是否可从数字罗盘中获取到有效数据
* CurrentValue - 数字罗盘当前的数据,CompassReading 类型
* TimeBetweenUpdates - 触发 CurrentValueChanged 事件的时间间隔,如果设置的值小于 Compass 允许的最小值,则此属性的值将被设置为 Compass 允许的最小值
* Start() - 打开磁力计
* Stop() - 关闭磁力计
* CurrentValueChanged - 数字罗盘传感器获取到的数据发生改变时所触发的事件,属性 TimeBetweenUpdates 的值决定触发此事件的时间间隔
* Calibrate - 当系统检测到数字罗盘需要校准时所触发的事件
*
* CompassReading - 数字罗盘传感器数据
* HeadingAccuracy - 数字罗盘的精度,其绝对值如果大于 10 则需要校准
* TrueHeading - 与地理北极的顺时针方向的偏角(单位:角度),经测试可用
* MagneticHeading - 与地磁北极的顺时针方向的偏角(单位:角度),经测试理解不了
* MagnetometerReading - 磁力计的原始数据(单位:微特斯拉),经测试理解不了
* DateTimeOffset - 从数字罗盘传感器中获取到数据的时间点
*
*
*
* 手机坐标系:以手机位置为参照,假设手机垂直水平面放(竖着放),屏幕对着你,那么
* 1、左右是 X 轴,右侧为正方向,左侧为负方向
* 2、上下是 Y 轴,上侧为正方向,下侧为负方向
* 3、里外是 Z 轴,靠近你为正方向,远离你为负方向
* 以上可以用相对于手机位置的右手坐标系来理解
*/ 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 Demo.Device
{
public partial class CompassDemo : PhoneApplicationPage
{
private Compass _compass;
private Accelerometer _accelerometer; public CompassDemo()
{
InitializeComponent(); // 判断设备是否支持数字罗盘
if (Compass.IsSupported)
{
lblCompassSupported.Text = "此设备支持数字罗盘";
}
else
{
lblCompassSupported.Text = "此设备不支持数字罗盘"; btnStart.IsEnabled = false;
btnStop.IsEnabled = false;
}
} private void btnStart_Click(object sender, RoutedEventArgs e)
{
if (_compass == null)
{
// 实例化 Compass,注册相关事件
_compass = new Compass();
_compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds();
_compass.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<CompassReading>>(_compass_CurrentValueChanged);
_compass.Calibrate += new EventHandler<CalibrationEventArgs>(_compass_Calibrate); lblTimeBetweenUpdates.Text = "TimeBetweenUpdates 设置为 1 毫秒,实际为 " + _compass.TimeBetweenUpdates.TotalMilliseconds.ToString() + " 毫秒"; // 实例化 Accelerometer,注册相关事件,用于判断手机是横放状态还是竖放状态
_accelerometer = new Accelerometer();
_accelerometer.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(_accelerometer_CurrentValueChanged);
} try
{
// 打开数字罗盘
_compass.Start();
lblCompassStatus.Text = "数字罗盘已打开"; _accelerometer.Start();
}
catch (Exception ex)
{
lblCompassStatus.Text = "数字罗盘打开失败";
MessageBox.Show(ex.ToString());
}
} private void btnStop_Click(object sender, RoutedEventArgs e)
{
if (_compass != null && _compass.IsDataValid)
{
// 关闭数字罗盘
_compass.Stop();
_accelerometer.Stop(); lblCompassStatus.Text = "数字罗盘已关闭";
}
} void _compass_CurrentValueChanged(object sender, SensorReadingEventArgs<CompassReading> e)
{
// 注:此方法是在后台线程运行的,所以需要更新 UI 的话注意要调用 UI 线程
Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));
} // 更新 UI
private void UpdateUI(CompassReading compassReading)
{
// 显示从数字罗盘中获取到的各个参数
lblMsg.Text = "magneticHeading: " + compassReading.MagneticHeading.ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "trueHeading: " + compassReading.TrueHeading.ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "headingAccuracy: " + Math.Abs(compassReading.HeadingAccuracy).ToString("0.0");
lblMsg.Text += Environment.NewLine; Vector3 magnetometerReading = compassReading.MagnetometerReading; lblMsg.Text += "magnetometerReading.X: " + magnetometerReading.X.ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "magnetometerReading.Y: " + magnetometerReading.Y.ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "magnetometerReading.Z: " + magnetometerReading.Z.ToString("0.0");
} void _compass_Calibrate(object sender, CalibrationEventArgs e)
{
// 注:此方法是在后台线程运行的,所以需要更新 UI 的话注意要调用 UI 线程 // 显示“提示页”,用于提示用户设备需要校准
Dispatcher.BeginInvoke(() => { gridCalibration.Visibility = Visibility.Visible; });
} private void btnKnown_Click(object sender, RoutedEventArgs e)
{
// 隐藏“提示页”
gridCalibration.Visibility = System.Windows.Visibility.Collapsed;
} // 判断手机是竖放还是横放
void _accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
Vector3 v = e.SensorReading.Acceleration; bool isCompassUsingNegativeZAxis = false; if (Math.Abs(v.Z) < Math.Cos(Math.PI / ) && (v.Y < Math.Sin( * Math.PI / )))
{
isCompassUsingNegativeZAxis = true;
} Dispatcher.BeginInvoke(() => { lblOrientation.Text = (isCompassUsingNegativeZAxis) ? "手机竖放" : "手机横放"; });
}
}
}
OK
[源码下载]
与众不同 windows phone (18) - Device(设备)之加速度传感器, 数字罗盘传感器的更多相关文章
- 与众不同 windows phone (19) - Device(设备)之陀螺仪传感器, Motion API
原文:与众不同 windows phone (19) - Device(设备)之陀螺仪传感器, Motion API [索引页][源码下载] 与众不同 windows phone (19) - Dev ...
- 与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态
原文:与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态 [索引页][源码下载] 与众不同 windows phone (23) - Devic ...
- 与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频)
原文:与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频) [索引页][源码下载] 与众不同 windows phone (22 ...
- 与众不同 windows phone (21) - Device(设备)之摄像头(拍摄照片, 录制视频)
原文:与众不同 windows phone (21) - Device(设备)之摄像头(拍摄照片, 录制视频) [索引页][源码下载] 与众不同 windows phone (21) - Device ...
- 与众不同 windows phone (20) - Device(设备)之位置服务(GPS 定位), FM 收音机, 麦克风, 震动器
原文:与众不同 windows phone (20) - Device(设备)之位置服务(GPS 定位), FM 收音机, 麦克风, 震动器 [索引页][源码下载] 与众不同 windows phon ...
- 张高兴的 Windows 10 IoT 开发笔记:三轴数字罗盘 HMC5883L
注意,数据不包含校验,准确的来说我不知道怎么校验,但方向看起来差不多是对的... GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/tre ...
- 与众不同 windows phone (2) - Control(控件)
原文:与众不同 windows phone (2) - Control(控件) [索引页][源码下载] 与众不同 windows phone (2) - Control(控件) 作者:webabcd介 ...
- 如何解决Windows 10系统下设备的声音问题
如何解决Windows 10系统下设备的声音问题? 请阅读下面的说明来解决Windows 10设备上的声音问题. 1. 检查设备管理器 打开开始菜单,键入设备管理器, 从出现的结果中选择并打开它. 在 ...
- 与众不同 windows phone 8.0 & 8.1 系列文章索引
[源码下载] [与众不同 windows phone 7.5 (sdk 7.1) 系列文章索引] 与众不同 windows phone 8.0 & 8.1 系列文章索引 作者:webabcd ...
随机推荐
- adxl345的STM32驱动程序和硬件设计
一.硬件电路接口图片 1.ADXL345硬件接口图片使用的是SPI端口进行通信,这样读取数据比较快且后续也可以转化为IIC通信接口. 在网上找一些发现IIC接口的比较多,所以本人就DIY做SPI的通信 ...
- [置顶] 浏览器模式和标准对于javascript的影响
今天在编写代码的时候遇到了一个莫名其妙的问题,请看下面 <html> <head> <title> Test </title> <!--<m ...
- oracle 11gR2默认密码修改
很久以前装了Oracle,今天终于下决心要学一学了,结果一上午的时间就贡献给如何连接数据库上了 忘记了安装时设置的用户名和密码怎么办?查了下网上的资料,终于解决了! 方法一: 首先进入sqlplus: ...
- BZOJ 3375: [Usaco2004 Mar]Paranoid Cows 发疯的奶牛( set )
果然写得短就跑得慢... 直接用set就行了(你要写棵平衡树也可以).没有包含的话, 假如L(i) <= L(j), 那么R[i] <= R[j]. 所以从小到大扫, 每次查找左端点小于当 ...
- 相对路径与绝对路径构造file对象
package file; import java.io.File; public class FileTest1 { public static void main(String[] args) { ...
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹和地图碰撞
上篇文章实现了坦克与地图碰撞的检测, 这篇我们继续完成子弹和地图的碰撞检测. 1.先设计一个子弹类Bullet,如下所示: class Bullet : public CCSprite { publi ...
- 一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码
前面两篇文章为了重点突出 CodeIgniter 框架的原理,程序的结构很乱,有很多全局变量,在这一课中我们采用面向对象的方法对原先代码进行重构. 到目前为止,程序主要完成的就是 URL 分析,并根据 ...
- dfs-hdu-4620-Fruit Ninja Extreme
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4620 题目大意: 切水果.给n刀,每刀的时间,每刀切的水果的种类.求能切的最多的刀数,使得每相邻的两 ...
- 在vc中使用xtremetoolkit界面库-----安装及环境配置
近期想用一下xtremetoolkitPro界面库.网上的使用教程资源也不多,当中着实遇到了很多的困难,毕竟是首次使用. 首先当然是配置发开环境了: 我使用的是vc6.0+xtremetoolkitP ...
- C++ strcpy strcpy_s strncpy strlcpy
strncpy的用法:它与strcpy的不同之处就在于复制n个字符,而不是把所有字符拷贝(包括结尾'\0'). 函数原型:char * strncpy(char *dst,const char * s ...