应用本地化:如何让澳大利亚地区加载美式英语(en-US)并最小改动?
最小改动实现澳大利亚区域强制使用en-US的方案
嘿,这个需求其实很容易搞定,完全不用动你已经创建好的三个strings.xml文件,只需要在应用启动阶段做一点Locale拦截处理就行,改动非常小。
核心思路
我们不需要删除或修改values-en-rAU文件夹里的资源,只需要在应用初始化时,把系统返回的澳大利亚Locale替换成en-US,这样应用就会自动加载values-en-rUS(也就是你说的默认语言)下的资源了。
具体实现步骤
第一步:创建自定义
ContextWrapper拦截Locale
写一个简单的包装类,用来修改Context的Locale获取逻辑:import android.content.Context; import android.content.ContextWrapper; import android.os.Build; import java.util.Locale; public class LocaleContextWrapper extends ContextWrapper { public LocaleContextWrapper(Context base) { super(base); } public static ContextWrapper wrap(Context context) { Locale currentLocale = context.getResources().getConfiguration().locale; // 判断当前是否是澳大利亚的英语Locale if (Locale.forLanguageTag("en-AU").equals(currentLocale)) { // 强制替换为美国英语Locale currentLocale = Locale.US; } // 应用修改后的Locale return updateLocale(context, currentLocale); } private static ContextWrapper updateLocale(Context context, Locale locale) { Locale.setDefault(locale); android.content.res.Configuration config = new android.content.res.Configuration(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { config.setLocale(locale); context = context.createConfigurationContext(config); } else { config.locale = locale; context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics()); } return new LocaleContextWrapper(context); } }第二步:在Application类中替换Context
如果你的应用已经有自定义的Application类,直接在attachBaseContext方法里调用上面的包装方法;如果没有,就新建一个:import android.app.Application; import android.content.Context; public class MyApp extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleContextWrapper.wrap(base)); } }别忘了在
AndroidManifest.xml里把Application的指向改成这个自定义类:<application android:name=".MyApp" <!-- 你的其他原有配置 --> >
为什么这是最小改动?
- 完全保留你已有的三个区域的strings资源,后续如果老板又改主意要恢复澳大利亚的本地化,只需要删掉判断逻辑就行
- 只需要新增1-2个类,代码量极少,不会影响原有业务逻辑
- 逻辑集中,后续调整其他区域的规则也只需要修改
wrap方法里的判断条件
测试小贴士
你可以把手机系统语言切换成澳大利亚英语,然后启动应用,就能看到应用加载的是en-US的内容了,完美符合需求。
内容的提问来源于stack exchange,提问作者sagar suri




