在应用程序中更改和设置默认语言环境的Android方法。

25
我正在全球化Android应用程序。我必须提供在应用程序内选择不同区域设置的选项。我在我的活动(HomeActivity)中使用以下代码,提供更改语言环境的选项。

我正在进行Android应用程序的全球化工作。我需要在应用程序内提供选择不同语言环境的选项。我在我的活动(HomeActivity)中使用以下代码,提供更改语言环境的选项。

Configuration config = new Configuration();
config.locale = selectedLocale; // set accordingly 
// eg. if Hindi then selectedLocale = new Locale("hi");
Locale.setDefault(selectedLocale); // has no effect
Resources res = getApplicationContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());

只要没有配置更改,例如屏幕旋转,此方法就能正常工作,其中区域设置默认为 Android 系统级别的区域设置,而不是代码设置的区域设置。

Locale.setDefault(selectedLocale);
我想到的一个解决办法是使用SharedPreferences持久化用户选择的语言环境,并在每个活动的onCreate()方法中将语言环境设置为持久化后的值,因为每次配置更改都会调用onCreate()方法。是否有更好的方法可以避免在每个活动中进行操作呢?
基本上,我想要的是:一旦在我的HomeActivity中更改/设置某种语言环境,我希望应用程序中的所有活动都使用该语言环境,而不考虑任何配置更改......直到从提供更改语言环境选项的应用程序的HomeActivity更改为其他语言环境为止。

解决方案可以在通过编程方式设置区域设置中找到。 - user905686
1个回答

29

虽然此回答中提到的解决方案在一般情况下有效,但我发现自己需要添加到偏好设置屏幕:

 <activity android:name="com.example.UserPreferences"
     android:screenOrientation="landscape"
     android:configChanges="orientation|keyboardHidden|screenSize">
 </activity>

这是因为当应用程序处于横屏模式且首选项屏幕处于竖屏模式时,更改语言环境并返回应用程序可能会出现问题。将两者都设置为横屏模式可以防止这种情况发生。

通用解决方案

您需要在应用程序级别更改语言环境,以便其影响到各个地方。

public class MyApplication extends Application
{
  @Override
  public void onCreate()
  {
    updateLanguage(this);
    super.onCreate();
  }

  public static void updateLanguage(Context ctx)
  {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
    String lang = prefs.getString("locale_override", "");
    updateLanguage(ctx, lang);
  }

  public static void updateLanguage(Context ctx, String lang)
  {
    Configuration cfg = new Configuration();
    if (!TextUtils.isEmpty(lang))
      cfg.locale = new Locale(lang);
    else
      cfg.locale = Locale.getDefault();

    ctx.getResources().updateConfiguration(cfg, null);
  }
}

那么在你的清单文件中,你需要编写:

<application android:name="com.example.MyApplication" ...>
  ...
</application>

如果我使用英语,我会这样调用 updateLanguage(this, "en");,对吗?或者尝试使用 updateLanguage(this, Locale.US.getDisplayLanguage());,但对我没有起作用。 - Huy Tower
"locale_override" 字符串应该被替换为你的偏好指向的语言的任何键。 - Mikaël Mayer
这是一个不错的解决方案。但不幸的是,只有在我调试时运行Android 4.4.2的Galaxy S4上才有效。在正常运行时,它不会改变语言,但会在LogCat中产生大量额外的输出。解决方案是在我的主活动的onCreate方法中调用静态方法updateLanguage(ctx),而不是在应用程序的onCreate中调用。但在这种情况下,我不需要派生Application类。 - infero
2
请注意,updateConfiguration()已被弃用。在以编程方式设置语言环境中提供了替代方案。 - user905686
有没有理由将 updateConfiguration() 定义为 static?@MikaëlMayer - Saleh
我在这里没有看到任何updateConfiguration的定义。如果你说的是“updateLanguage”,我将updateLanguage定义为静态的唯一原因是它不依赖于类本身,所以没有理由将其作为一个“方法”附加到类上。如果上下文或语言是类的成员,情况就会有所不同。 - Mikaël Mayer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接