首页 > 代码库 > 微软移动 Nokia Lumia SensorCore SDK 介绍及上手体验

微软移动 Nokia Lumia SensorCore SDK 介绍及上手体验

    早在今年的BUILD大会上,诺基亚就宣布了SensorCore以及它的部分演示。今天,它终于面世了,大家可以去Building Apps for Windows 上查看具体介绍,或者也可以去Nokia Developer上查看。SensorCore SDK的下载大家可以去nuget页面:Lumia SensorCore SDK 0.9.1.3。

1. SensorCore SDK是什么?

    SensorCore SDK是一组API,它可以访问手机上的多种传感器数据(加速度传感器/数字罗盘/陀螺仪)和位置信息。这些信息可以用来追踪用户的身体和运动状态。一般情况下,传感器以较低的功耗在后台运行,并保存最近10天内的数据。目前市场的Health &Fitness应用已经集成了SensorCore SDK,主要使用了其中的计步功能。其界面如下图1所示。

clip_image002image

图1:Health &Fitness应用的计步功能页面

    进一步的,它还提供了数据的统计和分析,如下图2所示。

clip_image002 clip_image004

图2:Health &Fitness应用的统计分析页面

    事实上,Health &Fitness应用只利用了SensorCore SDK中的Step Counter API,它还包括Activity Monitor API、Place Monitor API和Track Point Monitor API,我们在后面的文章中会有进一步的介绍。

2. 如何启用 SensorCore 功能

    为了使用SensorCore提供的API,我们需要在手机的功能中做一些设置,具体来说,是将Location和motion data功能打开,如下图3所示。

clip_image002[5] clip_image004[5]

图3:启用SensorCore需要的设置页面

    如果我们不希望透露这些用户信息,可以将这个功能关闭,也可以手动清除motion数据。另外,开发者必须处理“用户禁用Location和motion data”的情况,因为在这两者其中任何一个被禁用的情况下,SensorCore是无法正常工作的。

3. SensorCore API 简介

    SensorCore SDK包含的API包括Step Counter API、Activity Monitor API、Place Monitor API和Track Point Monitor API。

3.1 Step Counter API

    该API提供了用户步行或者是跑步的步数和距离信息。当然,如果用户将设备放在裤兜里面骑车或者乘坐汽车,那么,该API的计步功能就可能不准。

3.2 Activity Monitor API

    该API提供用户身体活动的状态信息,例如,用户何时开始步行,何时停止步行。当然,在用户活动转换的过程中,该API大概会有5-10秒钟的检测延时,主要是为了滤除噪声,降低误报的可能性。如果用户将设备放在裤兜里面骑车或者乘坐汽车,或者只是将设备拿在手里晃悠,就会产生误报。活动可以分为以下几类:

  • Idle:设备被放置于桌子等离开人体的环境中。
  • Stationary:用户随身携带设备,但出于静止状态。
  • Moving:包含Walking或者是Running两种状态。

    如果应用程序对用户的某些状态进行监控,那么在用户的状态发生变化时,应用程序会收到这个通知(notification)。

3.3 Place Monitor API

    该API提供了用户停留超过一定时间段的地理位置信息,它运行在后台,为了使得功耗尽量低,主要利用手机基站和WiFi接入点信息来定位。因此,它不会主动激活GPS进行地理位置追踪,除非其他应用已经在使用GPS(如导航类应用)。由于该类API是被动工作的,因此它提供的地理位置信息并非是实时的。除了提供相关的地理位置信息以外,它还会尝试推断用户的家和工作单位的地理位置。

    用户携带设备在某一个地点停留10分钟以上,该地点才会被认为是一个Known Places,同时加入到Known Places列表。一般来讲,单个Known Place的半径范围是200米。两个Known Place之间的距离一般要求500米以上,因此,即使500米范围内有两个不同的地理位置,该API会将这些位置融合为一个Known Place,这一点也是开发者需要考虑的。

    Place Monitor会尝试着将一个地点分类为“Home”,另一个地点分类为“Work”,分类的规则为:

  • 设备在一个Known Place中停留的时间段
  • 设备移动的频率和用户的行为状态
  • 设备被使用的频率
  • 设备被充电的频率

    基于以上的规则,分类处理程序一般会在2-3天内给出“Home”和“Work”的推断。如果用户换了工作单位,该API也会在一段时间以后修改“Home”和“Work”的推断。

    Place Monitor会动态的更新Known Places列表,如果已知的一个Known Place不再被访问了,那么一段时间以后,该Known Place就会从列表中删除。

    所有的Known Place会有如下属性:

  • ID:一个给定地点的唯一标识。
  • Kind:可以有以下三个值,frequent/home/work。
  • Position:地理位置信息。
  • Radius:以Position为中心的半径。

3.4 Track Point Monitor API

    该API提供用户移动的具体信息,它和Place Monitor API类似,但并不是追踪Home和Work位置,而是追踪用户行动的路径。一般情况下,Track Point Monitor API也是被动追踪,即利用手机基站和WiFi的信息来定位。如果有其他应用在使用GPS,那么Track Point Monitor API就会利用GPS信息来进行定位。

    Track Point最多5分钟更新一次,并且两个Track Point之间的距离要求大于500米。如果用户在500米范围内逗留的时间很长,那么该API会认为是同一个Track Point,不进行更新操作。Track Point的精度依赖于位置信息的精度,也就是说,在手机基站和WiFi接入点密集的地方,Track Point精度相对较高。而如果用户在一个偏僻的地方郊游,也没有开启GPS,那么Track Point可能更新的很慢,因为手机一直处于同一个基站的覆盖范围内。

    Track Point Monitor API提供如下信息:

  • Heading:Route Point记录的用户行动方向,该参数只有在GPS开启的情况下才有。
  • LengthofStay:设备在一个地点停留的时长。
  • Position:Route Point的地理位置信息。
  • Radius:位置的半径范围,和位置的精度信息有关。
  • Timestamp:用户进入该位置的时间点。

4. SensorCore 开发环境要求

    利用SensorCore进行应用开发,需要的开发环境为:Visual Studio 2013 Update 2 with Windows Phone SDK。SensorCore SDK 支持模拟器调试,但是支持的功能很有限。所以,如果实际开发应用的话,建议在解锁的开发设备上进行调试,比如最近发售的Lumia 630就可以。

5. SensorCore 实例Demo

    下面就Windows Phone 8.1 项目为例,演示如何使用SensorCore SDK。

5.1 新建项目

    首先,在Visual Studio中新建项目,选择

    Installed > Templates > Visual C# > Store Apps > Windows Phone Apps > Blank App (Windows Phone) ,同时,将项目名称命名为HelloSensorCore。

5.2 在项目中添加SensorCore SDK

    1. 选择Tools > NuGet Package Manager > Manage NuGet Packages for Solution

    2. 搜索Lumia SensorCore SDK点击安装。

    3. 如果要在模拟器中进行调试,还需要加入Lumia SensorCore SDK Testing Tools。操作步骤和Lumia SensorCore SDK一致。

    4. 添加完以后,可以查看项目的References目录,发现里面有Lumia.Sense, Lumia.Sense.Testing 和 Microsoft Visual C++ 2013 Runtime Package。如下图4所示。

12

图4:项目添加引用页面

5.3 在Package.appxmanifest文件中添加相关内容

    为了使得应用程序能够访问SensorCore的API,我们需要在Package.appxmanifest文件中添加相关capabilities。如果是通过添加引用的方式,那么开发环境会自动加入以下声明:

<DeviceCapability Name="location" />     <m2:DeviceCapability Name="humaninterfacedevice">         <m2:Device Id="vidpid:0421 0716">         <m2:Function Type="usage:ffaa 0001" />         <m2:Function Type="usage:ffee 0001" />         <m2:Function Type="usage:ffee 0002" />         <m2:Function Type="usage:ffee 0003" />         <m2:Function Type="usage:ffee 0004" />     </m2:Device> </m2:DeviceCapability>

    另外,为了使得程序能够正确的运行,我们需要对Configuration Manager中的目标平台进行配置。如果我们在实际设备中进行测试,那么必须选择ARM;如果在模拟器中进行测试,那么必须选择x86。如下图5所示。

3

图5:调试平台配置页面

5.4 在代码中使用SensorCore API

    我们这里新建一个非常简单的应用程序,主页面的Grid元素中包含一个ListBox,用于显示SensorCore返回的数据。在MainPage.xaml文件中添加以下代码:

<Grid>     <ListBox x:Name="SensorcoreList"/> </Grid>

    在后台代码文件MainPage.xaml.cs中,先要加入命名空间的引用:

using Windows.UI.Popups; using Lumia.Sense; using Lumia.Sense.Testing;using System.Threading.Tasks;

    在MainPage类中添加以下私有变量:

private PlaceMonitor _placeMonitor; private RouteTracker _routeTracker; private ActivityMonitor _activityMonitor; private StepCounter _stepCounter;

    下面,在MainPage的构造函数中添加Loaded事件处理代码:

this.Loaded += async (oo, ee) => {     await ShowStepCounter();     await ShowActivityMonitor();     await ShowRouteTracker();     await ShowPlacesMonitor(); };

    然后,根据应用的visibility来处理SensorCore的activation和deactivation:

Window.Current.VisibilityChanged += async (oo, ee) => {     if (!ee.Visible)     {         if (_placeMonitor != null) await CallSenseApiAsync(async () => await         _placeMonitor.DeactivateAsync());         if (_routeTracker != null) await CallSenseApiAsync(async () => await         _routeTracker.DeactivateAsync());         if (_activityMonitor != null) await CallSenseApiAsync(async () => await         _activityMonitor.DeactivateAsync());         if (_stepCounter != null) await CallSenseApiAsync(async () => await         _stepCounter.DeactivateAsync());         }     else     {         if (_placeMonitor != null) await CallSenseApiAsync(async () => await         _placeMonitor.ActivateAsync());         if (_routeTracker != null) await CallSenseApiAsync(async () => await         _routeTracker.ActivateAsync());         if (_activityMonitor != null) await CallSenseApiAsync(async () => await         _activityMonitor.ActivateAsync());         if (_stepCounter != null) await CallSenseApiAsync(async () => await         _stepCounter.ActivateAsync());     } };

定义两个方法来检查设备是否支持SensorCore SDK,并且检查Location和motion data是否已经打开。通常来讲,用户默认会关闭这两个选项,所以我们需要为用户提供快速设置的方法,而非去设置里面找这两个选项。

private async Task<bool> CallSenseApiAsync(Func<Task> action) {     Exception failure = null;     try     {        await action();     }     catch (Exception e)     {         failure = e;     }         if (failure != null)     {         switch (SenseHelper.GetSenseError(failure.HResult))         {         case SenseError.LocationDisabled:             await CreateMessageDialog("Location has been disabled. Do you want to open Location settings now?", "Information", "Yes", async cmd => await SenseHelper.LaunchLocationSettingsAsync(), true);             return false;         case SenseError.SenseDisabled:         await CreateMessageDialog("Motion data has been disabled. Do you want to open Motion data settings now?",  "Information", "Yes", async cmd => await SenseHelper.LaunchSenseSettingsAsync(), true);             return false;         default:             await CreateMessageDialog(SenseHelper.GetSenseError(failure.HResult).ToString(), "Failure", "OK", null, false);         return false;         }     }     return true; }
private static async Task CreateMessageDialog(string message, string title, string label, UICommandInvokedHandler command, bool no) {     var dialog = new MessageDialog(message, title);     dialog.Commands.Add(new UICommand(label,command));     if (no) dialog.Commands.Add(new UICommand("No"));     await dialog.ShowAsync(); }

    然后我们就可以开始使用StepCounter了。CallSenseApiAsync封装了安全访问SensorCore SDK的方法。在这个方法里面,我们先实例化一个StepCounter对象,并且调用StepCounter.IsSupportedAsync()来确认当前设备是否支持StepCounter。然后就可以获取当前StepCounter相关的数据,并且显示在主页面的Listbox中。

private async Task ShowStepCounter() {     await CallSenseApiAsync(async () =>     {        if (_stepCounter == null)         {             _stepCounter = await StepCounter.GetDefaultAsync();         }         if (await StepCounter.IsSupportedAsync())         {             var reading = await _stepCounter.GetCurrentReadingAsync();             SensorcoreList.Items.Add("Current step counter reading");             if (reading != null)             {                 SensorcoreList.Items.Add(reading.Timestamp.ToString());                 SensorcoreList.Items.Add("Walk steps = " + reading.WalkingStepCount);                 SensorcoreList.Items.Add("Walk time = " + reading.WalkTime.ToString());                 SensorcoreList.Items.Add("Run steps = " + reading.RunningStepCount);                 SensorcoreList.Items.Add("Run time = " + reading.RunTime.ToString());             }             else             {                 SensorcoreList.Items.Add("data not available");             }         }     }); }

    接下来,我们添加ActivityMonitor,显示当前的用户状态。处理流程和上面的StepCounter类似,实例化一个ActivityMonitor对象,检查设备是否支持,然后获取当前值,并且显示在Listbox中。下面是RouteTracker和PlacesMonitor部分,处理方式和上面类似,这里不再例举。可以参考附件的源代码工程。演示的主页面如下图6所示。

wp_ss_20140623_0001

图6:应用程序调式主页面信息

 

    另外,SDK还提供了几个Demo,包括Steps、Activities、Places和Tracks。演示的效果如下图6所示。大家可以去Nokia Developer上下载:链接。

    SDK提供的在线文档链接如下:文档链接

    接下来Lumia App Labs webinar会提供培训如何使用SensorCore SDK,注册地址为:培训视频注册链接

 

Enjoy!

 

参考链接:

1. Building Apps for Windows

2. Lumia SensorCore SDK 0.9.1.3

3. Nokia Developer

4. 在线文档链接

5. 培训视频注册链接

6. 工程源代码