web-dev-qa-db-ja.com

NFCタグ(IsoDep)からデータを読み取る

私はAndroid [〜#〜] nfc [〜#〜] APIの初心者です。

現在、NFCタグがあり、そこからデータを読み取るためのAndroidアプリを作成しています。スマートフォンが十分に近づくと、シンプルなアプリが起動します。 NFCタグ。しかし、NFCタグ内のデータを読み取る方法がわかりません。タグはIsoDepテクノロジーを使用しています。

私の現在のコード:

@Override
protected void onResume (){
    super.onResume();

    Intent intent = getIntent();
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    IsoDep isoDep = IsoDep.get(tag);

    // How to read data from IsoDep instance?

インターネットでグーグルで検索したところ、人々がIsoDepにコマンドを送信して、NFCタグから応答を取得していることに気付きました。応答から、タグ内のデータを解析できると思います。人々がこれをしているのを見ました:

 //What is the 'command' ? How to define the command?
 //e.g.:
 byte command = (byte) 0x6A
 isoDep.transceive(command)

しかし、コマンドは単なるbyteであり、初心者として、何が起こっているのかを理解するのは非常に困難です。データを読み取るコマンドを定義する方法がわかりませんか?誰でも私に説明できますか?または、コマンドについて学ぶことができるドキュメントはありますか?

一般に、コマンドを定義する方法と応答からデータを解析する方法についてのガイダンスが必要です。タグに保存されているデータを読み取り、UI要素(例:TextView)に文字列形式でデータを表示したいと思います。

* AND ***

これらの構成(AnroidManifest.xmlなど)に問題はありません。構成方法についてはガイドしないでください:)

15
Mellon

IsoDepを使用すると、ISO-14443-4接続を介してtransceive操作で通信できます。このプロトコルを介して、アプリケーションデータユニット(APDU)が交換されます。形式が指定されています。説明は Wikipedia。 にあります。

たとえば、特定のアプリケーション識別子(AID)を持つスマートカード上のアプリケーションを選択するには、次のAPDUコマンドを実行します。結果は、単にok(9000)またはエラーを示しています。

    byte[] SELECT = { 
        (byte) 0x00, // CLA Class           
        (byte) 0xA4, // INS Instruction     
        (byte) 0x04, // P1  Parameter 1
        (byte) 0x00, // P2  Parameter 2
        (byte) 0x0A, // Length
        0x63,0x64,0x63,0x00,0x00,0x00,0x00,0x32,0x32,0x31 // AID
    };

    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    IsoDep tag = IsoDep.get(tagFromIntent);

    tag.connect();
    byte[] result = tag.transceive(SELECT);
    if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00))
        throw new IOException("could not select applet");

アプリケーションを選択した後、アプリケーション固有のコマンドを実行できます。プログラムは通常、GlobalPlatorm仕様に準拠したJavaCardで記述されています。次の例は、上記で選択したアプリケーションで、最大11バイトのバイト配列を返すメソッド4(0x04)を実行します。次に、この結果は文字列に変換されます。

    byte[] GET_STRING = { 
        (byte) 0x80, // CLA Class        
        0x04, // INS Instruction
        0x00, // P1  Parameter 1
        0x00, // P2  Parameter 2
        0x10  // LE  maximal number of bytes expected in result
    };

    result = tag.transceive(GET_STRING);
    int len = result.length;
    if (!(result[len-2]==(byte)0x90&&result[len-1]==(byte) 0x00))
       throw new RuntimeException("could not retrieve msisdn");

    byte[] data = new byte[len-2];
    System.arraycopy(result, 0, data, 0, len-2);
    String str = new String(data).trim();

    tag.close();
17
Dominik