アクティビティが起動中のときだけ NFC に反応させる(Foreground Dispatch)
最近、 NFC タグで遊んでます。
でもなかなか、アプリのネタが思いつかないものです。
さて、今回は Android アプリで NFC アプリを開発する際のポイントのひとつについて書きます。
今だけ反応して欲しいんだけど…
たとえば、 NFC タグにデータ書き込みを行うアクティビティを作成していたとします。
NFC タグに反応するように、通常は以下のようにインテントフィルターをマニフェストファイルに書くと思います。
<activity android:name="NFC にデータを書き込むアクティビティ" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.nfc.action.TAG_DISCOVERED" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
しかし、上記の形式では
- アプリを起動していなくても、 NFC タグをかざすと常に書き込もうとする
ことになります。
でも、 NFC を使う場合って、書き込むよりは読み込む場面の方が多いですよね。
なので、
ということが求められます。
Foreground Dispatch
この要求を満たすために用意されている仕組みが、 Foreground Dispatch です。
マニフェストファイルにインテントフィルターを指定してしまうと、上記のように常に NFC に対してアクティビティが反応してしまいます。
そのため、コード内で動的にインテントフィルターを指定する必要があります。この場合、マニフェストファイルには NFC に関するインテントフィルターは記述しません。
アクティビティ内のコード例(抜粋)は以下となります。
private NfcAdapter mNfcAdapter; private PendingIntent mPendingIntent; private IntentFilter[] mIntentFilters; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 〜省略(レイアウトの指定など)〜 /* * Foreground Dispatch の設定 * このアプリが優先して Intent を受け取れるようにする * 実際の設定・解除は onResume と onPause で実行 */ mNfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext()); Intent intent = new Intent(getApplicationContext(), getClass()); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); mPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0); IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); mIntentFilters = new IntentFilter[]{intentFilter}; } @Override protected void onResume() { super.onResume(); // Resumed に移る前に、 Foreground Dispatch を有効にしておく mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, null); } @Override protected void onPause() { super.onPause(); // Paused に移る前に、 Foreground Dispatch を解除しておく mNfcAdapter.disableForegroundDispatch(this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); 〜 省略(NFC タグ発見時の読み込み or 書き込み処理) 〜 }
このように Foreground Dispatch を設定しておくことで、アクティビティが表示されている場合だけ NFC タグに対する処理を行うことができます。
それ以外の場合に NFC タグを近づけても、別の NFC 対応アプリが反応するようになります。