[英]In android studio, how to prevent errors with buffered reader reading from a url, when the phone has no internet
[英]Why when reading NFCtag with Android phone you get different tag ID then when reading with dedicated reader?
我使用的是 Android Cilico F750,专用 RFID 阅读器是 CF-RS103。 RFID 标签类型为 MIFARE Ultralight type C。
用专用读卡器读取时,标签id为:2054270212(10位)。
但是当用 Android 手机读取时,id 是:36139312876727556(17digit),反向 id 是:1316602805183616(16digit)。
有谁知道为什么会发生这种情况,以及是否可以将 10digit id 转换为 17digit id,反之亦然。
我使用意图来检测标签并解决我使用的意图:
public void resolveIntent(Intent intent){
String action = intent.getAction();
if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
||NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
||NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))
{
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs;
if(rawMsgs!=null)
{
msgs= new NdefMessage[rawMsgs.length];
for(int i=0; i<rawMsgs.length; i++)
{
msgs[i]=(NdefMessage) rawMsgs[i];
}
}
else
{
byte[] empty = new byte[0];
byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] payload = dumpTagData(tag).getBytes();
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN,empty,id,payload);
NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
msgs= new NdefMessage[] {msg};
}
displayMsgs(msgs);
}}
这是我的辅助功能:
private void displayMsgs(NdefMessage[] msgs)
{
if(msgs==null || msgs.length==0) {
return;
}
StringBuilder builder = new StringBuilder();
List<ParsedNdefRecord> records= NdefMessageParser.parse(msgs[0]);
final int size = records.size();
for(int i=0;i<size;i++)
{
ParsedNdefRecord record = records.get(i);
String str = record.str();
builder.append(str).append("\n");
}
text.setText(builder.toString());
}
private String dumpTagData(Tag tag) {
StringBuilder sb = new StringBuilder();
byte[] id = tag.getId();
sb.append("ID (hex): ").append(toHex(id)).append('\n');
sb.append("ID (reversed hex):").append(toReversedHex(id)).append('\n');
sb.append("ID (dec): ").append(toDec(id)).append('\n');
sb.append("ID (reversed dec):").append(toReversedDec(id)).append('\n');
String prefix = "android.nfc.tech.";
sb.append("Technologies: ");
for (String tech: tag.getTechList()) {
sb.append(tech.substring(prefix.length()));
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
for (String tech: tag.getTechList()) {
if (tech.equals(MifareClassic.class.getName())) {
sb.append('\n');
String type = "Unknown";
try {
MifareClassic mifareTag = MifareClassic.get(tag);
switch (mifareTag.getType()) {
case MifareClassic.TYPE_CLASSIC:
type = "Classic";
break;
case MifareClassic.TYPE_PLUS:
type = "Plus";
break;
case MifareClassic.TYPE_PRO:
type = "Pro";
break;
}
sb.append("Mifare Classic type: ");
sb.append(type);
sb.append('\n');
sb.append("Mifare size: ");
sb.append(mifareTag.getSize() + " bytes");
sb.append('\n');
sb.append("Mifare sectors: ");
sb.append(mifareTag.getSectorCount());
sb.append('\n');
sb.append("Mifare blocks: ");
sb.append(mifareTag.getBlockCount());
} catch (Exception e) {
sb.append("Mifare classic error: " + e.getMessage());
}
}
if (tech.equals(MifareUltralight.class.getName())) {
sb.append('\n');
MifareUltralight mifareUlTag = MifareUltralight.get(tag);
String type = "Unknown";
switch (mifareUlTag.getType()) {
case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight";
break;
case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C";
break;
}
sb.append("Mifare Ultralight type: ");
sb.append(type);
}
}
return sb.toString();
}
private String toHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = bytes.length - 1; i >= 0; --i) {
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
if (i > 0) {
sb.append(" ");
}
}
return sb.toString();
}
private String toReversedHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; ++i) {
if (i > 0) {
sb.append(" ");
}
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
}
return sb.toString();
}
private long toDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = 0; i < bytes.length; ++i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
private long toReversedDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = bytes.length - 1; i >= 0; --i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}`
编辑:我设法通过将 7 字节的十六进制 ID 截断为 4 字节来解决这个问题。 然后如果总长度小于 10 位,则使用此语句格式化十进制 ID,如果 DEC ID 小于 10 位,则基本上从左侧添加零:
String strFinal=String.format("%010d", Long.parseLong(str));
这份描述如何将 ID 从 HEX8 转换为 DEC10 的文档也对我有很大帮助: https ://www.batag.com/download/rfidreader/LF/RAD-A200-R00-125kHz.8H10D.EM.V1.1 。 pdf
非常感谢@Andrew 和@Karam 帮助我解决了这个问题!
我不知道你为什么总是试图转换为十进制? 请尝试解释更多有关您用于读取 UID 的代码的信息。
关于您的数字并将 17 位数字转换为 10 位数字; 我将它们都转换为十六进制:
36139312876727556(17 位)十六进制:8064837A71AD04。
2054270212(10 位)十六进制:7A71AD04
正如您所注意到的,您只需 tim 前三个字节即可获得 10 位数字。
我相信他们两个都不是 UID。 但是安德鲁所说的 7 字节,你已经在你的照片中读到了:(04:B5:71:7A:83:64:80)
所以我认为答案是,因为您将 7 字节 ID 转换为十进制,所以由于转换为十进制,您将获得可变长度的数字。
“字节数据类型是一个 8 位有符号二进制补码整数。它的最小值为 -128,最大值为 127(含)。”
来自https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
可以生成具有 1,2 或 3 个字符的十进制数,因此作为十进制,id 的长度可以不同。
看起来转换也出错了,因为理论上它也应该有负数。
如果您希望它是人类可读的,最好将其作为十六进制字符串处理。
Java中将ID的2页转换为十六进制的正确方法是
StringBuilder Uid;
for (int i = 0; i < result.length; i++) {
// byte 4 is a check byte
if (i == 3) continue;
Uid.append(String.format("%02X ", result[i]));
}
请注意卡的规格表https://www.nxp.com/docs/en/data-sheet/MF0ICU2_SDS.pdf (第 7.3.1 节)
校验字节是 ID 的一部分,而这在同一张卡上总是相同的,并且仍然会给你一个唯一的 ID,它在技术上不是 ID 的一部分。
或者如果不是在低水平阅读,那么
https://developer.android.com/reference/android/nfc/Tag#getId()
会给你身份证。
请注意,“36139312876727556(17digit) and reversed id”在转换为十六进制和反向实际时为 7 个字节,并以正确的数字开头。
10 位数字看起来就像 7 字节数字的前 4 个字节也颠倒了。
PC上的读卡器配置错误,当卡有7字节ID时,默认将ID显示为10位十进制数(4字节)。
因此它必须丢失一些数据,它是通过将 ID 截断为 7 字节 ID 的前4
个字节来实现的
使用 PC 上的软件将输出格式更改为适合 Mifare Ultralight C 卡(8 Hex?)上的 ID 大小的格式。
或者
改用 Mifare Classic 卡,因为这些卡有 4 字节 ID
或者
将代码中的 7 字节 ID 截断为 4 字节,例如将bytes.length
更改为4
(对 7 字节 ID 中的前 4 个字节进行硬编码),并处理存在大量(约 1670 万) Mifare Ultralight C 卡看起来与您想要显示的“ID”相同
这是因为亚马逊卖家提供的规范https://www.amazon.co.uk/Chafon-CF-RS103-Multiple-Support-Compatible-Black/dp/B017VXVZ66 (我在制造商的网站上找不到任何详细信息)
上面写着“默认输出10位十进制,通过软件控制输出格式。”
“支持windows、linux和android系统,但只能在windows pcs中设置输出格式。无需编程和软件,即插即用。”
唯一明智的答案是移动一切以使用 7 字节 ID。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.