글

라벨이 Android인 게시물 표시

[Android] RecyclerView와 SeekBar 스크롤링 중첩

스크롤링 중첩 혹시 개발 중 스크롤링이 중첩되는 경험을 한 적 있는가? 위의 영상에서 보면 RecyclerView의 아이템이 가지고 있는 SeekBar를 조작할 때 RecyclerView의 가로 스크롤이 작동한다.  내가 원하는 건 SeekBar의 Progress를 조절하는 것인데 이게 RecyclerView에서 가로채서 스크롤링을 하는 것이다. 이렇게 되면 내가 원하는 그림이 나오지 않기 때문에 SeekBar에서 터치 이벤트가 일어나면 부모뷰(RecyclerView)에 이벤트를 전달하지 않는 방법으로 해결해보겠다. 터치 이벤트 중첩 해결 방법은 간단하다.  SeekBar를 상속받아서 이벤트 처리를 할때 requestDisallowInterceptTouchEvent() 를 호출하여 부모뷰로 이벤트를 전달하지 않는것이다.  class CustomSeekBar(context: Context, attributeSet: AttributeSet? = null): AppCompatSeekBar(context, attributeSet) { override fun onTouchEvent(event: MotionEvent?): Boolean { when (event?.action) { MotionEvent.ACTION_DOWN -> { parent.requestDisallowInterceptTouchEvent(true) } MotionEvent.ACTION_MOVE -> { parent.requestDisallowInterceptTouchEvent(true) } MotionEvent.ACTION_UP -> { parent.requestDisallowInterceptTouchEvent(true) ...

[Android] MotionLayout 직계가 아닌 하위 View의 animation 미작동

이미지
MotionLayout 하위 View가 작동을 안한다. 어느 날과 같이 앱을 개발 중이었다. 나는 MotionLayout을 이용해서 유튜브의 미디어바와 같은 걸 만들려고 했다. 아래는 MotionLayout 계층 구조다. 계층 구조 이런 구조다. 열심히 만들어서 이제 애니메이션을 작동해보는데 ConstaintLayout은 작동을 하는데 View1, View2, View3은 내가 작성한 motion_scene처럼 작동을 안하는 것이다.  정확히 말하면 애니메이션은 작동을 하는데 View1, View2, View3의 사이즈와 위치 등과 같은 것이 적용이 안되었다.  그리고 2시간을 내다버리며 찾은 결과를 아래에 글로 쓴다. 사실 MotionLayout 적용할때마다 이러는거 같아서 글로 남긴다. MotionLayout은 직계 하위 View만 적용이 가능하다. 우선 View1, View2, View3이 Motion Scene에 작성한대로 작동안하는 이유는 MotionLayout의 직계 View가 아니라서다. 그렇다! MotionLayout은 직계 하위 View에만 영향을 미친다!! 그래서 ConstraintLayout는 MotionLayout 바로 하위에 위치해서 잘 작동했지만 View1, View2, View3은 MotionLayout의 직계 하위 View가 아니다. 그래서 작동을 안한거다.  그러면 어떻게 수정해줘야 할까?  보통 ConstraintLayout이 MotionLayout에 필요한 경우는 그 사이즈대로 하위 View의 위치를 제어하고 배경을 원하는 것으로 고정하기 위해서다. 그래서 나는 View1, View2, View3을 MotionLayout 하위로 이동시키고 ConstraintLayout은 프레임으로만 쓰기로 했다.  우선 아래는 수정 전 코드다. <? xml version ="1.0" encoding ="utf-8" ?> <layout> ...

[Android] 빌드 에러 - NoSuchAlgorithmException: Algorithm HmaxPBESHA256 not avaliable

이미지
에러 및 원인 AAB로 앱을 빌드하고 있는 데 갑자기 에러가 발생했다.  Android Studio 업데이트 전에는 빌드하는 데 문제가 없었다. 그래서 막연히 Android Studio 버전 문제라고 생각했다. 에러메세지는 위와 같이 떴다. 에러 메세지의 마지막 줄을 보면 NoSuchAlgorithmException: Algorithm HmaxPBESHA256 not avaliable 을 볼 수 있다. 이거 때문에 KeyStore에서 Key를 읽는게 실패했다는 뜻이다. 우선  HmaxPBESHA256 가 그렇다면 뭔지부터 확인해봤다.  HmaxPBESHA256 은 해시 기반 메세지 인증 코드(HMAC)를 사용하여 SHA-256 해시 함수를 암호화하는 기술이라고 한다. 이 알고리즘은 JDK 8 이상에서 지원한다. 최근 JDK에서도 이 알고리즘을 지원하다고 한다.  나는 각 버전마다 알고리즘이 동일하지가 않을 수 있다고 생각이 들었고 첫번째로 한 것은 JDK 버전을 확인했다. 동일하게 JDK 11.0.8을 사용했지만 이 방법으로는 계속 에러가 났다.  만약 JDK 버전을 동일하게 세팅을 했는데도 에러가 생긴다면 아래 방법을 참조한다. 해결 방법 우선 JDK 버전을 동일하게 설정했지만 같은 에러가 난다면 직접 JDK 경로를 지정해서 key를 생성한다. windows라면 cmd를 켜고 Mac이면 터미널을 연다. 아니면 Android Studio에 있는 Terminal에서 실행해도 무관하다. 1. JDK 경로 지정해서 Keystore 및 Key 생성 명령어 [JDK 경로]\bin\keytool -genkey -v -keystore [Keystore 경로] -keyalg RSA -keysize 2048 -validity 9125 -alias [키 이름] -storetype JKS 예시 C:\Java\jdk-11\bin\keytool  -genkey -v -keystore...

[Android] 코드 난독화와 Proguard

이미지
코드 난독화와 Proguard 코드 난독화는 프로그래밍 언어로 작성된 코드에 대해 읽기 어렵게 만드는 작업이다. 코드의 가독성을 낮춰 리버스엔지니어링의 대비책으로 사용된다.  Proguard는 자바 기반 코드를 난독화해주는 도구로, 난독화(Renaming), 용량 축소, 코드 추소, 최적화 등의 기능을 제공한다. 여기서 Proguard의 난독화는 식별자 전환, 클래스/메소드의 이름을 a,b,c 등 의미없는 이름으로 대체해주는 기능이다.  난독화의 종류는 다양하고 Proguard가 제공하는 난독화 기능은 정말 보안에 있어서 최소한의 성의다.  Proguard 설정 방법 설정은 매우 쉽다. App의 build.gradle 에 proguard의 설정을 true로 변경해주면 된다. bulid.gradle (:app) android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles('proguard-rules.pro') } debug { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles('proguard-rules.pro') } } } 위에 코드는 release와 debug 각각에 대한 proguard 설정이다. release와 debug에 대한 prog...

[Android] Kakao map API를 이용해서 지도 그리기

이미지
카카오 지도 API를 사용해서 앱에 지도를 그려볼것이다. 대표적인 지도 API에는 구글, 네이버, 카카오가 있다. 이번에 카카오 인증을 써야해서 지도 API도 카카오 지도를 사용하기로 결정했다. 카카오 지도 API는 구글이나 네이버에서 제공하는 지도 API와 비슷한데 다른 점은 애뮬레이터에서는 작동이 안되고 실물폰에서만 된다는 것이다. 이 부분도 설정을 추가하여 애뮬레이터에서도 작동할 수 있도록 하겠다. Android Studio 설정 1. settings.gradle 파일에 kakao SDK 추가 후 Sync now plugins { ... id 'org.jetbrains.kotlin.android' version '1.7.10' apply false id 'com.google.gms.google-services' version '4.3.13' apply false } 2. 앱 단의 build.gradle( build.gradle (:app) )에 kakao SDK 추가 후 Sync now android { ... defaultConfig { ... // 애뮬레이터에서 카카오 지도 맵을 사용하기 위한 설정 ndk { abiFilters 'arm64-v8a', 'armeabi-v7a' } } } dependencies { ... implementation "com.kakao.sdk:v2-user:2.12.1" // 카카오 로그인 모듈 (keyHash값 때문에 설정) implementation 'com.kakao.maps.open:android:2.6.0' // 카카오 맵 API } 3. res/values 폴더 마우스 우클릭 ...

[Android] Kakao 계정으로 Firebase Authentication 연동

이미지
Firebase의 Authentication은 손쉽게 로그인 기능을 구현해준다. Google, Facebook, Twitter, Github 등의 계정으로 사용자 인증을 가능하게 해준다. 위에 사진을 보면 어떤 로그인 제공업체가 있는지 알 수 있다. 익숙한 제공업체들이 보이는데 나는 Kakao 계정으로 Firebase와 연동하는게 필요했다. 공식문서를 뒤지고 구글링을 하니 커스텀 토큰 을 만들어서 Firebase Authentication의 인증을 받을 수 있는게 있다고 한다. 오..근데 문제가 있다. 커스텀 토큰을 만들때 JWT라는 토큰을 생성하고 다시 클라이언트(앱 사용자)에게 전달해줘야하는 서버가 필요한 것이다. 주니어 안드로이드 개발자로서 백엔드는 생소할 수 있다. 그래서 최대한 쉽게 설명하고자 한다. 참고로 JavaScript와 TypeScript가 아직 익숙하지 않아서 이상한 부분이 있다면 댓글로 알려주세요. 방법 소개 Firebase Authentication과 Kakao 로그인을 연동한다면, 무조건적으로 Firebase를 쓴다는 말이다. Firebase는 serverless다. 서버 없이도 서비스를 구현할 수 있게 도와준다는 말이다. 당연하게도 백엔드 서버처럼 함수 호출을 할 수 있는 기능을 제공해준다. 바로 Firebase Functions 이다. 우린 바로 이것을 사용할 것이다. javaScript 파일로 함수를 만들어서 배포하면 API 서버처럼 Firebase Functions으로 함수 호출이 가능하다. 이와 비슷한 제품으로는 AWS의 AWS Lambda가 있다. 다만, Firebase Functions 기능을 쓰려면 무료 요금제(spark)로는 안된다. 요금제 업그레이드(Blaze)가 필요하다. 프로세스 출처 : 초고강도 수정 위에 사진은 카카오 인증부터 Firebase Functions을 사용한 JWT 반환 후 Authentication에 인증하는 과정이다.  처음에 ...

[Android] 비동기 처리 방법 with MVVM 패턴

이미지
왜 필요한가? 정확하게 말하면 Activity에서 바로 Retrofit의 enqueue 를 호출해서 비동기적으로 처리하면 다른 특별한 방법은 필요없다. 이게 바로 비동기 처리 방법이기 때문이다. (코드예시 : 수정하기 전 코드) * Call.enqueue는 비동기적으로, Call.excute는 동기적으로 처리한다. 하지만 우리는 개발을 하면서 다양한 아키텍쳐 디자인 패턴을 사용하게 된다. 아키텍쳐 디자인 패턴을 적용하게 되면 코드가 분리되는데 데이터를 조회하는 코드도 분리가 된다. 이런 경우에는 데이터 조회하는 클래스에서 화면을 보여주는 클래스로 이 데이터를 전달하는 과정이 필요하다. 예를 들어, Repository에서 데이터를 조회한 후, ViewModel에 이 데이터를 저장하거나 거쳐서 Activity에 이 데이터를 화면에 보여주는 것이다. 이 경우에 ViewModel이나 Repository에서 어떻게 Activity까지 결과값을 전달해올지가 물음표다. 어떻게 넘겨야할지 감도 안잡힐수도 있다. 데이터를 가지고 와서 보여주기위해 Activity에서 ViewModel을 호출하고, ViewModel은 Repository의 데이터 호출 함수를 호출한다. 그럼 ViewModel과 Repository에서 데이터 호출을 실행하는 동안 비동기 처리를 안해주면 데이터를 조회해와도 Activity에 전달을 못하거나 Activity의 Thread가 멈추는 불상사가 발생한다. 그래서 이 글에선 Callback, Coroutine, Flow 등을 이용한 방법으로 데이터 조회하는 코드가 분리되는 경우 어떻게 비동기적으로 처리하는 지 기록한다. 깔끔하고 재사용성이 좋은 코드를 위해 MVVM 패턴으로 변경할 것이다. 이 글은 패턴에 대한게 중점이 아닌 비동기 처리 방법이 중점이므로 패턴 설명에 대한 것은 생략한다. 아래는 MVVM 패턴으로 적용하면서 다양한 비동기 처리 방법에 대한 내용이다. 수정하기 전 코드 참고로 아래 코드는 앱 만들다...