업데이트:

카테고리:

/

태그: ,

NFC

근거리 통신을 주고 받는 기능

NFC가 어플리케이션에 데이터를 주는 방법은 총 3가지

  • NDEF_DisCovered
    • NDEF 가 포함된 payload를 검사할 때 & 태그 유형이 인식 되었을 때
    • 우선순위가 가장 높으며, 다른 intent 이전에 이 intent로 활동하려한다.
  • TECH_DISCOVERED
    • 장치에서 지원하는 기술이 발견되었을 때
    • NDEF_DISCOVERED보다 우선순위가 낮음
  • TAG_DISCOVERED
    • 모든 NFC 태그를 검색할 때, 위의 두가지 경우에서 아무것도 걸리지 않았을 때
    • 가장 낮은 우선순위를 가짐

manifest 설정

<user-permission android:name="android.permission.NFC">

<!-- NDEF 설정 -->
<intent-filter>
	<action android:name="android.nfc.action.NDEF_DISCOVER" />
	<category android:name="android.intent.category.DEFAULT" />
	<data android:mimeType="text/plain" />
</intent-filter>

<!-- TECH 설정 -->
<meta-data android:name="android.nfc.action.TECH_DISCOVER"
	android:resource="@xml/nfc_tech_list"/>
	<!-- nfc_tech_list 에는 지원하는 기술을 모두 적어놔야함 -->
	
<!-- TAG 설정 -->
	<intent-filter>
		<action android:name="android.nfc.action.TAG_DISCOVER" />
	</intent-filter>

NFCAdapter를 통해 NFC와 통신할 수 있다.

nfc를 작동하면 실행한 앱에서 최우선으로 값을 가져와야한다.

// onResume()
override fun onResume() {
	if (NfcAdatper != null) {
		val intentFilters: List<IntentFilter> = IntentFilter {
			IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED)
		}
		val nfcintent = Intent(this.getClass(), addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP))
	
		// 백그라운드에서 Intent를 실행시켜 특정 시점에 Intent가 마무리 되도록 pendingIntent 사용
		val pendingIntent = PendingIntent.getActivity(this.O.nfcIntent)

		val techList = List<List<String>> { List<String> (NfcA::class.getName()) }
		// 어떤 앱보다 최우선으로 NFC를 인식하기 위해서 사용
		nfcadapter.enableForeGroundDispatch(this, pendingIntent, filters, techList)
	}
}

override fun onPause() {
	nfcAdapter.disableForegoundDispatch(this)
}

override fun onNewIntent(intent: Intent) {
	if (NfcAdapter.태그 유형.equals(Intent.getAction()) {
		// NFC가 감지되었을 때 실행할 코드
	}
}

태그 유형은 카드마다 타입이 다르고 가지고 있는 유형이 달라서 유형별로 파싱을 해줘야한다.

지문 카드나 특정 동작을 하는 카드의 경우는 해당 데이터를 안드로이드에서 가지고 있는 것이 아니라 특정 함수를 카드에 보내 카드에서 리턴된 값을 받아온다.

Host Card

삼성페이나 핸드폰을 nfc카드 처럼 사용하는 기능

사용법

  1. mainfest에서 권한 추가

     <user_feature android:name="FEATRUE_NFC_HOST_CARD_EMULATE"/>
     <user_feature android:name="BIND_NFC_SERVICE"/>
        
     <application..>
        
     	<intent-filter>
     		// 안드로이드에서 전달할 APDU 식별을 위한 옵션을 작성한다.
     	</intent-filter>
        
     	<meta-data
     		// 서비스가 받을 AID를 설정
     		/>
     </application>
    
  2. HostapduService 객체 생성

     class HostApduService: HostAdapService() {
     	override fun processComandApdu(commandApdu, extras): ByteArray {
     		// NFC 리더기에서 서비스에 보내는 APDU, 메인 스레드에서 우선적으로 실행
        	
     	}
     }
    

    사용하다보면 category 충돌이 발생

    isDefaultServiceForCategory 로 NFC가 기본 카테고리인지 확인 후 로직을 실행한다.

HCE도 NFC와 동일하게 onResume 일 때는 기능을 등록하고 onPause 일 때는 기능을 해지하도록 한다.