반응형
내가 프로젝트를 하면서 NFC 태그에 값을 작성해야 하는 상황이 생겼는데, 찾아보며 코드를 작성하니 자꾸 오류가 나서 내가 직접 올린다.
먼저 Manifest에 아래와 같은 코드를 작성해 주자.
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" />
<application
..
<activity
..>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="www.example.com" //패키지 이름
android:scheme="http" />
</intent-filter>
/>
그다음 엑티비티를 정의해주자.
@AndroidEntryPoint
class NfcActivity : AppCompatActivity() {
private lateinit var nfcAdapter: NfcAdapter
private lateinit var pending : PendingIntent
@Inject lateinit var vm : MainViewModel
private val binding : ActivityNfcBinding by lazy { ActivityNfcBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
supportActionBar?.hide()
binding.vm = vm
binding.lifecycleOwner = this
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
val launchIntent = Intent(this, this.javaClass)
launchIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
pending = PendingIntent.getActivity(this, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE)
}
override fun onStart() {
super.onStart()
nfcAdapter.enableReaderMode(this, NfcAdapter.ReaderCallback { tag: Tag? ->
val message = NdefMessage(NdefRecord.createUri(vm.getNfcData()))
val size = message.toByteArray().size
try {
val ndef = Ndef.get(tag)
if (ndef != null) {
ndef.connect()
if (!ndef.isWritable) {
Log.e("enter", "cannot write")
}
if (ndef.maxSize < size) {
Log.e("enter", "cannot size exception")
}
ndef.writeNdefMessage(message)
vm.nfcSuccess()
}
} catch (e: Exception) {
Log.i("writeError", e.message.toString());
}},
NfcAdapter.FLAG_READER_NFC_A
or NfcAdapter.FLAG_READER_NFC_B
or NfcAdapter.FLAG_READER_NFC_F
or NfcAdapter.FLAG_READER_NFC_V
or NfcAdapter.FLAG_READER_NFC_BARCODE,
null)
}
override fun onStop() {
super.onStop()
nfcAdapter.disableReaderMode(this);
vm.nfcInitialize()
}
}
처음에는 NfcAdapter.enableForegroundDispatch를 사용했는데 계속 onNewIntent에서 tag값을 가져오는데 null값을 가져오길래 그냥 enableRenderMode를 사용하였다. (참고로 내가 봤던 블로그가 전부다 ForegroundDispatch를 사용했다.)
이 enableforegroundDispatch를 사용하는데 RenderCallback에서 다른 함수호출이 안되더라. 왜 그런지는 모르겠다. (내가 실수한 걸 지도) 또 이 콜백함수 안에서 Toast 메시지를 만들면 함수가 그곳에서 끊겨버린다. 그렇기 때문에 Toast 메시지는 사용하는 걸 추천하지 않는다.
반응형
'안드로이드' 카테고리의 다른 글
[안드로이드/Kotlin] EditText SaveState 에러 (0) | 2023.10.31 |
---|---|
[안드로이드/Kotlin] DatePickerDialog 사용하기 (0) | 2022.10.05 |
[안드로이드/Kotlin] 카메라 사용하고 이미지 뷰에 띄워보기 (0) | 2022.08.26 |
[안드로이드/Kotlin] ViewPager2 사용해보기 (0) | 2022.08.25 |
[안드로이드/Kotlin] Retrofit2 사용하기 (0) | 2022.08.23 |