본문 바로가기

안드로이드/트러블 슈팅

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


안녕하세요. 이번 포스팅에서는 안드로이드 개발 실무에서 겪었던 이슈와 해결과정에 대해 적으려고 합니다. 제가 개발 중인 앱은 앱 내에 언어를 설정할 수 있는 기능이 있었습니다. 지원하는 언어는 한국어, 아랍어, 영어로 총 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() 함수를 사용해서 앱 내의 언어 설정을 제어할 수 있게 되었습니다.


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