Write application record to NFC tags. (#969)

* Write application record to NFC tags.

Relates to #876

This fixes an issue where on certain devices a dialog was showing up when scanning the NFC tags.

After this change, scanned NFC tags go directly into the home assistant android companion app.

I also tested on an iOS device to ensure the written NFC tag is correctly read.

* Add fallback to old version if the message is too large.
This commit is contained in:
Jay Newstrom 2020-09-22 21:06:12 -05:00 committed by GitHub
parent ec5295a546
commit 714060093b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -10,16 +10,19 @@ import android.nfc.NfcAdapter
import android.nfc.Tag import android.nfc.Tag
import android.nfc.tech.Ndef import android.nfc.tech.Ndef
import android.nfc.tech.NdefFormatable import android.nfc.tech.NdefFormatable
import io.homeassistant.companion.android.BuildConfig
import java.io.IOException import java.io.IOException
object NFCUtil { object NFCUtil {
@Throws(Exception::class) @Throws(Exception::class)
fun createNFCMessage(url: String, intent: Intent?): Boolean { fun createNFCMessage(url: String, intent: Intent?): Boolean {
val nfcRecord = NdefRecord.createUri(url) val nfcRecord = NdefRecord.createUri(url)
val nfcMessage = NdefMessage(arrayOf(nfcRecord)) val applicationRecord = NdefRecord.createApplicationRecord(BuildConfig.APPLICATION_ID)
val nfcMessage = NdefMessage(arrayOf(nfcRecord, applicationRecord))
val nfcFallbackMessage = NdefMessage(arrayOf(nfcRecord))
intent?.let { intent?.let {
val tag = it.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG) val tag = it.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
return writeMessageToTag(nfcMessage, tag) return writeMessageToTag(nfcMessage, nfcFallbackMessage, tag)
} }
return false return false
} }
@ -42,17 +45,25 @@ object NFCUtil {
} }
@Throws(Exception::class) @Throws(Exception::class)
private fun writeMessageToTag(nfcMessage: NdefMessage, tag: Tag?): Boolean { private fun writeMessageToTag(
nfcMessage: NdefMessage,
fallbackMessage: NdefMessage,
tag: Tag?
): Boolean {
val nDefTag = Ndef.get(tag) val nDefTag = Ndef.get(tag)
nDefTag?.let { nDefTag?.let {
it.connect() it.connect()
var messageToWrite = nfcMessage
if (it.maxSize < nfcMessage.toByteArray().size) { if (it.maxSize < nfcMessage.toByteArray().size) {
messageToWrite = fallbackMessage
}
if (it.maxSize < fallbackMessage.toByteArray().size) {
// Message to large to write to NFC tag // Message to large to write to NFC tag
throw Exception("Message is too large") throw Exception("Message is too large")
} }
return if (it.isWritable) { return if (it.isWritable) {
it.writeNdefMessage(nfcMessage) it.writeNdefMessage(messageToWrite)
it.close() it.close()
// Message is written to tag // Message is written to tag
true true