Android

    다국어 지원 (Wear OS)

    다국어 지원 (Wear OS)

    WearOS 용 Compose에서 Watch 단독사용을 가정한 설명입니다. 단순 언어 변경은 휴대폰과 페어링 돼있으면 6번은 할 필요 없이 안드로이드 디벨로퍼 사이트 단계를 따라 하시면 됩니다. 회사 프로젝트 중 워치에서 단독으로 다국어 지원할 경우가 생겨 구현해 봤습니다. 일반적인 워치앱은 휴대폰과 언어 설정이 동기화되어 코드로 강제전환 시킬 필요가 없지만 워치 단독 사용을 가정한 앱이라 넣었습니다. 과정 string.xml 정의 = Build.VERSION_CODES.TIRAMISU) { localeManager.applicationLocales = LocaleList.forLanguageTags("ko") } else{ LocaleListCompat.forLanguageTags("ko") } }) ..

    FusedLocationService로 위치 조회

    FusedLocationService로 위치 조회

    위치 인식 앱 빌드 | Android 개발자 | Android Developers 위치 인식 앱 빌드 모바일 애플리케이션의 고유한 기능 중 하나는 위치 인식 기능입니다. 모바일 사용자는 어디에나 기기를 휴대하기 때문에 앱에 위치 인식 기능을 추가하면 사용자에게 더욱 developer.android.com 안드로이드 공식문서에서 제공하는 위치 라이브러리입니다. 기존에 사용하던 LocationManager는 생각보다 정확하지 않아서 새로운 위치기반 API로 바꾸면서 정리해보려 합니다. 총 4단계로 의존성 주입 권한 설정 및 권한 검증 위치 기능 구현 사용 입니다. 의존성 주입 구글 위치 설정 라이브러리 의존성을 app 단 build.gradle에 넣어줍니다. //구글 위치 설정 라이브러리 implementa..

    SingleTon Holder로 편하게 SingleTon 쓰기

    SingleTon Holder로 편하게 SingleTon 쓰기

    class MyViewModel(){ companion object: SingleTonHolder } Compose에서 ViewModel로 데이터 전달을 하다 보니 항상 같은 인스턴스를 사용할 필요가 생겼습니다. 코드 1. 싱글톤으로 호출할 클래스의 생성자가 없는 경우 open class SingletonHolder (creator: () -> A) { private var creator: (() -> A)? = creator @Volatile private var instance: A? = null fun getInstance(): A{ val checkInstance = instance if(checkInstance != null) return checkInstance return synchroniz..

    ApplicationContext 일반 클래스에서 쓰기

    ApplicationContext 일반 클래스에서 쓰기

    개발하면서 Service가 아닌 Repository와 같이 사용자가 임의로 만든 클래스에서 Context가 필요한 경우가 있다. 일반적으로 패러미터로 넘기거나 클래스 생성자로 넘기는 방법이 있습니다. (생성자로 넘기게 되면 의존성이 강해지므로 권장하는 방법은 아니다. ) Context를 매번 넘길 필요 없이 어디에서든 ApplicationContext를 받는 방법이 있습니다. 만약 Context가 무엇인지 이해하지 못하고 있다면 아래글을 보는걸 추천드립니다. Context? 개발하면서 항상 헷깔렸던 Context에 대해 공식문서와 구글 검색을 통해 정리를 해봤다. 정의 문맥 또는 맥락은 언어학, 사회학에서 핵심이 되는 사건 주변의 실체 정의만 봤을 때 안드로이드에서 huzit.tistory.com 방법..

    [Retrofit 통신 실패]java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path $

    [Retrofit 통신 실패]java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path $

    원인 우리가 Response로 받을 거라 생각했던 타입과 실제 들어온 Response의 타입이 달랐을 때 발생하는 오류 해결 Response의 타입에 맞게 데이터 클래스를 선언해 주거나 오브젝트를 String으로 변환시켜 주는 ScalarsConverterFactory 라이브러리를 사용하거나 둘 중 하나를 택하면 된다. 2번을 선택할 경우 방법은 다음과 같다. 의존성 추가 implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' retrofit 선언부에 추가 .addConverterFactory(ScalarsConverterFactory.create()) val rt = retrofit2 .Retrofit .Builder() .baseUrl(bas..

    Key 1 was already used. If you are using LazyColumn/Row please make sure you provide a unique key for each item.

    Key 1 was already used. If you are using LazyColumn/Row please make sure you provide a unique key for each item.

    원인 LazyColumn 또는 LazyRow를 쓸 때 각 항목에 고유한 위치값을 안 썼기 때문 LazyColumn에 item을 추가하는 기능을 만들었을 때 발생할 수 있다. 기본 레이아웃일 경우 자체적으로 처리되지만 커스텀일 경우 items의 key 패러미터에 고유한 key값을 넘겨줘야 한다. itemsIndexed( items = cl, key = { index: Int, item: CheckListInfo -> item.hashCode() } ) 나의 경우 key값으로 item의 해시 값을 넣어줬지만 내용이 같으면 해시값도 같으므로 위와 같은 에러가 발생했다. 해결 간단하다. 안겹치는 고유한 키 값을 주면 된다. itemsIndexed( items = cl, key = { index: Int, _: ..

    Cannot figure out how to save this field into database. You can consider adding a type converter for it.

    Cannot figure out how to save this field into database. You can consider adding a type converter for it.

    원인 Room이 필드 타입을 인식하지 못해서 발생하는 문제, 보통 코틀린의 Basic Type이 아닌 직접 만든 데이터 클래스 리스트를 사용할 때 발생 Entity 클래스 @Entity(tableName = "checklist") data class CheckListEntity( @ColumnInfo(name = "checklist_info") var checkLists: List ){ @PrimaryKey(autoGenerate = true) var idx: Long = 0 } 데이터 클래스 data class CheckListInfo( //할 일 var checklistContent: String, //초기화 요일 var restartWeek: Set, //수행여부 var done: Boolean =..

    Navigation의 백스택을 관리해보자

    Navigation의 백스택을 관리해보자

    바텀 내비게이션과 내비게이션 컨트롤러를 이용한 프래그먼트의 이동을 구현하다 보면 꼬일 때가 있습니다. 위 상황처럼 홈에서 원 프래그먼트로 바로 이동하게 하면 다시 홈으로 갈 수 없는 것을 볼 수 있습니다. 왜 이런 상황이 발생하는지, 해결 방법이 무엇인지 알아봅시다. 내비게이션 백 스택의 구조 일반적인 내비게이션의 백스택입니다. 프래그먼트를 이동할 때마다 이전 프래그먼트가 백스택에 쌓이는 형식입니다. 그렇다면 바텀 내비게이션의 목적지는 어떨까요? 처음 바텀 내비게이션을 정의하면 목적지가 저장됩니다. 위에 보인 예제처럼 홈에서 임의로 액션을 정의하면 바텀 내비게이션의 목적지에 정의한 액션이 들어가게 됩니다. 따라서 위 gif처럼 바텀 내비게이션으로 홈 화면으로 돌아갈 수 없는 것입니다. 일반 내비게이션 백..