본문 바로가기
안드로이드

[kortlin/안드로이드] 안드로이드 NFC Write 해보기

by krapoi 2023. 6. 1.
반응형

내가 프로젝트를 하면서 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 메시지는 사용하는 걸 추천하지 않는다.

반응형