アプリ起動中にTag Intentをとる

2012-06-05   treby   技術メモ  , このエントリーをはてなブックマークに追加

ひとまずアプリ起動時にTag Intentをとる方法が分かったのでメモ。Beamもこの延長線上で実装できるはず。たぶん。

Android NFCアプリハンズオン資料によると、Android端末へのNFC機能実装方法は以下の3通りだという。

  1. 待ち受け時、NFCタグに反応する方法
  2. アプリ起動時、NFCタグに反応する方法
  3. 上記両方

1つ目については資料の中でも説明されているし、過去の記事ですでに書いた。今回は2つ目の実装方法について検討してみよう。いうまでもないが、前回の方法と今回の方法、両方を実装すれば3つ目の方法を実装できる。

前回との相違点

アプリ起動中のみNFCタグに反応させるのであれば、前回行った以下の項目が不要になる。

  • AndroidManifest.xmlにIntent-Filterの記述を追加する
  • android.nfc.tech.*用の新たなxmlファイルを作成する

Activityファイルの修正

アプリ起動時、FeliCaを検出しそのIDmを表示するコードを以下に示す。

package jp.atndk.nfc.handson;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.tech.NfcF;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
	private NfcAdapter mAdapter;
	private PendingIntent mPendingIntent;
	private IntentFilter[] mFilters;
	private String[][] mTechLists;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		mAdapter = NfcAdapter.getDefaultAdapter(this);
		mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
				getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
		IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
		mFilters = new IntentFilter[] { tech, };
		mTechLists = new String[][] { new String[] { NfcF.class.getName() } };
	}

	@Override
	public void onResume() {
		mAdapter.enableForegroundDispatch(
				this, mPendingIntent, mFilters, mTechLists);
		super.onResume();
	}

	@Override
	public void onPause() {
		if (this.isFinishing()) {
			mAdapter.disableForegroundDispatch(this);
		}
		super.onPause();
	}

	@Override
	public void onNewIntent(Intent intent) {
		String action = intent.getAction();
		if (action.equals((NfcAdapter.ACTION_TECH_DISCOVERED))) {
			byte[] rawId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
			String text = bytesToText(rawId);
			TextView nfcIdTextView = (TextView) findViewById(R.id.nfc_id_textview);
			nfcIdTextView.setText(text);
		}
	}

	private String bytesToText(byte[] bytes) {
		StringBuilder buffer = new StringBuilder();
		for (byte b : bytes) {
			String hex = String.format("%02X", b);
			buffer.append(hex).append(" ");
		}

		String text = buffer.toString().trim();
		return text;
	}
}

ポイントはNfcAdapterのenableForegroundDispatchメソッドとonNewIntentだった。これらを適切に使ってやるとアプリ起動中にタグの捕捉ができるようになるようだ。

参考リンク