반응형

진정한 용기

by netcanis

 

1985년 3월 6일, 미국 뉴욕주 올버니(Albany, New York)에 있는 엠파이어 스테이트 플라자 컨벤션 센터(Empire State Plaza Convention Center)에서 프로 데뷔전을 앞둔 마이크 타이슨은 겨우 18살의 청년이었다. 링 위에서 누구보다 강력해 보였던 그였지만, 시합 전 대기실에서는 한없이 떨고 있는 소년에 불과했다. 극도의 긴장감과 공포가 그를 압도했고, 결국 그는 눈물을 흘리며 두려움에 몸을 떨었다.그때 그의 스승이자 인생의 멘토였던 커스 다마토(Cus D’Amato)는 그에게 다가와 진심 어린 조언을 건넸다.

 

“두려움은 친구이자 적이다. 마치 타오르는 불과 같지. 조절만 잘하면 널 따뜻하게 해주지만, 그렇지 못하면 너의 모든 것을 태워버릴 것이다.”

이 말은 단순한 위로가 아니었다. 다마토는 타이슨에게 두려움을 억누르거나 외면하지 말고, 오히려 그것을 인정하고 받아들여야 한다고 가르쳤습니다. 그는 이어서 이렇게 말했다.

“위대한 전사로 남고 싶으면 두려움을 인정하고 받아들여라. 영웅은 두려움을 정면으로 맞서지만, 소인배는 도망친다.”

다마토의 가르침은 타이슨에게 단순히 권투 기술을 가르치는 것 이상이었다. 그는 두려움이란 누구에게나 존재하는 감정이며, 그것을 어떻게 다루느냐가 진정한 강함을 결정짓는 열쇠라는 사실을 타이슨에게 심어주었다. 타이슨이 경기를 앞두고 두려움에 떨 때마다 다마토는 이러한 철학적인 가르침을 반복해서 전했다. 이 과정에서 타이슨은 두려움을 피하는 대신 그 감정을 에너지로 전환하는 법을 배웠다.

 

두려움, 그리고 그를 초월한 챔피언

 

사람들은 흔히 세계 최고의 해비급 챔피언으로서 링 위에서 상대를 압도했던 마이크 타이슨을 기억한다. 하지만 그 화려한 모습 뒤에는 경기 전마다 두려움에 눈물 흘리던 청년의 모습이 있었다. 타이슨은 훗날 인터뷰에서 커스 다마토의 가르침 덕분에 자신의 두려움을 극복할 수 있었으며, 그 덕분에 링 위에서 무적의 파이터로 거듭날 수 있었다고 회상했다.

타이슨은 다음과 같이 말했다.

“나는 매 경기마다 두려웠다. 하지만 커스의 가르침 덕분에 두려움을 힘으로 바꾸는 법을 배웠다. 두려움을 정면으로 마주했기 때문에 지금의 내가 있을 수 있었다.”

결국, 타이슨은 두려움을 피하지 않고 정면으로 맞섰기 때문에 세계 최강의 복서로 성장할 수 있었다. 다마토는 그를 단순한 권투 선수가 아니라, 자신의 내면과 싸워 이겨낸 진정한 전사로 만들었다.

이 일화는 우리에게도 중요한 교훈을 남긴다. 누구나 두려움을 느낄 수 있다. 중요한 것은 그 두려움을 어떻게 다루느냐이다. 타이슨처럼 두려움을 인정하고, 그것을 나아가는 원동력으로 삼는다면, 우리는 더 큰 도전에서도 승리할 수 있을 것이다.


 


 

 


제이크 폴 vs 마이크 타이슨: 판정 결과와 경기 내용

2024년 11월 15일(미국 시간), 미국 텍사스주 댈러스의 AT&T 스타디움에서 열린 ‘넷플릭스 라이브 이벤트: 제이크 폴 vs 마이크 타이슨’ 경기에서 제이크 폴이 8라운드 종료 후 3-0 판정승을 거두었다. 이번 경기는 통상적인 3분 라운드와는 달리, 라운드당 2분으로 진행되었다. 이는 환갑에 가까운 나이의 타이슨을 고려한 규정이었다.

경기 결과에 대한 평가

비록 공식 판정으로는 제이크 폴이 승리했으나, 타이슨이 실질적으로 더 나은 경기력을 보여주었다는 평가도 존재한다. 

고령의 타이슨은 젊은 폴과의 장기전에서 체력적으로 불리할 수밖에 없었으며, 폴은 이를 전략적으로 활용하여 승리를 거머쥔 것으로 보인다. 타이슨은 비록 전성기 시절의 기량에는 미치지 못했으나, 여전히 강력한 공격력과 기술을 선보였으며, 팬들에게는 그가 여전히 ‘철의 남자’로서 건재함을 입증한 경기로 기억될 것이다.

 

반응형

'생각의 조각들' 카테고리의 다른 글

미래의 한국  (0) 2024.10.30
인공지능의 학습 한계  (0) 2024.10.10
Breaking Free from Musical Conventions  (0) 2024.10.06
게으른 야망의 딜레마  (0) 2024.10.06
성공과 실패  (0) 2024.10.02
블로그 이미지

SKY STORY

,
반응형

두가지 모두 비동기 프로그래밍을 위해 사용되는 기술로, 멀티 스레딩 및 동시성 처리를 할때 사용된다.

두 기술에 대한 비교는 다음과 같다.

 

  1. 비동기 작업 처리:
    • 두 기술 모두 비동기적으로 작업을 수행할 수 있다. 이를 통해 메인 스레드가 블로킹되지 않으며, 사용자 인터페이스가 멈추지 않게 할 수 있다.
  2. 멀티 스레딩 지원:
    • GCD는 작업을 비동기적으로 다양한 큐에서 실행하고, Swift Concurrency는 태스크를 사용하여 비동기 코드를 스케줄링한다.
    • 둘 다 멀티코어 CPU의 성능을 활용해 병렬 처리가 가능하다.
  3. 스레드 관리 자동화:
    • GCD는 스레드 풀을 관리하여 시스템 리소스를 효율적으로 사용한다.
    • Swift Concurrency도 내부적으로 Task Scheduler를 사용하여 스레드 관리와 태스크 스케줄링을 자동으로 최적화한다.
  4. QoS (Quality of Service):
    • 두 기술 모두 작업의 우선 순위를 지정할 수 있습니다.
      • GCD에서는 DispatchQoS를 사용해 작업 우선 순위를 설정한다.
      • Swift Concurrency에서는 Task의 우선 순위를 조정할 수 있다 (Task(priority: .high) 등).
  5. 캔슬 가능한 작업:
    • GCD에서 작업을 수동으로 취소할 수 있는 것은 아니지만, Swift Concurrency에서는 Task를 취소할 수 있다. 다만, GCD에서도 DispatchWorkItem을 사용하여 작업을 취소할 수 있는 형태로 구현할 수 있다.
    • Swift Concurrency에서는 Task.checkCancellation() 등을 사용해 비동기 태스크 내에서 취소 상태를 확인할 수 있다.

 

요약

공통점 GCD (Grand Central Dispatch) Swift Concurrency (Async/Await)
비동기 작업 처리 DispatchQueue.async {} async/await, Task
멀티 스레딩 지원 다양한 DispatchQueue Task 스케줄러
스레드 관리 자동화 자동으로 스레드 풀 관리 Task 스케줄러로 자동 최적화
우선 순위 제어 DispatchQoS Task(priority:)
작업 취소 지원 DispatchWorkItem (부분적으로 지원) Task.cancel(), Task.checkCancellation()

 

특징 GCD (Grand Central Dispatch) Swift Concurrency (Async/Await)
개념 스레드 풀을 사용해 작업을 비동기적으로 처리하기 위한 API. Swift 5.5에서 도입된 구조화된 비동기 프로그래밍 모델.
도입 시기 iOS 4 iOS 15, macOS 12
사용 방식 큐를 사용해 작업을 비동기적으로 추가하고, 콜백을 사용해 결과 처리. async/await 키워드를 사용해 코드 흐름을 동기적으로 작성.
코드 가독성 콜백 지옥 (Callback Hell) 발생 가능 코드 흐름이 동기 코드와 유사하여 가독성이 높음
성능 최적화 스레드 풀 관리, 우선순위 조정 등 수동으로 최적화 가능 시스템이 자동으로 최적화 (더 나은 스케줄링)
에러 처리 콜백 내에서 수동으로 에러 처리 do-catch 블록을 통한 구조화된 에러 처리
캔슬레이션 지원 수동으로 작업 취소 관리 Task 객체를 통한 내장된 캔슬레이션 지원
메모리 관리 클로저 캡처에 주의해야 하며, weak self를 사용해 메모리 누수 방지 async/await는 메모리 안전성을 자동으로 보장
주요 사용 사례 레거시 코드, iOS 14 이하 호환성 최신 iOS 프로젝트, 비동기 코드 리팩토링

 

GCD (Grand Central Dispatch) 샘플 코드

import UIKit

func fetchDataWithGCD() {
    let url = URL(string: "https://www.apple.com")!
    
    // 네트워크 요청을 백그라운드에서 수행하고, 메인 스레드에서 UI 업데이트를 수행
    DispatchQueue.global(qos: .userInitiated).async {
        // 클로저 내부에서 self를 캡처하기 때문에 메모리 누수 방지를 위해 [weak self]를 사용해야 한다.
        guard let data = try? Data(contentsOf: url) else { return }
        DispatchQueue.main.async {
            print("Data fetched: \(data)")
        }
    }
}

fetchDataWithGCD()

 

Swift Concurrency (Async/Await) 샘플 코드

import Foundation

func fetchData() async {
    let url = URL(string: "https://www.apple.com")!
    
    do {
        // async/await를 사용해 네트워크 요청을 수행하고 결과를 처리 (비동기 방식)
        let (data, _) = try await URLSession.shared.data(from: url)
        print("Data fetched: \(data)")
    } catch {
        print("Error fetching data: \(error)")
    }
}

// Task를 생성하여 비동기 함수 호출
Task {
    await fetchData()
}

 

iOS 15 이상을 타겟으로 하는 프로젝트에서는 Swift Concurrency (async/await)를 사용하는 것이 코드 가독성, 자동 메모리 관리, 에러 처리 등에서 GCD에 비해 이점이 있다.

 

반응형
블로그 이미지

SKY STORY

,
반응형

GitHub에서 포크한 저장소를 삭제하는 방법은 다음과 같다:

  1. GitHub에 로그인: GitHub 계정으로 로그인한다.
  2. 저장소 페이지로 이동: 삭제하려는 포크된 저장소 페이지로 이동한다.
  3. Settings (설정) 메뉴로 이동:
    • 저장소의 상단 메뉴에서 Settings 탭을 클릭한다.
  4. 저장소 삭제 옵션으로 이동:
    • Settings 페이지의 하단으로 스크롤하여 Danger Zone 섹션에서 Delete this repository 버튼을 클릭한다.
  5. 확인 및 삭제:
    • 나타나는 팝업 창에 저장소 이름을 정확히 입력한 후, 삭제 확인을 위해 다시 한 번 I understand the consequences, delete this repository 버튼을 클릭한다.

이 과정을 완료하면 포크한 저장소가 삭제된다. 

만약 포크한 저장소가 너무 많아서 일일이 삭제하기 어려운 경우, GitHub CLI를 사용하면 쉽게 일괄 삭제할 수 있다.

  1. GitHub CLI 설치: GitHub CLI가 설치되어 있지 않다면 GitHubCLI설치가이드에 따라 설치한다.
  2. GitHub 로그인:명령어를 입력하고, 지시에 따라 GitHub 계정으로 로그인한다.
    gh auth login
  3. 포크된 저장소 리스트 확인: 모든 포크된 저장소를 확인하려면 다음 명령어를 사용한다.
    gh repo list YOUR_USERNAME --fork --json name
  4. 포크된 저장소 일괄 삭제: 특정 조건을 만족하는 포크만 삭제하려면, 스크립트를 이용해 필터링하여 삭제할 수 있다. 아래는 모든 포크된 저장소를 삭제하는 예제이다.  주의: 이 스크립트는 본인 계정의 모든 포크된 저장소를 반복적으로 삭제한다.
    gh repo list YOUR_USERNAME --fork --json name -q '.[].name' | while read repo; do gh repo delete YOUR_USERNAME/$repo --confirm done

 

다른 방법으로 GitHub 개발자 설정에서 토큰을 발급 받은 후 아래와 같이 python 코드를 사용하여 삭제도 가능하다.

import requests
import time

# GitHub 개인 액세스 토큰과 사용자 이름
TOKEN = 'github_pat_11ABHO ... Q5L5R6ly7vhP'
USERNAME = 'YOUR USERNAME'

# GitHub API URL 설정
API_URL = f'https://api.github.com/users/{USERNAME}/repos'

# 요청 헤더 설정
headers = {
    'Authorization': f'token {TOKEN}'
}

# 저장소 목록 가져오기
response = requests.get(API_URL, headers=headers)

# 응답 상태 코드 확인
if response.status_code != 200:
    print(f"API 요청 실패: {response.status_code}, {response.text}")
else:
    repos = response.json()

    # 포크된 저장소만 필터링하여 삭제
    for repo in repos:
        if isinstance(repo, dict) and repo.get('fork') and repo.get('owner', {}).get('login') == USERNAME:
            repo_name = repo['name']
            delete_url = f'https://api.github.com/repos/{USERNAME}/{repo_name}'
            delete_response = requests.delete(delete_url, headers=headers)

            if delete_response.status_code == 204:
                print(f'{repo_name} 삭제 완료')
            else:
                print(f'{repo_name} 삭제 실패: {delete_response.status_code}, {delete_response.text}')
            
    print("모든 포크된 저장소 삭제 작업이 완료되었습니다.")

위 코드 실행시 약 25개정도 삭제될때마다 API 요청이 거절된다. 이유는 GitHub API는 짧은 시간에 많은 요청이 들어오면 요청을 제한하거나 차단한다. 요청시 일정 시간 딜레이를 주거나 여러번 실행하여 해결할 수 있다.

 

 

반응형
블로그 이미지

SKY STORY

,
반응형

1. 보안 칩의 존재: 테슬라 카드에는 단순한 NFC 태그가 아니라 보안 칩이 내장되어 있다. 이 칩은 카드와 차량 간의 인증을 위해 복잡한 암호화 연산을 수행하며, 단순히 카드의 데이터를 복제하는 것만으로는 이 칩의 기능을 모방할 수 없다.

2. 암호화된 동적 인증: 카드와 차량 간의 인증 과정에서 동적 키회전 키 같은 보안 기술이 사용된다. 이 기술은 시드 값이나 난수를 기반으로 카드가 매번 다른 암호화된 응답을 생성하는 방식이다. Proxmark3로 카드의 raw 데이터를 읽어낸다고 해도, 카드가 차량의 인증 요구에 맞춰 생성하는 암호화된 응답을 복제할 수는 없다.

3. 암호화 알고리즘: 테슬라 카드의 보안 칩은 RSA나 ECC 같은 고급 암호화 알고리즘을 사용해 데이터를 보호한다. Proxmark3는 데이터를 캡처할 수는 있어도, 암호화된 응답을 해독하거나 같은 방식으로 암호화된 데이터를 생성하지 못한다.

4. 복제 불가능한 보안 프로토콜: 테슬라는 차량 보안을 위해 커스터마이즈된 보안 프로토콜을 사용하고 있을 가능성이 높다. Proxmark3가 카드의 UID나 기본 데이터를 복제할 수는 있지만, 차량과 카드 간의 인증에 필요한 프로토콜과 응답 생성은 구현할 수 없다.

 

이런 이유들로 인해 Proxmark3 같은 장비를 사용하더라도 테슬라 카드의 완벽한 복제는 불가능하다. 복제된 카드가 실제로 차량에서 작동하려면, 보안 칩이 제공하는 암호화 및 인증 기능을 모방할 수 있어야 하지만, 이는 불가능에 가깝다.

 

반응형

'IOT > Proxmark3' 카테고리의 다른 글

Proxmark3 V5 개발환경 구축 (4/4)  (1) 2021.02.08
Proxmark3 V5 개발환경 구축 (3/4)  (0) 2021.02.08
Proxmark3 V5 개발환경 구축 (2/4)  (0) 2021.02.08
Proxmark3 V5 개발환경 구축 (1/4)  (0) 2021.02.08
Proxmark3 RFID Tool  (0) 2021.02.08
블로그 이미지

SKY STORY

,
반응형

.gitignore에 my_ignore_folder/ 폴더를 추가했음에도 Git이 계속 해당 폴더의 변경사항을 추적하는 이유는, 이미 Git이 이전에 해당 폴더를 트래킹하고 있기 때문이다. .gitignore 파일을 설정한 후에는 Git에 해당 폴더를 무시하도록 아래와 같이 추가 조치를 취해보자.

  1. 추적된 my_ignore_folder/ 폴더의 캐시 삭제
    .gitignore에 추가된 폴더가 이미 Git에서 추적 중인 상태라면 캐시를 삭제해야 한다. 
     
    git rm -r --cached my_ignore_folder/
  2. 변경 사항 커밋
    캐시에서 삭제된 내용을 커밋하여 기록에 반영한다.
     
    git commit -m "Remove my_ignore_folder folder from tracking"
  3. 푸시
    원격 저장소에 반영하려면 다음과 같이 푸시한다.
  4. git push

이 작업을 마친 후, my_ignore_folder/ 폴더는 .gitignore 설정에 따라 무시되어, 이후 변경 사항이 발생해도 Git이 추적하지 않게 된다.

만약 git rm -r --cached my_ignore_folder/ 명령을 실행했음에도 불구하고 my_ignore_folder/ 폴더가 여전히 Git에서 추적되고 있다면, 다음 사항들을 점검하고 추가 조치를 취해보자.

  1. .gitignore 파일이 제대로 설정되었는지 확인
    • .gitignore 파일에서 my_ignore_folder/ 경로가 올바르게 작성되었는지 다시 한번 확인한다.
    • .gitignore 파일이 Git의 루트 디렉토리에 위치해 있는지 확인한다. 프로젝트의 루트 디렉토리가 아니라면 무시되지 않을 수 있다.
  2. .gitignore 파일에 추가적인 경로 지정
    • .gitignore에 my_ignore_folder/ 외에 my_ignore_folder/*과 같은 패턴을 추가해 보세요. 간혹 Git이 하위 파일을 인식하는 경우가 있기 때문에, 아래와 같이 설정할 수도 있습니다:
       
      my_ignore_folder/
      my_ignore_folder/*
  3. git status로 확인
    • 터미널에서 git status 명령을 실행하여 my_ignore_folder/가 추적되고 있는지 확인해보자.
  4. 폴더 강제 삭제 후 커밋
    • 위 방법이 모두 실패한 경우, 강제로 my_ignore_folder/ 폴더를 무시하도록 처리한다.
      git rm -rf --cached my_ignore_folder
      git commit -m "Force ignore my_ignore_folder folder"
      git push
    • 이 명령어는 캐시에서 삭제를 강제하여 .gitignore 파일이 무시되도록 한다.
  5. 로컬 및 원격에 남아 있는지 확인
    • 최종적으로 SourceTree나 다른 Git 클라이언트를 사용하여 로컬과 원격 브랜치 모두에 my_ignore_folder/폴더가 여전히 남아 있는지 확인한다.

 

반응형
블로그 이미지

SKY STORY

,
반응형

아래 오류 메시지는 git push 과정에서 네트워크나 git 서버 쪽에서 발생한 500 오류로 인해 연결이 끊어진 상황을 나타낸다. 이 문제는 주로 네트워크 상태나 원격 서버의 일시적인 오류로 인해 발생할 수 있지만, 몇 가지 설정을 조정해보면 해결할 수 있는 경우도 있다.

git --no-optional-locks -c color.branch=false -c color.diff=false -c color.status=false -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree push -v --tags origin refs/heads/main:refs/heads/main 
Pushing to https://bitbucket.org/netcanis_workspace/gptapi.git
POST git-receive-pack (chunked)
error: RPC failed; HTTP 500 curl 22 The requested URL returned error: 500
send-pack: unexpected disconnect while reading sideband packet
fatal: the remote end hung up unexpectedly
Everything up-to-date
Completed with errors, see above

 

1. 캐시된 자격 증명 삭제 및 다시 로그인

git credential-osxkeychain erase

 

2. 푸시 버퍼 크기 증가

아래 설정은 500MB로 늘려주는 것으로, 서버와의 데이터 전송 오류를 해결할 수 있다. (대부분 이 문제이다.)

git config --global http.postBuffer 524288000

 

3. Bitbucket 서버 상태 확인

유지보수 작업등으로 인해 요류가 발생할 수 있다. (서버 상태를 확인해 본다.)

 

4. HTTP/2 사용 비활성화

일부 환경에서는 HTTP/2 프로토콜이 문제를 일으킬 수 있다. 아래 명령어를 통해 HTTP/2를 비활성화해 보자.

git config --global http.version HTTP/1.1

 

5. 다른 네트워크 사용

네트워크 연결 문제로 인해 푸시가 차단될 수 있다. 다른 네트워크(예: 핫스팟)로 전환 후 다시 푸시를 시도해 보자.

 

 

반응형

'개발 > Note' 카테고리의 다른 글

GitHub에서 포크한 저장소를 삭제  (0) 2024.11.06
특정 폴더 git 추적 삭제  (0) 2024.10.30
git 마지막 commit 취소, 메시지 수정  (0) 2024.10.16
BLE, Beacon, iBeacon  (0) 2024.01.11
BLE Advertising Payload format 샘플 분석  (1) 2024.01.11
블로그 이미지

SKY STORY

,
반응형

미래의 한국

by netcanis

 

한국의 인구 감소는 매우 빠른 속도로 진행되고 있다. 하지만 한국은 늘 그래왔듯 이번에도 해답을 찾을 것이다. 노동 인력의 감소를 보완하기 위해, 로봇과 인공지능(AI) 분야에서 세계적인 선두 주자로 자리 잡을 가능성이 크다.

현재 한국은 전 세계에서 사교육비 지출이 높은 국가 중 하나로, 학부모들이 막대한 비용을 투자하면서 고학력자가 빠르게 증가하고 있다. 향후 수십 년 안에는 대다수의 한국인이 고등 교육을 받은 인재가 될 가능성이 높지만, 이는 곧 사회 전반의 인력난과 특정 분야에 인재가 집중되는 현상을 심화시킬 수도 있다. 노동 시장의 불균형 속에서도 고학력화가 진행되는 한편, 필수 산업의 일손 부족 문제는 점차 더 심각해질 것이다.

인구 감소로 인한 인력 부족 문제는 초기에는 외국인 노동자를 유입시켜 해결하려 할 가능성이 크다. 그러나 로봇과 AI 기술이 발전함에 따라 이러한 인력은 점차 기술로 대체될 것이다. 이미 반복적인 단순 작업이나 위험하거나 고된 일자리에는 점차 로봇과 AI 기술이 도입되고 있으며, 앞으로 이러한 추세는 더욱 가속화될 전망이다.

이러한 도전에 대해 한국 사회가 이를 방관하지는 않을 것이다. 한국은 과거 수많은 도전과제에서 혁신적 해법을 찾아왔던 것처럼 이번에도 인구 감소 문제에 대한 해결책을 반드시 찾아낼 것이라 믿는다.

 

반응형

'생각의 조각들' 카테고리의 다른 글

진정한 용기  (4) 2024.11.16
인공지능의 학습 한계  (0) 2024.10.10
Breaking Free from Musical Conventions  (0) 2024.10.06
게으른 야망의 딜레마  (0) 2024.10.06
성공과 실패  (0) 2024.10.02
블로그 이미지

SKY STORY

,
반응형
 

알림 메시지, 데이터 메시지 차이점을 알아보자.


구분 알림 메시지 (Notification Message) 데이터 메시지 (Data Message)
목적 시스템이 자동으로 알림 표시 앱이 직접 알림을 처리해야 함
앱 상태 백그라운드/완전 종료에서도 알림 표시 가능 포그라운드 상태에서만 앱이 직접 처리 가능
구성 제목, 본문, 이미지 등 알림 내용 포함 데이터 키-값 쌍으로 구성
사용 예 간단한 알림 전송에 유용 앱에서 특정 작업 수행에 유용
배너 알림 표시 자동으로 베너 알림 표시 앱이 포그라운드일 때 코드로 구현 가능
예시 코드 { "notification": { "title": "알림 제목", "body": "알림 내용" } } { "data": { "key1": "value1", "key2": "value2" } }

 

요약 

알림 메시지 : 시스템이 자동으로 베너 형태의 알림을 관리해주며, 앱의 상태와 무관하게 표시된다.

데이터 메시지 : 앱이 실행 중일 때만 앱 내 코드로 처리할 수 있다. 베너 알림을 표시하려면 직접 구현해야 한다.

 

반응형

'개발 > Android' 카테고리의 다른 글

<application> 및 <activity> 태그 속성과 하위 요소  (0) 2024.10.25
멀티라인 Toast 메시지 출력  (0) 2024.10.24
NFC 권한설정  (1) 2024.10.21
NdefFormatable 태그  (0) 2024.10.21
NFC Tag 상세정보 출력  (2) 2024.10.18
블로그 이미지

SKY STORY

,