[안드로이드] 루팅 기기 체크하는 법 (Rooted device detection) 루팅 여부 체크를 위해서 새로 개발하기 귀찮으니 Rootbeer를 사용하고 있었는데, 루팅이 되어있지 않은 기기에도 루팅되었다는 false positive 케이스가 나와서 다른 방법을 찾아보게되었다. 오류 리포팅을 위해 Sentry를 앱에서 사용하고 있었는데, Sentry에서 root 체크가 되길래 Sentry의 RootBeer와 RootChecker 클래스를 참고하여 만들었다. RootBeer의 간단한 버전이라고 보면 되겠다. 프로그래밍/Android 2021.04.17
[블록체인] NFT 거래소에 내 그림을 파는 방법, NFT 만들기 (Opensea.io) NFT 무슨 그림이 72억에 팔렸다더라...일론 머스크 부인이 20분만에 60억을 챙겼다더라하는 뉴스를 보면 NFT라는 말이 등장한다. NFT란 Non-Fungible Token, 대체 불가능한 토큰이다. Fungible Token의 하나인 비트코인을 예로 들자면 나의 1 BTC와 일론 머스크가 가진 1 BTC는 동등한 가치를 지닌다. 서로 교환해도 가치가 같으니까 되는거다. 반면, NFT는 내가 가진 토큰과 다른 사람이 가진 토큰의 가치가 상이해서 1:1 교환을 할 수가 없다. 똑같은 캔버스 사이즈에 그린 피카소의 그림과 고흐의 그림처럼 말이다. 모든 디지털 자원을 NFT로 만들 수 있고, NFT의 이러한 특성때문에 현재 거래소에는 그림, 움짤, 가상 세계의 땅 등이 활발하게 거래되고 있다. 흠! 다른.. 프로그래밍/Blockchain 2021.04.14
[JD-GUI] 실행시 오류 해결방법 No suitable Java version found on your system! No suitable Java version found on your system! This program requires Java 1.8+ Make sure you install the required Java version. BigSur에서 JD-GUI를 실행시켰더니 이런 오류가 뜨며 안될 경우 JD-GUI 아이콘 우클릭 > 패키지 내용 보기 > Contents/MacOS/universalJavaApplicationStub.sh에 다음 라인을 추가한 후 저장한다. 위치는 주석 끝나고 맨 처음으로! export JAVA_HOME=$(/usr/libexec/java_home -v11) 이제 JD-GUI를 켜면 제대로 작동된다. 프로그래밍/General 2021.04.11
[안드로이드] 색상 변화 애니메이션 만들기 (ValueAnimator / Color change animation) Target API 21 이상으로 설정한다. private fun animateRainbow() { val anim = ValueAnimator.ofArgb( Color.RED, Color.YELLOW, Color.GREEN, Color.BLUE, Color.MAGENTA ).apply { duration = 1000 * 5 repeatCount = ValueAnimator.INFINITE repeatMode = ValueAnimator.REVERSE addUpdateListener { // tvRainbow가 TextView이다. binding.tvRainbow.setBackgroundColor(it.animatedValue as Int) } } anim.start() }각 컬러 값들은 ContextC.. 프로그래밍/Android 2021.04.10
[안드로이드] 앱이 버벅거리지 않게 하기 위해서 해야할 일 앱이 버벅댄다는건, 60FPS가 나오지 않는 상태를 의미한다. 16ms마다 그리기를 완성해야하는데 작업량이 많아 그것보다 시간이 더 걸리게되면 사용자가 알아채기 시작한다. 버튼이 그려지기까지의 과정 버튼같은 UI 오브젝트들은 먼저 CPU에의해 폴리곤(Polygon)과 텍스쳐(Texture)로 변환되어야한다. 이 변환 작업도 시간이 많이 걸리며(time-consuming), 이들을 CPU에서 OpenGL ES API를 통해 GPU로 업로드하는 작업도 시간이 많이 걸린다. GPU는 이들을 픽셀로 바꾸어 스크린에 보일 수 있게 만든다. 이 작업을 래스터화(Rasterization)라고한다. GPU로 올라간 메쉬(mesh)는 곧바로 사라지지않고, GPU에 머물게되고 나중에 사용할 일이있을때 재사용하게 된다. 메.. 프로그래밍/Android 2021.03.31
[Git] 빠르게 알아보는 Rebase VS Merge의 차이 Merge $ git pull // C1 $ git switch feature-2 // C6 $ git merge master // C7 Rebase $ git switch master // C1 $ git pull // C4 $ git switch feature-2 // C6 (09qr2) $ git rebase master feature-2 // C6 (a2b51) Rebase를 사용하는 이유 히스토리를 깔끔하게 유지하기 위해서 Rebase시 주의할점 Rebase는 히스토리를 지운다. 이로인해 Conflict가 날수도 있고, 데이터의 유실이 일어날 수 있다. 다른사람이 그 Branch에서 작업중일 수도 있기 때문에 공개된 (다른사람들이 접근할 수도있는) Branch에서 Rebase하면 안된다. 프로그래밍/General 2021.03.29
[안드로이드] V3 구글 인앱 결제 쉽게 구현하기 2021 - 정기결제 구독 상품편 Quick Links 강의 1 편 - 설정 강의 2편 - 인앱상품 강의 3편 - 구독상품 Github 예제 코드 이번에는 정기결제 상품 인앱 결제를 구현해 보도록 하겠습니다. 어떤 앱을 만들게 될지 짧은 동영상으로 먼저 보시죠! 아래 기능들을 구현해볼겁니다. - 정기결제 상품 정보 표시 - 정기결제 상태 확인 - 정기결제 업그레이드, 다운그레이드 - 정기결제 하기 구현에 앞서 참고 사항 라이브러리 구성과 같은 부분은 이전 인앱 결제하기 포스팅에서 따라하시고 오시면됩니다. 그 밖에 결제모듈에 대한 설명들도 모두 여기에서 하고있으니 이 포스팅을 보셨다는 가정하에 글을 쓰도록 하겠습니다. 화면 구성 화면쪽은 역시 빠르게 넘어가도록 하겠습니다. activity_subscription.xml Subscriptio.. 프로그래밍/Android 2021.03.22
[안드로이드] V3 구글 인앱 결제 쉽게 구현하기 2021 - 인앱 상품편 Quick Links 강의 1 편 - 설정 강의 2편 - 인앱상품 강의 3편 - 구독상품 Github 예제 코드 이제 인앱 상품 결제를 구현해 보겠습니다. 정확히 어떤 앱이 만들어질지 직접 동영상으로 확인 해 보세요! 1회성 구매 파트가 이번 포스팅 파트입니다. - 광고제거, 크리스탈 충전 상품정보를 받아와서 화면에 표시 - 광고제거 구매, 구매여부 체크 - 크리스탈 구매, 크리스탈 충전 구현에 앞서 참고사항 예제 코드들은 Kotlin으로 되어있으며, 비동기 처리에 Coroutine을 사용하기도 합니다. 하지만 Coroutine을 사용하지 않고 콜백형식으로 구현하는 방법도 간단히 설명드릴 예정입니다. (Kotlin과 Java의 전환이 어려우시다면 제 예전 글을 참조하셔서 Kotlin을 빠르게 배워보세요!.. 프로그래밍/Android 2021.03.21
[안드로이드] V3 구글 인앱 결제 쉽게 구현하기 2021 - 설정편 Quick Links 강의 1 편 - 설정 강의 2편 - 인앱상품 강의 3편 - 구독상품 Github 예제 코드 최근에 Google Play로 부터 아래와 같은 내용의 메일을 받으신 분들이 있을겁니다. 옛날 버전의 결제 모듈을 사용하고 계시다면, 이번 기회에 저와 함께 따라하면서 바꿔보세요! 앱이 이전 버전의 Google Play 결제를 사용하는것으로 확인되었습니다. 2021년 11월 1일까지 모든 앱 업데이트가 결제 라이브러리 버전 3 이상 을 사용해야 합니다. 이 날짜 이전에 결제 라이브러리 버전 3로 업데이트하시기 바랍니다. 이번 편은 "설정편"입니다. Google Play에 앱을 등록하고, 결제 테스트가 가능하도록 설정하는 과정이 여기에 포함됩니다. APK 업로드 이전, APK 업로드 이후 부분으.. 프로그래밍/Android 2021.03.21
[Big Query] 빅 쿼리 UNNEST 사용법 / 개념 데이터 구조 이해하기 우리가, 아니 적어도 내가 일반적으로 봐 왔던 데이터들은 이렇게 Key-Value 쌍으로 이루어진 Record의 연속이었다. 그런데 이번에 회사에서 일하면서 Big Query를 만지게 되었는데 데이터 구조가 생판 처음보는 식으로 되어있었다! 그림으로 표현하자면...이렇게? 필드 하나가 배열이 될수도 있고, 구조체가 되거나 구조체의 배열까지 될수 있는 복잡한 구조다. 예제로 알아보기 그래서 '일반적인' SQL문으로 내가 원하는 데이터를 뽑아내기는 어렵고, 특별한 문법요소 하나를 더 써야하는데 그것이 바로 UNNEST이다. 손을 더럽히면서 배워보자. bigquery.cloud.google.com/dataset/firebase-analytics-sample-data:android_data.. 프로그래밍/SQL 2021.03.18