为什么我只能显示 NFC 标签 (nDEF) 的前 4 页
Why am I only able to show the first 4 pages from an NFC Tag (nDEF)
我正在尝试访问驻留在 NFC 标签上的信息。我只能从标签内存的前 4 页检索数据。
有关我尝试从 TAG 读取的数据,请参见下面的屏幕截图。
我目前在 LogCat 中得到的回复是重复的:
I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000
I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00
I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000
I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00
I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000
I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00
I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000
I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00
public class MainActivity extends AppCompatActivity {
private TextView text;
private NfcAdapter mNfcAdapter;
private IntentFilter[] mFilters;
private String[][] mtechList;
PendingIntent pendingIntent;
static final String DATA = "Data";
private ArrayList<String> readTag;
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
readTag = new ArrayList<>();
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
}
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
mFilters = new IntentFilter[]{ndef};
mtechList = new String[][]{
new String[]{Ndef.class.getName()}
};
Intent i = getIntent();
if (i != null) {
if (i.getAction() == NfcAdapter.ACTION_TECH_DISCOVERED) {
readTheIntent(i);
}
}
}
private void readTheIntent(Intent intent) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
Boolean containsNfcA = Arrays.toString(techList).contains(NfcA.class.getName());
if (containsNfcA) {
ArrayList<Byte> result = readNfcATag(tag);
readTag.clear();
readTag.addAll(reformatByteStringArray(result));
}
for(String s: readTag){
Log.i("OUTPUT FROM TAG", s);
}
}
//40:BD:32:95:22:D8
public static ArrayList<String> reformatByteStringArray(ArrayList<Byte> bytelist){
int tempIndex = 0;
ArrayList<String> formatedList = new ArrayList<>();
if(bytelist != null){
String page = "";
for(int index = 0; index < bytelist.size(); index ++){
byte currentByte = bytelist.get(index);
String formatedString = String.format("%02X", currentByte);
page = page + formatedString;
tempIndex++;
if(tempIndex == 4){
tempIndex = 0;
formatedList.add(page);
page = "";
}
}
}
return formatedList;
}
public static ArrayList<Byte> readNfcATag(Tag tag) {
ArrayList<Byte> value = null;
NfcA nfcATag = NfcA.get(tag);
try {
nfcATag.connect();
if (nfcATag != null) {
int x = 0;
value = new ArrayList<>();
byte[] command = new byte[]{0x30 , (byte) x};
while (nfcATag.transceive(command) != null) {
byte[] payload = nfcATag.transceive(command);
int index = 0;
for (byte b : payload) {
value.add(b);
index++;
}
x += 4;
//TODO change this to check whether the first 8 elements in list are the same as equal to byte sequence
if(x == 16) break;
}
}
} catch (IOException e) {
Log.e(ReadNFCTagUtil.class.getSimpleName(), "09 " + e.getMessage());
e.printStackTrace();
} finally {
if (nfcATag != null) {
try {
nfcATag.close();
} catch (IOException ec) {
}
}
}
return value;
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
readTheIntent(intent);
}
@Override
protected void onPause() {
super.onPause();
mNfcAdapter.disableForegroundDispatch(this);
}
@Override
protected void onResume() {
super.onResume();
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, mFilters, mtechList);
}
}
您使用的是相同的 command
,但没有增加右侧焦点中 x 的值。所以你总是阅读相同的前四页。
尝试以下操作:
if (nfcATag != null) {
int x = 0;
value = new ArrayList<>();
while (x<MAXIMUN_SIZE_OF_NDEF_MESSAGE) {
//chose better condition to break the while, but not in any way your actuall condition.
byte[] command = new byte[]{0x30 , (byte) x};
byte[] payload = nfcATag.transceive(command);
int index = 0;
for (byte b : payload) {
value.add(b);
index++;
}
x += 4;
//TODO change this to check whether the first 8 elements in list are the same as equal to byte sequence
}
}
另外你需要重构整个代码,它是不可靠的。
我正在尝试访问驻留在 NFC 标签上的信息。我只能从标签内存的前 4 页检索数据。
有关我尝试从 TAG 读取的数据,请参见下面的屏幕截图。
我目前在 LogCat 中得到的回复是重复的:
I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00 I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00 I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00 I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00
public class MainActivity extends AppCompatActivity {
private TextView text;
private NfcAdapter mNfcAdapter;
private IntentFilter[] mFilters;
private String[][] mtechList;
PendingIntent pendingIntent;
static final String DATA = "Data";
private ArrayList<String> readTag;
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
readTag = new ArrayList<>();
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
}
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
mFilters = new IntentFilter[]{ndef};
mtechList = new String[][]{
new String[]{Ndef.class.getName()}
};
Intent i = getIntent();
if (i != null) {
if (i.getAction() == NfcAdapter.ACTION_TECH_DISCOVERED) {
readTheIntent(i);
}
}
}
private void readTheIntent(Intent intent) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
Boolean containsNfcA = Arrays.toString(techList).contains(NfcA.class.getName());
if (containsNfcA) {
ArrayList<Byte> result = readNfcATag(tag);
readTag.clear();
readTag.addAll(reformatByteStringArray(result));
}
for(String s: readTag){
Log.i("OUTPUT FROM TAG", s);
}
}
//40:BD:32:95:22:D8
public static ArrayList<String> reformatByteStringArray(ArrayList<Byte> bytelist){
int tempIndex = 0;
ArrayList<String> formatedList = new ArrayList<>();
if(bytelist != null){
String page = "";
for(int index = 0; index < bytelist.size(); index ++){
byte currentByte = bytelist.get(index);
String formatedString = String.format("%02X", currentByte);
page = page + formatedString;
tempIndex++;
if(tempIndex == 4){
tempIndex = 0;
formatedList.add(page);
page = "";
}
}
}
return formatedList;
}
public static ArrayList<Byte> readNfcATag(Tag tag) {
ArrayList<Byte> value = null;
NfcA nfcATag = NfcA.get(tag);
try {
nfcATag.connect();
if (nfcATag != null) {
int x = 0;
value = new ArrayList<>();
byte[] command = new byte[]{0x30 , (byte) x};
while (nfcATag.transceive(command) != null) {
byte[] payload = nfcATag.transceive(command);
int index = 0;
for (byte b : payload) {
value.add(b);
index++;
}
x += 4;
//TODO change this to check whether the first 8 elements in list are the same as equal to byte sequence
if(x == 16) break;
}
}
} catch (IOException e) {
Log.e(ReadNFCTagUtil.class.getSimpleName(), "09 " + e.getMessage());
e.printStackTrace();
} finally {
if (nfcATag != null) {
try {
nfcATag.close();
} catch (IOException ec) {
}
}
}
return value;
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
readTheIntent(intent);
}
@Override
protected void onPause() {
super.onPause();
mNfcAdapter.disableForegroundDispatch(this);
}
@Override
protected void onResume() {
super.onResume();
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, mFilters, mtechList);
}
}
您使用的是相同的 command
,但没有增加右侧焦点中 x 的值。所以你总是阅读相同的前四页。
尝试以下操作:
if (nfcATag != null) {
int x = 0;
value = new ArrayList<>();
while (x<MAXIMUN_SIZE_OF_NDEF_MESSAGE) {
//chose better condition to break the while, but not in any way your actuall condition.
byte[] command = new byte[]{0x30 , (byte) x};
byte[] payload = nfcATag.transceive(command);
int index = 0;
for (byte b : payload) {
value.add(b);
index++;
}
x += 4;
//TODO change this to check whether the first 8 elements in list are the same as equal to byte sequence
}
}
另外你需要重构整个代码,它是不可靠的。