앱 현지화

Android는 다양한 지역의 많은 기기에서 실행됩니다. 사용자 도달률을 최대로 높이려면 앱은 앱에 사용되는 언어에 맞게 텍스트, 오디오 파일, 숫자, 통화, 그래픽을 처리할 수 있어야 합니다.

이 페이지에서는 Android 앱 현지화를 위한 권장사항을 설명합니다.

Kotlin 또는 Java 프로그래밍 언어에 관한 실무 지식이 있어야 하고 Android 리소스 로드, XML에서의 사용자 인터페이스 요소 선언, 활동 수명 주기와 같은 개발 고려사항, 국제화 및 현지화의 일반 원칙을 숙지하고 있어야 합니다.

Android 리소스 프레임워크를 사용하여 앱의 현지화된 측면을 핵심 앱 기능과 최대한 분리하는 것이 좋습니다.

  • 이 페이지와 앱 리소스 개요에 설명된 대로 앱 사용자 인터페이스의 콘텐츠 중 대부분 또는 전체를 리소스 파일에 넣습니다.
  • 반면 사용자 인터페이스의 동작은 Kotlin 기반 또는 Java 기반 코드를 통해 이루어집니다. 예를 들어 사용자가 언어에 따라 다르게 형식을 지정하거나 정렬해야 하는 데이터를 입력하는 경우, 대개 Kotlin 또는 Java 프로그래밍 언어를 사용하여 프로그래매틱 방식으로 데이터를 처리합니다. 이 페이지에서는 Kotlin 기반 또는 Java 기반 코드를 현지화하는 방법은 다루지 않습니다.

앱의 문자열을 현지화하는 방법에 관한 간단한 가이드는 다양한 언어 및 문화 지원을 참고하세요.

개요: Android에서 리소스 전환

리소스는 Android 앱에 필요한 텍스트 문자열, 레이아웃, 사운드, 그래픽, 기타 정적 데이터입니다. 앱에는 여러 리소스 집합이 포함될 수 있으며 각 리소스는 다양한 기기 구성에 맞춤설정됩니다. 사용자가 앱을 실행하면 Android가 기기에 가장 잘 맞는 리소스를 자동으로 선택하여 로드합니다.

이 페이지에서는 현지화 및 언어에 중점을 둡니다. 리소스 전환, 그리고 화면 방향 또는 터치 스크린 유형 등 지정할 수 있는 모든 유형의 구성에 관한 자세한 설명은 대체 리소스 제공을 참고하세요.

앱을 작성할 때 앱에 사용할 기본 리소스 및 대체 리소스를 만듭니다. 그러면 사용자가 앱을 실행할 때 Android 시스템이 로드할 리소스를 기기 언어에 따라 선택합니다. 리소스를 만들려면 프로젝트의 res/ 디렉터리의 특별히 이름이 지정된 하위 디렉터리 내에 파일을 둡니다.

기본 리소스가 중요한 이유

앱이 언어별 텍스트를 제공하지 않는 언어로 실행되는 경우 Android는 res/values/strings.xml에서 기본 문자열을 로드합니다. 이 기본 파일이 없거나 앱에 필요한 문자열이 누락된 경우 앱은 실행되지 않고 오류를 표시합니다. 다음 예는 기본 텍스트 파일이 불완전한 경우 어떤 일이 발생할 수 있는지 보여줍니다.

예:

앱의 Kotlin 기반 또는 Java 기반 코드는 두 문자열(text_a, text_b)만 참조합니다. 이 앱에는 text_atext_b를 영어로 정의한, 현지화된 리소스 파일(res/values-en/strings.xml)이 들어 있습니다. 또한 기본 리소스 파일(res/values/strings.xml)도 포함되어 있는데, 이 파일에는 text_b에 관한 정의가 아닌 text_a에 관한 정의가 들어 있습니다.

  • 언어가 영어로 설정된 기기에서 이 앱이 실행되면 res/values-en/strings.xml에 필요한 텍스트 문자열이 모두 포함되어 있기 때문에 앱이 문제없이 실행될 수 있습니다.
  • 그러나 이 앱이 영어가 아닌 다른 언어로 설정된 기기에서 실행되면 사용자에게 오류 메시지와 강제 종료 버튼이 표시됩니다. 앱이 로드되지 않습니다.

이러한 상황을 방지하기 위해 res/values/strings.xml 파일이 존재하는지, 그리고 필요한 모든 문자열이 이 파일에 정의되어 있는지 확인하세요. 이 상황은 문자열만이 아니라 모든 유형의 리소스에 적용됩니다. 레이아웃, 드로어블, 애니메이션 등 앱에서 호출하는 모든 리소스가 포함된 기본 리소스 파일 집합을 만들어야 합니다. 테스트에 관한 자세한 내용은 기본 리소스 테스트 섹션을 참고하세요.

현지화를 위한 리소스 사용

이 섹션에서는 기본 리소스와 대체 리소스를 만드는 방법을 설명합니다. 또한 리소스에 우선순위가 할당되는 방식과 코드에서 리소스를 참조하는 방법을 설명합니다.

기본 리소스 만들기

앱의 기본 텍스트를 res/values/strings.xml에 넣습니다. 이러한 문자열에는 기본 언어(대부분의 앱 사용자가 사용할 것으로 예상되는 언어)를 사용합니다.

기본 리소스 세트에는 모든 기본 드로어블과 레이아웃도 포함되며 애니메이션과 같은 다른 유형의 리소스도 포함될 수 있습니다. 이러한 리소스는 다음 디렉터리로 이동합니다.

  • res/drawable/: Google Play의 앱 아이콘에 사용할 하나 이상의 그래픽 파일이 있는 필수 디렉터리
  • res/layout/: 기본 레이아웃을 정의하는 XML 파일이 있는 필수 디렉터리
  • res/anim/: res/anim-<qualifiers> 폴더가 있는 경우 필수임
  • res/xml/: res/xml-<qualifiers> 폴더가 있는 경우 필수임
  • res/raw/: res/raw-<qualifiers> 폴더가 있는 경우 필수임

도움말: 코드에서 Android 리소스의 각 참조를 검토합니다. 참조마다 기본 리소스가 정의되어 있는지 확인합니다. 또 기본 문자열 파일이 완전한지 확인합니다. 현지화된 문자열 파일에는 문자열의 하위 집합이 포함될 수 있지만 기본 문자열 파일에는 문자열이 반드시 모두 포함되어야 합니다.

대체 리소스 만들기

앱 현지화에서는 언어별 대체 텍스트를 제공하는 것이 큰 비중을 차지합니다. 경우에 따라 대체 그래픽, 사운드, 레이아웃 및 기타 언어별 리소스를 제공할 수도 있습니다.

앱에서는 각각 서로 다른 한정자를 갖는 res/<qualifiers>/ 디렉터리를 여러 개 지정할 수 있습니다. 언어별 대체 리소스를 만들려면 언어 또는 언어-지역 조합을 지정하는 한정자를 사용합니다. 리소스 디렉터리의 이름은 대체 리소스 제공에 설명된 이름 지정 체계를 준수해야 합니다. 그러지 않으면 앱이 컴파일되지 않습니다.

예:

앱의 기본 언어가 영어이고 앱의 모든 텍스트를 프랑스어로 현지화하고, 앱의 제목을 제외하고 모든 텍스트를 일본어로 현지화하려고 한다고 가정해 보겠습니다. 이 경우 언어별 리소스 디렉터리에 각각 저장된 strings.xml 파일을 세 개 만듭니다.

  1. res/values/strings.xml
    title 이름의 문자열 텍스트를 포함하여 앱에 사용되는 모든 문자열의 영어 텍스트가 들어 있습니다.
  2. res/values-fr/strings.xml
    title을 포함한 모든 문자열의 프랑스어 텍스트가 들어 있습니다.
  3. res/values-ja/strings.xml
    title제외한 모든 문자열의 일본어 텍스트가 들어 있습니다.

Kotlin 기반 또는 Java 기반 코드에서 R.string.title을 참조하는 경우 런타임 시 발생하는 상황은 다음과 같습니다.

  • 기기가 프랑스어가 아닌 다른 언어로 설정된 경우 Android는 res/values/strings.xml 파일에서 title을 로드합니다.
  • 기기가 프랑스어로 설정된 경우 Android는 res/values-fr/strings.xml 파일에서 title을 로드합니다.

기기가 일본어로 설정된 경우 Android는 res/values-ja/strings.xml 파일에서 title을 찾습니다. 그러나 그 파일에는 이 같은 문자열이 없기 때문에 Android는 다시 기본값으로 돌아가고 res/values/strings.xml 파일에서 영어로 된 title을 로드합니다.

어떤 리소스가 우선 적용되나요?

여러 개의 리소스 파일이 기기 구성과 일치하면 Android는 규칙에 따라 사용할 파일을 결정합니다. 리소스 디렉터리 이름에 지정할 수 있는 한정자 중에서 언어가 거의 언제나 우선 적용됩니다.

예:

앱에 기본 그래픽 집합 하나와 다른 그래픽 집합 두 개가 있고 각각 서로 다른 기기 설정에 최적화되었다고 가정해 보겠습니다.

  • res/drawable/
    기본 그래픽이 포함되어 있습니다.
  • res/drawable-small-land-stylus/
    스타일러스 입력이 필요하고 가로 방향의 QVGA 저밀도 화면을 사용하는 기기에 최적화된 그래픽이 포함되어 있습니다.
  • res/drawable-ja/
    일본어와 함께 사용하기에 최적화된 그래픽이 포함되어 있습니다.

앱이 일본어를 사용하도록 구성된 기기에서 실행되면, 스타일러스 입력이 필요하고 가로 방향의 QVGA 저밀도 화면이 있는 기기일지라도 Android는 res/drawable-ja/에서 그래픽을 로드합니다.

예외: 선택 프로세스에서 언어보다 우선하는 유일한 한정자는 모바일 국가 코드(MCC)와 모바일 네트워크 코드(MNC)입니다.

예:

다음과 같이 상황을 가정해 보겠습니다.

  • 앱 코드가 R.string.text_a를 호출합니다.
  • .
  • 다음의 두 관련 리소스 파일이 사용 가능합니다.
    • res/values-mcc404/strings.xml - 앱의 기본 언어(이 경우 영어)로 된 text_a가 포함되어 있습니다.
    • res/values-hi/strings.xml - 힌디어로 된 text_a가 포함되어 있습니다.
  • 앱이 다음과 같이 구성된 기기에서 실행됩니다.
    • SIM 카드가 인도의 모바일 네트워크(MCC 404)에 연결되어 있습니다.
    • 언어가 힌디어(hi)로 설정되어 있습니다.

Android는 기기가 힌디어로 구성된 경우에도 res/values-mcc404/strings.xml에서 text_a(영어로 됨)를 로드합니다. 이는 리소스 선택 프로세스에서 Android가 언어 일치보다 MCC 일치를 더 선호하기 때문입니다.

선택 프로세스는 예에서 제시된 것처럼 항상 단순하지는 않습니다. 프로세스에 관한 더 자세한 설명은 Android에서 가장 일치하는 리소스를 찾는 방법을 참고하세요. 모든 한정자는 앱 리소스 개요에 우선순위에 따라 설명 및 나열되어 있습니다.

코드에서 리소스 참조

앱의 Kotlin 기반 또는 Java 기반 코드에서 R.resource_type.resource_name 또는 android.R.resource_type.resource_name 문법을 사용하여 리소스를 참조합니다. 자세한 내용은 앱 리소스에 액세스를 참고하세요.

현지화를 위한 문자열 관리

이 섹션에서는 현지화와 관련된 문자열을 관리하기 위한 권장사항을 설명합니다.

모든 문자열을 strings.xml로 이동

앱을 빌드할 때 문자열을 하드코딩하지 마세요. 대신, 기본 strings.xml 파일에서 모든 문자열을 리소스로 선언합니다. 그러면 업데이트와 현지화 작업이 쉽습니다. 또 컴파일된 코드를 변경하지 않고도 strings.xml 파일의 문자열을 쉽게 추출하고 번역한 후 적합한 한정자와 함께 앱에 다시 통합할 수 있습니다.

텍스트가 있는 이미지를 생성할 경우 그러한 문자열도 strings.xml에 넣고 번역한 다음 이미지를 다시 생성하세요.

UI 문자열에 관한 Android 가이드라인 준수

UI를 디자인하고 개발할 때 사용자에게 메시지를 전달하는 방법에 세심한 주의를 기울여야 합니다. 대체로 친숙하면서도 짧은 간결한 스타일을 사용하고 UI 전반에서 일관된 스타일을 사용합니다.

작성 스타일 및 단어 선택과 관련하여 Material Design 추천을 읽고 따라야 합니다. 그러면 앱이 사용자에게 더욱 세련되게 표시되며 사용자가 UI를 더 빠르게 이해할 수 있습니다.

또한 앱 바, 옵션 메뉴, 시스템 표시줄, 알림과 같은 UI 요소에는 가능하면 항상 Android 표준 용어를 사용하세요. Android 용어를 제대로 일관되게 사용하면 번역이 용이해지고 사용자에게 더 나은 최종 제품을 제공할 수 있습니다.

선언된 문자열에 충분한 문맥 제공

strings.xml 파일에서 문자열을 선언할 때 문자열이 사용되는 문맥을 설명해야 합니다. 이 정보는 번역사에게 매우 중요한 의미를 가지며 번역 품질을 높입니다. 문자열을 더 효과적으로 관리하는 데도 도움이 됩니다.

예를 들면 다음과 같습니다.

<!-- The action for submitting a form. This text is on a button that can fit 30 chars -->
<string name="login_submit_button">Sign in</string>

다음과 같은 문맥 정보를 제공하는 것이 좋습니다.

  • 이 문자열의 용도는? 사용자에게 언제, 어디에서 표시되는가?
  • 레이아웃의 어디에 표시되는가? 예를 들어 텍스트 상자보다 버튼에 들어가는 번역이 좀 더 제약됩니다.

번역하지 않을 메시지 부분 표시

문자열에는 다른 언어로 번역되지 않아야 하는 텍스트가 포함되는 경우가 많습니다. 일반적인 예로 코드 부분이나 값의 자리표시자, 특수 기호, 이름을 들 수 있습니다. 번역할 문자열을 준비할 때 번역하지 않고 그대로 유지해야 하는 텍스트를 찾아 표시하여 번역사가 텍스트를 변경하지 않도록 합니다.

번역하지 않을 텍스트를 표시하려면 <xliff:g> 자리표시자 태그를 사용합니다. 다음은 메시지가 깨지지 않도록 텍스트 "%1$s"가 번역 중에 변경되지 않아야 함을 나타내는 태그 예입니다.

<string name="countdown">
  <xliff:g id="time" example="5 days">%1$s</xliff:g> until holiday
</string>

자리표시자 태그를 선언할 때는 무엇을 위한 자리표시자인지 설명하는 ID 속성을 추가합니다. 앱에서 나중에 자리표시자 값을 대체할 경우 예상되는 사용을 명확하게 하기 위한 속성 예를 제공해야 합니다.

다음은 자리표시자 태그에 관한 추가 예입니다.

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Example placeholder for a special Unicode symbol -->
<string name="star_rating">Check out our 5
    <xliff:g id="star">\u2605</xliff:g>
</string>
<!-- Example placeholder for a URL -->
<string name="app_homeurl">
    Visit us at <xliff:g
    id="application_homepage">http://my/app/home.html</xliff:g>
</string>
<!-- Example placeholder for a name -->
<string name="prod_name">
    Learn more at <xliff:g id="prod_gamegroup">Game Group</xliff:g>
</string>
<!-- Example placeholder for a literal -->
<string name="promo_message">
    Please use the "<xliff:g id="promotion_code">ABCDEFG</xliff:g>" to get a discount.
</string>
...
</resources>

현지화 체크리스트

Android 앱 현지화 및 배포 프로세스에 관한 전체 개요는 앱 번역 및 현지화를 참고하세요.

현지화 도움말

다음 도움말을 따라 앱을 현지화하세요.

앱이 모든 언어에서 작동하도록 설계

사용자가 앱을 실행하는 기기에 관해 아무것도 가정하지 마세요. 기기에 예상치 못한 하드웨어가 있을 수도 있고 계획하지 않았거나 테스트할 수 없는 언어로 설정되어 있을 수도 있습니다. 앱이 어떤 기기에서 실행되든 정상적으로 작동하거나 심각한 오류를 방지하도록 앱을 설계합니다.

중요: 앱에 기본 리소스 집합이 모두 포함되어 있는지 확인합니다. 폴더 이름에 추가 수정자가 없는 res/drawable/res/values/ 폴더를 포함하세요. 앱에 필요한 모든 이미지와 텍스트가 들어 있습니다.

기본 리소스가 하나라도 누락된 앱은 지원되지 않는 언어로 설정된 기기에서 실행되지 않습니다. 예를 들어 res/values/strings.xml 기본 파일에 앱에 필요한 문자열 하나가 없는 경우 앱이 지원되지 않는 언어로 실행되어 res/values/strings.xml을 로드하려고 하면 사용자에게 오류 메시지와 강제 종료 버튼이 표시됩니다.

자세한 내용은 기본 리소스 테스트 섹션을 참고하세요.

유연한 레이아웃 설계

특정 언어에 맞게 레이아웃을 재정렬해야 하는 경우 해당 언어의 대체 레이아웃을 만들 수 있습니다(예: 독일어 레이아웃의 경우 res/layout-de/main.xml). 하지만 이렇게 하면 앱을 유지하기가 더 어려워질 수 있습니다. 더 유연한 단일 레이아웃을 만드는 것이 좋습니다.

또 다른 일반적 상황은 언어마다 서로 다른 레이아웃을 요구하는 경우입니다. 예를 들어 앱이 일본어로 실행될 때는 연락처 양식에 이름 필드가 두 개 있고 그 밖의 다른 언어로 실행될 때는 세 개 있을 수 있습니다. 이 상황은 다음 두 가지 방법 중 하나로 처리할 수 있습니다.

  • 언어에 따라 프로그래매틱 방식으로 사용 설정 또는 중지할 수 있는 필드가 포함된 레이아웃을 하나 만듭니다.
  • 기본 레이아웃에 변경 가능한 필드가 포함된 다른 레이아웃을 넣습니다. 두 번째 레이아웃은 언어마다 구성이 다를 수 있습니다.

필요한 것보다 더 많은 리소스 파일과 텍스트 문자열 생성 방지

앱의 모든 리소스마다 언어별 대체 텍스트를 반드시 만들 필요는 없습니다. 예를 들어 res/layout/main.xml 파일에 정의된 레이아웃이 모든 언어에서 작동할 수 있으면 대체 레이아웃 파일을 만들 필요가 없습니다.

또한 모든 문자열마다 대체 텍스트를 만들 필요가 없을 수도 있습니다. 예를 들어 다음과 같이 가정해 보겠습니다.

  • 앱의 기본 언어가 미국식 영어입니다. 앱에 사용되는 모든 문자열은 미국식 영어 철자를 사용하여 res/values/strings.xml에 정의되었습니다.
  • 몇 가지 중요한 문구는 영국식 영어 철자법을 사용하고자 합니다. 이러한 대체 문자열은 앱이 영국에서 사용되는 기기에서 실행될 때 사용하고자 합니다.

이렇게 하려면 앱이 영국에서 실행될 때만 다른 문자열을 포함하는 res/values-en-rGB/strings.xml이라는 작은 파일을 만듭니다. 나머지 문자열의 경우 앱은 기본값으로 대체하고 res/values/strings.xml에 정의된 값을 사용합니다.

Android Context 객체를 사용하여 수동으로 언어 조회

다음 예와 같이 Android에서 제공하는 Context 객체를 사용하여 언어를 찾을 수 있습니다.

Kotlin

val primaryLocale: Locale = context.resources.configuration.locales[0]
val locale: String = primaryLocale.displayName

Java

Locale primaryLocale = context.getResources().getConfiguration().getLocales().get(0);
String locale = primaryLocale.getDisplayName();

앱 번역 서비스 사용

앱 번역 서비스Play Console에 통합되었습니다. 이 서비스를 통해 번역 회사에서 즉시 견적을 받고 번역을 요청할 수 있습니다. 앱 UI 문자열, Play 스토어 등록정보 텍스트, IAP 이름 및 광고 캠페인 텍스트를 하나 이상의 언어로 번역해 달라고 요청할 수 있습니다.

현지화된 앱 테스트

기기에서 또는 Android Emulator를 사용하여 현지화된 앱을 테스트합니다. 특히 앱을 테스트하여 필요한 모든 기본 리소스가 포함되어 있는지 확인합니다.

기기에서 테스트

테스트 중인 기기는 다른 위치의 소비자에게 제공되는 기기와 크게 다를 수 있다는 점에 유의하세요. 테스트 기기에서 사용할 수 있는 언어가 다른 기기에서 사용할 수 있는 언어와 다를 수 있습니다. 또한 기기 화면의 해상도와 밀도가 다를 수 있어 UI의 문자열 및 드로어블 표시에 영향을 줄 수 있습니다.

기기에서 언어를 변경하려면 설정 앱을 사용합니다.

에뮬레이터에서 테스트

에뮬레이터 사용에 관한 자세한 내용은 Android Emulator에서 앱 실행을 참고하세요.

맞춤 언어 만들기 및 사용

'맞춤' 언어는 Android 시스템 이미지에서 명시적으로 지원하지 않는 언어 또는 지역 조합입니다. 에뮬레이터에서 맞춤 언어를 만들어 앱이 맞춤 언어에서 어떻게 실행되는지 테스트할 수 있습니다. 이 작업을 실행하는 두 가지 방법은 다음과 같습니다.

  • 앱 탭에서 액세스할 수 있는 맞춤 언어 앱을 사용합니다. 맞춤 언어를 만든 후 언어 이름을 길게 터치하여 전환합니다.
  • 다음 섹션에 설명된 대로 adb 셸에서 맞춤 언어로 변경합니다.

Android 시스템 이미지에서 사용할 수 없는 언어로 에뮬레이터를 설정하면 시스템 자체는 기본 언어로 표시됩니다. 하지만 앱은 제대로 현지화됩니다.

adb 셸에서 에뮬레이터 언어 변경

adb 셸을 사용하여 에뮬레이터에서 언어를 변경하려면 다음 단계를 따르세요.

  1. 테스트할 언어를 선택하고 BCP-47 언어 태그(예: 프랑스어(캐나다) fr-CA)를 결정합니다.
  2. 에뮬레이터를 실행합니다.
  3. 호스트 컴퓨터의 명령줄 셸에서 다음 명령어를 실행합니다.
    adb shell
    또는 기기가 연결된 경우 -e 옵션을 추가하여 에뮬레이터를 원한다고 지정합니다.
    adb -e shell
  4. adb 셸 프롬프트(#)에서 다음 명령어를 실행합니다.
    setprop persist.sys.locale [BCP-47 language tag];stop;sleep 5;start
    대괄호로 묶은 섹션을 1단계의 적절한 코드로 바꿉니다.

    예를 들어 다음과 같이 캐나다 프랑스어로 테스트합니다.
    setprop persist.sys.locale fr-CA;stop;sleep 5;start

이렇게 하면 에뮬레이터가 다시 시작합니다. 홈 화면이 다시 표시되면 앱을 다시 실행합니다. 그러면 앱이 새 언어로 실행됩니다.

기본 리소스 테스트

앱에 필요한 문자열 리소스가 모두 포함되어 있는지 테스트하려면 다음 단계를 따르세요.

  1. 앱에서 지원하지 않는 언어로 에뮬레이터 또는 기기를 설정합니다. 예를 들어 앱의 res/values-fr/에 프랑스어 문자열은 있지만 res/values-es/에 스페인어 문자열이 없는 경우 에뮬레이터의 언어를 스페인어로 설정합니다. 맞춤 언어 앱을 사용하여 에뮬레이터를 지원되지 않는 언어로 설정할 수 있습니다.
  2. 앱을 실행합니다.
  3. 앱에 오류 메시지와 강제 종료 버튼이 표시되면 사용할 수 없는 문자열을 찾고 있는 것일 수 있습니다. 앱에 사용되는 모든 문자열에 관한 정의가 res/values/strings.xml 파일에 있는지 확인합니다.

테스트가 성공하면 다른 유형의 구성으로 테스트를 반복합니다. 예를 들어 앱에 res/layout-land/main.xml 레이아웃 파일은 있지만 res/layout-port/main.xml 파일은 없는 경우 에뮬레이터나 기기를 세로 모드 방향으로 설정하고 앱이 실행되는지 확인합니다.