[Android]
방법1. 실행시키길 원하는 앱의 소스코드 만지기
결과적으로는 https://github.com/observ3r/nfc-ndef-react-native 에 있는 android 코드를 사용했더니 됐다! (라이브러리 설치 없이)
1) android/app/src/main/AndroidManifest.xml 에 다음 권한 추가
<uses-permission android:name="android.permission.NFC" />
2) 같은 파일에 다음 코드 추가
...
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter> <!-- 기존 intent-filter -->
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter> <!-- 추가할 intent-filter -->
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>
<!-- 추가할 meta-data -->
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
activity 태그 안에 기존 intent-filter도 있다.
intent-filter를 정확하겐 모르지만 앱을 클릭해서 실행 또는 nfc로 태그해서 실행할 수 있음을 의미하는게 저 2개의 intent-filter 같음!
3) android/app/src/main/res/xml/nfc_tech_filter.xml (xml 폴더가 없으면 만들기)
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
</tech-list>
</resources>
4) 실물기기로 테스트 (adb devices로 실물 기기 연결되어있는지 확인)
react-native run-android
하고, 휴대폰을 nfc 스티커에 갖다대면 성공!!
5) 동영상
- 앱 실행 후 뜨는 nfc id는
react-native-nfc-manager 라이브러리를 이용했음.
(사용법이 필요하신 분은 댓글 달아주시면 올려드리겠습니다~!)
6) 주의할 점
백그라운드에 앱이 항상 있어야 한다. 백그라운드 앱 자동종료 방지하는 법은 이 블로그에 써있다.
https://saysensibility.tistory.com/1259
방법2. NFC에 데이터 write
이 블로그를 참고하면 NFC Tools PRO 라는 어플을 통해 NFC에 데이터를 write 할 수 있다. (결제 필요)
Write 탭 - Add a record - Application - 원하는 어플 선택 or 패키지명 적기 - 다시 Write 탭 와서 Write 버튼 - NFC 태그
하면 태그한 NFC에 설정이 완료된다.
휴대폰의 NFC를 활성화하고 방금 설정한 NFC를 태그하면 선택했던 어플이 바로 켜진다!
방법3. NFC 라이브러리 이용 (저는 이 방법을 이용합니다.)
이 라이브러리를 설치하고
Usage 이곳에 있는걸 그대로 가져다 쓰면 된다.
만약 nfc를 태그했을 때 원하는앱을 실행시키고 싶다면 일단 해당앱에서 데이터를 write 해주어야 한다. (또는 방법2를 사용하면 nfc write 과정은 생략할 수 있다.)
위 Usage 에서 uriRecord 대신 textRecord를 사용하고, "application/com.roubit" 처럼 application/ 뒤에 해당앱의 안드로이드 패키지 명을 param으로 넣어주면 된다.
(201004 업데이트) textRecord 대신 androidApplicationRecord를 사용하면 안드로이드 패키지로 데이터 입력이 가능하고, 아래 문제도 해결된다. (댓글로 남겨주신 Muhly님 감사합니다.)
문제는 text 태그로 application/com... 을 적으니 nfc 사용가능한 앱들 목록이 나오면서 선택하는 화면이 나옵니다.
어떻게 해결할 수 있을까요? application/com..을 빼도 동일한 화면이 나와 어플을 실행할 수 있는 걸 보니 잘못된 명령어가 아닌가 싶습니다..
참고링크
github.com/whitedogg13/react-native-nfc-manager/issues/330
제가 실제로 쓰고있는 코드를 공유합니다.
import NfcManager, {
NfcEvents,
TagEvent,
Ndef,
NfcTech,
} from 'react-native-nfc-manager';
const _cleanUp = () => {
NfcManager.cancelTechnologyRequest().catch(() => 0);
};
const buildTextPayload = (valueToWrite: string): Uint8Array => {
// iOS을 위한건 아직 없다.
return Ndef.encodeMessage([
// Ndef.textRecord(valueToWrite), // 이걸 사용하지 않고
Ndef.androidApplicationRecord(valueToWrite), // 이걸 사용한다
]);
};
const writeData = async (valueToWrite: string) => {
try {
const tech = NfcTech.Ndef;
console.warn('🔵 0', tech);
const resp = await NfcManager.requestTechnology(tech);
console.warn('🔵 1 resp', resp);
let ndef = await NfcManager.getNdefMessage();
console.warn('🔵 2 ndef', ndef);
const bytes = buildTextPayload(valueToWrite);
await NfcManager.writeNdefMessage(bytes);
console.warn('🔵 3 successfully write ndef');
_cleanUp();
} catch (ex) {
console.warn('🔵 writeData ex', ex);
_cleanUp();
}
};
번외 3-1. 앱 종료 상태에서 NFC 태그 시 데이터 가져오기 (Not Foreground, Background)
위 Usage에서 보이는
NfcManager.setEventListener(NfcEvents.DiscoverTag, tag => {
console.warn('tag', tag);
NfcManager.setAlertMessageIOS('I got your tag!');
NfcManager.unregisterTagEvent().catch(() => 0);
});
이 코드는 앱이 foreground, background 일 때만 유효하다. 앱이 종료된 후에 태그하면 아직 nfc 세팅이 되지 않아 당연히 nfc 데이터를 가져올 수 없는 것이다.
그렇다면 앱이 완전히 종료된 상태에서는 어떻게 가져올까? 해당 라이브러리에서 해결법을 제시하고 있다.
[iOS]
백그라운드에서 NFC를 태그했을 때 원하는 어플이 켜지는 동작은 아이폰 XS 이상 모델에서만 할 수 있고 아이폰 X 이하 모델엔 없다.
그래서 그 외의 모델은 NFC를 태그할 수 있는 어플 안에서만 NFC를 태그할 수 있다 <--- 이 방법이 최선
아직 실물 아이폰 XS 이상이 없어서 테스트는 못했음.
[참고]
https://stackoverflow.com/questions/26769810/android-intent-filter-for-multiple-nfc-types
https://github.com/observ3r/nfc-ndef-react-native
https://developer.android.com/guide/topics/connectivity/nfc/nfc.html#tech-disc
https://www.youtube.com/watch?v=jPJOPJWdEOE
Buy Me A Coffee!
https://www.buymeacoffee.com/daheeahn
'Develop > React Native' 카테고리의 다른 글
[React Native] 갤러리에서 사진 가져오기 (iOS) (8) | 2020.03.19 |
---|---|
[React Native] react-native-permission 사용법 (0) | 2020.03.19 |
[React Native] run-android 되지 않을 때 / Could not compile settings file /JDK 문제 (2) | 2020.03.17 |
[React/RN] useMutation react-apollo-hooks error (0) | 2020.03.13 |
React-navigation v5 에서 v4 때 쓰던 API 사용하는 방법 (ex. withNavigation, ... ) (0) | 2020.03.13 |