Androidアプリケーションのローカライズの簡単な実例を公開します。
ダウンロード: Eclipse Androidアプリケーションプロジェクト - I18N.zip
Androidアプリの国際化(Internationalization / I18N)および現地化(Localization / L10N)の方法は、Android開発者サイトの次の文書で紹介されています。 また、言語地域にしたがい、文字だけでなく、画像の自動切替えもできるサンプルアプリも提供されています。
以下では、Kobu.Comが用いているローカライズ手法にのっとり、英語と日本語を同時サポートするAndroidアプリを作ってみます。 これを私は「非英語ネーティブによるローカライズ手法」と呼んでいます。
ここでご説明するローカライズ手法をまとめると次のとおりです。
最初に英語をサポートすることでまず世界のそれなりの部分に対応できます。 英語圏の人のみならず、母国語は異なるが英語はある程度わかるという人が多いからです。 あとは必要と余力に応じ英語と自身の母国語以外の対応言語を増やしていけます。
以下、この手法を使ってAndroidアプリのローカライズを行ってみます。 Android OSが提供している国際化のしくみは非英語ネーティブ手法と相性がよいため、素直にローカライズを行うことができました。
Androidを搭載したスマートフォンやタブレットでは、設定画面で使用言語を切り換えることができます。
たとえば、日本語から英語に切り換えるには、[設定]→[言語とキーボード]→[言語を選択]を選び、Englishをタッチします。
Androidでは、言語を切り換えると、実行中のアクティビティが再起動されます。 つまりアクティビティの初期化メソッドのonCreate()が呼ばれます。 したがって、アプリ実行中にユーザーが言語を変えたらどうしよう、という心配は不要です。
サンプルアプリケーションの初期画面を示します。左側が言語が英語に設定されている場合の画面、右が日本語に設定されている場合の画面です。英語や日本語以外の言語に設定されている場合には左の英語の画面が表示されます。
ここには三つの文字列が見えています。 一番上のヘッダー部分がアプリケーションのアクティビティ名、真中がテキストビューウィジェットの文字列、一番下がボタンの名前です。
ここで、下のボタンをタッチすると、テキストビューに別の文字列が設定されます。
これだけのプログラムです。
ポイントは、いかにしてユーザが選択中の言語の文字列を表示できるようにするか、です。
簡単にいうと、文字列はプログラムのコードには書かず、外部ファイルに納めておきます。 これを必要に応じプログラムから参照します。 Androidでは画面レイアウトも外部の定義ファイルに書く場合が多いので、レイアウト定義からも外部ファイルに定義した文字列を参照できる必要があります。
Androidアプリケーションでは、ローカライズ対象とする文字列は文字列リソースファイルに入れておきます。
文字列リソースファイルは、アプリケーションフォルダーのresフォルダーの下のvaluesフォルダーに置きます。
名前は何でもよいですが、ふつうはstrings.xmlにします。
リソースファイルはテキストエディタで編集することも、Eclipse用Androidプラグインのグラフィカルなエディターで編集することもできます。
以下に、このアプリケーションの英語用の文字列リソースファイルを示します。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Internationalization and Localization</string>
<string name="hello">Hello World.</string>
<string name="byebye">Bye bye World</string>
<string name="button">Change Text</string>
</resources>
次が日本語のリソースファイルです。
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">国際化と現地化</string> <string name="hello">こんにちは、みなさん</string> <string name="byebye">さようなら、みなさん</string> <string name="button">テキストを変える</string> </resources>
おわかりのように、helloやbyebyeなどをキーにして、英語、日本語それぞれの言語の挨拶文が取得できるというわけです。
この判断はAndroid側が自動的に行ってくれます。
しくみは簡単。
現在の言語設定がxxであれば、values-xxに収められているstrings.xmlを参照します。
日本語の場合はvalues-ja、英語の場合はvalues-enです。
xxにあたるvalues-xxが用意されていない場合は、xxの付かないただのvaluesの下のstrings.xmlが参照されます。
つまり、values-xxが用意されている言語についてはその中のstrings.xmlが参照され、それ以外の場合はデフォルトのvaluesの中のstrings.xmlが参照されるというしくみです。
非英語ネーティブ手法では、デフォルトが英語、私の母国語の日本語がひとつめのローカライズ対象であるので、英語文字列はvalues/strings.xmlに、日本語文字列はvalues-ja/strings.xmlに置きます。
言語設定が日本語の場合のみvalues-ja/strings.xmlが使われ、それ以外の場合はデフォルトのvalues/strings.xmlが使われます。
つまり、言語設定が英語(en)であれ、韓国語(ko)であれ、ドイツ語(de)であれ、表示は英語になります。
プログラムの中から文字列リソース内の文字列を参照するのは簡単です。
public class I18N extends Activity ... {
...
public void onClick(View v) {
if (v.getId() == R.id.button1) {
String greeing = getString(R.string.byebye);
textView.setText(greeting);
}
}
}
上記のgetStringは、アクティビティクラス(android.app.Activity)の親クラスのひとつ、コンテキストクラス(android.content.Context)で定義されたメソッドです。
このようにアクティビティの中から一発呼び出しでローカライズ文字列が取得できます。
ここで「R.string」というのは何か、疑問がわくでしょう。
これはAndroidプラグインが、リソースファイルに文字列を追加すると自動的に生成してくれるIDです。
アプリケーションフォルダーのgenフォルダーの下のR.javaに収められています。
/* AUTO-GENERATED FILE. DO NOT MODIFY. * * This class was automatically generated by the * aapt tool from the resource data it found. It * should not be modified by hand. */ package sample.i18n; public final class R { public static final class attr { } public static final class drawable { public static final int icon=0x7f020000; } public static final class id { public static final int button1=0x7f050001; public static final int textView1=0x7f050000; } public static final class layout { public static final int main=0x7f030000; } public static final class string { public static final int app_name=0x7f040000; public static final int button=0x7f040003; public static final int byebye=0x7f040002; public static final int hello=0x7f040001; } }
文字列以外にも、アイコンなどの画像ファイル、レイアウト定義、UI部品も、同様にIDで参照されることがわかります。
Androidアプリの開発の際には、画面に表示するUI部品(ウィジェット)の種類と配置をレイアウトファイルと呼ぶXMLファイルに書くのがふつうです。 ウィジェットに設定する名前やテキストをローカライズするには、レイアウトファイル中で文字列リソースのIDを指定します。
レイアウトファイルはAndroidプラグンのグラフィカルエディタで編集できますが、結果は次のようなXMLファイルになります。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_weight="0.9" android:id="@+id/textView1"
android:text="@string/hello" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" android:isScrollContainer="true"
android:background="#AAAAAA" android:textColor="#333333">
</TextView>
<Button android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/button1"
android:layout_weight="0.1" android:text="@string/button"
android:gravity="center">
</Button>
</LinearLayout>
レイアウトXMLファイルからの文字列リソース参照の書式は「@string/<id>」です。 画面の中央に表示されるテキストビュー(TextView)には「hello」が指定されています。 これは英語の場合は「Hello World」です。 画面の下部のボタン(Button)の名前は「button」が設定されているので、英語の場合は「Change Text」になります。
ところで、strings.xmlに定義された文字列のうち、まだ使われていないものがあります。
app_nameはEclipseでAndroidプロジェクトを作成するとはじめから定義されているものです。
app_nameはアプリケーションの定義ファイル(AndroidManifest.xml)から参照されており、これが、ホーム画面のアイコンの下や、アプリが実行されたときの画面の上部に表示されます。
つまり、アプリケーション(やアクティビティ)の名前もローカライズ可能ということです。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android= ...
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".I18N"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
最後に、完結を期すため、このサンプルアプリのアクティビィのJavaコードを掲載します。
package sample.i18n;
import java.util.Locale;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
// Sample application for demonstrating non-English-speaker's
// localization strategy.
// 2011 Apr 17 Written for test by ARAI, Bunkichi, Kobu.Com,
// 2011 Jul 24 Updated for demonstration
public class I18N extends Activity implements OnClickListener {
private String logtag = getClass().getSimpleName();
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.textView1);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
Locale locale = Locale.getDefault(); // current locale
Locale locale = getResources().getConfiguration().locale; or you can ...
Log.d(logtag, "lang = " + locale.getLanguage());
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.button1) {
textView.setText(getString(R.string.byebye)); // set localized text
textView.setText(R.string.byebye); or you can do it faster
}
}
}
以上がAndroidアプリケーションのローカライズの簡単な実例でした。
上記ソースコードのほか、これまでに掲載した外部リソースファイルも、下記のEclipseプロジェクトに含まれています。
ダウンロード: Eclipse Androidアプリケーションプロジェクト - I18N.zip
このサイトで提供しているほかのローカライズサンプルです。
Kobu.Comでは、世界で使えるソフトウェアやドキュメントの制作で実績があります。
Copyright © 2011 Kobu.Com. All rights reserved.
制作: Kobu.Com
提供: Kobu.Com
Written 2011 Jul 25
公開するサンプルは試作品で、完全なものではありません。
この解説書とサンプルの転載はご遠慮ください。
リンク張りやお問合せやコメントを歓迎いたします。