本地化
快速查看
·
·
·
·
在本文中
参阅
Android会在各个地区的各种设备上运行。为了满足最大多数用户的需求,应用程序应该按照当地的习惯来处理文本、音频文件、数字、货币符号和图片。
本文是本地化Android应用程序的最佳实践。无论是利用Eclipse+ ADT、Ant工具,还是其它IDE来开发程序,以下原则都会适用。
本文假定你对Java有足够的了解,也熟悉了Android的资源装载、用XML对用户界面元素的声明、关于诸如Activity生命周期之类的开发经验、国际化和本地化的基本原则等内容。
利用Android的资源机制,尽可能地把应用程序中与地区相关的显示信息从核心Java代码中分离出来,这是一种好习惯:
l
l
按照本文叙述的方法,Hello, L10N 教程将带你一步一步创建一个简单的本地化应用程序,它使用了地区设置的资源。
概述:Android的资源切换
所谓资源,是指文本字符串、布局、声音、图片以及其它任何Android应用程序所需要的静态数据。应用程序可以包含多组资源,每组资源对应不同的硬件设备配置。当用户运行应用程序时,Android会自动选择并装载与硬件最匹配的资源。
(本文关注于本地化和地区设置。至于资源切换的完整描述,以及所有可以设定的配置——如屏幕方向、触摸屏类型等等,请参阅提供替代资源 。)
编写应用程序时: |
| 用户运行应用程序时: |
编写应用程序时,请创建所用到的缺省资源和替代资源。要创建资源,须将文件放入项目res/
目录的指定子目录下。
如果应用程序没有为运行的地区提供相应的本地化资源,Android将从res/values/strings.xml
装载缺省的字符串。如果这个缺省的文件缺失了,或者其中应用程序需要的字符串缺失了,应用程序将会停止运行并显示错误。以下例子说明了缺省文本资源文件不完整时将会发生什么。
示例:
应用程序的Java代码引用了两个字符串text_a
和text_b
。这个程序包括了本地化资源文件(res/values-en/strings.xml
),其中用英语定义了text_a
和text_b
。此程序还包含了缺省的资源文件(res/values/strings.xml
),其中包括了text_a
的定义,但却没有text_b
的定义。
l
l res/values-en/strings.xml
包含了两个用到的文本串。
l
为了防止出现这种情况,请确保res/values/strings.xml
文件的存在并且其中定义了所有所需的字符串。要考虑使用所有类型资源的情况,而不仅仅是字符串:需要创建一组缺省资源,其中包括了程序所用到的所有资源——布局、绘图、动画等等。关于测试的详细信息,请参阅测试缺省资源 。
使用本地化资源
把应用程序的缺省文本资源放入以下路径的文件内:
res/values/strings.xml
(必需目录)
res/values/strings.xml
内的文本串应该使用默认语言,即程序的大多数预期用户所用的语言。
默认资源组还必须包括所有默认的绘图和布局资源,还可能包括诸如动画之类的其它资源
(必需目录,至少保存一个图片文件,用于Market内应用程序图标)
(必需目录,保存定义缺省布局的XML文件)
(如果有res/anim-
<qualifiers> 目录则是必需的)
(如果有res/xml-
<qualifiers>目录则是必需的)
(如果有res/raw-
<qualifiers>目录则是必需的)
提示:建议在代码里检查每一个对Android资源的引用。确保所有的资源都定义了默认资源,还要确保缺省字符串文件是完整的:本地化字符串文件可以仅包含全部字符串的子集,但缺省字符串文件必须包含字符串的全集。
很大程度上,本地化应用程序的工作就是为各种语言提供可替代的文本资源。有时,还需要提供可替代的图片、声音、布局及其它地区设置相关资源。
应用程序可以指定多个res/
<qualifiers>/
目录,用不同名称qualifiers区分每个目录。目录名称代表语言或者语言-地区,为不同的地区在其中创建各替代资源。(资源目录的名称必须遵守提供替代资源的命名体系要求,否则无法进行编译。)
示例:
假定应用程序的默认语言是英语,并想把应用程序的所有文本本地化为法语、大部分文本(除应用程序标题外的所有文本)本地化为日语。这时,应该创建三套strings.xml
的替代资源,分别存放在地区设置资源目录下:
1. res/values/strings.xml
包含应用程序用到的所有字符串的英语文本,包括了名为title
的字符串。
2. res/values-fr/strings.xml
包含应用程序用到的所有字符串的法语文本,包括title
。
3. res/values-ja/strings.xml
包含应用程序用到的所有字符串的日语文本,除了title
。
如果Java代码引用了R.string.title
,运行时会发生以下情况:
l res/values/strings.xml
文件装载title
。
l res/values-fr/strings.xml
装载title
。
注意,如果设备设置为日语,Android将在res/values-ja/strings.xml
文件内查找title
。但因为其中没有这个字符串,Android将降到默认级别,从res/values/strings.xml
文件装入英文的title
。
那个资源优先采用?
如果有多个资源文件符合设备的区域配置,Android按照一套规则来确定使用哪一个文件。在可用的资源目录名称中,本地区的名称总是优先采用的。
例如:
假设应用程序包含一组默认的图片资源和两组其它的图片资源,每个都是为不同的设备地区配置做过优化的。
l res/drawable/
包含默认图片。
l res/drawable-small-land-stylus/
包含优化过的图片,用于带触笔输入及横向QVGA 低分辨率屏幕的设备。
l res/drawable-ja/
包含为使用日语优化过的图片。
如果应用程序运行在配置为日语的设备上,Android将从res/drawable-ja/
装入资源,即使设备正好也是带触笔输入及横向QVGA 低分辨率屏幕。
例外:只有MCC和MNC(移动国家代码和移动网络代码)配置是优先于地区设置资源的。
例如:
假设有如下场景:
l
应用程序需调用R.string.text_a
l
¡ res/values-mcc404/strings.xml
,包括缺省语言是英语的text_a
字符串。
¡ res/values-hi/strings.xml
,包括印度语的text_a
字符串。
l
¡
¡ hi
)。
Android将从res/values-mcc404/strings.xml
(英语)装入text_a
,即使设备配置成印度语。因为选择资源时,Android将优先匹配MCC而不是语言资源。
选择资源的过程往往不像上例这么简单。细节请参阅Android如何查找最匹配的资源。所有资源目录的命名都在提供替代资源-表2中按优先级列出了。
在Java代码中引用资源
在应用程序的Java代码中,可以用R.
resource_type.
resource_name或android.R.
resource_type.
resource_name的格式引用资源。详情参阅访问资源。
将应用程序设计为可在任何地区运行
对于用户将要运行程序的设备不能作出任何假定。设备的硬件可能是未知的,或者所设的地区没有考虑在内,或者此地区设置根本就无法测试。因此,无论运行的设备是什么样的,应用程序都要能够顺利运行或安全结束的。
重点:确保应用程序包含了默认资源的全集。
确保包含res/drawable/
和一个res/values/
目录(目录名称不能改动),其中包括了应用程序所需的所有图片和文本资源。
应用程序只要缺失了一个缺省资源,在地区设置不支持的设备上都不能运行。比如:res/values/strings.xml
缺省文件可能少了一个程序用到的字符串。如果程序运行在不支持的地区,并试图装载res/values/strings.xml
,用户将看到错误信息和强制退出按钮。Eclipse之类的IDE不会高亮提醒这种错误,在设成可支持地区的设备和仿真器上测试时也发现不了这个问题。
更多信息请参阅测试缺省资源。
设计自适应的布局
如果要调整布局来适应指定的语言(比如德语单词会很长),需要为这种语言创建一个替代布局(比如res/layout-de/main.xml
)。然而,这么做会使得程序更加难以维护。更好的方式是创建更加灵活的单一布局。
另一种典型情况是某语言需要与众不同的布局。比如:应用程序运行在日语环境时,联系人列表应该包含两个姓名字段的,而在其它语言时却要包含三个姓名字段。可以用以下方法之一来处理:
l
l
避免创建不必要的资源文件和文本字符串
也许并不需要为应用程序的每个资源都创建可替代的本地化资源。例如,res/layout/main.xml
文件内定义的布局可以在所有地区使用,这时就没有必要创建任何替代布局资源文件。
也不需要为所有字符串都创建替代文本资源。例如,假定:
l
l
要达到以上目的,应该创建一个res/values-en-rGB/strings.xml
文件,它只包含英国设置下拼写不同的字符串。针对其余字符串,应用程序会降到默认级别使用res/values/strings.xml
中的定义。
使用Android Context对象进行地区的人工查询
可以用Android 提供的Context
对象查询地区设置:
String locale =context.getResources().getConfiguration().locale.getDisplayName();
请记住:测试设备可能与其它地区用户所用的设备存在很大的差异。测试设备上可选的地区可能与其他设备上的不同。设备屏幕的分辨率也可能不一样,这会影响用户界面的字符串及绘图对象的显示。
使用系统设置来改变设备的地区设置(Home > Menu > Settings > Locale & text > Select locale)。
关于仿真器的使用详情,请参阅Android仿真器。
创建和使用自定义地区设置
“自定义”地区是指Android系统还未明确支持的语言/地区组合。(Android 平台支持的地区列表参见SDK 表中的版本说明。)通过在仿真器上创建自定义地区,可以对要在自定义地区运行的程序进行测试。有两种方式实现:
l
l
如果把仿真器设置成Android系统不支持的地区,系统本身将显示为缺省语言,而应用程序则会正常本地化。
用adb shell命令改变仿真器的地区设置
要用adb shell改变仿真器的地区设置:
1. 选出需要测试的地区,并确定语言及地区代码,比如fr
代表法语,CA
代表加拿大。
2. 启动仿真器。
3. 在主机的命令行环境下运行以下命令:
adb shell
如果仿真器已经启动,则通过加入-e
参数来指定仿真器:
adb -e shell
4. 在adb shell提示符(#
)下,运行以下命令:
setprop persist.sys.language [
language code];setprop persist.sys.country [
country code];stop;sleep 5;start
用第1步选出的语言和地区代码替换括号内部分。
例如:需在加拿大/法语环境下测试:
setprop persist.sys.language fr;setprop persist.sys.country CA;stop;sleep 5;start
这将导致仿真器重启(看上去像是完全重启,其实不是)。一旦首页再次出现,即可启动应用程序(比如在Eclipse 内点击运行),程序将在新的地区设置下运行。
下例演示了如何测试应用程序是否包含所有所需的字符串资源:
1. 把仿真器或设备设置为应用程序不支持的地区。比如,应用程序在res/values-fr/
中包含了法语字符串,但在res/values-es/
没有西班牙语字符串,则把仿真器设为西班牙语(可以用“选择语言”来把仿真器设置成不支持的地区)。
2. 运行应用程序。
3. 如果程序显示错误信息和强制退出按钮,那看来可能是存在找不到可用字符串的情况。请确保res/values/strings.xml
文件定义了程序用到的所有字符串。
如果测试成功,则再测试其它类型的资源。比如:应用程序包含了布局文件res/layout-land/main.xml
,但没有包含res/layout-port/main.xml
,则把仿真器设为竖向显示后再试试程序是否能够运行。
Android Market是Android应用程序主要的发布系统。要发布已本地化的应用程序,需要对其进行签名、版本化,其余步骤参阅准备发布。
如果应用程序拆分为多个.apk文件,则每个文件都能针对不同的地区进行设置,可参考以下步骤:
l
l
l
以下清单汇总了本地化Android 应用程序的步骤。当然,并不是每个应用程序都会用到列表里的所有步骤。
| 选择本地化策略。应用程序将支持哪些地区和语言?缺省国家和语言是什么?当没有为给定地区定义资源时,程序如何表现? |
| 明确认程序中需要本地化的每一项内容: l l |
| 编写Java代码时尽可能地把资源外置: l l |
| 在 |
| 获取准确可靠的静态文本的译文,包括菜单文字、按钮名称、出错信息和帮助文本,并放入 |
| 确保程序能够根据每个所支持的地区准确地格式化动态文本(比如数字和日期)。确保程序能根据每种所支持的语言正确处理好单词换行、标点和字母排序等。 |
| 必要的话,根据地区设置为图片和布局创建不同版本的资源,并放入 |
| 创建程序所需的其它本地化内容;例如:为每种语言创建必要的录音文件。 |
| 对所支持的每个地区测试应用程序。必要的话,请每个地区的当地人员对程序进行测试并给出反馈意见。 |
| 对设备或仿真器不支持的地区设置进行装载,然后测试默认资源。参阅测试默认资源。 |
| 在横向和纵向两种显示模式下对本地化字符串进行测试。 |
| 对程序进行签名并生成一个或多个最终运行版本文件。 |
| 把一个或多个.apk文件上传到Market,上传时请选择合适的语言。(详情参阅发布应用程序。) |