forked from home-assistant/android
/
NFCUtil.kt
93 lines (83 loc) · 3.13 KB
/
NFCUtil.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package io.homeassistant.companion.android.nfc
import android.app.Activity
import android.app.PendingIntent
import android.content.Intent
import android.content.IntentFilter
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.Ndef
import android.nfc.tech.NdefFormatable
import io.homeassistant.companion.android.BuildConfig
import java.io.IOException
object NFCUtil {
@Throws(Exception::class)
fun createNFCMessage(url: String, intent: Intent?): Boolean {
val nfcRecord = NdefRecord.createUri(url)
val applicationRecords = BuildConfig.APPLICATION_IDS.map {
NdefRecord.createApplicationRecord(it)
}
val nfcMessage = NdefMessage(arrayOf(nfcRecord) + applicationRecords)
val nfcFallbackMessage = NdefMessage(arrayOf(nfcRecord))
intent?.let {
val tag = it.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
return writeMessageToTag(nfcMessage, nfcFallbackMessage, tag)
}
return false
}
fun disableNFCInForeground(nfcAdapter: NfcAdapter, activity: Activity) {
nfcAdapter.disableForegroundDispatch(activity)
}
fun <T> enableNFCInForeground(nfcAdapter: NfcAdapter, activity: Activity, classType: Class<T>) {
val pendingIntent = PendingIntent.getActivity(
activity, 0,
Intent(activity, classType).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_IMMUTABLE
)
val nfcIntentFilter = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED)
val filters = arrayOf(nfcIntentFilter)
val techLists =
arrayOf(arrayOf(Ndef::class.java.name), arrayOf(NdefFormatable::class.java.name))
nfcAdapter.enableForegroundDispatch(activity, pendingIntent, filters, techLists)
}
@Throws(Exception::class)
private fun writeMessageToTag(
nfcMessage: NdefMessage,
fallbackMessage: NdefMessage,
tag: Tag?
): Boolean {
val nDefTag = Ndef.get(tag)
nDefTag?.let {
it.connect()
var messageToWrite = nfcMessage
if (it.maxSize < nfcMessage.toByteArray().size) {
messageToWrite = fallbackMessage
}
if (it.maxSize < fallbackMessage.toByteArray().size) {
// Message to large to write to NFC tag
throw Exception("Message is too large")
}
return if (it.isWritable) {
it.writeNdefMessage(messageToWrite)
it.close()
// Message is written to tag
true
} else {
throw Exception("NFC tag is read-only")
}
}
val nDefFormatableTag = NdefFormatable.get(tag)
nDefFormatableTag?.let {
try {
it.connect()
it.format(nfcMessage)
it.close()
// The data is written to the tag
} catch (e: IOException) {
// Failed to format tag
throw Exception("Failed to format tag", e)
}
}
return true
}
}