MutableLiveData
에 저장해서 해당 데이터를 observeAsState()
를 통해서 recomposition을 동작하도록 한다. NFC를 읽어오기 위해서 Manifest 기본 설정
Manifest.xml
<uses-permission android:name="android.permission.NFC" />
<uses-permission
android:name="android.hardware.nfc"
android:required="true" />
...
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.JetpackNFCTutorial">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
MainActivity에서 NFC 데이터 읽어오기
class MainActivity : ComponentActivity() {
private lateinit var nfcAdapter: NfcAdapter
private lateinit var pendingIntent: PendingIntent
private lateinit var filters: Array<IntentFilter>
private lateinit var navController: NavHostController
private val nfcViewModel by viewModels<NfcViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
JetpackNFCTutorialTheme {
MainScreen()
}
}
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
if (nfcAdapter == null) {
Toast.makeText(this, "NFC Tag", Toast.LENGTH_SHORT).show()
finish()
}
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)
pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_MUTABLE)
val filter = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED) // 제일 마지막 호출(태그면 다 불림)
filters = arrayOf(filter)
} // End of onCreate
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
setIntent(intent)
readNFC(getIntent())
} // End of onNewIntent
private fun readNFC(intent: Intent) {
val message = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
if (message != null) {
message.forEach {
val ndef = it as NdefMessage
for (rec in ndef.records) {
// Log.d(TAG, "TNF : ${rec.tnf}")
// Log.d(TAG, "ID : ${String(rec.id)}")
// Log.d(TAG, "TYPE : ${String(rec.type)}")
// Log.d(TAG, "PLoad: ${String(rec.payload)}")
val strPload = String(rec.payload)
Log.d(TAG, "processNFC: ${strPload.substring(3)}")
// nfcViewModel setNfcData
nfcViewModel.setNfcData(newNfcData = strPload.substring(3))
val type = String(rec.type)
when (type) {
"T" -> {
val payload = rec.payload
Log.d(TAG, "processNFC type T : ${String(payload)}")
}
"U" -> {
val uri = rec.toUri()
startActivity(Intent().apply {
setAction(Intent.ACTION_SENDTO)
data = uri
Log.d(TAG, "processNFC: $uri")
})
}
"Sp" -> {
Log.d(TAG, "processNFC: ${String(rec.type)}")
}
}
}
}
}
} // End of processNFC
} // End of MainActivity class
nfcViewModel.kt
class NfcViewModel : ViewModel() {
private val _nfcData = MutableLiveData<String>()
val nfcData: LiveData<String>
get() = _nfcData
fun setNfcData(newNfcData: String) {
_nfcData.value = newNfcData
Log.d(TAG, "setNfcData: $newNfcData")
} // End of setNfcData
} // End of NfcViewModel class
NFC 데이터를 표시해줄 Compose Screen
MainScreen.kt
@Composable
fun MainScreen(
nfcViewModel: NfcViewModel = viewModel(LocalContext.current as ComponentActivity),
) {
val nfcValue = nfcViewModel.nfcData.observeAsState()
MainTextBody( nfcData = nfcValue.value.toString())
} // End of MainScreen
@Composable
fun MainTextBody(
nfcData: String,
) {
val context = LocalContext.current
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = nfcData, fontSize = 24.sp)
}
} // End of MainTextScreen