【Android】NFCを使ってみる① (読み込み処理)
NFC(Near Field Communication)は、近距離無線のテクノロジーで、
Android 2.3からサポートされている技術です。
また、Android 4.0からは、Android Beam
という機能が加わり、
2つのAndroid搭載のデバイス間でのピアツーピアのデータ交換が可能となりました。
アプリケーションへの NFC タグのディスパッチ方式
AndroidデバイスがNFCを検知すると対応するインテントを発行します。
NFCに関する起動インテントには、下記の3種類があり、
それぞれの優先度が決まっています。
[ACTION_NDEF_DISCOVERED]
読み込んだタグが、NDEF(NFC Data Exchange Format)
ペイロードを持つ場合、
このアクションが定義されたアクティビティにIntentが通知されます。
起動インテントの優先度としては、最も高く、
このアクションでアクティビティが起動した場合は、ACTION_TECH_DISCOVERED
またはACTION_TAG_DISCOVERED
で登録されているアクティビティがあっても起動されません。
[ACTION_TECH_DISCOVERED]
ACTION_NDEF_DISCOVERED
インテントをハンドルするアクティビティが登録されていない場合には、
このアクションでが定義されたアクティビティにIntentが通知されます。
優先度としては、ACTION_NDEF_DISCOVERED
の次に高いです。
[ACTION_TAG_DISCOVERED]
このインテントはACTION_NDEF_DISCOVERED
または、ACTION_TECH_DISCOVERED
インテントをハンドルするアクティビティがない場合に開始されます。
読み込みサンプル
以下のサンプルは、NFCカードをかざすとNFCの識別子情報を読み取るサンプルになります。
Android Manufestの定義
Android Manufest
には、NFCを使用するためのパーミッションの定義と、
各ディスパッチ方式に対応するintent-filter
の定義が必要です。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.nfcreadsample" android:versionCode="1" android:versionName="1.0" > <!-- NFCを使用する為のパーミッションを付与 --> <uses-permission android:name="android.permission.NFC" /> <!-- Google Playで、NFCハードウェアを持つデバイスのみに制限するための 機能を定義 --> <uses-feature android:name="android.hardware.nfc" android:required="true" /> ・・・ <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.test.nfcreadsample.MainActivity" android:label="@string/app_name" > ・・・ <!-- NFC NDEF text --> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <!-- NFC TECH --> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <!-- ACTION_TAG_DISCOVEREDで登録するフィルタを参照する --> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> <!-- NFC TAG --> <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>
ACTION_NDEF_DISCOVERED
インテントをフィルタするには、
フィルタしたい対象データのタイプを加えたインテントフィルタを宣言します。
上記では、ACTION_NDEF_DISCOVERED
フィルタにtext/plain
のMIMEタイプを付加しています。
ACTION_TECH_DISCOVERED
インテントをフィルタさせる場合は、
XMLリソースファイルを作成し、tech-listセットの中にアクティビティがサポートするNFCのフォーマット形式を定義します。
作成したXMLファイルは、<project-root>/res/xml
ディレクトリ配下へ保存します。
以下は、tech-listリソースファイルのサンプルです。
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.IsoDep</tech> </tech-list> <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> <tech-list> <tech>android.nfc.tech.NfcV</tech> </tech-list> <tech-list> <tech>android.nfc.tech.Ndef</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NdefFormatable</tech> </tech-list> <tech-list> <tech>android.nfc.tech.MifareClassic</tech> </tech-list> <tech-list> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
NFCを読み込む
下記では、起動Activityより受信インテントを受け取り、
NFCの起動によるものかを判定しています。
インテントがNFCのアクションである場合、
NfcAdapter.EXTRA_ID
というキーを使ってNFCのIDm(固有識別子)を読み込んでいます。
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); String action = intent.getAction(); setContentView(R.layout.activity_main); // NFCかどうかActionの判定 if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) { // IDm(固有識別子)を表示させる String idm = getIdm(getIntent()); if (idm != null) { TextView idmView = (TextView) findViewById(R.id.idm); idmView.setText(idm); } } } /** * IDmを取得する * @param intent 受信インテント * @return IDm文字列 */ private String getIdm(Intent intent) { String idm = null; StringBuffer idmByte = new StringBuffer(); byte[] rawIdm = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID); if (rawIdm != null) { for (int i = 0; i < rawIdm.length; i++) { idmByte.append(Integer.toHexString(rawIdm[i] & 0xff)); } idm = idmByte.toString(); } return idm; } }