安卓开发语言国际化

安卓开发工具自带语言国际化的一整套方案,对于安卓开发同学来说,做多语言支持是比较方便的。日常开发中需要养成好的习惯,将跟语言相关的资源文件(文案、图片等),都放在配置文件中,不要写死到代码里。
当然,除了安卓代码中设置应用原生文案外,和后端及H5前端的接口也需要支持国际化,一般为在请求参数或header(使用”User-Agent”或增加”Accept-Language”)中增加当前语言配置的请求参数,非安卓端的实现方式这里不多做介绍了。

跟随系统语言方式

使用跟随系统语言的方案时,只需要安卓开发中,将需要支持多语言的文案、图片,用各种语言翻译了放置到相应的目录下即可。

1
2
3
4
5
-res
└--drawable-xxhdpi
└--drawable-zh-xxhdpi
└--values
└--values-zh

例如,应用的默认语言为英文,需同时支持中文和英文,则需要将带文案的图标和string.xml内的文本翻译出来,并放到对应的中文目录下。

应用内语言切换

日常会有很多这样的需求,应用的语言默认跟随系统语言显示,但用户可以在应用内手动设置使用某种语言。应用内切换语言,除了配置上述的各种语言目录外,还需要记录当前配置到SharedPreferences中,并设置各个页面的Context的Resources-Configuration。

获取/保存当前的语言设置

根据需求,将需要支持的各种语言定义为对应的常量,并和系统Local、res目录对应起来。比如,定义常量”zh”表示中文,对应于Locale.CHINA和values-zh资源目录。
用户设置语言时,将对应语言的常量保存到SharedPreferences中。
获取语言设置时,从SharedPreferences中获取保存的配置,如果之前未保存,则使用当前系统的语言。

1
2
3
4
5
6
7
8
9
10
public String getLanguage() {
String lan = DataManager.getPreferencesHelper().getLanguage(null);
if (lan == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
lan = Locale.getDefault().toLanguageTag();
} else {
lan = Locale.getDefault().getLanguage();
} }
return lan;
}

获取到语言对应的Local:

1
2
3
4
5
6
7
public Locale getLocale() {
if (LANGUAGE_CN.equals(getLanguage())) {
return Locale.CHINA;
} else {
return Locale.ENGLISH;
}
}

配置各个页面使用的语言

在应用的Application和Activity基类中,重写attachBaseContext方法,配置要使用的语言。

1
2
3
4
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(AppDataManager.attachBaseContext(newBase));
}

AppDataManager.attachBaseContext方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static Context attachBaseContext(Context context) {
Locale locale = getLocale();
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//7.1.1以上设置语言的方式
configuration.setLocale(locale);
return context.createConfigurationContext(configuration);
} else {
//7.1.1以下设置语言的方式
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}

备注

1.语言设置完成时,需要重启应用,来更新为最新的语言配置。

1
2
3
4
5
6
7
8
public static void restartApp(Context context) {
finishAllActivity(); //关闭应用内自己维护的页面栈内的全部页面
Intent intent = context.getPackageManager().getLaunchIntentForPackage(BuildConfig.APPLICATION_ID);
if (intent != null) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}

2.AndroidManifest.xml中设置的页面Label,对应用内设置的语言不生效,因此应用标题需要在代码中设置。