NFC を使った最先端のアプリの開発

近距離無線通信 (NFC) は、現在発展しつつある短距離のワイヤレス テクノロジです。NFC を利用すると、ちょうど 2 cm の範囲内で、デバイスどうしを物理的にタップしてコンテンツの送受信を行うことができます。タップすると、何か (またはだれか) をすばやく選択できます。これはすばやいだけでなく、わかりやすい操作でもあります。一度見れば理解できるので、説明書は必要ありません。

たとえば、友だちと一緒に写真を見ているとき、その友だちがあなたの写真をほしがったとします。NFC を使えば、あなたのデバイスを友だちの PC に対してタップするだけで写真を送信できます。この説明は少々単純化しすぎているかもしれませんが、要点は、デバイス間でのコンテンツの共有がシンプルになるということです。

'Nokia 360 スピーカーで Bluetooth ペアリング情報を Windows Phone と共有しているところ

図 1: Nokia 360 スピーカーで Bluetooth ペアリング情報を
Windows Phone と共有しているところ

Bluetooth や Wi-Fi と同様に、NFC は標準ワイヤレス プロトコルの 1 つで、NFC フォーラム (英語) によって定義されています。NFC を利用するには、PC が NFC 通信機能を搭載している必要があります。Windows 8 PC には、NFC 通信機能が直接組み込まれているものが多くあります。お使いの PC に NFC が搭載されていない場合は、NFC ドングルを購入して PC に装着することもできます。

NFC は便利な機能を実現します。タップして写真を送信したり、レストランでメニューをタップして料理を注文したりできるほか、タップして Bluetooth デバイスをペアリングすることも可能です。これらは互いに大きく異なるシナリオですが、"タップ" して操作を始めるという点が共通しています。NFC は、PC、携帯電話、スピーカー、ヘッドセット、ワイヤレス ディスプレイなど、さまざまなデバイスで使用され、きわめて直感的な方法でデバイスどうしを接続します。また、NFC で使われる RFID タグは、非常に安価で軽量な受動アンテナで、相当な量のデータを保持することができ、実質的に何にでも貼り付けることができます。よくある利用例はポスターです。たとえば、映画のチケット購入を、映画のポスターをタップするだけというシンプルな手順にできるのです。この記事では、NFC タグをタップする基本的な例を紹介しながら、NFC API の主要概念の一部について具体的に説明します。

その前に、デバイスどうしをタップするとはどういうことか、もう少し詳しく見てみましょう。

"タップ" の定義

タップして Bluetooth マウスをペアリングする場合でも、タップして写真を共有する場合でも、重要なのは、デバイスどうしを同じようにタップするという点です。タップ自体はよく知られた概念ですが、PC を別のデバイスに対してタップするという動作は、多くのユーザーにとって新しいものです。このようなタップ操作に関して、ユーザーに伝えるべき情報を示すガイドラインの一部を以下に紹介します。

  1. デバイスどうしをタップする位置を示す - タッチマークを使用して NFC アンテナの位置を示します。タッチマークは、"Tap and Do" ビジュアル マークとも呼ばれます。タップする部分は、PC のモデルによって異なります。たとえば、タブレットでは背面であったり、オールインワン モデルでは前面であったりする可能性があります。NFC 対応の Windows 8 PC では、次のようなマークが使われます。

    Tap and Do ビジュアル マーク

    図 2: Tap and Do ビジュアル マーク

  2. デバイスが相互に通信していることを示す - タップしている間、転送中のデータは目に見えなくても、何かが行われていることをユーザーが確信できるようにする必要があります。Windows では、デバイスどうしが通信範囲内にあって相互に通信しているときにサウンドが再生されます。

これらは Windows によって自動的に行われるため、アプリ開発者は気にする必要はありません。このようなユーザー エクスペリエンス要素の詳細については、「Windows 8 の近距離通信実装の仕様を参照してください。以上を念頭に置いたうえで、NFC で実現できる便利なシナリオをいくつか見ていきましょう。

NFC を活用できる場面

NFC は、アプリ内でユーザーが何かを選択する必要があるとき、またはだれかを選択する必要があるときに使用します。NFC によって実現される選択方法は直感的で、多くの場合、手動で検索するよりもすばやく (かつクールに) 行うことができます。この操作を開始するトリガーがタップです。操作の結果はアプリによって異なり、写真の受信からプレイリストの再生までさまざまなものがあります。タップの後に何が起きるかを決めるのは、それぞれのアプリに任されています。話をシンプルにするために、私たちはこの一連の動作をまとめて "Tap and Do" エクスペリエンスと呼んでいます。

以下に、NFC を使ってアプリで何かを選択する例をいくつか紹介します。たとえば、タップして次のようなことを実行できます。

  • ポスターから情報を取得する: NFC タグ (英語) は軽量で安価な RFID タグであり、$0.15 ~ $1.00 程度で入手できます (価格は印刷料金に応じて変わります)。これらは QR コードと互換性がありますが、より簡単にすばやく使用できます。タグをタップする操作は、バー コードの写真を (カメラのアングルを気にしながら) 撮影するよりも快適です。空港、地下鉄駅、バス停などの通行量の多い場所で、ポスターにタグを埋め込むメーカーが増えています。タグには 48 B ~ 4 KB のデータを保持できます。タグは、独自のアプリを起動して特定のページを開くようにプログラミングすることができます。
  • 連絡先情報を交換する: 自分の連絡先情報を友だちに伝えるとき、相手が正しく書き取ってくれることを期待しながら 1 文字ずつ説明する必要はありません。互いのデバイスをタップして連絡先情報を交換できます。同様の例として、NFC 対応の名刺/タグに自分の情報をプログラミングしたり、アプリを通じて直接情報を交換したりすることもできます。
  • お気に入りの音楽放送局を聴く: ジムに行こうとしているときでも、車に乗り込んだときでも、自宅でくつろいでいるときでも、NFC タグを使用してラジオを流し始めることができます。別々のタグに別々の音楽放送局をプログラミングすることも可能です。たとえば、ジム用のタグ、くつろいだ時間のためのタグ、就寝時のタグのように使い分けることができます。
  • 混雑したレストランで食事を注文する: 人気のあるレストランに夕食の時間帯に行くと、注文するだけでも長時間待たされることがあります。店員を待つ代わりに、テーブルでタグをタップして食事を注文できます。
  • 友だちとマルチプレイヤー ゲームをプレイする: バトルシップ、チェス、スクラブルなどのマルチプレイヤー ゲームで、デバイスどうしをタップするだけで簡単に友だちと接続できます。タップした後は、Bluetooth や Wi-Fi Direct など、より広範囲で高スループットの帯域外トランスポートを介して接続が維持されます。

ここまでの説明では、NFC を活用できる場面について魅力的なアイデアを紹介してきました。次はお待ちかね、Windows 8 の Proximity (NFC) API を使うアプリの作成方法についてお話しします。

NFC の実装方法

おわかりのように、NFC によって、エンド ユーザーはさまざまな日常のタスクをより簡単に行えるようになります。ここでは、例としてアラームの設定を取り上げます。朝のアラームの時刻を間違えて設定してしまった経験はだれにでもあるでしょう。夜遅くなって早く眠りたいと思っているときは、頭が十分に働いているとは限らないものです。でも、NFC を使えば簡単です。あらかじめ設定したタグをタップして確認するだけで、何の心配もなく眠ることができます。この毎日の習慣を支援するために、ここでは、NFC タグを使ってアラームを設定できる基本的なアラーム アプリを作成すると想定しましょう。これは 2 つのシナリオに分けられます。

  1. タグアラームを設定する: NFC タグは再利用が可能なので、アプリでは、ユーザーがアラームを設定するための手段を用意する必要があります。たとえば、平日用と週末用など、複数のアラームを設定したい場合があります。これは、タグにデータを発行するというシナリオです。
  2. タグからアラームを設定する: ユーザーがタグをタップしたら、アプリを起動してアラームの設定を確認する必要があります。これは、コンテキスト (引数) を指定してアプリを起動できるようにするということです。

NFC API には同じ処理を実現できる方法がいくつかありますが、ここでは最も簡単な方法でこのシナリオを実装します。

まず、NFC タグにアラームを設定する流れを順番に見ていきましょう。

  1. ユーザーがアラーム アプリを起動して時刻を設定します。設定時刻は午前 7 時とします。これは通常のアラームの操作で、まだ NFC は使いません。
  2. 次に、ユーザーが "NFC タグにアラームを設定する" オプションを選択します。このとき、アプリでは NFC API を呼び出して NFC 通信機器に情報を発行します。具体的には、アプリの識別子文字列と 07:00 という情報が発行されます。NFC タグでは NDEF (NFC Data Exchange Format) という標準メッセージ形式が使われますが、NDEF メッセージ形式へのデータの変換をアプリが心配する必要はなく、Windows が自動的に処理してくれます。これで、ユーザーが NFC タグをタップできるようになります。
  3. ユーザーが PC に対してタグをタップすると、アプリがタグのプログラミングを確認します。タグがタップされたら、アプリでタグを正しくプログラミングしたという結果をユーザーに通知することが重要です。既に説明したとおり、PC をタップする操作は多くのユーザーにとって新しい概念です。そのため、確認の通知を返して、操作がうまくいったことをユーザーが確信できるようにします。アプリでは、メッセージ転送ハンドラーを登録することで、メッセージが正しく転送されたことを検出できます。

NFC API は、Windows.Networking.Proximity 名前空間に用意されています。手順 2 でユーザーが "NFC タグのアラームを設定する" オプションを選択したら、この API の出番です。まず、アプリで近接通信オブジェクトを初期化します。近接通信オブジェクトは、タグ (またはデバイス) が範囲内に入ったこと、あるいは範囲から外れたことを検出するために使われます。次に、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’

}

次に、情報をタグに発行します。アプリが発行する情報は 2 つあります。1 つはアプリの識別子文字列で、これはアプリ ID とアプリ プラットフォームから構成されます。もう 1 つは起動引数です。Windows 8 では、アプリ ID は<パッケージのファミリ名>!<アプリ Id> (リンク先は英語の可能性があります)、アプリ プラットフォームは "Windows" になります。アプリ ID の値は、アプリのパッケージ マニフェストに記述されている Application 要素の ID 属性からコピーする必要があります。起動引数は "07:00" で、ユーザーが設定したアラームを表します。これを "メッセージ" と呼ぶことにしましょう。

アプリが複数のプラットフォームで動作する場合は、代替のアプリ ID とアプリ プラットフォームを発行できます。これにより、NFC をサポートする別のデバイス (Windows Phone 8 など) でも同じタグをタップできるようになります。代替 ID の詳細については、MSDN を参照してください。

アプリからタグにデータを発行するには、publishBinaryMessage というメソッドを使用します。このメソッドは、パラメーターとして messageType、message、および messageTransmittedHandler 関数の 3 つを受け取ります。今回の例では、messageType を "LaunchApp:WriteTag" に設定して、アプリから NFC タグに情報を書き込もうとしていることを Windows に伝えます。message は、先ほど定義したメッセージ (アプリの識別子文字列と起動引数) です。バッファーには、メッセージをバイナリ メッセージとして格納する必要があります。messageTransmittedHandler 関数はコールバックに登録されます。これを通じて、メッセージがタグに正しく書き込まれたことがアプリに通知されます。アプリでは、この関数を使って、メッセージがタグに正しく書き込まれたこと、およびタグを通信範囲内に保つ必要がなくなったことの 2 点をユーザーに通知します。

メッセージは、StopPublishingMessage 関数を呼び出すまで、または ProximityDevice オブジェクトが解放されるまで発行され続けます。この記事の例では停止関数を使用します。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. ユーザーは、ホーム画面をチェックしたり、メールを書いたり、ゲームで遊んだり、Windows を使ったりしているうちに、月曜日の朝のアラームを設定しなければならないと思い立ちました。そこでユーザーは、"平日のアラーム" というタグを持って PC とタップします。これにより、アラーム アプリの起動を促すトーストが表示されます。ここまでの処理はすべて Windows によって行われるため、アプリでは何もする必要はありません。
  2. ユーザーが承諾すると、アプリが起動してアラームの確認画面が表示され、午前 7 時という時刻が示されます。ユーザーがトーストを受け入れた後、アプリのアクティブ化の間に、Windows からアプリに起動引数 (上で説明したもの) が渡されます。これはコンテキストに応じた起動と呼ばれ、アプリを起動して特定のページを開くことと同じです。
  3. ユーザーがアラームを設定します。これは通常のアラームの操作で、NFC は使いません。

NFC タグから起動引数を取得するのは非常に簡単です。アプリでは、NFC タグに指定された起動時のコンテキストを適切に処理する必要があります。コンテキストに応じた起動とは、アプリを起動して特定のページを表示することと同じです。この例での起動引数は、午前 7 時というアラーム時刻を指定しています。アプリでは、この情報を使って指定されたアラームを表示します。さらに、アプリが PC にインストールされていない場合に備えて、Windows ストアからアプリをインストールするための案内も表示されます。これは 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 対応のエコシステムであり、よく設計されたエンド ツー エンドのユーザー エクスペリエンスを提供します。このテクノロジには、アプリやデバイス エクスペリエンスをこれまでにないほどインタラクティブにできる大きな可能性があります。NFC で実現される操作は、楽しくて直感的です。

NFC の応用分野は多岐にわたります。このブログでは、開発者から見た Windows 8 の NFC に関して、役立つ情報を他にも取り上げていく予定です。今後の記事にご注目ください。

NFC と近接通信の詳細については、以下のリソースを参照してください。

リソース

リンク

種類

近接通信を使った開発のガイドライン

ドキュメント

Proximity API

ドキュメント

近接通信アプリのテストとトラブルシューティング

ドキュメント

発行と受信登録 (詳細)

ドキュメント

近接通信アプリのサンプル (英語)

サンプル

近接通信に関する質問の投稿先 (英語)

フォーラム

お読みいただき、ありがとうございました。

Priya Dandawate

Devices and Networking プログラム マネージャー

協力: Max Morris、Marzena Makuta、Mike Loholt、Jake Sabulsky、Vishal Mhatre