微软移动 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. 工程源代码

posted on 2014-06-24 09:44  施炯  阅读(3319)  评论(2编辑  收藏  举报