Felicaのデータを読む (その1)

nfcを使って書くコードの取り敢えずのゴールを「Felicaカードのデータを読み出して人間が読める形式にする」という所に置こうと思う。※これは私が普段からPASMOを使用しており、一番身近でよく利用しているデバイスだからである。ほぼ毎日使用しているので、使用履歴も豊富だ。

Nexus Sのnfc機能は基本的にはnfcリーダでありFelicaフォーマットで書きこまれた非接触型のICカードデバイスからデータを読みだすことができるはずである。

  • カードを翳されたことを検知する

常駐しているサービス"NfcService"がFelicaカードが翳されたことを検知して、インテント"android.nfc.action.TAG_DISCOVERED"をブロードキャストで投じるので、それに呼応するActivityを作成しておけばシステムが勝手に起動してくれる。(このAndroidプラットホームを利用した機構こそが素晴らしい)

SDKに添付されている"NFCDemo"では上記の通り、マニフェストにインテントフィルタを記述してTagViewerというActivityを起動している。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.nfc"
>
    <uses-permission android:name="android.permission.NFC" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    〜 略
        <activity android:name="TagViewer"
            android:theme="@android:style/Theme.NoTitleBar">
            <intent-filter>
                <action android:name="android.nfc.action.TAG_DISCOVERED"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
</manifest>
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tag_viewer);
    mTagContent = (LinearLayout) findViewById(R.id.list);
    mTitle = (TextView) findViewById(R.id.title);
    resolveIntent(getIntent());
}

void resolveIntent(Intent intent) {
    // Parse the intent
    String action = intent.getAction();
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
        〜 NFCServiceからのインテントを処理する
    }

ここまでは何も問題は無い。
この後、用意されたクラスとメソッドでデータがすんなり読み出せればそれで終了なのだが、そうは問屋がおろさない。

今もいろいろやっているが未だに上手くデータを読み出せない。というのもAndroid 2.3で公開されている数少ないクラスとメソッドではFelicaのデータは読み出せないのである。

同じくTagViewer.java中のコードからの抜粋だと、デバイス側からデータを読み出すには以下のコードで良いはずである。

Parcelable rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msgs = new NdefMessage[rawMsgs.length];
List records = NdefMessageParser.parse(msgs[0]);

ところが実際にやってみると最初のNfcAdapter.EXTRA_NDEF_MESSAGESから取得できるはずのParcelableの配列がいきなりnullで戻る。 この段階では何もデータは取得できないのである。

さて困ったぞ。

※既に実現してる開発者がおりAndroidマーケットにアプリケーションが公開されているのは知っている。しかし、ソースコードが公開されていない以上、自分で納得のいくまでやってみたいのだ。