如何检测NFC芯片的类型
有谁知道我可以通过Android NFC API找出哪个NFC芯片用于我正在阅读的标签中?理想情况下,我喜欢获得芯片型号和制造商。如何检测NFC芯片的类型
是否可以在Tag对象的某个地方使用?
为了澄清,我并不是指手机中的读卡器芯片,而是NFC标签中的芯片。
我正在开发一款Android应用程序,用于NFC读/写/验证操作。以下是您需要的一些代码部分。
Android有三种主要卡类型,分别是Mifare Classic,Mifare Ultralight和Isodep(这是Desfire和Desfire EV1的类型)。所以,我得到一个标签感动,我运行这个操作:
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的类型。对于那些你需要一些字节,发送到卡:
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 Manufacturing Data。另外,我必须说这是我在互联网上用开放源代码找到的最全面的项目,但它只有Desfire标记的读取操作,而不是写入和验证。希望这可以帮助!
如果您拥有带NFC的Android设备,则有多种应用可以完成此操作(以及更多),例如NXP TagInfo或NFC TagInfo。
对于配台式阅读器的PC,可能有RFIDIOt。对于其他平台,类似的应用程序可能存在(或可能被创建),但我不熟悉它们。
我知道恩智浦的应用程序。不过,我想在我自己的应用程序中做到这一点。因此,我想知道我会在哪里获得这些信息,以便我可以通过SW获取信息。谢谢 – corvairjo
感谢分享。我会试一试 – corvairjo
干得好相当有帮助。 –