다국어 사용자의 경우 시스템 언어는 한 가지 언어(예: 영어)로 설정하지만 특정 앱에는 다른 언어(예: 네덜란드어나 중국어, 힌디어)를 선택하고자 할 수 있습니다. 앱이 이러한 사용자에게 더 나은 환경을 제공할 수 있도록 Android 13에서는 다국어를 지원하는 앱을 위한 다음과 같은 기능을 도입했습니다.
시스템 설정: 사용자가 각 앱의 기본 언어를 선택할 수 있는 중앙 위치입니다.
앱별 언어 설정을 지원하는 데 필요한 파일이 자동으로 생성되어 시스템 설정에 표시되도록 앱을 구성할 수 있습니다. 자세한 내용은 자동 앱별 언어 지원 사용 설정의 안내를 참고하세요.
추가 API: 공개 API(예:
LocaleManager
의setApplicationLocales()
및getApplicationLocales()
메서드)를 사용하면 앱이 런타임 중 시스템 언어와 다른 언어를 설정할 수 있습니다.이러한 API는 시스템 설정과 자동으로 동기화됩니다. 따라서 이러한 API를 사용하여 맞춤 인앱 언어 선택 도구를 만드는 앱은 언어 설정을 선택하는 위치와 관계없이 일관된 사용자 환경을 보장합니다. 또한 공개 API는 상용구 코드의 양을 줄이는 데 도움이 되고, 분할 APK를 지원하며, 앱 수준의 사용자 언어 설정을 저장하도록 앱 자동 백업을 지원합니다.
이전 Android 버전과의 호환성을 위해 AndroidX에서도 이에 상응하는 API를 사용할 수 있습니다. 그러나, Android 12(API 수준 32) 이하의 경우 이전 버전과 호환되는 API는 애플리케이션 컨텍스트가 아닌 AppCompatActivity 컨텍스트에서 작동합니다. Appcompat 1.6.0 이상을 사용하여 이전 버전과 호환되는 API에 액세스할 수 있습니다.
이 기능 구현 개요
다음 표에는 다양한 사용 사례에 기반한 권장되는 구현이 나와 있습니다.
사용 사례 | 권장되는 구현 |
---|---|
앱에 인앱 언어 선택 도구가 없는 경우 |
|
앱에 이미 인앱 언어 선택 도구가 있는 경우 |
|
사용자를 위한 시스템 설정
Android 13부터 Android에 앱별 언어 설정을 지정하는 중앙 위치가 시스템 설정에 포함됩니다. Android 13 및 이후 버전을 실행하는 기기의 시스템 설정에서 앱의 언어를 구성할 수 있도록 하려면 자동 앱별 언어 지원을 사용 설정하거나(권장) 수동으로 지원을 구성합니다.
자동 앱별 언어 지원 사용 설정
Android 스튜디오 Giraffe 및 AGP 8.1부터 앱별 언어 설정을 자동으로 지원하도록 앱을 구성할 수 있습니다. AGP는 프로젝트 리소스에 따라 LocaleConfig
파일을 생성하고 최종 매니페스트 파일에 이에 대한 참조를 추가하므로 개발자가 이 작업을 수동으로 하지 않아도 됩니다. AGP는 앱 모듈의 res
폴더에 있는 리소스 및 모든 라이브러리 모듈 종속 항목을 사용하여 LocaleConfig
파일에 포함할 언어를 결정합니다. 즉, 새 언어의 리소스를 앱에 추가한 후에도 LocaleConfig
파일을 직접 업데이트할 필요가 없습니다.
자동 앱별 언어 기능은 Android 13(API 수준 33) 및 이후 버전을 실행하는 앱을 지원합니다. 이 기능을 사용하려면 compileSdkVersion
을 33 이상으로 설정해야 합니다. 이전 버전의 Android에서 앱별 언어 설정을 구성하려면 API와 인앱 언어 선택 도구를 사용해야 합니다.
자동 앱별 언어 지원을 사용 설정하려면 다음 단계를 따르세요.
- 이 기능을 사용 설정하려면 모듈 수준
build.gradle.kts
파일(Groovy를 사용하는 경우build.gradle
파일)의androidResources {}
블록에 있는generateLocaleConfig
설정을 사용합니다. 이 기능은 기본적으로 사용 중지되어 있습니다.Kotlin
android { androidResources { generateLocaleConfig = true } }
Groovy
android { androidResources { generateLocaleConfig true } }
- 기본 언어를 지정합니다.
- 앱 모듈의
res
폴더에서resources.properties
라는 새 파일을 만듭니다. resources.properties
파일에서unqualifiedResLocale
라벨을 사용하여 기본 언어를 설정합니다. 언어 이름의 형식을 지정하려면 언어 이름을 구성하는 방법을 참고하세요.
- 앱 모듈의
AGP는 res
폴더의 values-*
디렉터리를 사용하여 이 기본 언어와 개발자가 지정한 모든 대체 언어를 자동 생성된 LocaleConfig
파일에 추가합니다.
언어 이름을 구성하는 방법
언어 이름을 만들려면 언어 코드에 스크립트(선택사항)와 지역 코드(선택사항)를 대시로 구분하여 결합합니다.
- 언어: 두 글자 또는 세 글자로 된 ISO 639-1 코드를 사용합니다.
- 스크립트(선택사항): ISO 15924 코드를 사용합니다.
- 지역(선택사항): 두 글자로 된 ISO 3166-1-alpha-2 코드 또는 3자리로 된 UN_M.49 코드를 사용합니다.
예를 들어 기본 언어가 미국 영어인 경우:
unqualifiedResLocale=en-US
android:localeConfig
를 사용하여 시스템 설정에 지원되는 언어 추가
Android 13 및 이후 버전을 실행하는 기기의 시스템 설정에서 언어를 구성할 수 있도록 앱을 수동으로 설정할 수 있습니다. 이렇게 하려면 locales_config
XML 파일을 만들고 android:localeConfig
속성을 사용하여 앱의 매니페스트에 이 파일을 추가합니다. android:localeConfig
매니페스트 항목 누락은 사용자가 시스템 설정에서 시스템 언어와 상관없이 앱의 언어를 설정할 수 없음을 나타냅니다.
앱에서 지원하는 언어를 사용자의 시스템 설정에 수동으로 추가하려면 다음 단계를 따르세요.
res/xml/locales_config.xml
이라는 파일을 만들고 앱의 최종 대체 언어(res/values/strings.xml
에 지정된 언어)를 비롯한 앱 언어를 지정합니다.형식 요구사항은 언어 이름을 구성하는 방법을 참고하세요. 가장 흔히 사용되는 언어 목록은 샘플
locale_config.xml
파일을 참고하세요.예를 들어 다음 언어를 지원하는 앱에서 다음과 같이
locales_config.xml
파일의 형식을 지정할 수 있습니다.- 영어(미국), 최종 대체 언어
- 영어(영국)
- 프랑스어
- 일본어
- 중국어(간체, 마카오)
- 중국어(번체, 마카오)
<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale android:name="en-US"/> <locale android:name="en-GB"/> <locale android:name="fr"/> <locale android:name="ja"/> <locale android:name="zh-Hans-MO"/> <locale android:name="zh-Hant-MO"/> </locale-config>
매니페스트에서 이 새 파일을 가리키는 줄을 추가합니다.
<manifest> ... <application ... android:localeConfig="@xml/locales_config"> </application> </manifest>
앱의 localeConfig
를 LocaleManager.setOverrideLocaleConfig
로 동적으로 업데이트하여 Android 설정의 앱별 언어 목록에 표시되는 언어 집합을 맞춤설정할 수 있습니다. 이렇게 하면
지역별 언어 목록을 맞춤설정하고, A/B 실험을 실행하고,
앱에서 서버 측 현지화 푸시를 사용하는 경우
다음 예를 참고하세요.
Kotlin
//For setOverrideLocaleConfig val localeManager = applicationContext .getSystemService(LocaleManager::class.java) localeManager.overrideLocaleConfig = LocaleConfig( LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG") ) //For getOverrideLocaleConfig // The app calls the API to get the override LocaleConfig val overrideLocaleConfig = localeManager.overrideLocaleConfig // If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales val supportedLocales = overrideLocaleConfig.supportedLocales()
자바
//For setOverrideLocaleConfig mContext.getSystemService(LocaleManager.class).setOverrideLocaleConfig(new LocaleConfig(LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG"))); //For getOverrideLocaleConfig // The app calls the API to get the override LocaleConfig LocaleConfig overrideLocaleConfig = mContext.getSystemService(LocaleManager.class).getOverrideLocaleConfig(); // If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales LocaleList supportedLocales = overrideLocaleConfig.getSupportedLocales();
또한 IME는 이제
LocaleManager.getApplicationLocales
드림
현재 앱의 UI 언어를 알고 키보드 언어를
게재 횟수:
Kotlin
val currentAppLocales: LocaleList = applicationContext.getSystemService(LocaleManager::class.java).getApplicationLocales(appPackageName)
Java
LocaleList currentAppLocales = mContext.getSystemService(LocaleManager.class).getApplicationLocales(appPackageName);
Gradle에서 지원되는 언어 지정
아직 없다면 앱의 모듈 수준 build.gradle
파일에 resourceConfigurations
속성을 사용하여 동일한 언어를 지정합니다.
android {
...
defaultConfig {
resourceConfigurations += ["en", "en-rGB", "fr", "ja", "b+zh+Hans+MO", "b+zh+Hant+MO"]
}
}
resourceConfigurations
속성이 있으면 빌드 시스템은 지정된 언어의 APK에만 언어 리소스를 포함하므로 앱에서 지원하지 않는 언어를 지원할 수 있는 다른 라이브러리의 번역된 문자열이 포함되지 않습니다. 자세한 내용은 앱에서 지원하는 언어 지정을 참고하세요.
사용자가 시스템 설정에서 앱 언어를 선택하는 방법
사용자는 시스템 설정을 통해 앱별로 원하는 언어를 선택할 수 있습니다. 이 설정은 다음과 같은 두 가지 방법으로 액세스할 수 있습니다.
시스템 설정을 통해 액세스
설정 > 시스템 > 언어 및 입력 > 앱 언어 > (앱 선택)
앱 설정을 통해 액세스
설정 > 앱 > (앱 선택) > 언어
인앱 언어 선택 도구 처리
이미 인앱 언어 선택 도구가 있거나 이를 사용하려는 앱은 맞춤 앱 로직 대신 공개 API를 사용하여 사용자가 선호하는 앱 언어를 설정하고 가져옵니다. 인앱 언어 선택 도구에 공개 API를 사용하는 경우, 사용자가 인앱 환경을 통해 선택한 언어와 일치하도록 기기의 시스템 설정이 자동으로 업데이트됩니다.
이전 Android 버전과의 호환성을 위해, 인앱 언어 선택 도구를 구현할 때는 AndroidX 지원 라이브러리를 사용하는 것이 좋습니다. 하지만 필요하다면 프레임워크 API를 직접 구현해도 됩니다.
AndroidX 지원 라이브러리를 사용하여 구현
Appcompat 1.6.0 이상의 setApplicationLocales()
및 getApplicationLocales()
메서드를 사용합니다. Android 12(API 수준 32) 이하의 경우 이전 버전과 호환되는 API는 애플리케이션 컨텍스트가 아닌 AppCompatActivity 컨텍스트에서 작동합니다.
예를 들어 사용자가 선호하는 언어를 설정하려면 사용자에게 언어 선택 도구에서 언어를 선택하도록 요청한 후 시스템에서 값을 설정합니다.
Kotlin
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY") // Call this on the main thread as it may require Activity.restart() AppCompatDelegate.setApplicationLocales(appLocale)
자바
LocaleListCompat appLocale = LocaleListCompat.forLanguageTags("xx-YY"); // Call this on the main thread as it may require Activity.restart() AppCompatDelegate.setApplicationLocales(appLocale);
앱 자체에서 언어 구성 변경을 처리하지 않는 한 setApplicationLocales()
를 호출하면 Activity
가 다시 생성됩니다.
AppCompatDelegate.getApplicationLocales()
를 사용하여 사용자의 기본 언어를 가져옵니다. 사용자가 시스템 설정 또는 인앱 언어 선택 도구에서 앱 언어를 선택했을 수 있습니다.
Android 12 및 이전 버전 지원
Android 12(API 수준 32) 및 이전 버전을 실행하는 기기를 지원하려면 다음 코드 스니펫과 같이 앱의 AppLocalesMetadataHolderService
서비스의 매니페스트 항목에서 autoStoreLocales
값을 true
로 설정하고 android:enabled
를 false
로 설정하여 AndroidX에 언어 저장소를 처리하도록 지시합니다.
<application
...
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>
autoStoreLocales
값을 true
로 설정하면 기본 스레드에서 블로킹 읽기가 발생하고, 스레드 위반을 기록하는 경우 StrictMode
diskRead
및 diskWrite
위반이 발생할 수도 있습니다. 자세한 내용은 AppCompatDelegate.setApplicationLocales()
를 참고하세요.
맞춤 저장소 처리
매니페스트 항목을 생략하거나 autoStoreLocales
를 false
로 설정하면 자체 저장소를 처리하고 있다고 알리는 것입니다. 이 경우 활동 수명 주기에서 onCreate
전에 저장된 언어를 제공해야 하고 Android 12(API 수준 32) 이하에서 AppCompatDelegate.setApplicationLocales()
호출을 제어해야 합니다.
앱에 맞춤 언어 저장소 위치가 있으면 사용자가 원하는 언어로 앱을 계속 즐길 수 있도록 맞춤 언어 저장소 솔루션과 autoStoreLocales
간에 일회성 핸드오프를 사용하는 것이 좋습니다. 기기가 Android 13으로 업그레이드된 후 앱을 처음 실행하는 경우에 특히 유용합니다. 이 경우 맞춤 저장소에서 언어를 가져와 AppCompatDelegate.setApplicationLocales()
에 전달하여 사용자가 요청한 기존 언어를 제공할 수 있습니다.
Android 프레임워크 API를 사용하여 구현
AndroidX 지원 라이브러리를 사용하여 인앱 언어 선택 도구를 구현하는 것이 좋지만 Android 13을 실행하는 기기의 경우 Android 프레임워크에서 setApplicationLocales()
및 getApplicationLocales()
메서드를 사용해도 됩니다.
예를 들어 사용자가 선호하는 언어를 설정하려면 사용자에게 언어 선택 도구에서 언어를 선택하도록 요청한 후 시스템에서 값을 설정합니다.
// 1. Inside an activity, in-app language picker gets an input locale "xx-YY"
// 2. App calls the API to set its locale
mContext.getSystemService(LocaleManager.class
).setApplicationLocales(new LocaleList(Locale.forLanguageTag("xx-YY")));
// 3. The system updates the locale and restarts the app, including any configuration updates
// 4. The app is now displayed in "xx-YY" language
언어 선택 도구에 표시할 사용자의 현재 선호 언어를 가져오려면 앱이 시스템에서 값을 다시 가져오면 됩니다.
// 1. App calls the API to get the preferred locale
LocaleList currentAppLocales =
mContext.getSystemService(LocaleManager.class).getApplicationLocales();
// 2. App uses the returned LocaleList to display languages to the user
추가 권장사항
다음 권장사항에 유의하세요.
다른 앱에서 인텐트를 호출할 때 언어를 고려합니다.
언어 중심 인텐트를 사용하면 호출된 앱의 언어를 지정할 수 있습니다. 한 가지 예로 Speech Recognizer API의 EXTRA_LANGUAGE
기능을 들 수 있습니다.
Chrome 맞춤 탭의 Accept-Language 헤더 고려하기
Chrome 맞춤 탭을 호출할 때 앱의 언어로 웹페이지를 열도록 Browser.EXTRA_HEADERS
를 통해 Accept-Language 헤더를 추가하는 것이 좋습니다.
시스템 설정에서 앱별 언어 설정을 삭제하는 경우 앱 언어를 시스템 언어로 재설정하기
시스템 설정에서 앱의 언어 환경설정을 삭제하면 (앱의 AndroidManifest.xml
에서 android:localeConfig
를 삭제하는 방식) 사용자가 앱의 언어를 시스템 기본값으로 다시 쉽게 재설정할 수 없습니다.
이러한 이유로 android:localeConfig
를 삭제하는 경우 다음 코드 스니펫에 나와 있는 것처럼 LocaleListCompat.getEmptyLocaleList()
또는 LocaleList.getEmptyLocaleList()
를 사용하여 앱 언어를 시스템 언어로 재설정하는 것이 좋습니다.
Kotlin
// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility AppCompatDelegate.setApplicationLocales( LocaleListCompat.getEmptyLocaleList() ) // Or use the Framework APIs for Android 13 and above to reset to the system locale val context = LocalContext.current context.getSystemService(LocaleManager::class.java) .applicationLocales = LocaleList.getEmptyLocaleList()
Java
// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility AppCompatDelegate.setApplicationLocales( LocaleListCompat.getEmptyLocaleList() ); // Or use the Framework APIs for Android 13 and above to reset to the system locale mContext.getSystemService(LocaleManager.class) .setApplicationLocales(LocaleList.getEmptyLocaleList());
추가 리소스
자세한 내용은 코드 샘플, 블로그 기사, 동영상을 참고하세요.
- 앱별 언어 설정 1부 블로그
- 앱별 언어 설정 2부 블로그
- 샘플 앱
- 다국어 환경을 위한 빌드 동영상
locale_config.xml 파일 샘플
기본적으로 Android는 가장 일반적으로 사용되는 표준 언어 세트의 Android 오픈소스 프로젝트 (AOSP)에 시스템 수준 번역을 포함합니다.
이 섹션에 포함된 샘플 locale_config.xml
파일은 이러한 각 언어에 권장되는 형식을 보여줍니다. 앱에서 지원하는 언어 집합에 관한 자체 locale_config.xml
파일을 구성하는 데 도움이 되도록 이 샘플 파일을 참고하세요.
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="af"/> <!-- Afrikaans -->
<locale android:name="am"/> <!-- Amharic -->
<locale android:name="ar"/> <!-- Arabic -->
<locale android:name="as"/> <!-- Assamese -->
<locale android:name="az"/> <!-- Azerbaijani -->
<locale android:name="be"/> <!-- Belarusian -->
<locale android:name="bg"/> <!-- Bulgarian -->
<locale android:name="bn"/> <!-- Bengali -->
<locale android:name="bs"/> <!-- Bosnian -->
<locale android:name="ca"/> <!-- Catalan -->
<locale android:name="cs"/> <!-- Czech -->
<locale android:name="da"/> <!-- Danish -->
<locale android:name="de"/> <!-- German -->
<locale android:name="el"/> <!-- Greek -->
<locale android:name="en-AU"/> <!-- English (Australia) -->
<locale android:name="en-CA"/> <!-- English (Canada) -->
<locale android:name="en-GB"/> <!-- English (United Kingdom) -->
<locale android:name="en-IN"/> <!-- English (India) -->
<locale android:name="en-US"/> <!-- English (United States) -->
<locale android:name="es"/> <!-- Spanish (Spain) -->
<locale android:name="es-US"/> <!-- Spanish (United States) -->
<locale android:name="et"/> <!-- Estonian -->
<locale android:name="eu"/> <!-- Basque -->
<locale android:name="fa"/> <!-- Farsi -->
<locale android:name="fi"/> <!-- Finnish -->
<locale android:name="fil"/> <!-- Filipino -->
<locale android:name="fr"/> <!-- French (France) -->
<locale android:name="fr-CA"/> <!-- French (Canada) -->
<locale android:name="gl"/> <!-- Galician -->
<locale android:name="gu"/> <!-- Gujarati -->
<locale android:name="hi"/> <!-- Hindi -->
<locale android:name="hr"/> <!-- Croatian -->
<locale android:name="hu"/> <!-- Hungarian -->
<locale android:name="hy"/> <!-- Armenian -->
<locale android:name="in"/> <!-- Indonesian -->
<locale android:name="is"/> <!-- Icelandic -->
<locale android:name="it"/> <!-- Italian -->
<locale android:name="iw"/> <!-- Hebrew -->
<locale android:name="ja"/> <!-- Japanese -->
<locale android:name="ka"/> <!-- Georgian -->
<locale android:name="kk"/> <!-- Kazakh -->
<locale android:name="km"/> <!-- Khmer -->
<locale android:name="kn"/> <!-- Kannada -->
<locale android:name="ko"/> <!-- Korean -->
<locale android:name="ky"/> <!-- Kyrgyz -->
<locale android:name="lo"/> <!-- Lao -->
<locale android:name="lt"/> <!-- Lithuanian -->
<locale android:name="lv"/> <!-- Latvian -->
<locale android:name="mk"/> <!-- Macedonian -->
<locale android:name="ml"/> <!-- Malayalam -->
<locale android:name="mn"/> <!-- Mongolian -->
<locale android:name="mr"/> <!-- Marathi -->
<locale android:name="ms"/> <!-- Malay -->
<locale android:name="my"/> <!-- Burmese -->
<locale android:name="nb"/> <!-- Norwegian -->
<locale android:name="ne"/> <!-- Nepali -->
<locale android:name="nl"/> <!-- Dutch -->
<locale android:name="or"/> <!-- Odia -->
<locale android:name="pa"/> <!-- Punjabi -->
<locale android:name="pl"/> <!-- Polish -->
<locale android:name="pt-BR"/> <!-- Portuguese (Brazil) -->
<locale android:name="pt-PT"/> <!-- Portuguese (Portugal) -->
<locale android:name="ro"/> <!-- Romanian -->
<locale android:name="ru"/> <!-- Russian -->
<locale android:name="si"/> <!-- Sinhala -->
<locale android:name="sk"/> <!-- Slovak -->
<locale android:name="sl"/> <!-- Slovenian -->
<locale android:name="sq"/> <!-- Albanian -->
<locale android:name="sr"/> <!-- Serbian (Cyrillic) -->
<locale android:name="sr-Latn"/> <!-- Serbian (Latin) -->
<locale android:name="sv"/> <!-- Swedish -->
<locale android:name="sw"/> <!-- Swahili -->
<locale android:name="ta"/> <!-- Tamil -->
<locale android:name="te"/> <!-- Telugu -->
<locale android:name="th"/> <!-- Thai -->
<locale android:name="tr"/> <!-- Turkish -->
<locale android:name="uk"/> <!-- Ukrainian -->
<locale android:name="ur"/> <!-- Urdu -->
<locale android:name="uz"/> <!-- Uzbek -->
<locale android:name="vi"/> <!-- Vietnamese -->
<locale android:name="zh-Hans"/> <!-- Chinese (Simplified) -->
<locale android:name="zh-Hant"/> <!-- Chinese (Traditional) -->
<locale android:name="zu"/> <!-- Zulu -->
</locale-config>