高度な NFC の概要

このドキュメントでは、さまざまなタグ技術の使用、 NFC タグへの書き込み、フォアグラウンド ディスパッチ(フォアグラウンドのアプリが 他のアプリが同じインテントをフィルタしている場合でも、インテントを処理できます。

サポートされているタグ テクノロジーを利用する

NFC タグや Android 搭載デバイスを使用する場合、読み取りに使用する主な形式は、 タグへの書き込みデータは NDEF です。デバイスが NDEF データが含まれるタグをスキャンすると、Android は以下をサポートします。 メッセージの解析と NdefMessage での配信に 考えていますただし、一部の URL が含まれていないタグをスキャンし、 NDEF データの場合、または NDEF データを MIME タイプまたは URI にマッピングできなかった場合。 そのような場合は、タグと直接通信し、 独自のプロトコル(生のバイト単位)でエンコードされます。Android は、 android.nfc.tech パッケージ(表 1 を参照)Google Chat では getTechList() メソッドを使用して、テクノロジーを判別する 対応する TagTechnology を作成します。 android.nfc.tech で提供されるクラスのいずれかを持つオブジェクト

表 1. サポートされているタグ テクノロジー

クラス 説明
TagTechnology すべてのタグ テクノロジー クラスで実装する必要があるインターフェースです。
NfcA NFC-A(ISO 14443-3A)プロパティと I/O オペレーションへのアクセスを提供します。
NfcB NFC-B(ISO 14443-3B)プロパティと I/O オペレーションへのアクセスを提供します。
NfcF NFC-F(JIS 6319-4)プロパティと I/O オペレーションへのアクセスを提供します。
NfcV NFC-V(ISO 15693)プロパティと I/O オペレーションへのアクセスを提供します。
IsoDep ISO-DEP(ISO 14443-4)プロパティと I/O オペレーションへのアクセスを提供します。
Ndef 次のようにフォーマットされた NFC タグの NDEF データとオペレーションへのアクセスを提供します。 NDEF。
NdefFormatable NDEF にフォーマット可能なタグに対するフォーマット オペレーションを提供します。

以下のタグ技術は、Android 搭載デバイスでサポートされている必要はありません。

表 2. サポートされているタグ テクノロジー(オプション)

クラス 説明
MifareClassic この Android デバイスの場合、MIFARE Classic プロパティと I/O オペレーションへのアクセス権を付与します MIFARE をサポートしています
MifareUltralight この Android の場合、MIFARE Ultralight プロパティと I/O オペレーションへのアクセスを提供します。 MIFARE をサポートしている。

タグ テクノロジーと ACTION_TECH_DISCOVERED インテントを利用する

デバイスが NDEF データが含まれているタグをスキャンしたものの、MIME または URI にマッピングできなかった場合、 タグ ディスパッチ システムが ACTION_TECH_DISCOVERED でアクティビティの開始を試みます。 使用します。ACTION_TECH_DISCOVERED は、タグが スキャンされます。この代替を使用すると、タグ上のデータを操作できるようになります。 直接渡されます。基本的な手順としては、 3 つあります

  1. ACTION_TECH_DISCOVERED インテントをフィルタして、 使用するタグ技術を選択しますNFC のフィルタリングをご覧ください。 インテントをご覧ください。一般に、タグ ディスパッチ システムは、NDEF メッセージを受け取ったときに ACTION_TECH_DISCOVERED インテントを開始しようとします。 MIME タイプまたは URI にマッピングできない、またはスキャンされたタグに NDEF データが含まれていない場合。対象 この決定方法の詳細については、タグ ディスパッチ システムをご覧ください。
  2. アプリがインテントを受け取ったら、Tag オブジェクトを取得します。 使用します。

    Kotlin

    var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
    

    Java

    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    
  3. 次のいずれかを呼び出して、TagTechnology のインスタンスを取得します。 android.nfc.tech パッケージ内のクラスの get ファクトリ メソッド。Google Chat では get ファクトリ メソッドを呼び出す前に getTechList() を呼び出して、タグでサポートされている技術を列挙するたとえば、インスタンスを取得するには、 MifareUltralightTag から作成する場合は、次の操作を行います。

    Kotlin

    MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
    

    Java

    MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
    

タグを読み書きする

NFC タグの読み取りと書き込みでは、インテントからタグを取得し、 タグとの通信を開始しますデータを読み書きするには、独自のプロトコル スタックを定義する必要がある 追加します。ただし、作業中は NDEF データの読み取りと書き込みを行うことは可能です。 直接渡されます。どのように構築するかはユーザー次第です。「 次の例は、MIFARE Ultralight タグの操作方法を示しています。

Kotlin

package com.example.android.nfc
import android.nfc.Tag
import android.nfc.tech.MifareUltralight
import java.io.IOException
import java.nio.charset.Charset

class MifareUltralightTagTester {

    fun writeTag(tag: Tag, tagText: String) {
        MifareUltralight.get(tag)?.use { ultralight ->
            ultralight.connect()
            Charset.forName("US-ASCII").also { usAscii ->
                ultralight.writePage(4, "abcd".toByteArray(usAscii))
                ultralight.writePage(5, "efgh".toByteArray(usAscii))
                ultralight.writePage(6, "ijkl".toByteArray(usAscii))
                ultralight.writePage(7, "mnop".toByteArray(usAscii))
            }
        }
    }

    fun readTag(tag: Tag): String? {
        return MifareUltralight.get(tag)?.use { mifare ->
            mifare.connect()
            val payload = mifare.readPages(4)
            String(payload, Charset.forName("US-ASCII"))
        }
    }
}

Java

package com.example.android.nfc;

import android.nfc.Tag;
import android.nfc.tech.MifareUltralight;
import android.util.Log;
import java.io.IOException;
import java.nio.charset.Charset;

public class MifareUltralightTagTester {

    private static final String TAG = MifareUltralightTagTester.class.getSimpleName();

    public void writeTag(Tag tag, String tagText) {
        MifareUltralight ultralight = MifareUltralight.get(tag);
        try {
            ultralight.connect();
            ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
        } catch (IOException e) {
            Log.e(TAG, "IOException while writing MifareUltralight...", e);
        } finally {
            try {
                ultralight.close();
            } catch (IOException e) {
                Log.e(TAG, "IOException while closing MifareUltralight...", e);
            }
        }
    }

    public String readTag(Tag tag) {
        MifareUltralight mifare = MifareUltralight.get(tag);
        try {
            mifare.connect();
            byte[] payload = mifare.readPages(4);
            return new String(payload, Charset.forName("US-ASCII"));
        } catch (IOException e) {
            Log.e(TAG, "IOException while reading MifareUltralight message...", e);
        } finally {
            if (mifare != null) {
               try {
                   mifare.close();
               }
               catch (IOException e) {
                   Log.e(TAG, "Error closing tag...", e);
               }
            }
        }
        return null;
    }
}

フォアグラウンド ディスパッチ システムを使用する

フォアグラウンド ディスパッチ システムにより、アクティビティはインテントとクレームをインターセプトできる 同じインテントを処理する他のアクティビティよりも優先されます。このシステムを使用するには、 データ構造をいくつか作成して、Android システムが 追加できます。フォアグラウンド ディスパッチ システムを有効にするには:

  1. アクティビティの onCreate() メソッドに次のコードを追加します。 <ph type="x-smartling-placeholder">
      </ph>
    1. Android システムが入力できるように、可変の PendingIntent オブジェクトを作成する タグの詳細が表示されます。

      Kotlin

      val intent = Intent(this, javaClass).apply {
          addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
      }
      var pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent,
              PendingIntent.FLAG_MUTABLE)
      

      Java

      PendingIntent pendingIntent = PendingIntent.getActivity(
          this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
          PendingIntent.FLAG_MUTABLE);
      
    2. インターセプトするインテントを処理するインテント フィルタを宣言します。前景 ディスパッチ システムは、受け取ったインテントを使用して、指定されたインテント フィルタをチェックします。 デバイスがタグをスキャンします一致した場合、アプリはそのインテントを処理します。発生した場合 一致しない場合、フォアグラウンド ディスパッチ システムはインテント ディスパッチ システムにフォールバックします。 インテント フィルタとテクノロジー フィルタの null 配列を指定すると、 TAG_DISCOVERED にフォールバックするすべてのタグを表示するフィルタ 使用します。以下のコード スニペットは、NDEF_DISCOVERED の MIME タイプをすべて処理します。マイページ 必要な処理のみを処理すべきです

      Kotlin

      val ndef = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply {
          try {
              addDataType("*/*")    /* Handles all MIME based dispatches.
                                       You should specify only the ones that you need. */
          } catch (e: IntentFilter.MalformedMimeTypeException) {
              throw RuntimeException("fail", e)
          }
      }
      
      intentFiltersArray = arrayOf(ndef)
      

      Java

      IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
          try {
              ndef.addDataType("*/*");    /* Handles all MIME based dispatches.
                                             You should specify only the ones that you need. */
          }
          catch (MalformedMimeTypeException e) {
              throw new RuntimeException("fail", e);
          }
         intentFiltersArray = new IntentFilter[] {ndef, };
      
    3. アプリケーションで処理するタグ テクノロジーの配列を設定します。呼び出し Object.class.getName() メソッドを使用して、目的のテクノロジーのクラスを取得します。 提供します

      Kotlin

      techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
      

      Java

      techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
      
  2. 次のアクティビティのライフサイクル コールバックをオーバーライドし、 アクティビティが失われたときのフォアグラウンド ディスパッチ(onPause()) (onResume())フォーカスを取り戻します。enableForegroundDispatch() は、 アクティビティがフォアグラウンドにある場合にのみ、メインスレッドで実行します(onResume() を呼び出すとこれが保証されます)。また、スキャンされた NFC からのデータを処理するために onNewIntent コールバックを実装する必要もあります。 できます。
  3. Kotlin

    public override fun onPause() {
        super.onPause()
        adapter.disableForegroundDispatch(this)
    }
    
    public override fun onResume() {
        super.onResume()
        adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)
    }
    
    public override fun onNewIntent(intent: Intent) {
        val tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
        // do something with tagFromIntent
    }
    

    Java

    public void onPause() {
        super.onPause();
        adapter.disableForegroundDispatch(this);
    }
    
    public void onResume() {
        super.onResume();
        adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
    }
    
    public void onNewIntent(Intent intent) {
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        // do something with tagFromIntent
    }