Androidプログラマへの道 〜 Moonlight 明日香 〜 - NFCでカードのIDを取得する
Androidに常駐しているサービス"NfcService"がNFCカード/タグを検出すると, インテント "android.nfc.action.XXX_DISCOVERED"を発行する.
NFCカード/タグのID情報を取得するには, この仕組みを利用する.

ID情報の取得

  • Nfc03.java
    • Intent#getIntentメソッドで, Intentのインスタンスを取得する.
    • インテントのアクションが, "ACTION_TECH_DISCOVERED"かチェックする.
    • Intent#getByteArrayExtraメソッドに, NfcAdapter.EXTRA_ID指定して, ID情報を取得する.
package com.moonlight_aska.android.nfc03;

import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.widget.TextView;

public class Nfc03 extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_nfc03);

    TextView text = (TextView)findViewById(R.id.tag_id);
    // インテントの取得
    Intent intent = getIntent();
    // ICカードの検出かチェック
    String action = intent.getAction();
    if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
      // NFCからID情報取得
      byte[] ids = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
      StringBuilder tagId = new StringBuilder("ID(" + ids.length + "bytes) : ");
      for (int i=0; i<ids.length; i++) {
        tagId.append(String.format("%02x", ids[i] & 0xff));
      }
      text.setText(tagId.toString());
    }
  }
}
  • res/xml/filter_nfc.xml
    • NFC TypeA, NFC TypeB, NFC TypeFを受け付けるように指定する.
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
  <tech-list>
    <tech>android.nfc.tech.NfcA</tech>
  </tech-list>
  <tech-list>
    <tech>android.nfc.tech.NfcB</tech>
  </tech-list>
  <tech-list>
    <tech>android.nfc.tech.NfcF</tech>
  </tech-list>
</resources>
  • AndroidManifest.xml
    • NFCを使用する場合, "android.permission.NFC"のパーミッションを設定する.
    • インストール時に, NFCデバイスが必要であることを設定する.
    • "android.nfc.action.TECH_DISCOVERED"でアプリが起動するよう, インテントフィルタを設定する.
    • メタデータ"xml/filter_nfc"を設定する.
  注) TAG_DISCOVEREDを使ったサンプルを見かけるが, Nexus 7ではNFC-F(Felica)は問題ないが, NFC-A(MIFARE)が検出できなかった.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.moonlight_aska.android.nfc03"
  android:versionCode="1"
  android:versionName="1.0" >

  <uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="15" />
  <uses-permission android:name="android.permission.NFC"/>
  <uses-feature android:name="android.hardware.nfc"
    android:required="true"/>

  <application}
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
      android:name=".Nfc03"
      android:label="@string/title_activity_nfc03" >
      <intent-filter>
        <action android:name="android.nfc.action.TECH_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      <meta-data
        android:name="android.nfc.action.TECH_DISCOVERED"
        android:resource="@xml/filter_nfc" />
    </activity>
  </application>
</manifest>
  • 動作例
    • NFC-A (MIFARE)
例 : MiniTrack NXP NTAG203

    • NFC-B
例 : 運転免許証

    • NFC-F (Felica)
例 : PiTaPa