1
votes

I've made an app from examples, for writing NFC codes on Android. My tags are NXP NTAG216.

But I have a problem: After writing tags with my app, NXP's TagWriter app shows the data as "unknown content" like this:

However, when I write the value as "Plain Text" using NXP TagWriter, I get:

Here is my code for onNewIntent:

@Override
protected void onNewIntent(Intent intent) {
    // Tag writing mode
    String zawartosc = "Data from field";
    if (mWriteMode && NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
        Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        NdefRecord record = NdefRecord.createMime(zawartosc, zawartosc.getBytes(Charset.forName("UTF-8")));
        NdefMessage message = new NdefMessage(new NdefRecord[]{record});

        if (writeTag(message, detectedTag)) {
            Toast.makeText(this, "Success", Toast.LENGTH_LONG)
                    .show();
        }
    }
}

And for writing the tag:

public boolean writeTag(NdefMessage message, Tag tag) {
    int size = message.toByteArray().length;
    try {
        Ndef ndef = Ndef.get(tag);
        if (ndef != null) {
            ndef.connect();
            if (!ndef.isWritable()) {
                Toast.makeText(getApplicationContext(),
                        "Unwritable",
                        Toast.LENGTH_SHORT).show();
                return false;
            }
            if (ndef.getMaxSize() < size) {
                Toast.makeText(getApplicationContext(),
                        "Text is too short",
                        Toast.LENGTH_SHORT).show();
                return false;
            }
            ndef.writeNdefMessage(message);
            return true;
        } else {
            NdefFormatable format = NdefFormatable.get(tag);
            if (format != null) {
                try {
                    format.connect();
                    format.format(message);
                    return true;
                } catch (IOException e) {
                    return false;
                }
            } else {
                return false;
            }
        }
    } catch (Exception e) {
        return false;
    }
}

Is there a way to somehow change the content type to the same that NXP TagWriter writes? I have a problem with reading the code properly later when it's an unknown type.

1

1 Answers

4
votes

What you get is exactly what you wrote to the tag, a MIME type record with the value set to the UTF-8 encoded string "{number_id:"test12"}" and the MIME type set to the exact same (and invalid!) value. You did this during creation of the MIME type record:

NdefRecord record = NdefRecord.createMime(zawartosc, zawartosc.getBytes(Charset.forName("UTF-8")));

Here, you set both the mimeType argument and the mimeData argument of createMime() to the string zawartosc.

What you actually wanted to do is to create a plain text record. This could either be an NFC Forum Text record or a MIME type record with the MIME type set to "text/plain". The NFC Forum Text record is also the record type that NXP TagWriter creates when selecting the "Plain text" option.

In Android, you can create a Text record using the createTextRecord() helper method:

NdefRecord record = NdefRecord.createTextRecord("en", zawartosc);

This works for API level 21+. See [Method NdefRecord.createTextRecord(“en” , “string”) not working below API level 21 (Method NdefRecord.createTextRecord("en" , "string") not working below API level 21) for an implementation of createTextRecord() that works for eariler Android versions.

If you prefer to use a MIME type record, you could also use:

NdefRecord record = NdefRecord.createMime("text/plain", zawartosc.getBytes(Charset.forName("US-ASCII")));

This would create a MIME type record of type "text/plain" containing the ASCII encoded value of the string zawartosc. Note that text/plain is defined to contain plain text data in ASCII encoding. If you want to use UTF-8 encoding, you would typically specify an explicit encoding in the type name:

NdefRecord record = NdefRecord.createMime("text/plain; encoding=utf-8", zawartosc.getBytes(Charset.forName("UTF-8")));

Finally, I wonder if you would really want to transport structured data (e.g. JSON or similar) in a Text record. A Text record indicates human-readable plain text. A better way to transport application-specific structured data are NFC Forum exteranl types or custom MIME type records.