Write NDEF RECORDS to NDEF TAG KOTLIN

101 Views Asked by At

I should prepare an demo application, which should read Ndef records and overrite them to card. I have 3 main functions: readNdef, writeNdef and readTag. readNdef and readTag are working properly. But when I try write new Ndef Records its not working properly. It write Records but change them something.I use NdefRecord.createTextRecord method. This method do some converting. I want to write tokens without any changes.

private fun readNdef(tag: Tag?) {
        val ndef = Ndef.get(tag)
        try {
            ndef.connect()
            val inNdef = ndef.ndefMessage
            Log.d("fdsfsdfsdf", inNdef.toString())
            val inNdefRecords = ndef.ndefMessage.records
            Log.d("fdsfsdfsdf", inNdefRecords.toString())
            // convert the payload to string and drop 3 characters to get
            // rid of the " en" prefix
            val payload = inNdefRecords[0].payload
            Log.d("fdsfsdfsdf", payload.toString())

            // figure out if we need to take out the " en" at the beginning
            val textEncoding = if (payload[0] and 128.toByte() == 0.toByte()) "UTF-8" else "UTF-16"
            val langCodeLength = payload[0] and 63.toByte()

            // create a string starting by skipping the first 3 characters
            // based on the language code length
            var inMessage = String(
                payload,
                langCodeLength + 1,
                payload.count() - langCodeLength - 1,
                charset(textEncoding)
            )

            // try to convert the message to json
            try {
                val json = inMessage
                Log.d("fdsfsdfsdf", json)
                //val json = JsonParser().parse(inMessage)

                // ... use json or whatever here
            } catch (error: Exception) {
                Log.d(
                    "fdsfsdfsdf",
                    "NFC tag data seems to invalid:\n\n$inMessage\n\n${error.localizedMessage}"
                )
            }

            // ... do whatever
        } catch (error: Exception) {
            Log.d("fdsfsdfsdf", "Error attempting to pull tag info: ${error.localizedMessage}")
        } finally {
            ndef.close()
        }
    }
fun readTag(tag: Tag?) {
        Coroutines.default(this@MainViewModel) {
            readNdef(tag)
            Log.d(TAG, "readTag(${tag} ${tag?.techList})")
            postNFCStatus(NFCStatus.Process)
            val stringBuilder: StringBuilder = StringBuilder()
            val id: ByteArray? = tag?.id
            Log.d("fdsfsdfsdf", "$id")
            stringBuilder.append("Tag ID (hex): ${bytesToHex(id!!)} \n")
            stringBuilder.append("Tag ID (dec): ${getDec(id)} \n")
            stringBuilder.append("Tag ID (reversed): ${getReversed(id)} \n")
            stringBuilder.append("Technologies: ")
            tag.techList.forEach { tech ->
                stringBuilder.append(tech.substring(prefix.length))
                stringBuilder.append(", ")
            }
            stringBuilder.delete(stringBuilder.length - 2, stringBuilder.length)
            tag.techList.forEach { tech ->
                if (tech.equals(MifareClassic::class.java.name)) {
                    stringBuilder.append('\n')
                    val mifareTag: MifareClassic = MifareClassic.get(tag)
                    val type: String
                    if (mifareTag.type == MifareClassic.TYPE_CLASSIC) type = "Classic"
                    else if (mifareTag.type == MifareClassic.TYPE_PLUS) type = "Plus"
                    else if (mifareTag.type == MifareClassic.TYPE_PRO) type = "Pro"
                    else type = "Unknown"
                    stringBuilder.append("Mifare Classic type: $type \n")
                    stringBuilder.append("Mifare size: ${mifareTag.size} bytes \n")
                    stringBuilder.append("Mifare sectors: ${mifareTag.sectorCount} \n")
                    stringBuilder.append("Mifare blocks: ${mifareTag.blockCount}")
                }
                if (tech.equals(MifareUltralight::class.java.name)) {
                    stringBuilder.append('\n');
                    val mifareUlTag: MifareUltralight = MifareUltralight.get(tag);
                    val type: String
                    if (mifareUlTag.type == MifareUltralight.TYPE_ULTRALIGHT) type =
                        "Ultralight"
                    else if (mifareUlTag.type == MifareUltralight.TYPE_ULTRALIGHT_C) type =
                        "Ultralight C"
                    else type = "Unkown"
                    stringBuilder.append("Mifare Ultralight type: ");
                    stringBuilder.append(type)
                }
            }
            Log.d(TAG, "Datum: $stringBuilder")
            Log.d(ContentValues.TAG, "dumpTagData Return \n $stringBuilder")
            postNFCStatus(NFCStatus.Read)
            liveTag.emit("${getDateTimeNow()} \n $stringBuilder")
        }
    }
fun writeNdef(tag: Tag?, context: Context) {
        val ndef = Ndef.get(tag)
        try {
            ndef.connect()
            val textRecord1 = NdefRecord.createTextRecord(
                "en",  // language code (ISO 639-1)
                "00000111111222222333333444444555555AABBEF"
                      //  context.getString(R.string.ndef_rcrd1) // text to send
            )
            val textRecord2 = NdefRecord.createTextRecord(
                "en",  // language code (ISO 639-1)
                "00000111111222222333333444444555555AABBEF"
                      //  context.getString(R.string.ndef_rcrd2) // text to send
            )
            val textRecord3 = NdefRecord.createTextRecord(
                "en",  // language code (ISO 639-1)
                "00000111111222222333333444444555555AABBEF"
                       // context.getString(R.string.ndef_rcrd3) // text to send
            )
            val textRecord4 = NdefRecord.createTextRecord(
                "en",  // language code (ISO 639-1)
                "00000111111222222333333444444555555AABBEF"
                        //context.getString(R.string.ndef_rcrd4) // text to send
            )
            val ndefMessage = NdefMessage(textRecord1, textRecord2, textRecord3, textRecord4)
            ndef.writeNdefMessage(ndefMessage)
            Coroutines.default(this@MainViewModel){
                postNFCStatus(NFCStatus.Write)
            }
            Log.d("fdsfsdfsdf","Edited: ${ndef.ndefMessage}")
        } catch (e: Exception) {
            Log.d("fdsfsdfsdf", "Error write: ${e.localizedMessage}")
        } finally {
            ndef.close()
        }
    }

I want to write new REcords without any converting.

1

There are 1 best solutions below

2
Andrew On

Don't use Ndef Text record format as this adds the language encoding to the record.

Use a MimeType record instead with createMime

e.g.

// Create Record
val textRecord1 = NdefRecord.createMime(
                "text/plain" // a standard mimeType
                "00000111111222222333333444444555555AABBEF".toByteArray()
            )

// Get String
val payloadString = inNdefRecords[0].payload.toString()

You can use a standard Mime Type like text/plain or custom one like yourapp/text

Thought you should probably do some checking of the payload.

e.g. check the that getTnf() is NdefRecord.TNF_MIME_MEDIA

and

inNdefRecords[0].toMimeType() is the mime type you chose to use