如何检测的NFC芯片的类型芯片、类型、NFC

2023-09-06 01:19:39 作者:旧人离梦

有谁知道我可以通过Android NFC API,它NFC芯片被用在我正在读一个标签发现的?理想情况下,我喜欢让芯片型号和制造商两者。

Does anyone know how I can find out via the Android NFC API which NFC chip is used in a tag which I am reading? Ideally I like to get the both the chip model and the manufacturer.

时,现有的某处标记对象?

Is that available somewhere in the Tag object?

有关澄清,我不是指阅读器芯片的手机,但在NFC标签芯片。

For clarification, I don't mean the reader chip in the phone, but the chip in the NFC tag.

推荐答案

我正在开发中的Andr​​oid应用程序的NFC读/写/验证操作。下面是一些code部位,你会喜欢的。

I'm developing an application in Android for NFC read/write/authentication operations. Here are some code parts you would like.

Android已经确定卡的3种主要类型,这些都是MIFARE经典,超轻的Mifare和Isodep(这是MIFARE和DESFire非EV1的类型)。所以,我得到一个标签感动,我运行此操作:

Android has 3 main types determined for cards, those are Mifare Classic, Mifare Ultralight and Isodep (this is the type of Desfire and Desfire EV1). So, as I get a tag touched, I run this operation:

private String[] getTagInfo(Intent intent) {
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    String prefix = "android.nfc.tech.";
    String[] info = new String[2];

    // UID
    byte[] uid = tag.getId();
    info[0] = "UID In Hex: " + Utils.convertByteArrayToHexString(uid) + "\n" +
              "UID In Dec: " + Utils.convertByteArrayToDecimal(uid) + "\n\n";

    // Tech List
    String[] techList = tag.getTechList();
    String techListConcat = "Technologies: ";
    for(int i = 0; i < techList.length; i++) {
        techListConcat += techList[i].substring(prefix.length()) + ",";
    }
    info[0] += techListConcat.substring(0, techListConcat.length() - 1) + "\n\n";

    // Mifare Classic/UltraLight Info
    info[0] += "Card Type: ";
    String type = "Unknown";
    for(int i = 0; i < techList.length; i++) {
        if(techList[i].equals(MifareClassic.class.getName())) {
            info[1] = "Mifare Classic";
            MifareClassic mifareClassicTag = MifareClassic.get(tag);

            // Type Info
            switch (mifareClassicTag.getType()) {
            case MifareClassic.TYPE_CLASSIC:
                type = "Classic";
                break;
            case MifareClassic.TYPE_PLUS:
                type = "Plus";
                break;
            case MifareClassic.TYPE_PRO:
                type = "Pro";
                break;
            }
            info[0] += "Mifare " + type + "\n";

            // Size Info
            info[0] += "Size: " + mifareClassicTag.getSize() + " bytes \n" +
                    "Sector Count: " + mifareClassicTag.getSectorCount() + "\n" +
                    "Block Count: " + mifareClassicTag.getBlockCount() + "\n";
        } else if(techList[i].equals(MifareUltralight.class.getName())) {
            info[1] = "Mifare UltraLight";
            MifareUltralight mifareUlTag = MifareUltralight.get(tag);

            // Type Info
            switch (mifareUlTag.getType()) {
            case MifareUltralight.TYPE_ULTRALIGHT:
                type = "Ultralight";
                break;
            case MifareUltralight.TYPE_ULTRALIGHT_C:
                type = "Ultralight C";
                break;
            }
            info[0] += "Mifare " + type + "\n";
        } else if(techList[i].equals(IsoDep.class.getName())) {
            info[1] = "IsoDep";
            IsoDep isoDepTag = IsoDep.get(tag);
            info[0] += "IsoDep \n";
        } else if(techList[i].equals(Ndef.class.getName())) {
            Ndef ndefTag = Ndef.get(tag);
            info[0] += "Is Writable: " + ndefTag.isWritable() + "\n" +
                    "Can Make ReadOnly: " + ndefTag.canMakeReadOnly() + "\n";
        } else if(techList[i].equals(NdefFormatable.class.getName())) {
            NdefFormatable ndefFormatableTag = NdefFormatable.get(tag);
        }
    } 

    return info;
}

然而,这并不直接得到DESFIRE和DESFIRE EV1的类型。为此,你需要一些字节发送到卡:

However, this doesn't directly get the type of Desfire and Desfire EV1. For that you need to send some bytes to card:

static final byte GET_MANUFACTURING_DATA = (byte) 0x60;

public DesfireManufacturingData getManufacturingData() throws Exception {
    byte[] respBuffer = sendRequest(GET_MANUFACTURING_DATA);
    if (respBuffer.length != 28)
        throw new Exception("Invalid response");
    return new DesfireManufacturingData(respBuffer);
}

private byte[] sendRequest (byte command) throws Exception {
    return sendRequest(command, null);
}

private byte[] sendRequest (byte command, byte[] parameters) throws Exception {
    ByteArrayOutputStream output = new ByteArrayOutputStream();

    byte[] recvBuffer = mTagTech.transceive(Utils.wrapMessage(command, parameters));

    while (true) {
        if (recvBuffer[recvBuffer.length - 2] != (byte) 0x91)
            throw new Exception("Invalid response");

        output.write(recvBuffer, 0, recvBuffer.length - 2);

        byte status = recvBuffer[recvBuffer.length - 1];
        if (status == OPERATION_OK) {
            break;
        } else if (status == ADDITIONAL_FRAME) {
            recvBuffer = mTagTech.transceive(Utils.wrapMessage(GET_ADDITIONAL_FRAME, null));


        } else if (status == PERMISSION_DENIED) {
            throw new Exception("Permission denied");
        }else if (status == LENGTH_ERROR) {
            throw new Exception("Length Error");
        } 
        else if (status == AUTHENTICATION_ERROR) {
            throw new Exception("Authentication error");
        }else if (status == PARAMETER_ERROR) {
            throw new Exception("Parameter Error");
        }else if (status == DUPLICATE_ERROR) {
            throw new Exception("Duplicate Error");
        }else if (status == NO_SUCH_KEY) {
            throw new Exception("No such key");
        }else {
            throw new Exception("Unknown status code: " + Integer.toHexString(status & 0xFF));
        }
    }

    return output.toByteArray();
}

在初始化制造业数据,你可以很容易地到达它的部分。 DesfireManufacturingData类是用于评估从标签到的有意义的反应,但我只给它的链接: DESFIRE制造业数据。另外,我必须说,这是最全能项目中,我找到了一条符合开放源代码的互联网,但它只有读取操作的DESFIRE标签,不会写和验证。希望这有助于!

After you initialize the Manufacturing data, you can easily reach it's parts. DesfireManufacturingData class is for evaluating the response from the tag into meaningful parts, but I'll only give link of it: Desfire Manufacturing Data. Also, I must say this is the most all-around project I have found in the Internet with open source, but it only has reading operations for Desfire tags, not write and authenticate. Hope this helps!