我们用IsoDep.transceive(byte []数据)发送什么类型的字节?

时间:2014-01-13 17:23:09

标签: java android nfc

我正在编写一个Android应用程序,用ISO-DEP协议读取非接触式卡(通过我的计算机在卡模拟模式下的SpringCard)。

当我使用IsoDep.transceive(byte []数据)方法时,我总是得到一个IOException,但我的非接触式卡很好地接收了我的字节并发送了一个响应(我在我的卡仿真程序日志中看到它)。

问题是我是否必须为收发器方法发送特定的格式数据字节(例如APDU)?

package com.example.nfccardreader;

import java.io.IOException;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {

    private NfcAdapter mAdapter;
    private PendingIntent mPendingIntent;

    private final byte[] DATA = { 
            (byte) 0xFF,
            (byte) 0xFA
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        resolveIntent(getIntent());
        mAdapter= NfcAdapter.getDefaultAdapter(this);
        mPendingIntent= PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    }

     @Override
     protected void onResume() {
         super.onResume();
         mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
     }

     @Override
     protected void onPause() {
         super.onPause();
         if (mAdapter != null) {
             mAdapter.disableForegroundDispatch(this);
         }
     }

     private void resolveIntent(Intent intent) {
         String action= intent.getAction();

        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)){
             Tag tag= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
             communication(tag);
        } else {
             //log error
        }
     }

     private void communication(Tag tag) {
         byte[] received= null;
         IsoDep card= IsoDep.get(tag);
         try {
             card.connect();
             received= card.transceive(DATA);
         } catch (IOException e) {
             //log error
         } finally {
             try {
                 card.close();
             } catch (IOException e) {
                 //log error
             }
         }
     }

     @Override
     public void onNewIntent(Intent intent) {
         setIntent(intent);
         resolveIntent(intent);
     }

}

2 个答案:

答案 0 :(得分:1)

使用IsoDep.transceive()发送(和接收)的字节数组的格式没有限制。

由于您的代码是模拟代码,因此响应可能会慢一些。您可以尝试使用setTimeout()来增加超时。

答案 1 :(得分:-1)

是的,您必须在transceive()方法中发送APDU,但这取决于您模拟的卡的类型。 尝试用

替换DATA
    public static byte[] GET_RANDOM = { 
        (byte) 0x00, // CLA Class        
        (byte) 0x84, // INS Instruction
        (byte) 0x00, // P1  Parameter 1
        (byte) 0x00, // P2  Parameter 2
        (byte) 0x08  // LE  maximal number of bytes expected in result
    };

如果模拟卡符合ISO 14443,则会返回随机数据。仿真卡通常响应缓慢。您可以尝试使用像NFC TagInfo这样的Android应用程序来阅读它,以检查它是否运行良好。