Notice
Recent Posts
Recent Comments
Link
투케이2K
140. (TWOK/UTIL) [Android/Java] C_Nfc_Card_Module : NFC 기능 활성 및 카드 Read , Write 관련 모듈 본문
투케이2K 유틸파일
140. (TWOK/UTIL) [Android/Java] C_Nfc_Card_Module : NFC 기능 활성 및 카드 Read , Write 관련 모듈
투케이2K 2024. 10. 5. 09:24[설 명]
프로그램 : Android / Java
설 명 : C_Nfc_Card_Module : NFC 기능 활성 및 카드 Read , Write 관련 모듈
[소스 코드]
package com.example.javaproject.C_Module;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcF;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcelable;
import com.example.javaproject.C_Encryption;
import com.example.javaproject.C_Util;
import com.example.javaproject.S_FinalData;
import com.example.javaproject.S_Log;
import org.json.JSONObject;
import java.io.IOException;
import io.reactivex.rxjava3.core.Observable;
public class C_Nfc_Card_Module {
/**
* // --------------------------------------------------------------------------------------
* TODO [클래스 설명]
* // --------------------------------------------------------------------------------------
* 1. [설명] : NFC 기능 활성 및 카드 Read , Write 관련 모듈
* // --------------------------------------------------------------------------------------
* 2. 필요 퍼미션 :
*
* <uses-permission android:name="android.permission.NFC"/>
* <uses-feature android:name="android.hardware.nfc" android:required="true" />
* // --------------------------------------------------------------------------------------
* 3. 참고 사이트 :
*
* UID 및 NDEF 메시지 읽기, 쓰기 : https://blog.naver.com/kkh0977/223128033201?trackingCode=blog_bloghome_searchlist
*
* 마이페어 카드 섹터 블럭 읽기 : https://blog.naver.com/kkh0977/223015747045
*
* 안드로이드 어댑터 클래스 : https://developer.android.com/reference/android/nfc/NfcAdapter
* // --------------------------------------------------------------------------------------
* */
/**
* // --------------------------------------------------------------------------------------
* TODO [빠른 로직 찾기 : 주석 로직 찾기]
* // --------------------------------------------------------------------------------------
*
* // --------------------------------------------------------------------------------------
*
* // --------------------------------------------------------------------------------------
*
* // --------------------------------------------------------------------------------------
*
* // --------------------------------------------------------------------------------------
*/
// ------------------------------------------------------------------------------------------
// TODO [사용 방법] : [전역 변수 선언]
// ------------------------------------------------------------------------------------------
/*
private NfcAdapter nfcAdapter = null; // [NfcAdapter]
C_Nfc_Card_Module c_nfc_card_module = C_Nfc_Card_Module.getInstance(); // [C_Nfc_Card_Module 클래스 인스턴스 초기화]
*/
// ------------------------------------------------------------------------------------------
// TODO [사용 방법] : [onCreate]
// ------------------------------------------------------------------------------------------
/*
try {
// ---------------------------------------------------------------
// TODO [C_Nfc_Card_Module 클래스 Context 지정]
// ---------------------------------------------------------------
c_nfc_card_module.setContext(A_Intro.this);
// ---------------------------------------------------------------
// TODO [NfcAdapter 객체 생성 수행]
// ---------------------------------------------------------------
c_nfc_card_module.setNfcAdapter();
}
catch (Exception e) {
e.printStackTrace();
}
*/
// ------------------------------------------------------------------------------------------
// TODO [사용 방법] : [onResume]
// ------------------------------------------------------------------------------------------
/*
c_nfc_card_module.onResumeNfcReadingEnable();
*/
// ------------------------------------------------------------------------------------------
// TODO [사용 방법] : [onNewIntent]
// ------------------------------------------------------------------------------------------
/*
@Override
protected void onNewIntent(Intent intent){
super.onNewIntent(intent);
// ---------------------------------------------------------------
// [NFC 태그 데이터 읽기 메소드 호출]
// ---------------------------------------------------------------
c_nfc_card_module.observableReadNfc(intent)
.subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
.observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
.subscribe(new Observer<JSONObject>() { // [Observable.create 타입 지정]
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull JSONObject value) {
S_Log._W_("observableReadNfc :: NFC Intent 확인 수행", new String[]{String.valueOf(value)});
}
@Override
public void onError(@NonNull Throwable e) {
S_Log._E_("observableReadNfc :: NFC Intent 확인 에러", new String[]{String.valueOf(e.getMessage())});
}
@Override
public void onComplete() {
}
});
}
*/
// ------------------------------------------------------------------------------------------
// TODO [사용 방법] : [onPause]
// ------------------------------------------------------------------------------------------
/*
c_nfc_card_module.onPauseNfcReadingDisabled();
*/
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
// TODO [전역 변수 선언]
// ------------------------------------------------------------------------------------------
public String ACTIVITY_NAME = "C_Nfc_Card_Module";
private Context mMainCtx; // [컨텍스트]
private NfcAdapter nfcAdapter = null; // [NfcAdapter]
public static final String NFC_HEX_TAG_ID = "NFC_HEX_TAG_ID";
public static final String NFC_STRING_NDEF_MSG = "NFC_STRING_NDEF_MSG";
public static final String NFC_HEX_MIFARE_DATA = "NFC_HEX_MIFARE_DATA";
// ------------------------------------------------------------------------------------------
// TODO [콘텍스트 지정]
// ------------------------------------------------------------------------------------------
public void setContext(Context ctx) {
mMainCtx = ctx;
}
// ------------------------------------------------------------------------------------------
// TODO [인스턴스 생성]
// ------------------------------------------------------------------------------------------
public static C_Nfc_Card_Module getInstance() { return C_Nfc_Card_Module.LazyHolder.INSTANCE; }
private static class LazyHolder {
private static final C_Nfc_Card_Module INSTANCE = new C_Nfc_Card_Module();
}
// ------------------------------------------------------------------------------------------
// TODO [NfcAdapter 객체 생성 수행]
// ------------------------------------------------------------------------------------------
public void setNfcAdapter() {
S_Log._D_(ACTIVITY_NAME + " : setNfcAdapter : NfcAdapter 객체 생성 수행", null);
try {
if (mMainCtx != null && nfcAdapter == null){
nfcAdapter = NfcAdapter.getDefaultAdapter(mMainCtx);
}
else {
nfcAdapter = null;
}
}
catch (Exception e){
e.printStackTrace();
nfcAdapter = null;
}
}
// ------------------------------------------------------------------------------------------
// TODO [onResume : NfcAdapter 읽기 모드 설정 및 활성]
// ------------------------------------------------------------------------------------------
public void onResumeNfcReadingEnable() {
S_Log._W_(ACTIVITY_NAME + " : onResumeNfcReadingEnable : NfcAdapter 읽기 모드 설정 수행", null);
try {
if (mMainCtx != null && nfcAdapter != null){
// ----------------------------------------------------
// TODO [카드 읽기 타입 지정]
// ----------------------------------------------------
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
IntentFilter techDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
IntentFilter[] nfcIntentFilter = new IntentFilter[]{techDetected,tagDetected,ndefDetected}; // [배열에 추가]
// ----------------------------------------------------
// ----------------------------------------------------
// TODO [PendingIntent 선언]
// ----------------------------------------------------
PendingIntent pendingIntent = null;
Intent intent = new Intent(mMainCtx, mMainCtx.getClass());
//intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){ // TODO [타겟 31 이상]
pendingIntent = PendingIntent.getActivity(mMainCtx, 0, intent, PendingIntent.FLAG_MUTABLE );
}
else { // TODO [타겟 31 미만]
pendingIntent = PendingIntent.getActivity(mMainCtx, 0, intent, 0);
}
// ----------------------------------------------------
// ----------------------------------------------------
// TODO [포그라운드 태그 활성 대기]
// ----------------------------------------------------
String [][] techListsArray = new String[][]{new String[]{NfcF.class.getName()}};
nfcAdapter.enableForegroundDispatch((Activity) mMainCtx, pendingIntent, nfcIntentFilter, techListsArray);
// ----------------------------------------------------
}
else {
S_Log._E_(ACTIVITY_NAME + " : onResumeNfcReadingEnable : NfcAdapter 읽기 모드 설정 에러", new String[]{"Error :: mMainCtx , nfcAdapter Is Null"});
}
}
catch (Exception e){
e.printStackTrace();
}
}
// ------------------------------------------------------------------------------------------
// TODO [onPause : NfcAdapter 읽기 모드 비활성]
// ------------------------------------------------------------------------------------------
public void onPauseNfcReadingDisabled() {
S_Log._E_(ACTIVITY_NAME + " : onPauseNfcReadingDisabled : NfcAdapter 읽기 모드 비활성 수행", null);
try {
if (mMainCtx != null && nfcAdapter != null){
// ----------------------------------------------------
// TODO [카드 읽기 타입 지정]
// ----------------------------------------------------
nfcAdapter.disableForegroundDispatch((Activity) mMainCtx);
// ----------------------------------------------------
}
else {
S_Log._E_(ACTIVITY_NAME + " : onPauseNfcReadingDisabled : NfcAdapter 읽기 모드 비활성 에러", new String[]{"Error :: mMainCtx , nfcAdapter Is Null"});
}
}
catch (Exception e){
e.printStackTrace();
}
}
// -----------------------------------------------------------------------------------------
// TODO [onNewIntent] : [Intent 카드 데이터 Tag , NDEF 읽기 메소드]
// -----------------------------------------------------------------------------------------
// TODO [호출 방법 소스 코드]
// -----------------------------------------------------------------------------------------
/*
try {
c_nfc_card_module.observableReadNfc(intent)
.subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
.observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
.subscribe(new Observer<JSONObject>() { // [Observable.create 타입 지정]
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull JSONObject value) {
S_Log._W_("observableReadNfc :: NFC Intent Tag , NDEF 확인 수행", new String[]{String.valueOf(value)});
}
@Override
public void onError(@NonNull Throwable e) {
S_Log._E_("observableReadNfc :: NFC Intent Tag , NDEF 확인 에러", new String[]{String.valueOf(e.getMessage())});
}
@Override
public void onComplete() {
}
});
}
catch (Exception e){
S_Log._printStackTrace_(null, S_FinalData.LOG_BUG_STATE, null, e);
}
*/
// -----------------------------------------------------------------------------------------
public Observable<JSONObject> observableReadNfc(Intent intent){
/*
W ===================================================================
[LOG :: CLASS PLACE :: com.example.javaproject.A_Test$2.onNext(A_Test.java:257)]
----------------------------------------------------
[LOG :: NOW TIME :: 2024-09-06 11:10:18 금요일]
----------------------------------------------------
[LOG :: DESCRIPTION :: observableReadNfc :: NFC Intent 확인 수행]
----------------------------------------------------
[LOG :: {"NFC_HEX_TAG_ID":"67eb9ed3","NFC_STRING_NDEF_MSG":"twok"}]
W ===================================================================
// */
// [로직 처리 실시]
return Observable.create(subscriber -> {
try {
// ===============================================================
S_Log._D_(ACTIVITY_NAME + " :: NFC 카드 데이터 읽기 수행", null);
// ===============================================================
// [팝업창 생성 실시]
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
if (mMainCtx != null && nfcAdapter != null){
if (intent != null){
// -------------------------------------------------
// TODO [NFC 태그 ID 데이터 읽기]
// -------------------------------------------------
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] tagId = null;
if (tag != null){
tagId = tag.getId();
}
// -------------------------------------------------
// -------------------------------------------------
// TODO [NDEF 메시지 읽기]
// -------------------------------------------------
Parcelable[] rawMessage = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
String payloadStr = "";
if (rawMessage != null){
NdefMessage[] messages = new NdefMessage[rawMessage.length];
for (int i=0; i<messages.length; i++){
messages[i] = (NdefMessage) rawMessage[i];
}
for (int i=0; i<messages.length; i++){
try {
NdefRecord[] records = messages[i].getRecords();
for(NdefRecord rec : records) {
byte[] payload = rec.getPayload();
String textEncoding = "UTF-8";
if (payload.length > 0) {
textEncoding = (payload[0] & 0200) == 0 ? "UTF-8" : "UTF-16";
}
// TODO [Get the Language Code]
int languageCodeLength = payload[0] & 0077;
String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
// TODO [Get the Text]
payloadStr = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
}
catch (Exception e){}
}
}
// -------------------------------------------------
// -------------------------------------------------
// TODO [리턴 JSON 반환]
// -------------------------------------------------
try {
JSONObject jsonObject = new JSONObject();
// ---------------------------------------------
if (tagId != null && tagId.length > 0){ // TODO [태그 ID]
String hexTagId = C_Encryption.byteToHex(tagId);
hexTagId = hexTagId.replaceAll("0x", "");
hexTagId = hexTagId.replaceAll("0X", "");
hexTagId = hexTagId.replaceAll(" ", "");
jsonObject.put(NFC_HEX_TAG_ID, hexTagId);
}
else {
jsonObject.put(NFC_HEX_TAG_ID, "");
}
// ---------------------------------------------
if (C_Util.stringNotNull(payloadStr) == true){ // TODO [NDEF 메시지]
jsonObject.put(NFC_STRING_NDEF_MSG, payloadStr);
}
else {
jsonObject.put(NFC_STRING_NDEF_MSG, "");
}
// ---------------------------------------------
if (subscriber != null && subscriber.isDisposed() == false){ // TODO [리턴 반환]
subscriber.onNext(jsonObject);
subscriber.onComplete();
}
// ---------------------------------------------
}
catch (Exception et){
et.printStackTrace();
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Exception] : " + String.valueOf(et.getMessage())));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
else {
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Error] : Intent Is Null"));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
else {
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Error] : Context , nfcAdapter Is Null"));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
}, 0);
} catch (final Exception e){
S_Log._printStackTrace_(null, S_FinalData.LOG_BUG_STATE, null, e);
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Exception] : " + String.valueOf(e.getMessage())));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
});
}
// -----------------------------------------------------------------------------------------
// TODO [Observable] : [NDEF 카드 데이터 쓰기]
// -----------------------------------------------------------------------------------------
// TODO [호출 방법 소스 코드]
// -----------------------------------------------------------------------------------------
/*
try {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String message = "hello twok";
c_nfc_card_module.observableNdefWriteNfc(tag, message)
.subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
.observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
.subscribe(new Observer<Boolean>() { // [Observable.create 타입 지정]
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Boolean value) {
S_Log._W_("observableReadNfc :: NFC NDEF 메시지 쓰기 확인 수행", new String[]{String.valueOf(value)});
}
@Override
public void onError(@NonNull Throwable e) {
S_Log._E_("observableReadNfc :: NFC NDEF 메시지 쓰기 에러", new String[]{String.valueOf(e.getMessage())});
}
@Override
public void onComplete() {
}
});
}
catch (Exception e){
S_Log._printStackTrace_(null, S_FinalData.LOG_BUG_STATE, null, e);
}
*/
// -----------------------------------------------------------------------------------------
public Observable<Boolean> observableNdefWriteNfc(Tag tag, String message){
/*
D ===================================================================
[LOG :: CLASS PLACE :: com.example.javaproject.C_Module.C_Nfc_Card_Module.lambda$observableNdefWriteNfc$1$com-example-javaproject-C_Module-C_Nfc_Card_Module(C_Nfc_Card_Module.java:572)]
----------------------------------------------------
[LOG :: NOW TIME :: 2024-09-06 11:29:15 금요일]
----------------------------------------------------
[LOG :: DESCRIPTION :: C_Nfc_Card_Module :: NFC 카드 NDEF 메시지 쓰기 수행]
----------------------------------------------------
[LOG :: hello twok]
D ===================================================================
*/
// [로직 처리 실시]
return Observable.create(subscriber -> {
try {
// ===============================================================
S_Log._D_(ACTIVITY_NAME + " :: NFC 카드 NDEF 메시지 쓰기 수행", new String[]{String.valueOf(message)});
// ===============================================================
// [팝업창 생성 실시]
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
if (mMainCtx != null && nfcAdapter != null){
if (tag != null){
// -------------------------------------------------
// TODO [NFC NDEF 메시지 쓰기]
// -------------------------------------------------
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null){
NdefRecord mRecord = NdefRecord.createTextRecord("en",String.valueOf(message)); // [레코드 생성]
NdefMessage mMsg = new NdefMessage(mRecord); // [메시지 생성]
ndef.connect(); // [연결]
ndef.writeNdefMessage(mMsg); // [쓰기]
ndef.close(); // [종료]
if (subscriber != null && subscriber.isDisposed() == false){ // TODO [리턴 반환]
subscriber.onNext(true);
subscriber.onComplete();
}
}
else {
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Error] : Ndef Is Null"));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
catch (Exception es){
es.printStackTrace();
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Exception] : " + String.valueOf(es.getMessage())));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
else {
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Error] : Tag Is Null"));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
else {
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Error] : Context , nfcAdapter Is Null"));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
}
}, 0);
} catch (final Exception e){
S_Log._printStackTrace_(null, S_FinalData.LOG_BUG_STATE, null, e);
// TODO [리턴 데이터 반환]
try {
if (subscriber != null && subscriber.isDisposed() == false){
subscriber.onError(new Throwable("[Exception] : " + String.valueOf(e.getMessage())));
subscriber.onComplete();
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
});
}
} // TODO [클래스 종료]
반응형
'투케이2K 유틸파일' 카테고리의 다른 글
Comments