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.xml
<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>
-
- TagViewer.java
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]; Listrecords = NdefMessageParser.parse(msgs[0]);
ところが実際にやってみると最初のNfcAdapter.EXTRA_NDEF_MESSAGESから取得できるはずのParcelableの配列がいきなりnullで戻る。 この段階では何もデータは取得できないのである。
さて困ったぞ。
※既に実現してる開発者がおりAndroidマーケットにアプリケーションが公開されているのは知っている。しかし、ソースコードが公開されていない以上、自分で納得のいくまでやってみたいのだ。