I'm working on an application about NFC writing. Lets call it Writer... I am writing data to a NfcV tag.
The string I am trying to write is String test = "this is\ta real\ttestcase\tyou tag";
To write data I'm using NfcV's transceive
method.
So this is my writer-method:
public static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
Formatter formatter = new Formatter(sb);
for (byte b : bytes) {
formatter.format("%02X", b);
}
formatter.close();
return sb.toString();
}
public void write(View v) {
try {
String[] tagInfoArray = new String[tagData.size()];
for (int i = 0; i < tagData.size(); i++)
tagInfoArray[i] = tagData.get(i).getText().toString();
String tagInfo = join(tagInfoArray, "\t");
//String test = "this is\ta real\ttestcase\tyou tag";
writeTag(tag, tagInfo);
} catch (NullPointerException e) {
Toast.makeText(this, "How about providing a tag!",
Toast.LENGTH_LONG).show();
} finally {
write.setBackgroundResource(R.layout.bluebutton);
}
}
public String join(String[] input, String delim) {
String output = "";
if (input.length > 0)
output += input[0];
if (input.length > 1)
for (int i = 1; i < input.length; i++)
output += delim + input[i];
return output;
}
public void exitButton(View v) {
this.foreground.disableForeground();
System.exit(0);
}
public void writeTag(Tag tag, String data) {
NfcV myTag = NfcV.get(tag);
try {
myTag.connect();
if (myTag.isConnected()) {
byte[] info = data.getBytes();
int dataLength = info.length;
if (data.length()/4 <= 64){
byte[] args = new byte[15];
args[0] = 0x20;
args[1] = 0x21;
byte[] id = tag.getId();
for (int o=0; o<8; o++)
args[o+2] = id[o];
for (int i = 0; i<64; i++) {
args[10] = (byte) i;
args[11] = 0x00;
args[12] = 0x00;
args[13] = 0x00;
args[14] = 0x00;
byte[] out = myTag.transceive(args);
String out2 = bytesToHex(out);
System.out.println("1:.. " + printHex(out2));
}
for (int i = 0; i<=dataLength/4; i++) {
args[10] = (byte) i;
args[11] = getByte(info, (i*4)+0);
args[12] = getByte(info, (i*4)+1);
args[13] = getByte(info, (i*4)+2);
args[14] = getByte(info, (i*4)+3);
byte[] out = myTag.transceive(args);
String out2 = bytesToHex(out);
System.out.println("2:.. " + printHex(out2));
}
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
if (myTag != null) {
try {
myTag.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
public static byte getByte(byte[] input, int key){
try {
return input[key];
} catch (Exception e){
return (byte)0x00;
}
}
public String printByte(byte[] input){
try {
return new String(input, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
public String printHex(String input){
return input;
}
So when im writing stuff the outcome is not what I am expecting it to be. It's either not writing at all, or just writing parts, while not overwriting, what has been on the tag before.
This is the output:
11-05 15:32:33.139: I/System.out(1390): 1:.. 00
11-05 15:32:33.249: I/System.out(1390): 1:.. 00
11-05 15:32:33.349: I/System.out(1390): 1:.. 00
11-05 15:32:33.449: I/System.out(1390): 1:.. 00
11-05 15:32:33.549: I/System.out(1390): 1:.. 00
11-05 15:32:33.649: I/System.out(1390): 1:.. 00
11-05 15:32:33.759: I/System.out(1390): 1:.. 00
11-05 15:32:33.859: I/System.out(1390): 1:.. 00
11-05 15:32:33.959: I/System.out(1390): 1:.. 00
11-05 15:32:34.059: I/System.out(1390): 1:.. 00
11-05 15:32:34.159: I/System.out(1390): 1:.. 00
11-05 15:32:34.259: I/System.out(1390): 1:.. 00
11-05 15:32:34.359: I/System.out(1390): 1:.. 00
11-05 15:32:34.469: I/System.out(1390): 1:.. 00
11-05 15:32:34.569: I/System.out(1390): 1:.. 00
11-05 15:32:34.669: I/System.out(1390): 1:.. 00
11-05 15:32:34.769: I/System.out(1390): 1:.. 00
11-05 15:32:34.869: I/System.out(1390): 1:.. 00
11-05 15:32:34.979: I/System.out(1390): 1:.. 00
11-05 15:32:35.079: I/System.out(1390): 1:.. 00
11-05 15:32:35.179: I/System.out(1390): 1:.. 00
11-05 15:32:35.289: I/System.out(1390): 1:.. 00
11-05 15:32:35.389: I/System.out(1390): 1:.. 00
11-05 15:32:35.489: I/System.out(1390): 1:.. 00
11-05 15:32:35.589: I/System.out(1390): 1:.. 00
11-05 15:32:35.689: I/System.out(1390): 1:.. 00
11-05 15:32:35.789: I/System.out(1390): 1:.. 00
11-05 15:32:35.889: I/System.out(1390): 1:.. 00
11-05 15:32:35.989: I/System.out(1390): Transceive failed
To summarize the various issues in the initial post:
NfcV.getMaxTransceiveLength()
returns information about the maximum number of bytes that can be exchanged in one command/one response. It does not provide information about the tag size!.Tag.getId()
to get the ID and parse it according to the tag manufacturers' data sheets). Another approach is to read until the first IOException and infer the tag size from that information. You can later reconnect the tag to continue reading/writing. However, keep in mind that any other interruptions in communication (e.g. the user not properly scanning the tag) may also lead to IOExceptions and may consequently falsify your estimated tag size.