为啥我会得到一个反向的 NFC 标签 ID(十六进制)?
Posted
技术标签:
【中文标题】为啥我会得到一个反向的 NFC 标签 ID(十六进制)?【英文标题】:Why am I getting a reversed NFC Tag ID (Hex)?为什么我会得到一个反向的 NFC 标签 ID(十六进制)? 【发布时间】:2020-06-01 13:59:43 【问题描述】:我希望我的应用程序扫描 NFC 标签并获取其 ID 和标签类型。但不知何故,我的代码读取了一个反向的标签 ID。
例如,我的应用读取以下标签 ID(十六进制):80 65 69 e2 f5 fe 04 而来自 Google Play 商店的其他 4 个类似应用读取以下 ID:4 fe f5 e2 69 65 80(其中第一个零也丢失了)
我希望我的应用在不还原字节的情况下读取标签 ID,我该如何实现?这是我的完整代码:
package com.asetnfc;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.MifareUltralight;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcB;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.os.AsyncTask;
import android.os.Parcelable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import static android.content.ContentValues.TAG;
//public class MainActivity extends AppCompatActivity
public class InfoNFC extends Activity
private TextView mTextView; //ECP 2017-01-16
// list of NFC technologies detected:
private final String[][] techList = new String[][]
new String[]
NfcA.class.getName(),
NfcB.class.getName(),
NfcF.class.getName(),
NfcV.class.getName(),
IsoDep.class.getName(),
MifareClassic.class.getName(),
MifareUltralight.class.getName(), Ndef.class.getName()
;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.infonfc);
mTextView = (TextView) findViewById(R.id.infonfctype);
mTextView.setText("Data Tampil Disini");
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
@Override
protected void onResume()
super.onResume();
Log.d("onResume", "1");
//mTextView.setText("onResume:");
// creating pending intent:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// creating intent receiver for NFC events:
IntentFilter filter = new IntentFilter();
filter.addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
filter.addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filter.addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
// enabling foreground dispatch for getting intent from NFC event:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, new IntentFilter[]filter, this.techList);
@Override
protected void onPause()
super.onPause();
Log.d("onPause", "1");
// disabling foreground dispatch:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.disableForegroundDispatch(this);
@Override
protected void onNewIntent(Intent intent)
Log.d("onNewIntent", "1");
if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED))
Log.d("onNewIntent", "2");
mTextView.setText( "NFC Tag\n" + ByteArrayToHexString(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID)));
//if(getIntent().hasExtra(NfcAdapter.EXTRA_TAG))
Parcelable tagN = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tagN != null)
Log.d(TAG, "Parcelable OK");
NdefMessage[] msgs;
byte[] empty = new byte[0];
byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
byte[] payload = dumpTagData(tagN).getBytes();
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
NdefMessage msg = new NdefMessage(new NdefRecord[] record );
msgs = new NdefMessage[] msg ;
//Log.d(TAG, msgs[0].toString());
else
Log.d(TAG, "Parcelable NULL");
Parcelable[] messages1 = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages1 != null)
Log.d(TAG, "Found " + messages1.length + " NDEF messages");
else
Log.d(TAG, "Not EXTRA_NDEF_MESSAGES");
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndef = Ndef.get(tag);
if(ndef != null)
Log.d("onNewIntent:", "NfcAdapter.EXTRA_TAG");
Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null)
Log.d(TAG, "Found " + messages.length + " NDEF messages");
else
Log.d(TAG, "Write to an unformatted tag not implemented");
//mTextView.setText( "NFC Tag\n" + ByteArrayToHexString(intent.getByteArrayExtra(NfcAdapter.EXTRA_TAG)));
private String dumpTagData(Parcelable p)
StringBuilder sb = new StringBuilder();
Tag tag = (Tag) p;
byte[] id = tag.getId();
sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
sb.append("Tag ID (dec): ").append(getDec(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');
MifareClassic mifareTag = MifareClassic.get(tag);
String type = "Unknown";
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());
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);
Log.d("Datos: ", sb.toString());
mTextView.setText('\n' + sb.toString());
return sb.toString();
private String getHex(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 long getDec(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 String ByteArrayToHexString(byte [] inarray)
Log.d("ByteArrayToHexString", inarray.toString());
int i, j, in;
String [] hex = "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F";
String out= "";
for(j = 0 ; j < inarray.length ; ++j)
in = (int) inarray[j] & 0xff;
i = (in >> 4) & 0x0f;
out += hex[i];
i = in & 0x0f;
out += hex[i];
//CE7AEED4
//EE7BEED4
Log.d("ByteArrayToHexString", String.format("%0" + (inarray.length * 2) + "X", new BigInteger(1,inarray)));
return out;
【问题讨论】:
【参考方案1】:在您的函数getHex()
中,您从最后一个字节开始,然后递减i
计数器。
尝试使用此功能:
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHexString(byte[] bytes)
if (bytes == null)
return null;
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++)
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
return new String(hexChars);
【讨论】:
你能给我完整的代码吗?我在“hexArray”中收到错误 对不起,这是我的错误,给你:private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
我使用Eclipse开发NFC应用,可能有一些差异,但它仍然可以工作。谢谢。
可以使用 StringBuilder 在 "for" 循环中附加一个 String.format("%02X ", bytes[i]) 作为将十六进制转换为字符串的更简单方法以上是关于为啥我会得到一个反向的 NFC 标签 ID(十六进制)?的主要内容,如果未能解决你的问题,请参考以下文章
为啥十六进制的 5D 表示为 bytearray(b']')?