使用 NFC 开发前沿应用

近场通信 (NFC) 是一种新兴的短距离无线通信技术。在 2 厘米的精确范围内,人们可以通过物理方式点击连接设备来发送/接收内容。通过点击可以快速选择人或物。这种信息交流方式不仅速度快,而且易于理解。操作方法一目了然,无需阅读任何手册。

例如,假设您与好友正在共同欣赏一些照片,并且她想要您的照片;使用 NFC,您只需对着她的 PC 点击您的设备就可以发送照片。是否觉得过于简单了?也许是,不过此项技术的初衷就是为了简单地在设备之间共享内容。

'此图显示 Nokia 360 音箱与 Windows Phone 共享蓝牙配对信息

图 1:此图显示 Nokia 360 音箱
与 Windows Phone 共享蓝牙配对信息

与蓝牙或 Wi-Fi 类似,NFC 是由 NFC 论坛 (NFC Forum) 定义的一种标准无线传输协议。您的 PC 需要 NFC 无线通信装置。许多 Windows 8 PC 中直接集成了 NFC 无线通信装置。如果您的 PC 未集成 NFC,可以购买 NFC 收发器,并将其插入您的 PC。

NFC 提供了一些非常酷的功能。人们可以点击并发送照片,在餐馆点击菜谱并订餐,甚至可以通过点击与蓝牙设备配对。这些场景彼此有很大不同,但一个共同点是通过“点击”启动体验。NFC 可用于各种设备,如 PC、电话、音箱、耳机、无线显示器等,这使得将设备连接在一起成为一种真正直观的体验。此外,NFC 还使用 RFID 标签;它们是真正便宜、轻巧的无源天线,可容纳大量的数据,并可以粘贴在几乎任何物体上,最常用于海报。例如,购买电影票如同点击电影海报一样简单!这就是 NFC 标签。我们将通过点击 NFC 标签这样一个基本示例来演示 NFC API 的一些关键概念。

但是,首先我们仔细看一下点击设备进行连接意味着什么。

定义“点击”

无论是点击将蓝牙鼠标配对还是点击共享照片,重要的是用户需要以相同的方式点击设备进行连接。尽管点击是一个很好理解的概念,但对着另一设备点击您的 PC 对于大多数人而言还是一个新概念。下面是有关点击的一些指导原则,以便让用户知道:

  1. 在何处点击设备进行连接 – 通过使用触摸标记(也称为“轻触并执行”视觉标记)指示 NFC 天线的位置。根据 PC 型号的不同,您需要点击 PC 的不同部分。例如,在平板电脑上需要点击背面,但在多功能一体机上则需要点击正面。下面是该标记在所有启用 NFC 的 Windows 8 PC 上的图标:

    “轻触并执行”视觉标记

    图 2:“轻触并执行”视觉标记

  2. 设备正在相互通信 - 在点击过程中,用户相信正在执行某些操作;即使他们看不到数据正在传输。因此,当设备在感应范围内并且正在相互通信时,Windows 将播放声音。

Windows 会自动执行这些操作,因此您无需为它们操心。有关这些用户体验要素的更多信息,请参阅 Windows 8 近场邻近感应实施规范了解上述内容之后,让我们看一些使用 NFC 可以体验的超酷场景。

何时使用 NFC

当用户需要在您的应用中选择人或物时使用 NFC。NFC 为您提供了一种直观的选择方式;它通常比手动搜索速度要快(而且更酷!)。点击是一种启动体验的触发操作;根据应用的不同,得到的体验也不同,范围从接收照片到启动播放列表,不一而足。点击之后发生的操作实际上由您的应用决定。因此,为简单起见,我们将此系列体验归类为“轻触并执行”体验。

下面是一些使用 NFC 在应用中选择内容的示例。您可以点击并…

  • 从海报获取信息NFC 标签是轻巧、便宜的 RFID 标签;它们的成本介于 0.15 - 1.00 美元之间(价格因印刷成本而异)。它们相当于二维条码,但使用起来更方便、速度更快。点击标签比拍摄条码(需要将相机调到正确角度)感觉更舒服。制造商越来越多地将标签嵌入在人流密集的地方(如机场、地铁站和公交车站)张贴的海报中。它们可以保存 48 B – 4 KB 的数据。您可以对标签编程,以启动您的应用并打开特定的页面。
  • 交换联系信息:只需点击设备进行连接即可交换联系信息,而不必再向您的好友拼读联系信息,也不必担心对方出现任何拼写错误。与以上类似,您可以通过编程方式将自己的信息写入 NFC 名片/标签;也可以通过应用直接交换信息。
  • 播放您喜爱的音乐电台:无论您是在外工作、开车出游还是在家休息 – 使用 NFC 标签即可启动广播电台。您甚至可以在不同的标签上以编程方式写入不同的音乐电台;例如,一个标签用于健身房,一个用于休闲,一个用于睡眠。
  • 在繁忙的餐厅订餐:在受欢迎的餐厅就餐时,仅为了订餐就可能需要花很长时间等待。而使用这种标签,只需在您的餐桌上点击标签就可以预订您的菜品。
  • 与好友玩多人游戏:通过点击设备进行连接,您可以轻松连接多人游戏,与好友玩战舰、国际象棋或拼字游戏等。点击之后,此连接将持续保持,支持更大范围和更高吞吐量的带外传输(如蓝牙或 Wi-Fi Direct)。

到目前为止,我们对何时使用 NFC 有了相当不错的想法;现在对于娱乐内容而言 – 构建一个使用我们的 Windows 8 邻近感应 (NFC) API 的应用。

如何实施 NFC

您可以看到,使用 NFC,最终用户可以更加轻松地处理许多日常任务。我们以设置闹铃为例进行说明。我敢肯定,每个人都有多次这样的经历,他们将闹铃错设成早晨的其他时间。夜深人困时,您只想着尽快入睡,思维并非总是处于最活跃状态。使用 NFC 就轻松多了,您只需点击一个预设的标签,再确认一下,然后就可以安然入睡了。因此,为了帮助用户完成这个日常任务,让我们假设您编写了一个基本的闹铃应用,用户可以使用一个 NFC 标签设置闹铃。这分为两种情况

  1. 在标签上设置闹铃:NFC 标签可以重用,因此该应用应有一种方法供用户对闹铃编程。例如,用户可能希望编写不同的闹铃程序 – 一个用于工作日,另一个用于周末。这称为将数据发布到标签。
  2. 从标签设置闹铃:在用户点击标签之后,该应用将启动以确认设置闹铃。这意味着可以使用上下文或参数启动该应用。

NFC API 支持使用多种方式达到同一目的,不过,我将介绍实现此场景的最简单的方法。

下面我们了解在 NFC 标签上设置闹铃的过程:

  1. Mario 启动闹铃应用,并设置时间,假设为早晨 7:00。这是一个普通闹铃,与 NFC 尚无任何关系。
  2. Mario 选择一个选项“在 NFC 标签上设置闹铃”。这时,该应用将调用 NFC API 将信息发布到 NFC 无线通信装置,具体是一个应用标识字符串和 07:00。NFC 标签使用一个称为 NDEF(NFC 定义交换格式)的标准化消息格式。您的应用无需担心是否可以将数据格式化为 NDEF 消息;Windows 会为您完成此任务!现在,用户可以点击 NFC 标签。
  3. Mario 对着 PC 点击该标签,应用确认正在对该标签编程。在点击标签之后,务必让用户知道您的应用已成功对标签编程。我们刚才谈到,点击您的 PC 对大多数人来说是一个新概念,因此通过确认可让用户相信他们刚才的操作已经奏效。该应用通过注册消息传输处理程序,知道该消息已成功传输。

NFC API 位于 Windows.Networking.Proximity 命名空间中。它们在第 2 步中使用 – 在用户选择选项“在 NFC 标签上设置闹铃”之后。首先,该应用初始化邻近感应对象。邻近感应对象用于检测是否有标签(或设备)处于感应范围以内/以外。接下来,我们将添加 DeviceArrival 事件处理程序。该处理程序识别何时点击了标签,这意味着我们可以开始向标签写入信息。让用户知道您正在向标签写入很有必要,以便他们此时不会将其移出感应范围。您可以使用相同事件来识别何时点击了任何邻近感应设备。

下面的代码片段显示了如何初始化和添加 DeviceArrival 事件处理程序。

JavaScript

 var proximityDevice;

function initializeProximityDevice() {
    proximityDevice = Windows.Networking.Proximity.ProximityDevice.getDefault();

    if (proximityDevice) {
        proximityDevice.addEventListener("devicearrived", proximityDeviceArrived);
       
}
   else {
        // No NFC radio on the PC, display an error message
    }


function proximityDeviceArrived(device) {
        // Let the user know we’re ‘Writing to Tag’

}
}

C#

 private void InitializeProximityDevice()
{

Windows.Networking.Proximity.ProximityDevice proximityDevice;
    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();

    if (proximityDevice != null) {
        proximityDevice.DeviceArrived += ProximityDeviceArrived;
    
    }
    else
    {
        // No NFC radio on the PC, display an error message
    }
}

private void ProximityDeviceArrived(Windows.Networking.Proximity.ProximityDevice device)
{
            // Let the user know we’re ‘Writing to Tag’

}

接下来,我们向该标签发布信息。该应用发布两项内容:一个应用标识字符串,其中包含一个应用 ID 和应用平台,以及启动参数。对于 Windows 8,应用 ID 是 <package family name>!<app Id>,应用平台是“Windows”。您必须从应用软件包清单中应用程序元素的 ID 属性中复制应用 ID 值。启动参数是“07:00”– 该闹铃由用户设置。我们将其称为“消息”。

如果该应用跨平台运行,可以通过 Windows 发布备选应用 ID 和应用平台;这意味着您可以在支持 NFC 的不同设备(如 Windows Phone 8)上点击相同的标签!您可以在 MSDN 上找到有关备选 ID 的更多信息。

该应用使用名为 publishBinaryMessage 的方法将数据发布到标签。此方法采用三个参数 – messageType、message 和一个 messageTransmittedHandler 函数。我们将 messageType 设置为“LaunchApp:WriteTag”,这可让 Windows 知道您的应用希望向 NFC 标签写入信息。message 就是我们刚才定义的消息(应用识别的字符串和启动参数);我们需要在缓冲区中将此消息存储为二进制消息。messageTransmittedHandler 函数注册回调。这可让您的应用知道消息已成功写入标签。我们使用此方法告诉用户两个信息:我们已将消息成功写入标签,标签不再需要位于感应范围内。

消息将持续发布,直到我们调用 StopPublishingMessage 函数或者释放 ProximityDevice 对象之后才结束。在本例中,我们将使用 stop 函数。PublishBinaryMessage 返回一个发布 ID;我们将使用这一发布 ID 停止向 NFC 无线通信装置发布消息。

下面的代码片段显示了如何向 NFC 标签写入数据:

JavaScript

 var proximityDevice;

function getAlarmTime(){

    // Grab time set by the user, call this variable ‘Alarm’
    return Alarm;

}

function publishLaunchApp() {
    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();

if (proximityDevice) {
        // The format of the app launch string is: "<args>\tWindows\t<AppName>".
        // The string is tab or null delimited.

        // The <args> string can be an empty string ("").
        var launchArgs = getAlarmTime();

        // The format of the AppName is: PackageFamilyName!PRAID.
        var praid = "AlarmApp"; // The Application Id value from your package.appxmanifest.

        var appName = Windows.ApplicationModel.Package.current.id.familyName + "!" + praid;

        var launchAppMessage = launchArgs + "\tWindows\t" + appName;

        var dataWriter = new Windows.Storage.Streams.DataWriter();
        dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
        dataWriter.writeString(launchAppMessage);
        var launchAppPubId =
             proximityDevice.publishBinaryMessage(
                 "LaunchApp:WriteTag", 
                 dataWriter.detachBuffer(), 
                 proximityWriteTagLaunchAppMessageTransmitCallback);
        
    if (launchAppPubId != -1) {
            // Stop publishing the message on NFC radio
        proximityDevice.stopPublishingMessage(launchAppPubId);
    }

     }
}

function proximityWriteTagLaunchAppMessageTransmitCallback() {
    // Inform the user that: the message has been successfully written to a tag & the tag no longer needs to be in range
}

C#

 Windows.Networking.Proximity.ProximityDevice proximityDevice;

private string GetAlarmTime(){

    // Grab time set by the user, call this variable ‘Alarm’
    return Alarm;
}

private void PublishLaunchApp()
{
    proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault();

if (proximityDevice != null)
    {
        // The format of the app launch string is: "<args>\tWindows\t<AppName>".
        // The string is tab or null delimited.

        // The <args> string can be an empty string ("").
        string launchArgs = getAlarmTime();

        // The format of the AppName is: PackageFamilyName!PRAID.
        string praid = "MyAppId"; // The Application Id value from your package.appxmanifest.

        string appName = Windows.ApplicationModel.Package.Current.Id.FamilyName + "!" + praid;

        string launchAppMessage = launchArgs + "\tWindows\t" + appName;

        var dataWriter = new Windows.Storage.Streams.DataWriter();
        dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;
        dataWriter.WriteString(launchAppMessage);
        var launchAppPubId =
        proximityDevice.PublishBinaryMessage(
            "LaunchApp:WriteTag", dataWriter.DetachBuffer(), 
            proximityWriteTagLaunchAppMessageTransmitCallback);
    
    if (launchAppPubId!= -1)
    {
        proximityDevice.StopPublishingMessage(launchAppPubId);
    // Stop publishing the message on NFC radio
    }

    }
}

private void proximityWriteTagLaunchAppMessageTransmitCallback(
    Windows.Networking.Proximity.ProximityDevice sender,
    long messageId)
{
        // Inform the user that: the message has been successfully written to a tag & the tag no longer needs to be in range
}

就是这样!现在您已经知道如何从 Windows 应用商店应用向 NFC 标签写入信息。非常简单;因此,我们转到下一个场景 - 从标签设置闹铃。我们来看一下从 NFC 标签读取闹铃的过程:

  1. Mario 正在阅读他的主屏幕内容/写电子邮件/玩游戏/使用 Windows,他意识到需要为周一早上设置一个闹铃。他拿起“工作日闹铃”标签,然后对着自己的 PC 点击该标签。他获得一个 toast,邀请他启动您的闹铃应用。Windows 将照顾一切,直到这一刻为止;您的应用无需执行任何操作。
  2. Mario 接受邀请,您的应用启动到“确认闹铃?”屏幕,时间为早晨 7:00。在 Mario 接受 toast 之后,Windows 在激活过程中将启动参数(与上述参数一样)传递到您的应用。这称为外部启动,这与将您的应用启动到特定页是一样的。
  3. Mario 设置闹铃。这是一个普通闹铃,与 NFC 无关。

从 NFC 标签获取启动参数非常容易。应用需要处理来自 NFC 标签的外部启动。外部启动与将您的应用启动到特定页同义。我们的启动参数指定一个早晨 7:00 的闹铃,您的应用使用它来显示一个建议的闹铃。此外,如果 PC 上未安装您的应用,Windows 将邀请 Mario 从 Windows 应用商店安装该应用 – 安装过程完全自动!

以下代码片段显示了如何实现上下文启动。

JavaScript

 app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        if (args.detail.arguments == "Windows.Networking.Proximity.PeerFinder:StreamSocket") {
            //do nothing here.
        }
        else {
    // Use args.detail.arguments to parse out ’07.00’ string, and display to the user
        }

        args.setPromise(WinJS.UI.processAll());
    }
}

C#

 async protected override void OnLaunched(LaunchActivatedEventArgs args)
        {
            if (args.Arguments == "Windows.Networking.Proximity.PeerFinder:StreamSocket")
            {
                _isLaunchedByTap = true;
            }
            else
            {
// Use args.Arguments to parse out ’07.00’ string, and display to the user

            }
            Window.Current.Activate();
        }

这就是您的应用为支持读写 NFC 标签所需的全部操作;对于前沿场景而言相当简单。为了能够良好运行,在结束之前,让我们探讨一下错误处理问题。

错误处理

您的应用可能会遇到许多常见的错误。

  • 点击的标签不是 NDEF 格式。Windows 8 不支持将标签自动重新格式化为 NDEF,因此您需要下载并安装 NDEF 格式化程序。
  • 点击的标签为只读模式。一些 NFC 标签可能被锁定为只读模式(类似于旧式 VHS 录像带)。
  • 点击的标签容量太小,无法容纳所有数据。
  • 用户的 PC 没有 NFC。我在开头已经提到,NFC 是一种新兴的技术;普通采用仍需时日。要检查 PC 是否支持邻近感应,请使用 ProximityDevice.getDefault() 方法;如果未安装 NFC 无线通信装置,该方法将返回 NULL。

就这么有趣、直观!

NFC 终于到来了,它已经为主流消费者做好了准备 – Windows 有相应的生态体系和设计精良的端到端用户体验。该技术具有很大的潜力,可让应用和设备获得令人难以置信的交互式体验。就这么有趣、直观。

NFC 是一个广阔的领域,因此,请继续关注有关其他超酷 Windows 8 NFC 开发人员体验的更多博文。

有关 NFC 和邻近感应的更多信息,请参阅下面的资源。

资源

链接

类型

邻近感应体验使用指南

文档

邻近感应 API

文档

测试邻近感应应用并排除故障

文档

发布和订阅(详细说明)

文档

邻近感应应用示例

示例

遇到有关邻近感应的问题?请在这里询问

论坛

谢谢!

Priya Dandawate

设备和网络项目经理

投稿者:Max Morris、Marzena Makuta、Mike Loholt、Jake Sabulsky 和 Vishal Mhatre