투케이2K

575. (Android/Java) [Android 13] 안드로이드 NFC NDEF 메시지 Read 읽기 , Write 쓰기 모드 수행 본문

Android

575. (Android/Java) [Android 13] 안드로이드 NFC NDEF 메시지 Read 읽기 , Write 쓰기 모드 수행

투케이2K 2023. 6. 13. 21:07

[개발 환경 설정]

개발 툴 : AndroidStudio

 

[소스 코드]

package com.example.javaproject;
import android.app.PendingIntent;
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.Ndef;
import android.nfc.tech.NfcF;
import android.os.Build;
import android.os.Bundle;

import android.os.Parcelable;
import android.view.KeyEvent;

import androidx.appcompat.app.AppCompatActivity;

import java.nio.charset.Charset;
import java.util.Arrays;

public class A_Nfc_Read_Write extends AppCompatActivity {



    /**
     * // --------------------------------------------------------------------------------------
     * TODO [클래스 설명]
     * // --------------------------------------------------------------------------------------
     * 1. NFC 태그 쓰기 클래스
     * // --------------------------------------------------------------------------------------
     * */





    /**
     * // --------------------------------------------------------------------------------------
     * TODO [빠른 로직 찾기 : 주석 로직 찾기]
     * // --------------------------------------------------------------------------------------
     * // [SEARCH FAST] : []
     * // --------------------------------------------------------------------------------------
     */




    // -----------------------------------------------------------------------------------------
    // TODO [전역 변수]
    // -----------------------------------------------------------------------------------------
    private static final String ACTIVITY_NAME = "A_Nfc_Read_Write";

    private NfcAdapter nfcAdapter = null; // [NfcAdapter]





    // -----------------------------------------------------------------------------------------
    // TODO [액티비티 onCreate]
    // -----------------------------------------------------------------------------------------
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ===============================================================
        S_Log._D_(S_FinalMsg.LOG_Activity_onCreate, new String[]{ S_FinalMsg.LOG_NOW() });
        // ===============================================================


        // ---------------------------------------------------------------
        // [타이틀 바 없애기]
        // ---------------------------------------------------------------
        C_App.setTitleBarRemove(A_Nfc_Read_Write.this);


        // ---------------------------------------------------------------
        // [액티비티 레이아웃 지정 실시]
        // ---------------------------------------------------------------
        setContentView(R.layout.activity_a_intro);


        // ---------------------------------------------------------------
        // [로직 처리 실시]
        // ---------------------------------------------------------------
        try {

            /**
             * ---------------------------------
             * [필요 퍼미션 등록]
             * ---------------------------------
             * <uses-permission android:name="android.permission.NFC"/>
             * <uses-feature android:name="android.hardware.nfc" android:required="true" />
             * ---------------------------------
             * */


            // [NFC 사용 여부 및 활성 상태 확인]
            if (C_StateCheck.getNfcState(A_Nfc_Read_Write.this) == true){
                S_Log._W_(S_FinalMsg.LOG_Status_Check, new String[]{ "NFC 활성 상태" });

                // [NFC 어댑터 지정 실시]
                nfcAdapter = NfcAdapter.getDefaultAdapter(this);

            }
            else {
                S_Log._E_(S_FinalMsg.LOG_Status_Check, new String[]{ "NFC 비활성 상태" });
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }


    } // TODO [메인 종료]





    // -----------------------------------------------------------------------------------------
    // TODO [액티비티 onResume]
    // -----------------------------------------------------------------------------------------
    @Override
    public void onResume(){
        super.onResume();
        // ===============================================================
        S_Log._D_(S_FinalMsg.LOG_Activity_onResume, new String[]{ S_FinalMsg.LOG_NOW() });
        // ===============================================================


        // ---------------------------------------------------------------
        // 외부 브라우저 복귀 시 화면 전환 애니메이션 없애기 위함
        // ---------------------------------------------------------------
        try {
            overridePendingTransition(0, 0);
        }
        catch (Exception e){
            e.printStackTrace();
        }


        // ---------------------------------------------------------------
        // [NFC 리더 모드 등록]
        // ---------------------------------------------------------------
        try {

            if (nfcAdapter != null) {

                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};

                PendingIntent pendingIntent = null;
                Intent intent = new Intent(this, this.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){ // [타겟 31 이상]
                    pendingIntent = PendingIntent.getActivity(getApplication(), 0, intent, PendingIntent.FLAG_MUTABLE );
                }
                else { // [타겟 31 미만]
                    pendingIntent = PendingIntent.getActivity(getApplication(), 0, intent, 0);
                }

                String [][] techListsArray = new String[][]{new String[]{NfcF.class.getName()}};

                nfcAdapter.enableForegroundDispatch(this, pendingIntent, nfcIntentFilter, techListsArray);

            }
        }
        catch (Exception e){
            e.printStackTrace();
        }

    }





    // -----------------------------------------------------------------------------------------
    // TODO [onNewIntent 감지]
    // -----------------------------------------------------------------------------------------
    @Override
    protected void onNewIntent(Intent intent){
        super.onNewIntent(intent);

        // ---------------------------------------------------------------
        // [NFC 읽기 메소드 호출]
        // ---------------------------------------------------------------
        readNfcNdef(intent);
    }





    // -----------------------------------------------------------------------------------------
    // TODO [액티비티 onPause]
    // -----------------------------------------------------------------------------------------
    @Override
    public void onPause(){
        super.onPause();
        // ===============================================================
        S_Log._E_(S_FinalMsg.LOG_Activity_onPause, new String[]{ S_FinalMsg.LOG_NOW() });
        // ===============================================================


        // ---------------------------------------------------------------
        // [NFC 리더 모드 해제]
        // ---------------------------------------------------------------
        try {

            if (nfcAdapter != null) {
                nfcAdapter.disableForegroundDispatch(this);
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }

    }




    // -----------------------------------------------------------------------------------------
    // TODO [액티비티 onDestroy]
    // -----------------------------------------------------------------------------------------
    @Override
    public void onDestroy(){
        super.onDestroy();
        // ===============================================================
        S_Log._E_(S_FinalMsg.LOG_Activity_onDestroy, new String[]{ S_FinalMsg.LOG_NOW() });
        // ===============================================================
    }





    // -----------------------------------------------------------------------------------------
    // TODO [모바일 키 이벤트 발생 체크 부분]
    // -----------------------------------------------------------------------------------------
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) { // TODO [모바일 디바이스의 뒤로가기 키 이벤트가 발생한 경우]
            // ===============================================================
            S_Log._W_(S_FinalMsg.LOG_Activity_onBackKey, new String[]{ S_FinalMsg.LOG_NOW() });
            // ===============================================================


            // ---------------------------------------------------------------
            // [액티비티 종료 실시]
            // ---------------------------------------------------------------
            try {
                finish();
                overridePendingTransition(0, 0);
            }
            catch (Exception e){}
            // ---------------------------------------------------------------
        }
        return true;
    }





    // -----------------------------------------------------------------------------------------
    // TODO [NFC NDEF 메시지 읽기]
    // -----------------------------------------------------------------------------------------
    public void readNfcNdef(Intent intent){
        try {
            // ===============================================================
            S_Log._W_(S_FinalMsg.LOG_Event, new String[]{ "TIME :: " + S_FinalMsg.LOG_NOW(), "ACTION :: " + intent.getAction() });
            // ===============================================================
            if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){

                // TODO [NFC 태그 ID 데이터 읽기]
                Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

                if (tag != null){

                    // [getId]
                    byte[] tagId = tag.getId();

                    S_Log._W_(S_FinalMsg.LOG_Data, new String[]{ "tagId :: " + C_Encryption.byteToHex(tagId) });

                }


                // TODO [NDEF 메시지 읽기]
                Parcelable[] rawMessage = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

                if (rawMessage != null){
                    NdefMessage[] messages = new NdefMessage[rawMessage.length];

                    for (int i=0; i<messages.length; i++){
                        messages[i] = (NdefMessage) rawMessage[i];
                    }

                    S_Log._W_(S_FinalMsg.LOG_Data, new String[]{ "NdefMessage :: " + Arrays.toString(messages) });

                    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";
                                }

                                // [Get the Language Code]
                                int languageCodeLength = payload[0] & 0077;
                                String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");

                                // [Get the Text]
                                String payloadStr = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);

                                S_Log._W_(S_FinalMsg.LOG_Data, new String[]{
                                        "languageCode :: " + languageCode,
                                        "payloadStr :: " + payloadStr
                                });
                            }
                        }
                        catch (Exception e){}

                    }
                }


                // TODO [NDEF 메시지 쓰기]
                if (tag != null) {

                    writeNfcNdef(Ndef.get(tag));

                }

            }
            // ===============================================================

        }
        catch (Exception e){
            e.printStackTrace();
        }
    }





    // -----------------------------------------------------------------------------------------
    // TODO [NFC NDEF 메시지 쓰기]
    // -----------------------------------------------------------------------------------------
    public void writeNfcNdef(Ndef ndef){
        try {
            // ===============================================================
            S_Log._D_(S_FinalMsg.LOG_Event, new String[]{ "TIME :: " + S_FinalMsg.LOG_NOW(), "설 명 :: " + "NDEF 메시지 쓰기 수행" });
            // ===============================================================

            if (ndef != null){

                NdefRecord mRecord = NdefRecord.createTextRecord("en","TWOK"); // [레코드 생성]

                NdefMessage mMsg = new NdefMessage(mRecord); // [메시지 생성]

                ndef.connect(); // [연결]

                ndef.writeNdefMessage(mMsg); // [쓰기]
                
                ndef.close(); // [종료]

                // ===============================================================
                S_Log._W_(S_FinalMsg.LOG_Result, new String[]{ "TIME :: " + S_FinalMsg.LOG_NOW(), "설 명 :: " + "NDEF 메시지 쓰기 완료" });
                // ===============================================================

            }

        }
        catch (Exception e){
            e.printStackTrace();
        }
    }


} // TODO [클래스 종료]
 

[결과 출력]

 

W///===========//: ================================================
I/: [LOG :: CLASS PLACE :: com.example.javaproject.A_Nfc_Read_Write.readNfcNdef(A_Nfc_Read_Write.java:329)]
I/: ----------------------------------------------------
I/: [LOG :: DESCRIPTION :: 데이터 확인]
I/: ----------------------------------------------------
I/: [LOG :: languageCode :: en]
I/: ----------------------------------------------------
I/: [LOG :: payloadStr :: TWOK]
W///===========//: ================================================

반응형
Comments