[안드로이드 트러블 슈팅] 인앱 다국어 설정 버그 Android 13, Android 14

2024. 3. 8. 11:30·안드로이드/트러블 슈팅
반응형

안녕하세요. 이번 포스팅에서는 안드로이드 개발 실무에서 겪었던 이슈와 해결과정에 대해 적으려고 합니다. 제가 개발 중인 앱은 앱 내에 언어를 설정할 수 있는 기능이 있었습니다. 지원하는 언어는 한국어, 아랍어, 영어로 총 3개였는데 몇 년째 문제가 없다가 최근에 다국어 설정이 제대로 되지 않는다는 연락을 받았습니다. 분석한 결과, 안드로이드 13과 안드로이드 14에서 발생하는 이슈였습니다. 그런데 이상하게도 여러 가지 언어가 섞여서 보인다는 점이었습니다. 예를 들어, 영어로 설정했을 때 한국어와 영어가 섞여서 보이는 현상이 있었습니다. 기나긴 사투 끝에 결국 해결을 했고 그 과정에 대해서 기록하고자 합니다.

1. 안드로이드 인앱 다국어 기능

안드로이드는 다국어를 지원하기 위해서 res 폴더 내에 values를 언어별로 설정할 수 있습니다. 이렇게 설정을 하면 안드로이드 OS 설정화면에서 설정한 언어에 따라서 사용하는 string.xml이 결정됩니다. 

언어별로 string.xml을 생성한 모습
언어별로 string.xml을 생성한 모습


그런데 제가 개발한 앱은 인앱에서 언어를 직접 설정하는 기능이 있었습니다. Activity의 attachBaseContext() 함수를 오버라이딩해서 context를 전달받는 아래와 같은 함수를 만들어서 활용하고 있었습니다. 안드로이드 12까진 정상적으로 작동했습니다.

private fun updateResources(context: Context, language: String?, country: String?): Context {
    val locale = Locale(language, country)
    Locale.setDefault(locale)

    val configuration = context.resources.configuration
    configuration.setLocale(locale)
    configuration.setLayoutDirection(locale)

    try {
        // 일부 언어변경이 정상적으로 적용되지 않는 현상 수정
        context.resources.updateConfiguration(configuration, context.resources.displayMetrics)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return context.createConfigurationContext(configuration)
}

2. 안드로이드 13&14에서 발생한 문제와 해결과정

안드로이드 13 이상부터는 앱마다 사용할 언어를 설정할 수 있는 기능이 추가되었습니다. 안드로이드 14 기준으로 '설정 >  일반 > 앱 언어' 메뉴를 통해 설정할 수 있게 됐습니다. 그래서 이 기능을 컨트롤할 수 있는 함수가 추가되었습니다. AppCompat 1.6.0 이상에서만 사용 가능한 setApplicationLocales()와 getApplicationLocales()입니다. 언어를 변경했을 때 해당 함수를 사용해서 문제를 해결했습니다.

아래 예시 코드를 보면 안드로이드 버전 13 이상에서만 작동하며, 사용자가 선택한 언어에 따라서 LocaleListCompat.forLanguageTags() 함수가 반환한 값을 setApplicationLocales() 함수의 매개변수로 전달하고 있습니다. 그리고 앱을 재시작하는 코드를 넣음으로써 언어를 정상적으로 전환할 수 있었습니다.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    val appLocale = when (yourLanguageCode) {
        "MY_CODE_EN" -> {
            LocaleListCompat.forLanguageTags("en")
        }
        "MY_CODE_KO" -> {
            LocaleListCompat.forLanguageTags("ko")
        }
        "MY_CODE_AR" -> {
            LocaleListCompat.forLanguageTags("ar")
        }
        else -> {
            LocaleListCompat.forLanguageTags("ko")
        }
    }
    // Call this on the main thread as it may require Activity.restart()
    AppCompatDelegate.setApplicationLocales(appLocale)
}

3. 안드로이드 13&14 인앱 다국어 설정 정리

이번 포스팅을 통해 안드로이드 13, 14에서 발생한 인앱 다국어 설정 문제와 그 해결 방법을 살펴보았습니다. 기존에는 Activity의 'attachBaseContext()' 함수를 오버라이딩하고 'context.createConfigurationContext()' 함수를 사용해서 언어 설정을 지원했었는데 안드로이드 13 이상 버전에서는 정상적으로 적용되지 않았습니다. 그래서 AppCompat 1.6.0 이상 버전에서 제공하는 setApplicationLocales() 함수를 사용해서 앱 내의 언어 설정을 제어할 수 있게 되었습니다.


안드로이드는 시스템의 변화에 따라 기존에 잘 작동하던 코드도 문제가 발생할 수 있으므로 최신 안드로이드 버전에 대한 지속적인 관심, 공부, 테스트가 필요함을 다시 한번 느낄 수 있었습니다. 이러한 경험들을 공유함으로써 다른 분들께도 도움이 되었으면 좋겠습니다.

저작자표시 비영리 변경금지 (새창열림)

'안드로이드 > 트러블 슈팅' 카테고리의 다른 글

[안드로이드 트러블 슈팅] 웹뷰 JavascriptInterface 난독화 주의할 점  (0) 2024.03.24
[안드로이드 트러블 슈팅] 코틀린에서 가변인자(vararg)를 사용할 때 주의할 점  (0) 2024.03.22
[안드로이드 트러블 슈팅] 서버 데이터 매핑 시, @SerializedName 어노테이션의 중요성  (0) 2024.03.11
[안드로이드 트러블 슈팅] 빌드 시간 600초에서 30초로 단축한 사례  (0) 2024.03.10
'안드로이드/트러블 슈팅' 카테고리의 다른 글
  • [안드로이드 트러블 슈팅] 웹뷰 JavascriptInterface 난독화 주의할 점
  • [안드로이드 트러블 슈팅] 코틀린에서 가변인자(vararg)를 사용할 때 주의할 점
  • [안드로이드 트러블 슈팅] 서버 데이터 매핑 시, @SerializedName 어노테이션의 중요성
  • [안드로이드 트러블 슈팅] 빌드 시간 600초에서 30초로 단축한 사례
코딩덕
코딩덕
안드로이드, 리액트 등의 개발 노하우와 최신 AI 기술을 다루는 기술 블로그입니다. 실무 중심의 경험을 바탕으로 마주한 문제와 해결 과정을 체계적으로 기록하며, 개발자에게 실질적으로 도움 되는 프로그래밍 팁과 인사이트를 쉽고 명확하게 공유하고자 합니다.
  • 코딩덕
    개발자가 들려주는 IT 이야기
    코딩덕
  • 전체
    오늘
    어제
    • 분류 전체보기 (66)
      • 안드로이드 (62)
        • 멀티 모듈 (11)
        • 클린 아키텍처 (11)
        • 트러블 슈팅 (5)
        • 코틀린 (3)
        • 코루틴 (2)
        • Compose (1)
        • Compose UI (6)
        • Compose Dialog (8)
        • Compose Paging3 (11)
        • Compose State (2)
        • Util (1)
      • Github (3)
        • PR Template (2)
        • AI Code Review (1)
      • 리액트 (1)
        • NextJs (1)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    데이터 레이어
    Clean Architecture
    Usecase
    멀티 모듈
    안드로이드
    pr template
    jsonadapter
    multi module
    Gradle
    sealed class
    ScrollView
    Dialog
    paging3
    MutableState
    Jetpack Compose
    ai code review
    코틀린
    트러블슈팅
    ViewModel
    pager
    flow
    Github
    dynamic json
    enum class
    recyclerview
    코루틴
    UI Layer
    클린 아키텍처
    OnBackPressedDispatcher
    LazyRow
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩덕
[안드로이드 트러블 슈팅] 인앱 다국어 설정 버그 Android 13, Android 14
상단으로

티스토리툴바