如何检测NFC芯片的类型 [英] How to detect the type of an NFC chip

查看:18
本文介绍了如何检测NFC芯片的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道我如何通过 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.

在 Tag 对象的某处可用吗?

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.

推荐答案

我正在 Android 中开发一个用于 NFC 读/写/身份验证操作的应用程序.以下是您想要的一些代码部分.

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

Android 为卡确定了 3 种主要类型,即 Mifare Classic、Mifare Ultralight 和 Isodep(这是 Desfire 和 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) + "
" +
              "UID In Dec: " + Utils.convertByteArrayToDecimal(uid) + "

";

    // 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) + "

";

    // 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 + "
";

            // Size Info
            info[0] += "Size: " + mifareClassicTag.getSize() + " bytes 
" +
                    "Sector Count: " + mifareClassicTag.getSectorCount() + "
" +
                    "Block Count: " + mifareClassicTag.getBlockCount() + "
";
        } 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 + "
";
        } else if(techList[i].equals(IsoDep.class.getName())) {
            info[1] = "IsoDep";
            IsoDep isoDepTag = IsoDep.get(tag);
            info[0] += "IsoDep 
";
        } else if(techList[i].equals(Ndef.class.getName())) {
            Ndef ndefTag = Ndef.get(tag);
            info[0] += "Is Writable: " + ndefTag.isWritable() + "
" +
                    "Can Make ReadOnly: " + ndefTag.canMakeReadOnly() + "
";
        } 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 its 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!

这篇关于如何检测NFC芯片的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆