안드로이드 앱에 다국어 지원이라는 주제로 글을 적어봅니다.
문자열은 별도의 xml 파일에 저장 후 Layout이나 Java에서 이것을 이용해야 하지만, 귀찮다는 이유로 Java에 하드코딩 하는 경우도 있을 것입니다.
추천하는 방법은 아니지만, 앱에서 지원해야 언어가 많지 않고 굳이 Java에서 다국어 지원을 처리해야겠다 할 경우에 어떻게 하면 되는지 기술해보겠습니다.
간단한 테스트를 위해서 버튼을 누르면 텍스트가 출력되는 앱을 만들도록 하겠습니다.
언어 변경을 위해서는 "설정(Settings) 앱 - 언어(Language)" 에 가서 원하는 언어로 변경하면 되지만, 테스트를 위해서 매번 그렇게 하기에는 번거롭기 때문에 앱에서 볼륨키를 눌러서 언어를 변경하도록 예제를 만들어보겠습니다.
[다국어지원 - JAVA에서 하드코딩 방식]
레이아웃은 가운데 Button이 하나가 있고, 그 위에 문자열 출력을 위한 TextView가 있도록 만들었습니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</android.support.constraint.ConstraintLayout>
자바 (MainActivity.java)
실행하면 onCreate에서 TextView와 Button에 "Thanks"와 "Default(English)"가 화면에 출력됩니다.
dispatchKeyEvent에서는 볼륨 상하키를 누르는 방향에 따라서 언어를 지정하는 변수가 변경 1되고, 버튼을 누르면 기본 언어인 영어 "Thanks"에 해당하는 변경된 언어가 TextView에 표시됩니다.
package com.example.help.multilanguagetest;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView mTextView;
private Button mButton;
private int mLang;
private final static String [] THANKS = {"Thanks.", "Gracias.", "Danke.", "Merci.", "감사합니다."};
private final static String [] LANGUAGES = {"Default(English)", "Spanish", "German", "French", "한국어"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
mTextView.setText(THANKS[0]);
mButton = findViewById(R.id.button);
mButton.setText(LANGUAGES[0]);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTextView.setText(THANKS[mLang]);
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
switch(event.getKeyCode()) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (event.getAction() == KeyEvent.ACTION_UP) {
if (mLang < LANGUAGES.length - 1) {
mLang++;
}
mButton.setText(LANGUAGES[mLang]);
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (event.getAction() == KeyEvent.ACTION_UP) {
if (mLang > 0) {
mLang--;
}
mButton.setText(LANGUAGES[mLang]);
}
return true;
default:
break;
}
return super.dispatchKeyEvent(event);
}
}
프로젝트 압축화일
실행결과
※볼륨키로 언어 변경 에뮬레이팅 없이 실제 세팅에서 언어를 변경할 경우
onCreate에서 로케일의 언어 값을 읽어와서 해당하는 언어에 맞는 문자열을 세팅해주면 됩니다.
세팅에서 변경한 언어가 지원하지 않으면 기본 언어인 영어로 해줍니다.
package com.example.help.multilanguagetest;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Locale;
public class MainActivity extends Activity {
TextView mTextView;
Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Locale locale;
String language;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locale = getResources().getConfiguration().getLocales().get(0);
} else {
locale = getResources().getConfiguration().locale;
}
language = locale.getLanguage();
mTextView = findViewById(R.id.textView);
mButton = findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
switch(language) {
case "en":
mButton.setText("Default(English)");
mTextView.setText("Thanks.");
break;
case "es":
mButton.setText("Español");
mTextView.setText("Gracias.");
break;
case "de":
mButton.setText("Deutsch");
mTextView.setText("Danke.");
break;
case "fr":
mButton.setText("Français");
mTextView.setText("Merci.");
break;
case "ko":
mButton.setText("한국어");
mTextView.setText("감사합니다.");
break;
default:
mButton.setText(language);
mTextView.setText("Thanks.");
break;
}
}
}
프로젝트 압축화일
[다국어지원 - xml 처리 방식]
Java에서 하드코딩 하는 방식은 가능은 하지만 지원하는 언어가 많거나 문자열이 여러 개인 경우 비효율적입니다.
xml에서 다국어 지원하는 방식은 기본 언어에 대해서만 작업을 해주고, 나머지 언어에 대해서는 번역업체에 아웃소싱으로 처리할 수 있기 때문에 프로젝트 진행하는 데 있어서 효율적입니다.
xml 방식은 기본언어의 경우 res/values 디렉터리에 strings.xml(프로젝트 생성시 기본으로 만들어짐)에 저장을 하고 추가 언어는 res/values-"language"-"country"/ 디렉터리에 언어별로 strings.xml 파일을 만들어줍니다.
예로 들면, 기본 언어(영어)와 한국어, 프랑스어(캐나다)를 지원하는 앱을 개발한다고 했을 경우 아래와 같이 디렉터리를 구성 후 strings.xml 파일을 만들어주면 됩니다.
res/values/strings.xml
values-ko/strings.xml
values-fr-rCA/strings.xml
초기에는 디렉터리만 만들어주고, 파일은 기본언어의 strings.xml을 복사해서 넣어주면 됩니다.
그런 다음에 아웃소싱한 번역업체에 넘겨주어서 번역 작업을 의뢰합니다.
다행히도 안드로이드 스튜디오에서는 다국어 작업은 조금 편하게 할 수 있도록 Translations Editor라는 것을 가지고 있습니다. 이것을 이용하면 외부에서 언어별 디렉터리를 만들어주거나 디렉터리마다 파일을 복사해야 하는 번거로움이 해결됩니다.
앞서 만든 예제와 같게 xml 처리 방식으로 만들어 보겠습니다.
Translations Editor
먼저 strings.xml 편집 창에서 오른쪽 위에 있는 Open editor를 클릭하면 Translations Editor가 실행됩니다.
Translations Editor가 실행되면 아래와 같은 화면이 나옵니다.
아래 노란색 상자에 있는 버튼들에 대해 설명을 하겠습니다.
1번: 키를 추가합니다. 여기서 키는 그 문자열의 이름이 되겠습니다.
2번: 키를 삭제합니다.
3번: 로케일를 추가합니다. 지원하기 위한 언어를 추가하는 걸 말합니다.
한국어를 추가해보겠습니다.
3번 로케일 추가 버튼을 눌러서 한국어를 선택합니다.
지원하려는 나머지 언어도 추가해주면 아래와 같은 화면이 나옵니다.
언어별로 첫 번째 키(app_name)의 키값이 기본값으로 모두 채워져 있습니다.
Translations Editor가 동작하기 위해서 첫 번째 키값이 모두 채워진 상태로 시작되어야 합니다.
혹시 나중에 번역하면 넣으려고 첫 번째 키값을 삭제해버린 상태에서 Translations Editor를 종료하면, 그다음에 Translations Editor 진입하면 추가한 언어들이 나오지 않게 됩니다. (중요함)
번역이 필요한 키 항목은 빨간색 글자로 나타납니다.
첫 번째(app_name) 키값들은 나중에 처리하고, 두 번째(language) 키값들은 언어별 키값의 Translation 편집 창에 채워 넣습니다.
첫 번째 키값은 앱의 이름으로 번역을 하지 않고, 타 언어들에도 기본값으로 나오도록 할 예정입니다.
이때는 Untranslatable을 선택해줍니다.
이때 키 항목의 글자가 빨간색으로 표시되는 것은 번역이 필요 없는데 타언어들에 키값이 채워져있어서 발생하는 현상입니다. 그래서, 이 키 항목의 기본값을 제외하고 타언어들의 키값들은 삭제해줍니다.
아래가 지원하는 언어의 번역을 추가해서 완료된 화면입니다.
왼쪽에 보면 지원하는 언어별 values 디렉터리가 만들어져 있는 것을 확인하실 수 있습니다.
레이아웃 (activity_main.xml)
앞선 JAVA에서 하드코딩 방식과 달리 레이아웃에 문자열을 바로 삽입해줍니다. "@string/키" 형태로 넣어주면 됩니다.
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/thanks"
android:textColor="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:text="@string/language"
android:textColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</android.support.constraint.ConstraintLayout>
자바 (MainActivity.java)
다국어 작업을 Translations Editor로 처리했기 때문에 자바 쪽에서는 처리해줘야 할 것이 없습니다.
package com.example.help.multilanguagetest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView mTextView;
Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
mButton = findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//TODO
}
});
}
}
프로젝트 압축화일
실행결과
이상으로 "안드로이드 다국어 지원"에 대해서 알아보았습니다.
조금이나마 도움이 되셨으면 아래 ♡공감 버튼을 눌러주세요.
- 설정앱(Settings) - 언어(Language) 변경을 에뮬레이팅하는 것. [본문으로]
'Android Dev > Compatibility' 카테고리의 다른 글
values-mcc 의미 및 활용 (mnc 포함) (0) | 2019.12.31 |
---|---|
앱을 안드로이드 9 파이로 마이그레이션 과정 (Android 9 Pie migration) (0) | 2019.04.19 |
안드로이드 플랫폼 스트링(다국어 지원) 사용하기 (1) | 2018.12.10 |
Google Play에 등록한 앱이 특정 기기에서 검색되지 않는 이유 및 해결방법 (3) | 2018.10.20 |