連載
» 2013年02月12日 18時00分 公開

AndroidビームとPush通知で最強のO2Oアプリを作るAndroidで使えるO2O技術まとめ解説(終)(3/3 ページ)

[金岡徹,TIS コーポレート本部 戦略技術センター]
前のページへ 1|2|3       

Androidビーム(NFC)の機能をアプリに組み込むには

 続いてNFCを利用した機能をアプリに組み込みます。実装に入る前にシナリオと、NFCを利用して、どのような機能を実装するかを確認しておきます。以下のようなシナリオを想定します。

  1. Android端末Aを持っているユーザーXとAndroid端末Bを持っているユーザーYが同じ部屋に入る
  2. Android端末A、Bにあいさつ可能な(同じ部屋にいる)友達リストが表示される
  3. ユーザーXがあいさつを送りたい友達(ユーザーY)を選択し、NFCを利用してあいさつを送る
  4. ユーザーYに通知される
あいさつ(NFC)

 ここでも、1および2の説明は割愛し、あいさつ可能なユーザーのリストが表示された状態から説明を始めます。3、4の部分をNFCを利用して実現します。

 実装するのは「端末を近づけるとデータをやりとりして、あいさつを成立させる」機能です。あいさつを成立させるには、あいさつを送った人と送られた人を特定する必要があります。そのため、NFCを利用してあいさつを送ってくれたユーザーのIDをメッセージとして送信し、あいさつを受け取った方は、自分のユーザーIDと相手のユーザーIDをサーバに送信しあいさつが成立したことを知らせます。

 サーバ側に知らせる理由としては、サーバ側で一括してあいさつの管理(回数、あいさつの形式)をしているためです(このアプリの仕様なので、もちろんこの通りにする必要はありません)。

 ということで、実際に実装する処理としては「NFC搭載端末同士を近づけると端末Aから端末Bに向けてメッセージが送信され、そのメッセージを端末Bで受け取り、その情報を元にサーバ側にリクエストを送る」ことになります。

 この機能をAndroidビームを利用して実現します。AndroidビームではPtoPでNDEF(NFC Data Exchange Format)のメッセージを交換できるので、このフォーマットにのっとってメッセージを組み立てます。

 Androidビームを利用してNDEFメッセージを交換するためには、端末が以下のような条件でなければならないので、注意が必要です。

  • フォアグラウンドにいなければならない
  • データを受信するデバイスはロックされていない状態でなければならない

 NDEFメッセージのプッシュはAPI レベル 10 で利用可能になりましたが、Android 4.0(APIレベル14)以降でより簡単に実装できるようになったので、今回はAPIレベル14(Android 4.0)のNexus Sを利用して実装してみます。

Androidビームを利用するための設定

 NFCを利用するにはPermissionの設定が必要です。AndroidManifestに以下のように追記します。

<uses-permission android:name="android.permission.NFC"></uses-permission>
 
<activity android:name="DirectPecoriActivity">
  <intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
  </intent-filter>
</activity>
AndroidManifest.xml

NDEFメッセージのハンドリング

 NDEFメッセージのハンドリングを実際に実装したものが以下のDirectPecoriActivityです。ハンドリングは大きくNDEFメッセージの送信・受信の2つに分けられますが、それらの処理が1つのActivityに書かれているので、それぞれ別々に説明していきます。

 まず、NDEFメッセージの送信について説明します。

public class DirectPecoriActivity extends Activity implements CreateNdefMessageCallback {
 
〜(省略)〜
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.direct_pecori);
  
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mNfcAdapter == null) {
            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
        }
  
        SharedPreferences sharedpref = getSharedPreferences("preference", MODE_PRIVATE);
        mMyfacebookId = sharedpref.getString("facebook_id", "");
        String name = sharedpref.getString("name", "");
        mSender = new User(mMyfacebookId, name);
  
        mNfcAdapter.setNdefPushMessageCallback(this, this);
        mMessage = (TextView) findViewById(R.id.greet_message);
  
    }
  
    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
  
        String id = mMyfacebookId;
        String name= mSender.getName();
  
        NdefRecord[] records = {
            new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), new byte[] {}, id.getBytes()),
            new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), new byte[] {}, name.getBytes()),
            NdefRecord.createApplicationRecord("com.example.pecorin")
        };
  
        NdefMessage msg = new NdefMessage(records);
        return msg;
    }
}
DirectPecoriActivity.java

 APIレベル14以降でNDEFメッセージを送信(NDEFメッセージをプッシュ)するには、「setNdefPushMessageCallback(NfcAdapter.CreateNdefMessageCallback callback, Activity activity, Activity... activities)」というメソッドを利用すると簡単に実現できます。

 このメソッドを適切に設定すると、NDEFメッセージが送信可能になったときに事前に組み立てたNDEFメッセージを送信してくれます。

 具体的には、「setNdefPushMessageCallback(NfcAdapter.CreateNdefMessageCallback callback, Activity activity, Activity... activities)」は、第1引数がNfcAdapter.CreateNdefMessageCallbackインターフェイスを実装したクラスを指定するようになっているので、Activity自体にCreateNdefMessageCallbackインターフェイスを実装しています。

 また、CreateNdefMessageCallbackインターフェイスは「createNdefMessage(NfcEvent event)」メソッドを持っているので、Activity内にオーバライドする形で実装します。

 createNdefMessage(NfcEvent event) は、NDEFメッセージのプッシュが可能になったとき(デバイスがビームできる範囲に入ったとき)に呼び出され、戻り値であるNDEFメッセージが送信されます。そのため本メソッド内で送信したいNDEFメッセージを組み立てます。

 NDEFメッセージは1つ以上のレコード ( NdefRecord ) を含む形で組み立てます。上記の実装では、MIMEタイプが「"text/plain"」のデータであるid(ユーザーのID)、 name(ユーザー名)をそれぞれ1つずつ、計2レコード作成して詰めています。また、メッセージの最後に「AAR(Android アプリケーション レコード)」と呼ばれるレコードを入れています。

 AARは、パッケージ名を基に起動するアプリケーションを指定できるレコードで、「NdefRecord.createApplicationRecord(String packageName)」で作成できます。AARを含めていない場合、NFCタグの読み込みが可能なアプリがダイアログ形式で選択できますが、確実に指定のアプリケーションを起動したい場合はAARを含んでおくといいでしょう。

 ちなみに、AARをNDEFメッセージに含めるときは、最初のレコードはタグのMIMEタイプやURIを決定する目的でNDEFメッセージの最初のレコードをチェックするため、NDEFメッセージの最初のレコードにしないよう注意してください。

 続いて、NDEFメッセージの受信について説明します。

public class DirectPecoriActivity extends Activity implements CreateNdefMessageCallback {
  
〜(省略)〜
  
    @Override
    public void onResume() {
        super.onResume();
  
        final Intent intent = getIntent();
  
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
  
            new AlertDialog.Builder(this).setTitle(R.string.greet_message_title).setPositiveButton("Yes",new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
  
                    NdefMessage msg = (NdefMessage) rawMsgs[0];
                    byte[] payload = msg.getRecords()[1].getPayload();
                    String name = new String(payload);
  
                    mMessage.setText(name);
  
                    String type = "nfc";
                    greetTask task = new greetTask(mSender, type);
                    task.execute(message);
                }
            }).setNegativeButton("No",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                }
            }).show();
        }
    }
}
DirectPecoriActivity.java

 NDEFメッセージの受信処理はonResume()で実装しています。Android端末がNDEFメッセージを検知すると、メッセージのパースおよびMIMEタイプなどのチェックを行い、Intentにカプセル化されるようになっています。

 NDEFメッセージをフィルタするには、先に示したようにAndroidManifestにIntentフィルタを記述する必要があります。具体的には、以下の部分です。

<action android:name="android.nfc.action.NDEF_DISCOVERED" />
AndroidManifestにIntentフィルタを記述

 この場合のインテントのアクションは、ACTION_NDEF_DISCOVEREDになるので、アクションをチェックしてその後の処理を記述していきます。

※NFCタグなどをスキャンした場合は「NDEFメッセージをカプセル化したインテント」の他に2種類あり、インテントのアクションもそれぞれ異なるのですが、それらの説明は割愛します。詳細は、記事「AndroidアプリでNFCタグを読み書きするための基礎知識」を参照してください。

 その後の処理は「メッセージの取り出し」「あいさつの成立」になります。メッセージの取り出しについては、16行目の以下のコードでパースされたNDEFメッセージの配列が取得できます。

Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)

 そのため、各レコード(今回はAARを含め、3レコード含まれているので先頭の2つのレコード)を取得して、もともとのメッセージ(ここではユーザーのIDとユーザー名)を復元させます。

 あいさつを成立させるには、サーバ側にリクエストを送信する必要があるので、GCMの部分で説明したgreetTask(User mSender, String type)を利用してサーバ側にあいさつを確定するように指示します。

実際に、アプリを動かすと……

 これでNFCを利用したあいさつは完了です。実際のアプリの挙動は以下のようになります。

Android端末Xでフォアグランドにして端末を近づける
Android端末XでAndroidビームを使ってメッセージを送信
メッセージを受け取るとAndroid端末Yにダイアログが表示される

 このようにAndroidビームを使うと、NDEFメッセージを簡単に送信できます。今回は「PtoP」モードの通信だけを紹介しましたが、単純にNFCのタグを読み込んだり書き込んだりする「リーダー/ライター」モードに対応させる場合は、メッセージの受信部分のソースコードを参考に簡単に実装できます。

いろいろな切り口からO2Oの可能性を探ろう

 今回はオンライン(Facebookの友達情報)とオフライン(あいさつ)を結びつけるAndroidアプリの例を示しつつ、NFCとPush Notificationについて解説していきました。

 Push型通知はGCM、NFCはAndroidビームがそれぞれ登場したことにより、これらの技術を利用したアプリを作成することが簡単になってきました。Push型通知もNFCも一見仕組みは複雑そうですが、いったん分かってしまえば実装することは難しくないと思っていただけたのではないでしょうか。

 第1回の記事でも触れていますが、スマートフォンを利用することでO2Oの可能性が広がってきました。アプリ開発の環境も整ってきたため、本特集で紹介した屋内測位技術やPush Notification、NFCといった技術だけでなく、また別の技術なども組み合わせて、いろいろな切り口からO2Oの可能性を探ってみると良いと思います。

前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。