Android Resource Localization

Victor·2026년 2월 14일

Android 리소스 지역화 가이드

다양한 언어 및 문화 지원

앱에는 특정 문화에 고유할 수 있는 리소스가 포함됩니다. 예를 들어, 앱에는 현재 로캘의 언어로 번역된 문화권별 문자열이 포함될 수 있습니다.

문화권별 리소스를 앱의 나머지 부분과 분리하여 관리하는 것이 좋은 방법입니다. 안드로이드는 시스템 로캘 설정을 기반으로 언어 및 문화권별 리소스를 결정합니다. 안드로이드 프로젝트의 리소스 디렉터리를 사용하여 다양한 로캘에 대한 지원을 제공할 수 있습니다.

앱을 사용하는 사람들의 문화에 맞게 맞춤화된 리소스를 지정할 수 있습니다. 사용자의 언어와 문화에 적합한 모든 리소스 유형을 제공할 수 있습니다. 예를 들어, 다음 스크린샷은 기기의 기본 en_US 로캘과 스페인어 es_ES 로캘에서 문자열 및 드로어블 리소스를 표시하는 앱을 보여줍니다.

그림 1은 현재 로캘에 따라 다른 리소스를 사용하는 앱을 보여줍니다. 안드로이드 SDK 도구를 사용하여 프로젝트를 생성하면 도구는 프로젝트의 최상위 수준에 res/ 디렉터리를 생성합니다. 이 res/ 디렉터리 안에는 다양한 리소스 유형을 위한 하위 디렉터리가 있습니다. 문자열 값을 보유하는 res/values/strings.xml 파일과 같은 몇 가지 기본 파일도 있습니다.

다양한 언어를 지원하는 것은 로캘별 리소스를 사용하는 것 이상입니다. 일부 사용자는 UI 로캘로 아랍어 또는 히브리어와 같이 오른쪽에서 왼쪽으로 쓰는(RTL) 스크립트를 사용하는 언어를 선택합니다. UI 로캘을 영어와 같이 왼쪽에서 오른쪽으로 쓰는(LTR) 스크립트를 사용하는 언어로 설정한 다른 사용자는 RTL 스크립트를 사용하는 언어로 된 콘텐츠를 보거나 생성할 수 있습니다. 두 유형의 사용자 모두를 지원하려면 앱에서 다음을 수행해야 합니다. RTL 로캘에 대해 RTL UI 레이아웃을 사용해야 합니다. 형식화된 메시지 내에 표시되는 텍스트 데이터의 방향을 감지하고 선언해야 합니다. 일반적으로 이 가이드에서 설명하는 대로 텍스트 데이터의 방향을 대신 결정하는 메서드를 호출할 수 있습니다.

로캘 디렉터리 및 리소스 파일 생성

BCP 47 방식

더 많은 로캘에 대한 지원을 추가하려면 res/ 내에 추가 디렉터리를 생성해야 합니다. 각 디렉터리의 이름은 다음 형식을 준수해야 합니다. 형식은 리소스 유형-b+언어 코드[+국가 코드]입니다. 예를 들어 values-b+es/는 언어 코드가 es인 로캘에 대한 문자열 리소스를 포함합니다. 마찬가지로 mipmap-b+es+ES/는 언어 코드가 es이고 국가 코드가 ES인 로캘에 대한 아이콘을 포함합니다. 안드로이드는 런타임에 기기의 로캘 설정에 따라 적절한 리소스를 로드합니다.

지원할 로캘을 결정한 후 리소스 하위 디렉터리 및 파일을 생성해야 합니다. 예를 들어 MyProject/res/ 하위에 values/strings.xml, values-b+es/strings.xml, mipmap/country_flag.png, mipmap-b+es+ES/country_flag.png과 같은 구조를 갖출 수 있습니다.

언어 스크립트 형식

언어는 두 자리 ISO 639-1 언어 코드로 정의되며, 선택적으로 두 자리 ISO 3166-1-alpha-2 지역 코드가 뒤에 올 수 있습니다. 지역 코드 앞에는 소문자 r이 붙습니다. 코드는 대소문자를 구분하지 않습니다. r 접두사는 지역 부분을 구분하는 데 사용됩니다. 지역만 단독으로 지정할 수는 없습니다.

안드로이드 7.0(API 레벨 24)에서는 언어 및 지역별 리소스를 지정하는 데 사용할 수 있는 BCP 47 언어 태그 지원이 도입되었습니다. 언어 태그는 하나 이상의 하위 태그 시퀀스로 구성되며, 각 하위 태그는 전체 태그로 식별되는 언어의 범위를 세분화하거나 좁힙니다.

BCP 47 언어 태그를 사용하려면 b+와 두 자리 ISO 639-1 언어 코드를 결합하고, 선택적으로 +로 구분된 추가 하위 태그를 뒤에 붙여야 합니다. 사용자가 시스템 설정에서 언어를 변경하면 앱이 실행되는 동안 언어 태그가 변경될 수 있습니다.

RTL & LTR 처리

예시

앱이 때때로 런타임에 %s 자리에 주소가 삽입된 "Did you mean %s?"라는 메시지를 표시해야 한다고 가정해 보겠습니다. 앱은 서로 다른 UI 로캘을 지원하므로 메시지는 로캘별 리소스에서 가져오고 기기가 RTL 로캘로 설정된 경우 RTL 방향을 사용합니다. 예를 들어 히브리어 UI의 경우 메시지는 다음과 같이 표시됩니다. 히브리어 텍스트와 %s가 조합된 형태입니다.

하지만 제안된 주소는 로캘의 언어로 된 텍스트를 포함하지 않는 데이터베이스에서 가져온 것일 수 있습니다. 예를 들어 주소가 캘리포니아에 있는 장소인 경우 영어 텍스트를 사용하여 데이터베이스에 나타납니다. 텍스트 방향에 관한 힌트를 제공하지 않고 RTL 메시지에 "15 Bay Street, Laurel, CA" 주소를 삽입하면 결과가 예상과 다르거나 정확하지 않습니다.

번지수가 의도한 대로 왼쪽이 아닌 주소의 오른쪽에 나타납니다. 이로 인해 번지수가 이상한 우편번호처럼 보이게 됩니다. 동일한 문제가 LTR 텍스트 방향을 사용하는 메시지 내에 RTL 텍스트를 포함하는 경우에도 발생할 수 있습니다.

설명 및 해결 방법

이 예시의 문제는 텍스트 포맷터가 "15"가 주소의 일부임을 지정하지 않아 시스템이 "15"가 그 앞에 오는 RTL 텍스트의 일부인지 아니면 그 뒤에 오는 LTR 텍스트의 일부인지 결정할 수 없기 때문에 발생합니다.

이 문제를 해결하려면 BidiFormatter 클래스의 unicodeWrap() 메서드를 사용해야 합니다. 이 메서드는 문자열의 방향을 감지하고 해당 방향을 선언하는 유니코드 형식 지정 문자로 문자열을 감쌉니다.

이제 "15"가 LTR로 선언된 텍스트 내에 나타나므로 올바른 위치에 표시됩니다.

다음 중 하나가 적용되는 경우를 제외하고 지역화된 메시지에 삽입하는 모든 텍스트 조각에 unicodeWrap() 메서드를 사용해야 합니다.

  • 텍스트가 URI 또는 SQL 쿼리와 같이 기계가 읽을 수 있는 문자열에 삽입되는 경우
  • 해당 텍스트 조각이 이미 적절하게 감싸져 있음을 알고 있는 경우

기본 및 현지화 리소스

유저가 앱을 실행하면, 안드로이드 시스템은 디바이스의 로캘에 근거하여 특정 리소스를 선택합니다.

기본 리소스가 중요한 이유

로캘별 텍스트를 제공하지 않은 로캘에서 앱이 실행되면 안드로이드는 res/values/strings.xml에서 기본 문자열을 로드합니다. 이 기본 파일이 없거나 앱에 필요한 문자열이 누락된 경우 앱이 실행되지 않고 오류가 표시됩니다.

다음 예시는 기본 텍스트 파일이 불완전할 때 어떤 일이 발생할 수 있는지 보여줍니다.

앱의 코틀린 또는 자바 코드가 두 개의 문자열 text_a와 text_b를 참조한다고 가정해 보겠습니다. 앱에는 영어로 text_a와 text_b를 정의하는 지역화된 리소스 파일(res/values-en/strings.xml)이 포함되어 있습니다. 또한 앱에는 text_a에 대한 정의는 포함되어 있지만 text_b에 대한 정의는 포함되어 있지 않은 기본 리소스 파일(res/values/strings.xml)이 포함되어 있습니다.

이 앱이 로캘이 영어로 설정된 기기에서 실행되면 필요한 모든 텍스트 문자열이 포함되어 있어 문제없이 실행될 수 있습니다.

하지만 이 앱이 영어가 아닌 언어로 설정된 기기에서 실행되면 사용자는 오류 메시지와 강제 종료 버튼을 보게 되며 앱이 로드되지 않습니다.

이 상황을 방지하려면 res/values/strings.xml 파일이 존재하고 필요한 모든 문자열을 정의하는지 확인해야 합니다. 이 상황은 문자열뿐만 아니라 모든 유형의 리소스에 적용됩니다. 레이아웃, 드로어블, 애니메이션 등 앱이 호출하는 모든 리소스를 포함하는 기본 리소스 파일 세트를 생성해야 합니다.

기본 리소스 생성

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

기본 리소스 세트에는 기본 드로어블 및 레이아웃이 포함되며 애니메이션과 같은 다른 유형의 리소스도 포함될 수 있습니다.

  • res/drawable/은 Google Play의 앱 아이콘용 그래픽 파일을 하나 이상 포함해야 하는 필수 디렉터리입니다.

  • res/layout/은 기본 레이아웃을 정의하는 XML 파일을 포함해야 하는 필수 디렉터리입니다.

  • res/anim-한정자 폴더가 있는 경우 필수인 res/anim/ 디렉터리가 있습니다.

  • res/xml-한정자 폴더가 있는 경우 필수인 res/xml/ 디렉터리가 있습니다.

  • res/raw-한정자 폴더가 있는 경우 필수인 res/raw/ 디렉터리가 있습니다.

코드에서 안드로이드 리소스에 대한 각 참조를 검사해야 합니다. 각 참조에 대해 기본 리소스가 정의되어 있는지 확인해야 합니다. 또한 기본 문자열 파일이 완전한지 확인해야 합니다. 지역화된 문자열 파일은 문자열의 하위 집합을 포함할 수 있지만 기본 문자열 파일은 모든 문자열을 포함해야 합니다.

대체 리소스 생성

앱을 현지화하는 큰 부분은 서로 다른 언어에 대한 대체 텍스트를 제공하는 것입니다. 어떤 경우에는 대체 그래픽, 사운드, 레이아웃 및 기타 로캘별 리소스도 제공합니다.

앱은 각각 서로 다른 한정자를 사용하여 많은 res/한정자/ 디렉터리를 지정할 수 있습니다. 특정 로캘에 대한 대체 리소스를 생성하려면 언어 또는 언어-지역 조합을 지정하는 한정자를 사용해야 합니다. 리소스 디렉터리의 이름은 명명 규칙을 준수해야 하며 그렇지 않으면 앱이 컴파일되지 않습니다.

예를 들어 기본 언어가 영어이고 앱의 모든 텍스트를 프랑스어로, 제목을 제외한 모든 텍스트를 일본어로 현지화한다고 가정해 보겠습니다. 이 경우 res/values/strings.xml은 title이라는 문자열을 포함하여 모든 문자열에 대한 영어 텍스트를 가집니다. res/values-fr/strings.xml은 title을 포함한 모든 문자열의 프랑스어 텍스트를 가집니다. res/values-ja/strings.xml은 title을 제외한 모든 문자열의 일본어 텍스트를 가집니다.

  • 런타임에 기기가 프랑스어 이외의 언어로 설정되면 안드로이드는 res/values/strings.xml 파일에서 title을 로드합니다.

  • 런타임에 기기가 프랑스어로 설정되면 안드로이드는 res/values-fr/strings.xml 파일에서 title을 로드합니다.

  • 기기가 일본어로 설정된 경우 안드로이드는 res/values-ja/strings.xml에서 title을 찾지만 해당 문자열이 없으므로 기본값으로 대체하여 res/values/strings.xml 파일의 영어 title을 로드합니다.

기본 및 대체 리소스 우선순위 결정 규칙

어떤 리소스가 우선순위를 갖는지 이해하는 것은 앱의 동작을 예측하는 데 매우 중요합니다. 여러 리소스 파일이 기기의 현재 구성과 일치할 때가 있습니다. 이때 안드로이드 시스템은 정해진 규칙에 따라 사용할 파일을 결정합니다. 리소스 디렉터리 이름에 지정할 수 있는 한정자 중에서 로캘은 거의 항상 우선순위를 갖습니다.

구체적인 예시 상황으로, 앱에 기본 그래픽 세트와 함께 서로 다른 기기 설정에 최적화된 두 개의 그래픽 세트가 더 포함되어 있다고 가정해 보겠습니다. 하나는 스타일러스 입력을 기대하고 가로 방향의 QVGA 저밀도 화면을 가진 기기에 최적화된 그래픽 세트입니다. 다른 하나는 일본어 사용에 최적화된 그래픽 세트입니다.

앱이 일본어를 사용하도록 구성된 기기에서 실행된다면 안드로이드는 일본어 리소스를 로드합니다. 기기가 스타일러스 입력을 기대하고 가로 방향 화면을 가졌더라도 결과는 동일합니다. 선택 프로세스에서 로캘보다 우선하는 유일한 한정자는 모바일 국가 코드(MCC)와 모바일 네트워크 코드(MNC)뿐입니다.

언어 설정보다 MCC가 우선하는 구체적인 사례를 확인해 보겠습니다. 앱 코드에서 R.string.text_a 리소스를 호출하는 상황입니다. 현재 두 개의 관련 리소스 파일을 사용할 수 있다고 가정합니다.

첫 번째는 영어인 앱의 기본 언어로 작성된 인도 모바일 네트워크(MCC 404)용 리소스 파일입니다. 두 번째는 힌디어로 작성된 리소스 파일입니다. 이때 앱은 다음과 같은 구성을 가진 기기에서 실행 중입니다. 기기의 심 카드가 인도 모바일 네트워크(MCC 404)에 연결되어 있습니다. 또한 기기 언어는 힌디어(hi)로 설정되어 있습니다.

이 경우 안드로이드는 힌디어가 아닌 영어를 로드하게 됩니다. 기기가 힌디어로 구성되어 있어도 결과는 바뀌지 않습니다. 리소스 선택 프로세스에서 안드로이드가 언어 일치보다 MCC 일치를 선호하기 때문입니다. 선택 프로세스가 이 예시들만큼 항상 간단한 것은 아닙니다. 상세한 설명은 안드로이드가 가장 잘 일치하는 리소스를 찾는 방법을 참고하시기 바랍니다. 모든 한정자는 앱 리소스 개요에 우선순위 순서대로 설명되어 있습니다.

실제 사용

정적 파일

구글 콘솔

0개의 댓글