Android

- 캘린더형 위젯을 지원 중인데, 자정이 지나도 위젯이 갱신되지 않고 전날 날짜가 그대로 유지되는 현상이 발견되었다. - 자정이 되는 시점을 감지하고, 위젯을 update 시켜주는 로직 구성 작업이 필요했다.  - 안드로이드 4대 컴포넌트 중 하나인 BroadcaseReceiver를 사용하면 된다.What are the four components of an android application?ActivitiesServicesBroadcast ReceiversContent Providers- 자정 시간을 알람 시간으로 등록하고 해당 시간이 되면 PendingIntent를 통해 리시버를 동작시킨다.class MidNightReceiver: BroadcastReceiver() { override fun..
- 보통 뷰에 특정 배경색 또는 테두리 효과를 주입하는 것은 아래처럼 drawable XML 소스를 구현하면 된다.  - 하지만 테두리의 경우 그러데이션을 자체적으로 지원하지는 않은 것으로 확인되어 Paint를 활용해 그려서 커스텀 뷰를 구현하는 작업을 진행했다.class GradientStrokeButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatImageButton(context, attrs, defStyleAttr) { private var cornerRadius = 0f private var bord..
- 자사 서비스에서 Realm DB를 활용하고 있다. - Realm DB는 빠르고 가벼운 로컬 데이터 저장을 위한 객체 기반 데이터베이스이다.  - Realm DB의 객체로 리스트를 구성할 때는 RealmRecyclerViewAdapter를 이용하여 구성할 수 있다. - 내부 구성은 일반 RecyclerView와 크게 다르지 않다. 하지만 getItem 등의 함수가 RealmDB 자체에서 오리지널 인스턴스를 가져오는 방식으로 동작한다./** * Returns the item in the underlying data associated with the specified position. * * This method will return {@code null} if the Realm instance has ..
- 기존 프로젝트 내에 인앱 결제 관련 로직이 너무 노후화되어 있었고, 함수도 분산되어 있어서 관리하기가 난해했다. - 최근에 모듈을 최신화하면서 주요 함수를 BillingManager라는 싱글톤 object로 정리했는데, 그 내용을 기록해 본다.결제 모듈 초기화object BillingManager { private var billingClient: BillingClient? = null /** * 결제 모듈 초기화 완료 여부 */ fun isReady(): Boolean { val client = this.billingClient ?: return false return client.isReady }- 결제 모듈 초기화 완료 여부를 확인하는..
- 페이징 라이브러리를 사용한 것은 아니고, 파라미터로 page: Int를 보내고 response로 hasNext: Boolean을 수신받을 수 있는 형태의 api에서 페이징을 자체 코드로 간단하게 구현한 예시다.상단 구성 - Scaffold 구조로 상단에 TopAppBar를 가지고 내부 content로 리스트를 가지는 화면에서 페이징을 구성했다.Scaffold(topBar = { TopAppBar(modifier = Modifier.padding(start = 12.dp), title = { Text() }, navigationIcon = { IconButton(modifier = Modifier .size..
((Vibrator)AppCore.context.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(10);- 기존 코드에서 사용하던 디바이스 진동 효과를 발생시키는 vibrate 코드가 deprecated 되어 있었다. - 10m/s 동안만 일시적으로 진동을 울리는 코드인데, Android O(26)부터 아래와 같이 수정이 필요하다.Vibrator vibrator = (Vibrator) AppCore.context.getSystemService(Context.VIBRATOR_SERVICE);if (vibrator != null && vibrator.hasVibrator()) { // 진동 기능이 있는지 확인 vibrator.vibrate(Vibrat..
Places Api (New) 활용- 사내 프로젝트에 예전부터 Places SDK가 적용되어 위치 검색 기능을 담당하고 있었는데, 어느 시점부터 아래와 같이 오류가 표시되는 지역들이 증가하기 시작했다.- Google Places API(신규)는 기존 Places API를 대체하는 서비스로, 장소 검색, 자동완성, 상세 정보 조회, 좌표 변환 등의 기능을 제공한다. 그리고 데이터가 등록된 장소 개수 자체도 훨씬 많은 것으로 알고 있다. - 기존에 사용하고 있던 API Key가 있다면 Places Api (New)를 사용으로 설정한 뒤, 제한 목록에 추가해 주면 된다.- 신규, 기존 상관없이 적어도 아래 목록은 키 제한 API 목록에 포함시켜야한다. 그렇지 않다면 권한 거부 오류가 발생한다.Places SD..
- apng라는 파일 형식이 있다. PNG 포맷을 기반으로 한 애니메이션 이미지 포맷으로서 GIF와 비슷하지만 더 높은 품질과 투명도를 지원하는 특징이 있다. - 기존에 png, jpg, gif를 활용했었으나 용량 관리 측면에서 apng가 유리하여 새롭게 사용하게 되었다. - APNG 파일은 PNG와 동일한 구조를 가지므로, APNG를 지원하지 않는 프로그램에서도 정적인 PNG 이미지로 보일 수 있음 (하위 호환성) - 그래서 apng가 움직이지 않고 정적인 이미지로 보인다면, 사실 완벽한 렌더링에는 실패했거나 해당 기반 프로그램이 지원하지 않는 것 - 토스와 라인도 apng를 많이 사용하고, 라인에서 안드로이드에서 해당 형식 렌더링을 위한 라이브러리도 구현해 주어서 직접 사용해 봤다. https://g..
안드로이드 스튜디오를 업데이트하고 빌드하는데, 갑자기 위와 같은 오류가 발생했다.명확한 원인을 알기 힘들어서 여러 가지 삽질을 했다... 일단 Settings - Gradle에서 현재 사용 중인 자바 버전을 맞춰줬다. 그리고 ilbs.versions.toml 파일에서 코틀린 버전도 업데이트했다.[versions]accompanistSystemuicontroller = "0.36.0"activityComposeVersion = "1.8.0-alpha07"agp = "8.5.0"biometric = "1.2.0-alpha05"converterGson = "2.9.0"glanceAppwidget = "1.1.1"hiltAndroid = "2.44"kotlin = "1.9.23"coreKtx = "1.12.0"..
- 운영 중인 서비스 로직은 서버로부터 새로운 리소스를 받으면 항상 고정된 경로의 로컬 파일 Storage 경로로 저장을 하고, Glide로 해당 이미지 리소스를 렌더링 하고 있었다. - 그런데 어느날 서버로부터 변경된 리소스를 내려받아도 렌더링 단계에서 해당 리소스가 갱신되지 않는 문제를 발견. - 분명히 로컬 저장 단계까지 변경된 리소스가 저장되는 것까지 확인했으나 원인은 Glide 동작 설정에 있었다. - Glide는 기본적으로 캐싱 기능을 가진다. 디스크 캐시와 메모리 캐시를 활용하여 이미지를 빠르게 로드하고 불필요한 네트워크 요청을 줄이는 기능을 가지고 있다.1. 메모리 캐시 (Memory Cache)이미 로드된 이미지를 RAM에 저장하여 빠르게 다시 불러올 수 있도록 함앱이 종료되거나 메모리가..
SeungYong.Lee
'Android' 태그의 글 목록 (9 Page)