How to detect the type of an NFC chip(如何检测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芯片的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何检测NFC芯片的类型
基础教程推荐
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01