안드로이드 앱 내부 언어 변경 - andeuloideu aeb naebu eon-eo byeongyeong

앱별 언어 환경설정

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

다국어 사용자의 경우 시스템 언어는 한 가지 언어(예: 영어)로 설정하지만 특정 앱에는 다른 언어(예: 네덜란드어나 중국어, 힌디어)를 선택하고자 할 수 있습니다. 앱이 이러한 사용자에게 더 나은 환경을 제공할 수 있도록 Android 13에서는 다국어를 지원하는 앱을 위한 다음과 같은 기능을 도입했습니다.

  • 사용자가 중앙 집중화된 위치에서 각 앱의 기본 언어를 선택할 수 있도록 지원하는 시스템 설정

    앱은 앱의 매니페스트에서 android:localeConfig 속성을 선언하여 시스템에 여러 언어를 지원한다는 것을 알려야 합니다. 자세한 내용은 리소스 파일을 만들고 앱의 매니페스트 파일에서 선언하는 방법에 관한 안내를 참고하세요.

  • 앱이 사용자 인터페이스에 사용할 다른 언어를 런타임에 설정하도록 지원하는 API

    맞춤 인앱 언어 선택 도구를 사용하는 앱은 사용자가 언어 환경설정을 선택하는 위치와 관계없이 일관된 사용자 환경이 제공될 수 있도록 새 API를 사용해야 합니다. 또한 새 API는 상용구 코드의 양을 줄이는 데 도움이 되고, 분할 APK를 지원하며, 앱 수준의 사용자 언어 설정을 저장하도록 앱 자동 백업을 지원합니다.

    이전 Android 버전과의 호환성을 위해 AndroidX에서도 API를 사용할 수 있습니다. Appcompat 1.6.0-alpha04 이상을 사용하는 것이 좋습니다.

다국어를 지원하지 않는 앱은 이러한 변경사항의 영향을 받지 않습니다.

이 기능 구현 개요

다음 표에는 다양한 사용 사례에 기반한 권장되는 구현이 나와 있습니다.

사용 사례권장되는 구현
앱에 인앱 언어 선택 도구가 없습니다.
  1. 앱 매니페스트에서 android:localeConfig 속성을 사용하여 휴대전화 설정에 앱의 언어를 추가합니다.
  2. 필요에 따라 인앱 언어 선택 도구를 추가하려면 AndroidX 라이브러리를 사용하고 API 구현을 선택하여 autoStoreLocales를 통한 이전 버전과의 호환성을 지원합니다.
앱에 이미 인앱 언어 선택 도구가 있습니다.
  1. 앱 매니페스트에서 android:localeConfig 속성을 사용하여 휴대전화 설정에 앱의 언어를 추가합니다.
  2. 새로운 API를 사용하도록 앱의 맞춤 로직을 이전하여 사용자에게 일관된 환경을 제공합니다.
  3. 다음과 같은 특수한 사례를 처리합니다.
    1. Android 13을 실행하는 기기에서 앱을 처음 실행할 때 AppCompatDelegate.setApplicationLocales()를 호출합니다.
    2. 다음과 같은 경우 AppCompatDelegate.setApplicationLocales()를 호출하여 사용자가 요청한 기존 언어를 시스템에 제공합니다.
      • 앱에서 Android 12(API 수준 32) 이하의 자동 저장소를 사용하도록 선택하는 경우
      • 앱이 맞춤 백업 저장소 위치에서 데이터를 이전해야 하는 경우

사용자를 위한 시스템 설정

Android 13에서는 앱별 언어 설정을 위한 중앙 집중화된 위치가 휴대전화에 추가되었습니다. Android 13을 실행하는 기기의 시스템 설정에서 앱의 언어를 구성할 수 있도록 하려면 locales_config XML 파일을 만들고 android:localeConfig 속성을 사용하여 앱의 매니페스트에 이 파일을 추가합니다. android:localeConfig 매니페스트 항목 누락은 사용자가 휴대전화 설정에서 시스템 언어와 상관없이 앱의 언어를 설정할 수 없음을 나타냅니다.

android:localeConfig를 사용하여 지원되는 언어를 휴대전화 설정에 추가하세요.

앱에서 지원하는 언어를 사용자의 휴대전화 설정에 추가하려면 다음 단계를 따르세요.

  1. res/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="ja"/>
       <locale android:name="fr"/>
       <locale android:name="en"/>
    </locale-config>
    
  2. 매니페스트에서 이 새 파일을 가리키는 줄을 추가합니다.

    <manifest
        ...
        <application
            ...
            android:localeConfig="@xml/locales_config">
        </application>
    </manifest>
    

사용자가 시스템 설정에서 앱 언어를 선택하는 방법

사용자는 새로운 시스템 설정을 통해 앱별로 원하는 언어를 선택할 수 있습니다. 이 설정은 다음과 같은 두 가지 방법으로 액세스할 수 있습니다.

  • 시스템 설정을 통해 액세스

    설정 > 시스템 > 언어 및 입력 > 앱 언어 > (앱 선택)

  • 설정을 통해 액세스

    설정 > 앱 > (앱 선택) > 언어

알려진 문제

앱을 테스트할 때 유의해야 하는 몇 가지 알려진 문제가 있습니다.

  • AGP 7.3.0-alpha07과 관련하여 알려진 문제로 인해 android:localeConfig에서 리소스 연결이 실패할 수 있습니다. 이 문제를 해결하려면 이전 버전의 AGP를 사용하세요. 이 문제는 향후 출시에서 해결됩니다.

인앱 언어 선택 도구 처리

이미 인앱 언어 선택 도구가 있거나 이를 사용하려는 앱은 맞춤 앱 로직 대신 새로운 API를 사용하여 사용자가 선호하는 앱 언어를 설정하고 가져옵니다.

이전 Android 버전과의 호환성을 위해, 인앱 언어 선택 도구를 구현할 때는 AndroidX 지원 라이브러리를 사용하는 것이 좋습니다. 하지만 필요하다면 프레임워크 API를 직접 구현해도 됩니다.

AndroidX 지원 라이브러리를 사용하여 구현

Appcompat 1.6.0-alpha04 이상에서 setApplicationLocales() 메서드를 사용합니다.

예를 들어 사용자가 선호하는 언어를 설정하려면 사용자에게 언어 선택 도구에서 언어를 선택하도록 요청한 후 시스템에서 값을 설정합니다.

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);

Android 12 이하 지원

Android 12(API 수준 32) 이하를 실행하는 기기를 지원하려면 다음 코드 스니펫과 같이 앱의 AppLocalesMetadataHolderService 서비스의 매니페스트 항목에서 autoStoreLocales 값을 true로 설정하고 android:enabledfalse로 설정하여 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 diskReaddiskWrite 위반이 발생할 수도 있습니다. 자세한 내용은 AppCompatDelegate.setApplicationLocales()를 참고하세요.

맞춤 저장소 처리

매니페스트 항목을 생략하거나 autoStoreLocalesfalse로 설정하면 자체 저장소를 처리하고 있다고 알리는 것입니다. 이 경우 활동 수명 주기에서 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(newLocaleList(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 맞춤 탭을 호출할 때 앱의 언어로 웹페이지를 열도록 Browser.EXTRA_HEADERS를 통해 Accept-Language 헤더를 추가하는 것이 좋습니다.

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2022-07-04 UTC.

[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"필요한 정보가 없음" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"너무 복잡함/단계 수가 너무 많음" },{ "type": "thumb-down", "id": "outOfDate", "label":"오래됨" },{ "type": "thumb-down", "id": "translationIssue", "label":"번역 문제" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"샘플/코드 문제" },{ "type": "thumb-down", "id": "otherDown", "label":"기타" }] [{ "type": "thumb-up", "id": "easyToUnderstand", "label":"이해하기 쉬움" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"문제가 해결됨" },{ "type": "thumb-up", "id": "otherUp", "label":"기타" }]